value flow: fixed fp when while condition contains variable that is changed in loop body

This commit is contained in:
Daniel Marjamäki 2014-01-11 20:25:49 +01:00
parent 75f9111775
commit 4d045879aa
2 changed files with 34 additions and 0 deletions

View File

@ -141,6 +141,27 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLog
continue;
}
// bailout: while-condition, variable is changed in while loop
for (const Token *tok2 = tok; tok2; tok2 = tok2->previous()) {
if (tok2->str() == ")")
tok2 = tok2->link();
else if (tok2->str() == "(") {
if (Token::Match(tok2->previous(), "for|while (") && Token::Match(tok2->link(), ") {")) {
const Token *start = tok2->link()->next();
const Token *end = start->link();
if (Token::findmatch(start,"++|--| %varid% ++|--|=",end,varid))
varid = 0U;
}
break;
}
}
if (varid == 0U) {
if (settings->debugwarnings)
bailout(tokenlist, errorLogger, tok, "variable " + var->nameToken()->str() + " used in loop ");
continue;
}
// extra logic for unsigned variables 'i>=1' => possible value can also be 0
const ValueFlow::Value val(tok, num);
ValueFlow::Value val2;
if (var && num==1U && Token::Match(tok,"<=|>=")) {

View File

@ -138,6 +138,19 @@ private:
ASSERT_EQUALS(false, testValueOfX(std::string("void setx(int &x);")+code, 2U, 1));
ASSERT_EQUALS(false, testValueOfX(code, 2U, 1));
// while, for, do-while
code = "void f(int x) {\n"
" a = x;\n" // x can be 37
" while (x == 37) {}\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 2U, 37));
code = "void f(int x) {\n"
" a = x;\n" // don't assume that x can be 37
" while (x != 37) { x++; }\n"
"}";
ASSERT_EQUALS(false, testValueOfX(code, 2U, 37));
// bailout: ?:
bailout("void f(int x) {\n"
" y = ((x<0) ? x : ((x==2)?3:4));\n"