Skip to content

Commit 7acbb65

Browse files
authored
Fix 11412: False positive: uninitvar (#4624)
* Dont remove modified variables from dead code * Add test for 11412 * Format
1 parent c150317 commit 7acbb65

4 files changed

Lines changed: 30 additions & 13 deletions

File tree

lib/forwardanalyzer.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -394,24 +394,24 @@ struct ForwardTraversal {
394394
return true;
395395
if (Token::simpleMatch(condTok, ":"))
396396
return true;
397-
bool changed = false;
397+
bool stepChangesCond = false;
398398
if (stepTok) {
399399
std::pair<const Token*, const Token*> exprToks = stepTok->findExpressionStartEndTokens();
400400
if (exprToks.first != nullptr && exprToks.second != nullptr)
401-
changed |= isExpressionChanged(condTok, exprToks.first, exprToks.second->next(), settings, true);
401+
stepChangesCond |= isExpressionChanged(condTok, exprToks.first, exprToks.second->next(), settings, true);
402402
}
403-
changed |= isExpressionChanged(condTok, endBlock->link(), endBlock, settings, true);
403+
const bool bodyChangesCond = isExpressionChanged(condTok, endBlock->link(), endBlock, settings, true);
404404
// Check for mutation in the condition
405-
changed |= nullptr !=
406-
findAstNode(condTok, [&](const Token* tok) {
405+
const bool condChanged =
406+
nullptr != findAstNode(condTok, [&](const Token* tok) {
407407
return isVariableChanged(tok, 0, settings, true);
408408
});
409+
const bool changed = stepChangesCond || bodyChangesCond || condChanged;
409410
if (!changed)
410411
return true;
411412
ForwardTraversal ft = fork(true);
412-
ft.analyzer->assume(condTok, false, Analyzer::Assume::Absolute);
413413
ft.updateScope(endBlock);
414-
return ft.isConditionTrue(condTok);
414+
return ft.isConditionTrue(condTok) && bodyChangesCond;
415415
}
416416

417417
Progress updateInnerLoop(Token* endBlock, Token* stepTok, Token* condTok) {

lib/programmemory.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,8 +461,12 @@ void ProgramMemoryState::assume(const Token* tok, bool b, bool isEmpty)
461461
programMemoryParseCondition(pm, tok, nullptr, settings, b);
462462
const Token* origin = tok;
463463
const Token* top = tok->astTop();
464-
if (top && Token::Match(top->previous(), "for|while ("))
465-
origin = top->link();
464+
if (top && Token::Match(top->previous(), "for|while|if (") && !Token::simpleMatch(tok->astParent(), "?")) {
465+
origin = top->link()->next();
466+
if (!b && origin->link()) {
467+
origin = origin->link();
468+
}
469+
}
466470
replace(pm, origin);
467471
}
468472

lib/valueflow.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2790,11 +2790,13 @@ struct ValueFlowAnalyzer : Analyzer {
27902790
if (Token::simpleMatch(startBlock, ";") && Token::simpleMatch(parent->tokAt(-2), "} while ("))
27912791
startBlock = parent->linkAt(-2);
27922792
const Token* endBlock = startBlock->link();
2793-
pms.removeModifiedVars(endBlock);
2794-
if (state)
2793+
if (state) {
2794+
pms.removeModifiedVars(endBlock);
27952795
pms.addState(endBlock->previous(), getProgramState());
2796-
else if (Token::simpleMatch(endBlock, "} else {"))
2797-
pms.addState(endBlock->linkAt(2)->previous(), getProgramState());
2796+
} else {
2797+
if (Token::simpleMatch(endBlock, "} else {"))
2798+
pms.addState(endBlock->linkAt(2)->previous(), getProgramState());
2799+
}
27982800
}
27992801

28002802
if (!(flags & Assume::Quiet)) {

test/testuninitvar.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5396,6 +5396,17 @@ class TestUninitVar : public TestFixture {
53965396
" return n;\n"
53975397
"}\n");
53985398
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:1]: (warning) Uninitialized variable: i\n", errout.str());
5399+
5400+
// #11412
5401+
valueFlowUninit("void f(int n) {\n"
5402+
" short* p;\n"
5403+
" if (n) {\n"
5404+
" p = g(n);\n"
5405+
" }\n"
5406+
" for (int i = 0; i < n; i++)\n"
5407+
" (void)p[i];\n"
5408+
"}\n");
5409+
ASSERT_EQUALS("", errout.str());
53995410
}
54005411

54015412
void valueFlowUninitBreak() { // Do not show duplicate warnings about the same uninitialized value

0 commit comments

Comments
 (0)