diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 753a5c846..37d1a3337 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -507,18 +507,16 @@ void execute(const Token *expr, else { bool error2 = false; execute(expr->astOperand2(), programMemory, result, &error2); - if (error1 && error2) + if (error1 || error2) *error = true; - if (error2) - *result = 1; - else - *result = !!*result; } } else if (expr->str() == "||") { execute(expr->astOperand1(), programMemory, result, error); - if (*result == 0 && *error == false) + if (*result == 1 && *error == false) + *result = 1; + else if (*result == 0 && *error == false) execute(expr->astOperand2(), programMemory, result, error); } diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 760af450a..7063f2a38 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -140,6 +140,7 @@ private: TEST_CASE(valueFlowCrashConstructorInitialization); TEST_CASE(valueFlowUnknownMixedOperators); + TEST_CASE(valueFlowIdempotent); } static bool isNotTokValue(const ValueFlow::Value &val) { @@ -5014,6 +5015,42 @@ private: ASSERT_EQUALS(false, testValueOfXKnown(code, 4U, 1)); } + + void valueFlowIdempotent() { + const char *code; + + code = "void f(bool a, bool b) {\n" + " bool x = true;\n" + " if (a)\n" + " x = x && b;\n" + " bool result = x;\n" + "}\n"; + ASSERT_EQUALS(false, testValueOfXKnown(code, 5U, 1)); + + code = "void f(bool a, bool b) {\n" + " bool x = false;\n" + " if (a)\n" + " x = x && b;\n" + " bool result = x;\n" + "}\n"; + ASSERT_EQUALS(true, testValueOfXKnown(code, 5U, 0)); + + code = "void f(bool a, bool b) {\n" + " bool x = true;\n" + " if (a)\n" + " x = x || b;\n" + " bool result = x;\n" + "}\n"; + ASSERT_EQUALS(true, testValueOfXKnown(code, 5U, 1)); + + code = "void f(bool a, bool b) {\n" + " bool x = false;\n" + " if (a)\n" + " x = x || b;\n" + " bool result = x;\n" + "}\n"; + ASSERT_EQUALS(false, testValueOfXKnown(code, 5U, 0)); + } }; REGISTER_TEST(TestValueFlow)