Fixed #2246 (Improve check: Memory leak, function is not noreturn if return value is taken)
This commit is contained in:
parent
c8775344d6
commit
2a77dd3df1
|
@ -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";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue