ValueFlowBeforeCondition: Fix wrong value in do-while condition when there is a break in the loop body
This commit is contained in:
parent
1b53e3ec1d
commit
7701e4594a
|
@ -1126,6 +1126,36 @@ static void valueFlowReverse(TokenList *tokenlist,
|
|||
continue;
|
||||
}
|
||||
|
||||
// do-while condition, break in the loop body
|
||||
{
|
||||
const Token *parent = tok2->astParent();
|
||||
while (parent && !Token::simpleMatch(parent->previous(), "while ("))
|
||||
parent = parent->astParent();
|
||||
if (parent && Token::simpleMatch(parent->tokAt(-2), "} while (") && Token::simpleMatch(parent->linkAt(-2)->previous(), "do {")) {
|
||||
bool breakBailout = false;
|
||||
for (const Token *iftok = parent->linkAt(-2); iftok != parent; iftok = iftok->next()) {
|
||||
if (!Token::simpleMatch(iftok, "if ("))
|
||||
continue;
|
||||
if (!Token::Match(iftok->linkAt(1), ") { break"))
|
||||
continue;
|
||||
ProgramMemory programMemory;
|
||||
programMemory.setIntValue(varid, num);
|
||||
if (conditionIsTrue(iftok->next()->astOperand2(), programMemory)) {
|
||||
breakBailout = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (breakBailout) {
|
||||
if (settings->debugwarnings)
|
||||
bailout(tokenlist,
|
||||
errorLogger,
|
||||
tok2,
|
||||
"no simplification of " + tok2->str() + " in do-while condition since there is a break in the loop body");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setTokenValue(tok2, val, settings);
|
||||
if (val2.condition)
|
||||
setTokenValue(tok2,val2, settings);
|
||||
|
|
|
@ -707,6 +707,16 @@ private:
|
|||
" if (x == 123) {}\n"
|
||||
"}";
|
||||
ASSERT_EQUALS(true, testValueOfX(code, 3U, 123));
|
||||
|
||||
// after loop
|
||||
code = "void f(struct X *x) {\n"
|
||||
" do {\n"
|
||||
" if (!x)\n"
|
||||
" break;\n"
|
||||
" } while (x->a);\n"
|
||||
" if (x) {}\n"
|
||||
"}\n";
|
||||
ASSERT_EQUALS(false, testValueOfX(code, 5U, 0));
|
||||
}
|
||||
|
||||
void valueFlowBeforeConditionAssignIncDec() { // assignment / increment
|
||||
|
|
Loading…
Reference in New Issue