diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index da40345db..4ec4a651f 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1146,13 +1146,16 @@ static bool valueFlowForward(Token * const startToken, } } + const Token * const condTok = tok2->next()->astOperand2(); + const bool condAlwaysTrue = (condTok && condTok->values.size() == 1U && condTok->values.front().isKnown() && condTok->values.front().intvalue != 0); + // Should scope be skipped because variable value is checked? std::list truevalues; for (std::list::const_iterator it = values.begin(); it != values.end(); ++it) { - if (!conditionIsFalse(tok2->next()->astOperand2(), getProgramMemory(tok2, varid, *it))) + if (condAlwaysTrue || !conditionIsFalse(condTok, getProgramMemory(tok2, varid, *it))) truevalues.push_back(*it); } - if (truevalues.size() != values.size()) { + if (truevalues.size() != values.size() || condAlwaysTrue) { // '{' Token * const startToken1 = tok2->linkAt(1)->next(); @@ -1171,6 +1174,10 @@ static bool valueFlowForward(Token * const startToken, // goto '}' tok2 = startToken1->link(); + + if (condAlwaysTrue && isReturn(tok2)) + return false; + continue; } diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 86e2d8061..03c0779e0 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -829,11 +829,18 @@ private: code = "void f() {\n" " X *x = getx();\n" - " if(false) { x = 0; }\n" + " if(0) { x = 0; }\n" " else { x->y = 1; }\n" "}"; ASSERT_EQUALS(false, testValueOfX(code, 4U, 0)); + code = "void f() {\n" // #6239 + " int x = 4;\n" + " if(1) { x = 0; }\n" + " a = x;\n" + "}"; + ASSERT_EQUALS(false, testValueOfX(code, 4U, 4)); + code = "void f() {\n" " int x = 32;\n" " if (x>=32) return;\n"