Skip to content

Commit fdd0dae

Browse files
author
Your Name
committed
Handle conditional escape
1 parent 08db304 commit fdd0dae

2 files changed

Lines changed: 36 additions & 0 deletions

File tree

lib/forwardanalyzer.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,11 @@ namespace {
395395
bool structuralUnknown = false;
396396
const bool structuralEscape = isEscapeScope(branch.endBlock, structuralUnknown);
397397
branch.escapeUnknown = !structuralEscape || structuralUnknown;
398+
// The traversal stopped at the escape, so the rest of the scope was not walked; a
399+
// fall-through path could still modify the value there - include the whole scope's
400+
// actions so isModified() sees it.
401+
if (branch.escapeUnknown)
402+
branch.action |= analyzeScope(branch.endBlock);
398403
} else {
399404
// Detect an escape the traversal did not flag (e.g. an unknown noreturn call);
400405
// escapeUnknown reports a possible (unknown) escape.

test/testcondition.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4935,6 +4935,37 @@ class TestCondition : public TestFixture {
49354935
" if (v > 0) {}\n"
49364936
"}\n");
49374937
ASSERT_EQUALS("", errout_str());
4938+
4939+
check("bool f();\n" // a modification after a conditional escape must still be seen
4940+
"int main() {\n"
4941+
" bool datumAdded = false;\n"
4942+
" if (f()) {\n"
4943+
" if (f()) return 1;\n"
4944+
" if (f()) datumAdded = true;\n"
4945+
" }\n"
4946+
" if (datumAdded) {}\n"
4947+
"}\n");
4948+
ASSERT_EQUALS("", errout_str());
4949+
4950+
check("bool f();\n"
4951+
"int main() {\n"
4952+
" bool b = false;\n"
4953+
" if (f()) {\n"
4954+
" if (f()) return 1;\n"
4955+
" b = true;\n"
4956+
" }\n"
4957+
" if (b) {}\n"
4958+
"}\n");
4959+
ASSERT_EQUALS("", errout_str());
4960+
4961+
check("bool f();\n" // the branch always escapes - keep the known value
4962+
"int main() {\n"
4963+
" bool b = false;\n"
4964+
" if (f()) { b = true; return 1; }\n"
4965+
" if (b) {}\n"
4966+
"}\n");
4967+
ASSERT_EQUALS("[test.cpp:5:9]: (style) Condition 'b' is always false [knownConditionTrueFalse]\n",
4968+
errout_str());
49384969
}
49394970

49404971
void alwaysTrueSymbolic()

0 commit comments

Comments
 (0)