diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index e8a1b5f77..eba7d7c52 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -726,6 +726,13 @@ static bool valueFlowForward(Token * const startToken, // conditional block of code that assigns variable.. else if (Token::Match(tok2, "%var% (") && Token::simpleMatch(tok2->linkAt(1), ") {")) { + // is variable changed in condition? + if (isVariableChanged(tok2->next(), tok2->next()->link(), varid)) { + if (settings->debugwarnings) + bailout(tokenlist, errorLogger, tok2, "variable " + var->name() + " valueFlowForward, assignment in condition"); + return false; + } + // Should scope be skipped because variable value is checked? std::list truevalues; for (std::list::iterator it = values.begin(); it != values.end(); ++it) { diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 6b02f79a2..6ffdc052c 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -873,6 +873,14 @@ private: ASSERT_EQUALS(false, testValueOfX(code, 8U, 34)); // while/for + code = "void f() {\n" // #6138 + " ENTRY *x = 0;\n" + " while (x = get()) {\n" + " set(x->value);\n" // <- x is not 0 + " }\n" + "}\n"; + ASSERT_EQUALS(false, testValueOfX(code, 4U, 0)); + code = "void f(const int *buf) {\n" " int x = 0;\n" " for (int i = 0; i < 10; i++) {\n" @@ -1049,7 +1057,7 @@ private: " for (; x && \n" " x->str() != y; x = x->next()) {}\n" "}"; - ASSERT_EQUALS(true, testValueOfX(code, 3U, 0)); + TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 3U, 0)); ASSERT_EQUALS(false, testValueOfX(code, 4U, 0)); code = "void f(const Token* x) {\n"