Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #2246 (Improve check: Memory leak, function is not noreturn if …

…return value is taken)
  • Loading branch information...
commit 2a77dd3df150e3db7608e07621a03256974b0a7a 1 parent c877534
Daniel Marjamäki danmar authored
Showing with 24 additions and 4 deletions.
  1. +4 −3 lib/checkmemoryleak.cpp
  2. +20 −1 test/testmemleak.cpp
7 lib/checkmemoryleak.cpp
View
@@ -678,7 +678,7 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<co
return 0;
}
- if (noreturn.find(tok->str()) != noreturn.end())
+ if (noreturn.find(tok->str()) != noreturn.end() && tok->strAt(-1) != "=")
return "exit";
if (varid > 0 && (getAllocationType(tok, varid) != No || getReallocationType(tok, varid) != No || getDeallocationType(tok, varid) != No))
@@ -733,12 +733,13 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<co
// how many parameters is there in the function call?
int numpar = countParameters(tok);
if (numpar <= 0)
- return "callfunc";
+ return (tok->previous()->str() != "=") ? "callfunc" : NULL;
unsigned int par = 1;
unsigned int parlevel = 0;
const bool dot(tok->previous()->str() == ".");
+ const bool eq(tok->previous()->str() == "=");
for (; tok; tok = tok->next())
{
@@ -749,7 +750,7 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<co
--parlevel;
if (parlevel < 1)
{
- return (_settings->inconclusive) ? 0 : "callfunc";
+ return (eq || _settings->inconclusive) ? 0 : "callfunc";
}
}
21 test/testmemleak.cpp
View
@@ -292,6 +292,8 @@ class TestMemleakInFunction : public TestFixture
TEST_CASE(exit2);
TEST_CASE(exit4);
TEST_CASE(exit5);
+ TEST_CASE(exit6);
+ TEST_CASE(exit7);
TEST_CASE(noreturn);
TEST_CASE(stdstring);
@@ -475,9 +477,10 @@ class TestMemleakInFunction : public TestFixture
ASSERT_EQUALS(";;;", getcode("char *s; s = strcpy(s, p);", "s"));
// callfunc..
- ASSERT_EQUALS(";;assigncallfunc;", getcode("char *s; s = a();", "s"));
+ ASSERT_EQUALS(";;assign;", getcode("char *s; s = a();", "s"));
ASSERT_EQUALS(";;callfunc;", getcode("char *s; a();", "s"));
ASSERT_EQUALS(";;callfunc;", getcode("char *s; abc.a();", "s"));
+ ASSERT_EQUALS(";;;", getcode("char *s; x = a();", "s")); // the function call is irrelevant
// exit..
ASSERT_EQUALS(";;exit;", getcode("char *s; exit(0);", "s"));
@@ -2585,6 +2588,22 @@ class TestMemleakInFunction : public TestFixture
ASSERT_EQUALS("", errout.str());
}
+ void exit7()
+ {
+ check("int a(int x) {\n"
+ " if (x == 0) {\n"
+ " exit(0);\n"
+ " }\n"
+ " return x + 2;\n"
+ "}\n"
+ "\n"
+ "void b() {\n"
+ " char *p = malloc(100);\n"
+ " int i = a(123);\n"
+ "}\n");
+ ASSERT_EQUALS("[test.cpp:11]: (error) Memory leak: p\n", errout.str());
+ }
+
void noreturn()
{
check("void fatal_error()\n"
Please sign in to comment.
Something went wrong with that request. Please try again.