diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 2d50e32b6..762b7dfce 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -3749,12 +3749,16 @@ struct ValueFlowConditionHandler { // if astParent is "!" we need to invert codeblock { - const Token *parent = tok->astParent(); - while (parent && parent->str() == "&&") - parent = parent->astParent(); - if (parent && (parent->str() == "!" || Token::simpleMatch(parent, "== false"))) { - check_if = !check_if; - check_else = !check_else; + const Token *tok2 = tok; + while(tok2->astParent()){ + const Token *parent = tok2->astParent(); + while (parent && parent->str() == "&&") + parent = parent->astParent(); + if (parent && (parent->str() == "!" || Token::simpleMatch(parent, "== false"))) { + check_if = !check_if; + check_else = !check_else; + } + tok2 = parent; } } diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 55f0cc68b..d87685e0f 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -81,6 +81,7 @@ private: TEST_CASE(valueFlowAfterAssign); TEST_CASE(valueFlowAfterCondition); + TEST_CASE(valueFlowAfterConditionSeveralNot); TEST_CASE(valueFlowForwardCompoundAssign); TEST_CASE(valueFlowForwardCorrelatedVariables); TEST_CASE(valueFlowForwardModifiedVariables); @@ -2244,6 +2245,37 @@ private: ASSERT_EQUALS(false, testValueOfX(code, 6U, 0)); } + void valueFlowAfterConditionSeveralNot() { + const char *code; + + code = "int f(int x, int y) {\n" + " if (x!=0) {}\n" + " return y/x;\n" + "}"; + ASSERT_EQUALS(true, testValueOfX(code, 3U, 0)); + + code = "int f(int x, int y) {\n" + " if (!!(x != 0)) {\n" + " return y/x;\n" + "}\n" + "}"; + ASSERT_EQUALS(false, testValueOfX(code, 3U, 0)); + + code = "int f(int x, int y) {\n" + " if (!!!(x != 0)) {\n" + " return y/x;\n" + "}\n" + "}"; + ASSERT_EQUALS(true, testValueOfX(code, 3U, 0)); + + code = "int f(int x, int y) {\n" + " if (!!!!(x != 0)) {\n" + " return y/x;\n" + "}\n" + "}"; + ASSERT_EQUALS(false, testValueOfX(code, 3U, 0)); + } + void valueFlowForwardCompoundAssign() { const char *code;