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;
}
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";
}
}

View File

@ -292,6 +292,8 @@ private:
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 @@ private:
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 @@ private:
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"