Memory leaks: Improved handling of allocation functions that contains ::. Ticket: #4494
This commit is contained in:
parent
444f80c4bb
commit
f86e83d813
|
@ -140,80 +140,86 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2,
|
|||
if (! tok2->isName())
|
||||
return No;
|
||||
|
||||
// Does tok2 point on "malloc", "strdup" or "kmalloc"..
|
||||
static const char * const mallocfunc[] = {
|
||||
"malloc",
|
||||
"calloc",
|
||||
"strdup",
|
||||
"strndup",
|
||||
"kmalloc",
|
||||
"kzalloc",
|
||||
"kcalloc"
|
||||
};
|
||||
for (unsigned int i = 0; i < sizeof(mallocfunc)/sizeof(*mallocfunc); i++) {
|
||||
if (tok2->str() == mallocfunc[i])
|
||||
return Malloc;
|
||||
}
|
||||
|
||||
// Using realloc..
|
||||
if (varid && Token::Match(tok2, "realloc ( %any% ,") && tok2->tokAt(2)->varId() != varid)
|
||||
return Malloc;
|
||||
|
||||
// Does tok2 point on "g_malloc", "g_strdup", ..
|
||||
static const char * const gmallocfunc[] = {
|
||||
"g_new",
|
||||
"g_new0",
|
||||
"g_try_new",
|
||||
"g_try_new0",
|
||||
"g_malloc",
|
||||
"g_malloc0",
|
||||
"g_try_malloc",
|
||||
"g_try_malloc0",
|
||||
"g_strdup",
|
||||
"g_strndup",
|
||||
"g_strdup_printf"
|
||||
};
|
||||
for (unsigned int i = 0; i < sizeof(gmallocfunc)/sizeof(*gmallocfunc); i++) {
|
||||
if (tok2->str() == gmallocfunc[i])
|
||||
return gMalloc;
|
||||
}
|
||||
|
||||
if (Token::Match(tok2, "new struct| %type% [;()]") ||
|
||||
Token::Match(tok2, "new ( std :: nothrow ) struct| %type% [;()]") ||
|
||||
Token::Match(tok2, "new ( nothrow ) struct| %type% [;()]"))
|
||||
return New;
|
||||
|
||||
if (Token::Match(tok2, "new struct| %type% [") ||
|
||||
Token::Match(tok2, "new ( std :: nothrow ) struct| %type% [") ||
|
||||
Token::Match(tok2, "new ( nothrow ) struct| %type% ["))
|
||||
return NewArray;
|
||||
|
||||
if (Token::Match(tok2, "fopen|tmpfile|g_fopen ("))
|
||||
return File;
|
||||
|
||||
if (standards.posix) {
|
||||
if (Token::Match(tok2, "open|openat|creat|mkstemp|mkostemp (")) {
|
||||
// simple sanity check of function parameters..
|
||||
// TODO: Make such check for all these functions
|
||||
unsigned int num = countParameters(tok2);
|
||||
if (tok2->str() == "open" && num != 2 && num != 3)
|
||||
return No;
|
||||
|
||||
// is there a user function with this name?
|
||||
if (tokenizer && Token::findmatch(tokenizer->tokens(), ("%type% *|&| " + tok2->str()).c_str()))
|
||||
return No;
|
||||
return Fd;
|
||||
if (!Token::Match(tok2, "%type% :: %type%")) {
|
||||
// Does tok2 point on "malloc", "strdup" or "kmalloc"..
|
||||
static const char * const mallocfunc[] = {
|
||||
"malloc",
|
||||
"calloc",
|
||||
"strdup",
|
||||
"strndup",
|
||||
"kmalloc",
|
||||
"kzalloc",
|
||||
"kcalloc"
|
||||
};
|
||||
for (unsigned int i = 0; i < sizeof(mallocfunc)/sizeof(*mallocfunc); i++) {
|
||||
if (tok2->str() == mallocfunc[i])
|
||||
return Malloc;
|
||||
}
|
||||
|
||||
if (Token::simpleMatch(tok2, "popen ("))
|
||||
return Pipe;
|
||||
// Using realloc..
|
||||
if (varid && Token::Match(tok2, "realloc ( %any% ,") && tok2->tokAt(2)->varId() != varid)
|
||||
return Malloc;
|
||||
|
||||
// Does tok2 point on "g_malloc", "g_strdup", ..
|
||||
static const char * const gmallocfunc[] = {
|
||||
"g_new",
|
||||
"g_new0",
|
||||
"g_try_new",
|
||||
"g_try_new0",
|
||||
"g_malloc",
|
||||
"g_malloc0",
|
||||
"g_try_malloc",
|
||||
"g_try_malloc0",
|
||||
"g_strdup",
|
||||
"g_strndup",
|
||||
"g_strdup_printf"
|
||||
};
|
||||
for (unsigned int i = 0; i < sizeof(gmallocfunc)/sizeof(*gmallocfunc); i++) {
|
||||
if (tok2->str() == gmallocfunc[i])
|
||||
return gMalloc;
|
||||
}
|
||||
|
||||
if (Token::Match(tok2, "new struct| %type% [;()]") ||
|
||||
Token::Match(tok2, "new ( std :: nothrow ) struct| %type% [;()]") ||
|
||||
Token::Match(tok2, "new ( nothrow ) struct| %type% [;()]"))
|
||||
return New;
|
||||
|
||||
if (Token::Match(tok2, "new struct| %type% [") ||
|
||||
Token::Match(tok2, "new ( std :: nothrow ) struct| %type% [") ||
|
||||
Token::Match(tok2, "new ( nothrow ) struct| %type% ["))
|
||||
return NewArray;
|
||||
|
||||
if (Token::Match(tok2, "fopen|tmpfile|g_fopen ("))
|
||||
return File;
|
||||
|
||||
if (standards.posix) {
|
||||
if (Token::Match(tok2, "open|openat|creat|mkstemp|mkostemp (")) {
|
||||
// simple sanity check of function parameters..
|
||||
// TODO: Make such check for all these functions
|
||||
unsigned int num = countParameters(tok2);
|
||||
if (tok2->str() == "open" && num != 2 && num != 3)
|
||||
return No;
|
||||
|
||||
// is there a user function with this name?
|
||||
if (tokenizer && Token::findmatch(tokenizer->tokens(), ("%type% *|&| " + tok2->str()).c_str()))
|
||||
return No;
|
||||
return Fd;
|
||||
}
|
||||
|
||||
if (Token::simpleMatch(tok2, "popen ("))
|
||||
return Pipe;
|
||||
|
||||
if (Token::Match(tok2, "opendir|fdopendir ("))
|
||||
return Dir;
|
||||
}
|
||||
|
||||
if (Token::Match(tok2, "opendir|fdopendir ("))
|
||||
return Dir;
|
||||
}
|
||||
|
||||
while (Token::Match(tok2,"%type% :: %type%"))
|
||||
tok2 = tok2->tokAt(2);
|
||||
|
||||
// User function
|
||||
const Function* func = tokenizer->getSymbolDatabase()->findFunctionByName(tok2->str(), tok2->scope());
|
||||
const Function* func = tokenizer->getSymbolDatabase()->findFunctionByNameAndArgs(tok2, tok2->scope());
|
||||
if (func == NULL)
|
||||
return No;
|
||||
|
||||
|
|
|
@ -240,6 +240,7 @@ private:
|
|||
TEST_CASE(allocfunc10);
|
||||
TEST_CASE(allocfunc11);
|
||||
TEST_CASE(allocfunc12); // #3660: allocating and returning non-local pointer => not allocfunc
|
||||
TEST_CASE(allocfunc13); // Ticket #4494 - class function
|
||||
|
||||
TEST_CASE(throw1);
|
||||
TEST_CASE(throw2);
|
||||
|
@ -2583,6 +2584,16 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void allocfunc13() { // #4494: class function
|
||||
check("namespace n {\n"
|
||||
" char *a() { return malloc(100); }\n"
|
||||
"}\n"
|
||||
"void b() {\n"
|
||||
" char *x = n::a();\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:6]: (error) Memory leak: x\n", errout.str());
|
||||
}
|
||||
|
||||
void throw1() {
|
||||
check("void foo()\n"
|
||||
"{\n"
|
||||
|
|
Loading…
Reference in New Issue