value flow: fixed fp when while condition contains variable that is changed in loop body
This commit is contained in:
parent
75f9111775
commit
4d045879aa
|
@ -141,6 +141,27 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLog
|
||||||
continue;
|
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);
|
const ValueFlow::Value val(tok, num);
|
||||||
ValueFlow::Value val2;
|
ValueFlow::Value val2;
|
||||||
if (var && num==1U && Token::Match(tok,"<=|>=")) {
|
if (var && num==1U && Token::Match(tok,"<=|>=")) {
|
||||||
|
|
|
@ -138,6 +138,19 @@ private:
|
||||||
ASSERT_EQUALS(false, testValueOfX(std::string("void setx(int &x);")+code, 2U, 1));
|
ASSERT_EQUALS(false, testValueOfX(std::string("void setx(int &x);")+code, 2U, 1));
|
||||||
ASSERT_EQUALS(false, testValueOfX(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: ?:
|
||||||
bailout("void f(int x) {\n"
|
bailout("void f(int x) {\n"
|
||||||
" y = ((x<0) ? x : ((x==2)?3:4));\n"
|
" y = ((x<0) ? x : ((x==2)?3:4));\n"
|
||||||
|
|
Loading…
Reference in New Issue