Skip to content

Commit 7701e45

Browse files
committed
ValueFlowBeforeCondition: Fix wrong value in do-while condition when there is a break in the loop body
1 parent 1b53e3e commit 7701e45

2 files changed

Lines changed: 40 additions & 0 deletions

File tree

lib/valueflow.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,36 @@ static void valueFlowReverse(TokenList *tokenlist,
11261126
continue;
11271127
}
11281128

1129+
// do-while condition, break in the loop body
1130+
{
1131+
const Token *parent = tok2->astParent();
1132+
while (parent && !Token::simpleMatch(parent->previous(), "while ("))
1133+
parent = parent->astParent();
1134+
if (parent && Token::simpleMatch(parent->tokAt(-2), "} while (") && Token::simpleMatch(parent->linkAt(-2)->previous(), "do {")) {
1135+
bool breakBailout = false;
1136+
for (const Token *iftok = parent->linkAt(-2); iftok != parent; iftok = iftok->next()) {
1137+
if (!Token::simpleMatch(iftok, "if ("))
1138+
continue;
1139+
if (!Token::Match(iftok->linkAt(1), ") { break"))
1140+
continue;
1141+
ProgramMemory programMemory;
1142+
programMemory.setIntValue(varid, num);
1143+
if (conditionIsTrue(iftok->next()->astOperand2(), programMemory)) {
1144+
breakBailout = true;
1145+
break;
1146+
}
1147+
}
1148+
if (breakBailout) {
1149+
if (settings->debugwarnings)
1150+
bailout(tokenlist,
1151+
errorLogger,
1152+
tok2,
1153+
"no simplification of " + tok2->str() + " in do-while condition since there is a break in the loop body");
1154+
break;
1155+
}
1156+
}
1157+
}
1158+
11291159
setTokenValue(tok2, val, settings);
11301160
if (val2.condition)
11311161
setTokenValue(tok2,val2, settings);

test/testvalueflow.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,16 @@ class TestValueFlow : public TestFixture {
707707
" if (x == 123) {}\n"
708708
"}";
709709
ASSERT_EQUALS(true, testValueOfX(code, 3U, 123));
710+
711+
// after loop
712+
code = "void f(struct X *x) {\n"
713+
" do {\n"
714+
" if (!x)\n"
715+
" break;\n"
716+
" } while (x->a);\n"
717+
" if (x) {}\n"
718+
"}\n";
719+
ASSERT_EQUALS(false, testValueOfX(code, 5U, 0));
710720
}
711721

712722
void valueFlowBeforeConditionAssignIncDec() { // assignment / increment

0 commit comments

Comments
 (0)