diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index a59d2eb59..047559feb 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1089,6 +1089,13 @@ static bool valueFlowForward(Token * const startToken, const Token *end = start->link(); if (Token::simpleMatch(end, "} while (")) end = end->linkAt(2); + + if (isVariableChanged(start, end, varid)) { + if (settings->debugwarnings) + bailout(tokenlist, errorLogger, tok2, "variable " + var->name() + " valueFlowForward, assignment in do-while"); + return false; + } + handleKnownValuesInLoop(start, end, &values, varid); } diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index d91067bbb..66e12759b 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -1065,6 +1065,15 @@ private: "}"; ASSERT_EQUALS(false, testValueOfX(code, 3U, 87)); + code = "void f() {\n" + " int first=-1, x=0;\n" + " do {\n" + " if (first >= 0) { a = x; }\n" // <- x is not 0 + " first++; x=3;\n" + " } while (1);\n" + "}"; + ASSERT_EQUALS(false, testValueOfX(code, 4U, 0)); + // pointer/reference to x code = "int f(void) {\n" " int x = 2;\n" @@ -1709,14 +1718,11 @@ private: bool isNotKnownValues(const char code[], const char str[]) { const std::list values = tokenValues(code, str); - bool possible = false; for (std::list::const_iterator it = values.begin(); it != values.end(); ++it) { if (it->isKnown()) return false; - if (it->isPossible()) - possible = true; } - return possible; + return true; } void knownValue() { @@ -1831,16 +1837,6 @@ private: ASSERT_EQUALS(1, value.intvalue); ASSERT(value.isPossible()); - code = "void f() {\n" - " int x = 0;\n" - " do {\n" - " if (!x) { x = y; }\n" // <- possible value - " } while (count < 10);\n" - "}"; - value = valueOfTok(code, "!"); - ASSERT_EQUALS(1, value.intvalue); - ASSERT(value.isPossible()); - code = "void f() {\n" " int x = 0;\n" "a:\n"