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;
|
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);
|
setTokenValue(tok2, val, settings);
|
||||||
if (val2.condition)
|
if (val2.condition)
|
||||||
setTokenValue(tok2,val2, settings);
|
setTokenValue(tok2,val2, settings);
|
||||||
|
|
|
@ -707,6 +707,16 @@ private:
|
||||||
" if (x == 123) {}\n"
|
" if (x == 123) {}\n"
|
||||||
"}";
|
"}";
|
||||||
ASSERT_EQUALS(true, testValueOfX(code, 3U, 123));
|
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
|
void valueFlowBeforeConditionAssignIncDec() { // assignment / increment
|
||||||
|
|
Loading…
Reference in New Issue