diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index ea05eef37..309fb5f39 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1908,25 +1908,22 @@ static void valueFlowAST(Token *tok, nonneg int varid, const ValueFlow::Value &v } /** if known variable is changed in loop body, change it to a possible value */ -static void handleKnownValuesInLoop(const Token *startToken, +static bool handleKnownValuesInLoop(const Token *startToken, const Token *endToken, std::list *values, nonneg int varid, bool globalvar, const Settings *settings) { - bool isChanged = false; + const bool isChanged = isVariableChanged(startToken, endToken, varid, globalvar, settings, true); + if (!isChanged) + return false; for (std::list::iterator it = values->begin(); it != values->end(); ++it) { if (it->isKnown()) { - if (!isChanged) { - if (!isVariableChanged(startToken, endToken, varid, globalvar, settings, true)) - break; - isChanged = true; - } - it->setPossible(); } } + return isChanged; } static bool evalAssignment(ValueFlow::Value &lhsValue, const std::string &assign, const ValueFlow::Value &rhsValue) @@ -2113,8 +2110,10 @@ static bool valueFlowForward(Token * const startToken, } // if known variable is changed in loop body, change it to a possible value.. - if (Token::Match(tok2, "for|while")) - handleKnownValuesInLoop(tok2, tok2->linkAt(1)->linkAt(1), &values, varid, var->isGlobal(), settings); + if (Token::Match(tok2, "for|while")) { + if (handleKnownValuesInLoop(tok2, tok2->linkAt(1)->linkAt(1), &values, varid, var->isGlobal(), settings)) + number_of_if++; + } // Set values in condition for (Token* tok3 = tok2->tokAt(2); tok3 != tok2->next()->link(); tok3 = tok3->next()) { diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 940aa116e..bba2e27fd 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -1912,6 +1912,21 @@ private: "}\n"; ASSERT_EQUALS(true, testValueOfX(code, 9U, 0)); // x can be 0 at line 9 + code = "void f(const int *buf) {\n" + " int x = 111;\n" + " bool found = false;\n" + " for (int i = 0; i < 10; i++) {\n" + " if (buf[i] == 123) {\n" + " x = i;\n" + " found = true;\n" + " break;\n" + " }\n" + " }\n" + " if (found)\n" + " a = x;\n" // <- x can't be 111 + "}\n"; + ASSERT_EQUALS(false, testValueOfX(code, 12U, 111)); // x can not be 111 at line 9 + code = "void f(const int *buf) {\n" " int x = 0;\n" " for (int i = 0; i < 10; i++) {\n"