diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 5b8b4c222..51072e8a4 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4578,6 +4578,17 @@ static ValueFlow::Value makeSymbolic(const Token* tok, MathLib::bigint delta = 0 return value; } +static std::set getVarIds(const Token* tok) +{ + std::set result; + visitAstNodes(tok, [&](const Token* child) { + if (child->varId() > 0) + result.insert(child->varId()); + return ChildrenToVisit::op1_and_op2; + }); + return result; +} + static void valueFlowSymbolic(TokenList* tokenlist, SymbolDatabase* symboldatabase) { for (const Scope* scope : symboldatabase->functionScopes) { @@ -4607,8 +4618,11 @@ static void valueFlowSymbolic(TokenList* tokenlist, SymbolDatabase* symboldataba } else if (isDifferentType(tok->astOperand2(), tok->astOperand1())) { continue; } + const std::set rhsVarIds = getVarIds(tok->astOperand2()); const std::vector vars = getLHSVariables(tok); - if (std::any_of(vars.begin(), vars.end(), [](const Variable* var) { + if (std::any_of(vars.begin(), vars.end(), [&](const Variable* var) { + if (rhsVarIds.count(var->declarationId()) > 0) + return true; if (var->isLocal()) return var->isStatic(); return !var->isArgument(); diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 50fde0d5a..f9b87b979 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -3937,6 +3937,17 @@ private: " }\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + // #10649 + check("void foo(struct diag_msg *msg) {\n" + " msg = msg->next;\n" + " if (msg == NULL)\n" + " return CMD_OK;\n" + " msg = msg->next;\n" + " if (msg == NULL)\n" + " return CMD_OK;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void alwaysTrueInfer() { diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index b47462509..07c001928 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -2092,7 +2092,8 @@ private: " if (!y) {}\n" " }\n" "}\n"); - ASSERT_EQUALS( + TODO_ASSERT_EQUALS( + "", "[test.cpp:13] -> [test.cpp:9]: (warning) Either the condition '!y' is redundant or there is possible null pointer dereference: x->g().\n", errout.str()); }