diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index cec306160..5d91f35e3 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4424,6 +4424,31 @@ struct ValueFlowConditionHandler { } } + { + const Token *tok2 = tok; + std::string op; + bool mixedOperators = false; + while (tok2->astParent()) { + const Token *parent = tok2->astParent(); + if (Token::Match(parent, "%oror%|&&")) { + if (op.empty()) { + op = parent->str() == "&&" ? "&&" : "||"; + } else if (op != parent->str()) { + mixedOperators = true; + break; + } + } + if (parent->str()=="!") { + op = (op == "&&" ? "||" : "&&"); + } + tok2 = parent; + } + + if (mixedOperators) { + continue; + } + } + if (top && Token::Match(top->previous(), "if|while (") && !top->previous()->isExpandedMacro()) { // does condition reassign variable? if (tok != top->astOperand2() && Token::Match(top->astOperand2(), "%oror%|&&") && diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 4ed668e14..215d6f8bc 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -138,6 +138,8 @@ private: TEST_CASE(valueFlowCrash); TEST_CASE(valueFlowHang); TEST_CASE(valueFlowCrashConstructorInitialization); + + TEST_CASE(valueFlowUnknownMixedOperators); } static bool isNotTokValue(const ValueFlow::Value &val) { @@ -4827,6 +4829,20 @@ private: "}"; valueOfTok(code, "path"); } + + void valueFlowUnknownMixedOperators() { + const char *code= "int f(int a, int b, bool x) {\n" + " if (a == 1 && (!(b == 2 && x))) {\n" + " } else {\n" + " if (x) {\n" + " }\n" + " }\n" + "\n" + " return 0;\n" + "}" ; + + ASSERT_EQUALS(false, testValueOfXKnown(code, 4U, 1)); + } }; REGISTER_TEST(TestValueFlow)