Fix 11412: False positive: uninitvar (#4624)
* Dont remove modified variables from dead code * Add test for 11412 * Format
This commit is contained in:
parent
c150317f02
commit
7acbb656f3
|
@ -394,24 +394,24 @@ struct ForwardTraversal {
|
|||
return true;
|
||||
if (Token::simpleMatch(condTok, ":"))
|
||||
return true;
|
||||
bool changed = false;
|
||||
bool stepChangesCond = false;
|
||||
if (stepTok) {
|
||||
std::pair<const Token*, const Token*> exprToks = stepTok->findExpressionStartEndTokens();
|
||||
if (exprToks.first != nullptr && exprToks.second != nullptr)
|
||||
changed |= isExpressionChanged(condTok, exprToks.first, exprToks.second->next(), settings, true);
|
||||
stepChangesCond |= isExpressionChanged(condTok, exprToks.first, exprToks.second->next(), settings, true);
|
||||
}
|
||||
changed |= isExpressionChanged(condTok, endBlock->link(), endBlock, settings, true);
|
||||
const bool bodyChangesCond = isExpressionChanged(condTok, endBlock->link(), endBlock, settings, true);
|
||||
// Check for mutation in the condition
|
||||
changed |= nullptr !=
|
||||
findAstNode(condTok, [&](const Token* tok) {
|
||||
const bool condChanged =
|
||||
nullptr != findAstNode(condTok, [&](const Token* tok) {
|
||||
return isVariableChanged(tok, 0, settings, true);
|
||||
});
|
||||
const bool changed = stepChangesCond || bodyChangesCond || condChanged;
|
||||
if (!changed)
|
||||
return true;
|
||||
ForwardTraversal ft = fork(true);
|
||||
ft.analyzer->assume(condTok, false, Analyzer::Assume::Absolute);
|
||||
ft.updateScope(endBlock);
|
||||
return ft.isConditionTrue(condTok);
|
||||
return ft.isConditionTrue(condTok) && bodyChangesCond;
|
||||
}
|
||||
|
||||
Progress updateInnerLoop(Token* endBlock, Token* stepTok, Token* condTok) {
|
||||
|
|
|
@ -461,8 +461,12 @@ void ProgramMemoryState::assume(const Token* tok, bool b, bool isEmpty)
|
|||
programMemoryParseCondition(pm, tok, nullptr, settings, b);
|
||||
const Token* origin = tok;
|
||||
const Token* top = tok->astTop();
|
||||
if (top && Token::Match(top->previous(), "for|while ("))
|
||||
origin = top->link();
|
||||
if (top && Token::Match(top->previous(), "for|while|if (") && !Token::simpleMatch(tok->astParent(), "?")) {
|
||||
origin = top->link()->next();
|
||||
if (!b && origin->link()) {
|
||||
origin = origin->link();
|
||||
}
|
||||
}
|
||||
replace(pm, origin);
|
||||
}
|
||||
|
||||
|
|
|
@ -2790,12 +2790,14 @@ struct ValueFlowAnalyzer : Analyzer {
|
|||
if (Token::simpleMatch(startBlock, ";") && Token::simpleMatch(parent->tokAt(-2), "} while ("))
|
||||
startBlock = parent->linkAt(-2);
|
||||
const Token* endBlock = startBlock->link();
|
||||
if (state) {
|
||||
pms.removeModifiedVars(endBlock);
|
||||
if (state)
|
||||
pms.addState(endBlock->previous(), getProgramState());
|
||||
else if (Token::simpleMatch(endBlock, "} else {"))
|
||||
} else {
|
||||
if (Token::simpleMatch(endBlock, "} else {"))
|
||||
pms.addState(endBlock->linkAt(2)->previous(), getProgramState());
|
||||
}
|
||||
}
|
||||
|
||||
if (!(flags & Assume::Quiet)) {
|
||||
if (flags & Assume::ContainerEmpty) {
|
||||
|
|
|
@ -5396,6 +5396,17 @@ private:
|
|||
" return n;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:1]: (warning) Uninitialized variable: i\n", errout.str());
|
||||
|
||||
// #11412
|
||||
valueFlowUninit("void f(int n) {\n"
|
||||
" short* p;\n"
|
||||
" if (n) {\n"
|
||||
" p = g(n);\n"
|
||||
" }\n"
|
||||
" for (int i = 0; i < n; i++)\n"
|
||||
" (void)p[i];\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void valueFlowUninitBreak() { // Do not show duplicate warnings about the same uninitialized value
|
||||
|
|
Loading…
Reference in New Issue