CheckMemoryLeak: Handling functions that allocate memory

This commit is contained in:
Daniel Marjamäki 2008-05-10 07:33:50 +00:00
parent 58b1b5f101
commit 7ae162792e
2 changed files with 72 additions and 6 deletions

View File

@ -14,10 +14,24 @@
#include <string.h> #include <string.h>
#endif #endif
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
enum AllocType { No, Malloc, New, NewA }; 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 ) static AllocType GetAllocationType( const TOKEN *tok2 )
{ {
@ -53,8 +67,17 @@ static AllocType GetAllocationType( const TOKEN *tok2 )
return New; return New;
if ( Match( tok2, "new %type% [" ) ) 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; return No;
} }
@ -215,7 +238,7 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[]
if ( Match( tok, "= & %var1% . %var% ;", varnames ) ) if ( Match( tok, "= & %var1% . %var% ;", varnames ) )
return; return;
// Linux lists.. // Linux lists.. todo: check if the first struct member is passed
if ( Match( tok, "%var% ( & %var1% .", varnames ) ) if ( Match( tok, "%var% ( & %var1% .", varnames ) )
{ {
if ( strstr(tok->str, "list_add") ) if ( strstr(tok->str, "list_add") )
@ -250,7 +273,37 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[]
} }
if ( ! retvar ) 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 ) if ( indentlevel <= alloc_indentlevel )
return; return;

View File

@ -668,6 +668,19 @@ static void memleak_in_function()
" p = &abc1->a;\n" " p = &abc1->a;\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, test19, "" ); 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" );
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------