diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 49bd15e82..4c3bbc648 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -213,7 +213,12 @@ const Token * astIsVariableComparison(const Token *tok, const std::string &comp, ret = tok->astOperand1(); } } else if (comp == "!=" && rhs == std::string("0")) { - ret = tok; + if (tok->str() == "!") { + ret = tok->astOperand1(); + // handle (!(x==0)) as (x!=0) + astIsVariableComparison(ret, "==", "0", &ret); + } else + ret = tok; } else if (comp == "==" && rhs == std::string("0")) { if (tok->str() == "!") { ret = tok->astOperand1(); diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 7bbabd66f..4c375deae 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -138,6 +138,7 @@ private: TEST_CASE(ifelse14); // #9130 - if (x == (char*)NULL) TEST_CASE(ifelse15); // #9206 - if (global_ptr = malloc(1)) TEST_CASE(ifelse16); // #9635 - if (p = malloc(4), p == NULL) + TEST_CASE(ifelse17); // if (!!(!p)) // switch TEST_CASE(switch1); @@ -1517,6 +1518,24 @@ private: ASSERT_EQUALS("", errout.str()); } + void ifelse17() { + check("int *f() {\n" + " int *p = realloc(nullptr, 10);\n" + " if (!p)\n" + " return NULL;\n" + " return p;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check("int *f() {\n" + " int *p = realloc(nullptr, 10);\n" + " if (!!(!p))\n" + " return NULL;\n" + " return p;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + } + void switch1() { check("void f() {\n" " char *p = 0;\n"