CheckMemoryLeak: Handling functions that allocate memory
This commit is contained in:
parent
58b1b5f101
commit
7ae162792e
|
@ -14,10 +14,24 @@
|
|||
#include <string.h>
|
||||
#endif
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
enum AllocType { No, Malloc, New, NewA };
|
||||
|
||||
// Extra allocation..
|
||||
class allocfunc
|
||||
{
|
||||
public:
|
||||
const char *funcname;
|
||||
AllocType alloctype;
|
||||
|
||||
allocfunc(const char f[], AllocType a)
|
||||
{
|
||||
funcname = f;
|
||||
alloctype = a;
|
||||
}
|
||||
};
|
||||
static std::list<allocfunc> listallocfunc;
|
||||
|
||||
static AllocType GetAllocationType( const TOKEN *tok2 )
|
||||
{
|
||||
|
@ -53,8 +67,17 @@ static AllocType GetAllocationType( const TOKEN *tok2 )
|
|||
return New;
|
||||
|
||||
if ( Match( tok2, "new %type% [" ) )
|
||||
return NewA;
|
||||
|
||||
return NewA;
|
||||
|
||||
// Userdefined allocation function..
|
||||
std::list<allocfunc>::const_iterator it = listallocfunc.begin();
|
||||
while ( it != listallocfunc.end() )
|
||||
{
|
||||
if ( strcmp(tok2->str, it->funcname) == 0 )
|
||||
return it->alloctype;
|
||||
++it;
|
||||
}
|
||||
|
||||
return No;
|
||||
}
|
||||
|
||||
|
@ -215,7 +238,7 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[]
|
|||
if ( Match( tok, "= & %var1% . %var% ;", varnames ) )
|
||||
return;
|
||||
|
||||
// Linux lists..
|
||||
// Linux lists.. todo: check if the first struct member is passed
|
||||
if ( Match( tok, "%var% ( & %var1% .", varnames ) )
|
||||
{
|
||||
if ( strstr(tok->str, "list_add") )
|
||||
|
@ -250,7 +273,37 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[]
|
|||
}
|
||||
|
||||
if ( ! retvar )
|
||||
MemoryLeak( tok, varname );
|
||||
MemoryLeak( tok, varname );
|
||||
|
||||
else
|
||||
{
|
||||
// The allocated memory is returned.. check that it is deallocated
|
||||
|
||||
// Get function name..
|
||||
const char *funcname = 0;
|
||||
int indentlevel = 0;
|
||||
for ( const TOKEN *ftok = tokens; ftok && ftok != tok; ftok = ftok->next )
|
||||
{
|
||||
if ( ftok->str[0] == '{' )
|
||||
indentlevel++;
|
||||
|
||||
else if ( ftok->str[0] == '}' )
|
||||
indentlevel--;
|
||||
|
||||
if ( indentlevel <= 0 )
|
||||
{
|
||||
if ( Match(ftok, "[};]") )
|
||||
funcname = 0;
|
||||
else if ( Match(ftok, "%var% (") )
|
||||
funcname = ftok->str;
|
||||
}
|
||||
}
|
||||
|
||||
if ( funcname )
|
||||
{
|
||||
listallocfunc.push_back( allocfunc(funcname, Alloc) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( indentlevel <= alloc_indentlevel )
|
||||
return;
|
||||
|
|
13
tests.cpp
13
tests.cpp
|
@ -668,6 +668,19 @@ static void memleak_in_function()
|
|||
" p = &abc1->a;\n"
|
||||
"}\n";
|
||||
check( CheckMemoryLeak, __LINE__, test19, "" );
|
||||
|
||||
|
||||
const char test20[] = "static char *dmalloc()\n"
|
||||
"{\n"
|
||||
" char *p = new char[100];\n"
|
||||
" return p;\n"
|
||||
"}\n"
|
||||
"static void f()\n"
|
||||
"{\n"
|
||||
" char *p = dmalloc();\n"
|
||||
"}\n";
|
||||
check( CheckMemoryLeak, __LINE__, test20, "[test.cpp:8]: Memory leak: p\n" );
|
||||
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
|
Loading…
Reference in New Issue