diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index becad1a12..0a9d1406e 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -263,8 +263,8 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken, const Token *tok2 = tok->linkAt(1); if (Token::simpleMatch(tok2, ") {")) { - VarInfo varInfo1(*varInfo); - VarInfo varInfo2(*varInfo); + VarInfo varInfo1(*varInfo); // VarInfo for if code + VarInfo varInfo2(*varInfo); // VarInfo for else code if (Token::Match(tok->next(), "( %var% )")) { varInfo2.erase(tok->tokAt(2)->varId()); @@ -274,6 +274,14 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken, varInfo1.erase(tok->tokAt(3)->varId()); } else if (Token::Match(tok->next(), "( %var% ( ! %var% ) )|&&")) { varInfo1.erase(tok->tokAt(5)->varId()); + } else if (Token::Match(tok->next(), "( %var% < 0 )|&&")) { + varInfo1.erase(tok->tokAt(2)->varId()); + } else if (Token::Match(tok->next(), "( 0 > %var% )|&&")) { + varInfo1.erase(tok->tokAt(4)->varId()); + } else if (Token::Match(tok->next(), "( %var% > 0 )|&&")) { + varInfo2.erase(tok->tokAt(2)->varId()); + } else if (Token::Match(tok->next(), "( 0 < %var% )|&&")) { + varInfo2.erase(tok->tokAt(4)->varId()); } checkScope(tok2->next(), &varInfo1, notzero); diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 4364d98c2..7d4d03b5b 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -73,6 +73,7 @@ private: TEST_CASE(ifelse4); TEST_CASE(ifelse5); TEST_CASE(ifelse6); // #3370 + TEST_CASE(ifelse7); // #5576 - if (fd < 0) // switch TEST_CASE(switch1); @@ -469,6 +470,16 @@ private: ASSERT_EQUALS("[test.c:6]: (error) Memory leak: a\n", errout.str()); } + void ifelse7() { // #5576 + check("void f() {\n" + " int x = malloc(20);\n" + " if (x < 0)\n" // assume negative value indicates its unallocated + " return;\n" + " free(x);\n" + "}"); + ASSERT_EQUALS("", errout.str()); + } + void switch1() { check("void f() {\n" " char *p = 0;\n"