diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index a3fb9d6db..05ae576db 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -641,6 +641,7 @@ static bool valueFlowForward(Token * const startToken, unsigned int number_of_if = 0; int varusagelevel = -1; bool returnStatement = false; // current statement is a return, stop analysis at the ";" + bool read = false; // is variable value read? for (Token *tok2 = startToken; tok2 && tok2 != endToken; tok2 = tok2->next()) { if (indentlevel >= 0 && tok2->str() == "{") @@ -692,6 +693,9 @@ static bool valueFlowForward(Token * const startToken, bool varusage = (indentlevel >= 0 && constValue && number_of_if == 0U) ? isVariableChanged(start,end,varid) : (nullptr != Token::findmatch(start, "%varid%", end, varid)); + if (!read) { + read = bool(nullptr != Token::findmatch(tok2, "%varid% !!=", end, varid)); + } if (varusage) { varusagelevel = indentlevel; @@ -699,7 +703,7 @@ static bool valueFlowForward(Token * const startToken, return false; // TODO: don't check noreturn scopes - if (number_of_if > 0U || Token::findmatch(tok2, "%varid%", start, varid)) { + if (read && (number_of_if > 0U || Token::findmatch(tok2, "%varid%", start, varid))) { if (settings->debugwarnings) bailout(tokenlist, errorLogger, tok2, "variable " + var->nameToken()->str() + " is assigned in conditional code"); return false; @@ -731,7 +735,7 @@ static bool valueFlowForward(Token * const startToken, } if (isVariableChanged(start, end, varid)) { - if (number_of_if == 0 && + if ((!read || number_of_if == 0) && Token::simpleMatch(tok2, "if (") && !(Token::simpleMatch(end, "} else {") && (Token::findmatch(end, "%varid%", end->linkAt(2), varid) || diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 63bdb964f..253499f97 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -678,9 +678,9 @@ private: " int x = 123;\n" " if (condition1) x = 456;\n" " if (condition2) x = 789;\n" - " a = 2 + x;\n" + " a = 2 + x;\n" // <- either assignment "x=123" is redundant or x can be 123 here. "}"; - ASSERT_EQUALS(false, testValueOfX(code, 4U, 123)); + ASSERT_EQUALS(true, testValueOfX(code, 5U, 123)); code = "void f(int a) {\n" " int x = 123;\n"