diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index b9dd9430e..06316b368 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -153,6 +153,11 @@ static std::map getProgramMemory(const Token *tok if (vartok->varId() != 0U && programMemory.find(vartok->varId()) == programMemory.end()) 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 (indentlevel <= 0) break; @@ -658,8 +663,24 @@ static bool valueFlowForward(Token * const startToken, for (Token *tok2 = startToken; tok2 && tok2 != endToken; tok2 = tok2->next()) { if (indentlevel >= 0 && tok2->str() == "{") ++indentlevel; - else if (indentlevel >= 0 && tok2->str() == "}") + else if (indentlevel >= 0 && tok2->str() == "}") { --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::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 (")) tok2 = tok2->linkAt(1); diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index ac5406503..db46b1d1c 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -998,8 +998,8 @@ private: TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 3U, 0)); ASSERT_EQUALS(false, testValueOfX(code, 4U, 0)); - // stop at return - code = "void f(int x) {\n" + // return + code = "void f(int x) {\n" // #6024 " if (x == 5) {\n" " if (z) return; else return;\n" " }\n" @@ -1007,6 +1007,15 @@ private: "}"; 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 code = "void f(float x) {\n" " if (x == 0.5) {}\n"