Skip to content

Commit a055544

Browse files
pfultz2Your Name
andauthored
Fix 14895: FP knownConditionTrueFalse: regression related to ' Partial fix for 9049: False negative: uninitialized variable with nested ifs (#8680)' (#8701)
Co-authored-by: Your Name <you@example.com>
1 parent 592e7b7 commit a055544

2 files changed

Lines changed: 37 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/testvalueflow.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3214,6 +3214,38 @@ class TestValueFlow : public TestFixture {
32143214
" return x;\n"
32153215
"}\n";
32163216
ASSERT_EQUALS(true, testValueOfXKnown(code, 3U, 0));
3217+
3218+
code = "bool f();\n" // a modification after a conditional escape must still be seen
3219+
"void g() {\n"
3220+
" bool x = false;\n"
3221+
" if (f()) {\n"
3222+
" if (f()) return;\n"
3223+
" if (f()) x = true;\n"
3224+
" }\n"
3225+
" if (x) {}\n"
3226+
"}\n";
3227+
ASSERT_EQUALS(true, testValueOfX(code, 8U, 0));
3228+
ASSERT_EQUALS(false, testValueOfXKnown(code, 8U, 0));
3229+
3230+
code = "bool f();\n"
3231+
"void g() {\n"
3232+
" bool x = false;\n"
3233+
" if (f()) {\n"
3234+
" if (f()) return;\n"
3235+
" x = true;\n"
3236+
" }\n"
3237+
" if (x) {}\n"
3238+
"}\n";
3239+
ASSERT_EQUALS(true, testValueOfX(code, 8U, 0));
3240+
ASSERT_EQUALS(false, testValueOfXKnown(code, 8U, 0));
3241+
3242+
code = "bool f();\n" // the branch always escapes - keep the known value
3243+
"void g() {\n"
3244+
" bool x = false;\n"
3245+
" if (f()) { x = true; return; }\n"
3246+
" if (x) {}\n"
3247+
"}\n";
3248+
ASSERT_EQUALS(true, testValueOfXKnown(code, 5U, 0));
32173249
}
32183250

32193251
void valueFlowAfterSwap()

0 commit comments

Comments
 (0)