Fixed #2246 (Improve check: Memory leak, function is not noreturn if return value is taken)

This commit is contained in:
Daniel Marjamäki 2011-01-01 20:14:01 +01:00
parent c8775344d6
commit 2a77dd3df1
2 changed files with 24 additions and 4 deletions

View File

@ -678,7 +678,7 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<co
return 0; return 0;
} }
if (noreturn.find(tok->str()) != noreturn.end()) if (noreturn.find(tok->str()) != noreturn.end() && tok->strAt(-1) != "=")
return "exit"; return "exit";
if (varid > 0 && (getAllocationType(tok, varid) != No || getReallocationType(tok, varid) != No || getDeallocationType(tok, varid) != No)) 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? // how many parameters is there in the function call?
int numpar = countParameters(tok); int numpar = countParameters(tok);
if (numpar <= 0) if (numpar <= 0)
return "callfunc"; return (tok->previous()->str() != "=") ? "callfunc" : NULL;
unsigned int par = 1; unsigned int par = 1;
unsigned int parlevel = 0; unsigned int parlevel = 0;
const bool dot(tok->previous()->str() == "."); const bool dot(tok->previous()->str() == ".");
const bool eq(tok->previous()->str() == "=");
for (; tok; tok = tok->next()) for (; tok; tok = tok->next())
{ {
@ -749,7 +750,7 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<co
--parlevel; --parlevel;
if (parlevel < 1) if (parlevel < 1)
{ {
return (_settings->inconclusive) ? 0 : "callfunc"; return (eq || _settings->inconclusive) ? 0 : "callfunc";
} }
} }

View File

@ -292,6 +292,8 @@ private:
TEST_CASE(exit2); TEST_CASE(exit2);
TEST_CASE(exit4); TEST_CASE(exit4);
TEST_CASE(exit5); TEST_CASE(exit5);
TEST_CASE(exit6);
TEST_CASE(exit7);
TEST_CASE(noreturn); TEST_CASE(noreturn);
TEST_CASE(stdstring); TEST_CASE(stdstring);
@ -475,9 +477,10 @@ private:
ASSERT_EQUALS(";;;", getcode("char *s; s = strcpy(s, p);", "s")); ASSERT_EQUALS(";;;", getcode("char *s; s = strcpy(s, p);", "s"));
// callfunc.. // 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; a();", "s"));
ASSERT_EQUALS(";;callfunc;", getcode("char *s; abc.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.. // exit..
ASSERT_EQUALS(";;exit;", getcode("char *s; exit(0);", "s")); ASSERT_EQUALS(";;exit;", getcode("char *s; exit(0);", "s"));
@ -2585,6 +2588,22 @@ private:
ASSERT_EQUALS("", errout.str()); 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() void noreturn()
{ {
check("void fatal_error()\n" check("void fatal_error()\n"