Fixed #6086 (False positive: valueFlow, conditional code returns)

This commit is contained in:
Daniel Marjamäki 2014-08-27 16:59:18 +02:00
parent c242faf45e
commit ae8a20b197
2 changed files with 33 additions and 3 deletions

View File

@ -153,6 +153,11 @@ static std::map<unsigned int, MathLib::bigint> getProgramMemory(const Token *tok
if (vartok->varId() != 0U && programMemory.find(vartok->varId()) == programMemory.end()) if (vartok->varId() != 0U && programMemory.find(vartok->varId()) == programMemory.end())
programMemory[vartok->varId()] = MathLib::toLongNumber(numtok->str()); programMemory[vartok->varId()] = MathLib::toLongNumber(numtok->str());
} }
if (Token::Match(tok2, "[;{}] %varid% = %var% ;", varid)) {
const Token *vartok = tok2->tokAt(3);
if (vartok->varId() != 0U)
programMemory[vartok->varId()] = value.intvalue;
}
if (tok2->str() == "{") { if (tok2->str() == "{") {
if (indentlevel <= 0) if (indentlevel <= 0)
break; break;
@ -658,8 +663,24 @@ static bool valueFlowForward(Token * const startToken,
for (Token *tok2 = startToken; tok2 && tok2 != endToken; tok2 = tok2->next()) { for (Token *tok2 = startToken; tok2 && tok2 != endToken; tok2 = tok2->next()) {
if (indentlevel >= 0 && tok2->str() == "{") if (indentlevel >= 0 && tok2->str() == "{")
++indentlevel; ++indentlevel;
else if (indentlevel >= 0 && tok2->str() == "}") else if (indentlevel >= 0 && tok2->str() == "}") {
--indentlevel; --indentlevel;
if (indentlevel == 0 && isReturn(tok2) && Token::simpleMatch(tok2->link()->previous(), ") {")) {
const Token *condition = tok2->link()->linkAt(-1)->astOperand2();
bool bailoutflag = false;
for (std::list<ValueFlow::Value>::const_iterator it = values.begin(); it != values.end(); ++it) {
if (conditionIsTrue(condition, getProgramMemory(condition->astParent(), varid, *it))) {
bailoutflag = true;
break;
}
}
if (bailoutflag) {
if (settings->debugwarnings)
bailout(tokenlist, errorLogger, tok2, "variable " + var->name() + " valueFlowForward, conditional return is assumed to be executed");
return false;
}
}
}
if (Token::Match(tok2, "sizeof|typeof|typeid (")) if (Token::Match(tok2, "sizeof|typeof|typeid ("))
tok2 = tok2->linkAt(1); tok2 = tok2->linkAt(1);

View File

@ -998,8 +998,8 @@ private:
TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 3U, 0)); TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 3U, 0));
ASSERT_EQUALS(false, testValueOfX(code, 4U, 0)); ASSERT_EQUALS(false, testValueOfX(code, 4U, 0));
// stop at return // return
code = "void f(int x) {\n" code = "void f(int x) {\n" // #6024
" if (x == 5) {\n" " if (x == 5) {\n"
" if (z) return; else return;\n" " if (z) return; else return;\n"
" }\n" " }\n"
@ -1007,6 +1007,15 @@ private:
"}"; "}";
ASSERT_EQUALS(false, testValueOfX(code, 5U, 5)); ASSERT_EQUALS(false, testValueOfX(code, 5U, 5));
code = "void f(int x1) {\n" // #6086
" int x = x1;\n"
" if (x1 >= 3) {\n"
" return;\n"
" }\n"
" a = x;\n"
"}";
ASSERT_EQUALS(false, testValueOfX(code, 6U, 3));
// TODO: float // TODO: float
code = "void f(float x) {\n" code = "void f(float x) {\n"
" if (x == 0.5) {}\n" " if (x == 0.5) {}\n"