From f847631cdb65b33ad65bc32b21ea121f026a43e0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= <daniel.marjamaki@gmail.com>
Date: Fri, 30 Jun 2017 23:05:09 +0200
Subject: [PATCH] Fixed #5273 (FP memleak: Unknown if() condition should make
 error inconclusive)

---
 lib/checkleakautovar.cpp | 18 ++++++++++++++++++
 test/testleakautovar.cpp | 11 +++++++++++
 2 files changed, 29 insertions(+)

diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp
index a59f95dcc..cca22ac4a 100644
--- a/lib/checkleakautovar.cpp
+++ b/lib/checkleakautovar.cpp
@@ -351,6 +351,24 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
                     if (tok3->str() == "(" && Token::Match(tok3->astOperand1(), "UNLIKELY|LIKELY")) {
                         tokens.push(tok3->astOperand2());
                         continue;
+                    } else if (tok3->str() == "(" && Token::Match(tok3->previous(), "%name%")) {
+                        std::vector<const Token *> params = getArguments(tok3->previous());
+                        for (unsigned int i = 0; i < params.size(); ++i) {
+                            const Token *par = params[i];
+                            if (!par->isComparisonOp())
+                                continue;
+                            const Token *vartok = nullptr;
+                            if (astIsVariableComparison(par, "!=", "0", &vartok) ||
+                                astIsVariableComparison(par, "==", "0", &vartok) ||
+                                astIsVariableComparison(par, "<", "0", &vartok) ||
+                                astIsVariableComparison(par, ">", "0", &vartok) ||
+                                astIsVariableComparison(par, "==", "-1", &vartok) ||
+                                astIsVariableComparison(par, "!=", "-1", &vartok)) {
+                                varInfo1.erase(vartok->varId());
+                                varInfo2.erase(vartok->varId());
+                            }
+                        }
+                        continue;
                     }
 
                     const Token *vartok = nullptr;
diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp
index 9ff6296e3..68cb5c5d5 100644
--- a/test/testleakautovar.cpp
+++ b/test/testleakautovar.cpp
@@ -89,6 +89,7 @@ private:
         TEST_CASE(ifelse6); // #3370
         TEST_CASE(ifelse7); // #5576 - if (fd < 0)
         TEST_CASE(ifelse8); // #5747 - if (fd == -1)
+        TEST_CASE(ifelse9); // #5273 - if (X(p==NULL, 0))
 
         // switch
         TEST_CASE(switch1);
@@ -1024,6 +1025,16 @@ private:
         ASSERT_EQUALS("", errout.str());
     }
 
+    void ifelse9() { // #5273
+        check("void f() {\n"
+              "    char *p = malloc(100);\n"
+              "    if (dostuff(p==NULL,0))\n"
+              "        return;\n"
+              "    free(p);\n"
+              "}");
+        ASSERT_EQUALS("", errout.str());
+    }
+
     void switch1() {
         check("void f() {\n"
               "    char *p = 0;\n"