CheckMemoryLeak: Made the checking a lot simpler when "--all" is not

given. This should give few false positives
This commit is contained in:
Daniel Marjamäki 2008-08-15 19:17:06 +00:00
parent fcbd297ff0
commit c833b51b25
2 changed files with 116 additions and 29 deletions

View File

@ -124,7 +124,7 @@ static void MemoryLeak( const TOKEN *tok, const char varname[] )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] ) static void CheckMemoryLeak_CheckScope_All( const TOKEN *Tok1, const char varname[] )
{ {
const char *varnames[2]; const char *varnames[2];
varnames[0] = varname; varnames[0] = varname;
@ -151,7 +151,7 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[]
if ( indentlevel < 0 ) if ( indentlevel < 0 )
{ {
if ( Alloc != No ) if ( Alloc != No )
MemoryLeak( Tok1, varname ); MemoryLeak( tok, varname );
return; return;
} }
@ -360,7 +360,7 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[]
{ {
if ( Alloc != No && Alloc != dealloc ) if ( Alloc != No && Alloc != dealloc )
{ {
MismatchError( Tok1, varname ); MismatchError( tok, varname );
return; return;
} }
@ -478,6 +478,85 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[]
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
extern bool ShowAll;
// Simpler but less powerful than "CheckMemoryLeak_CheckScope_All"
static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] )
{
if ( ShowAll )
{
CheckMemoryLeak_CheckScope_All(Tok1, varname);
return;
}
const char *varnames[2];
varnames[0] = varname;
varnames[1] = 0;
AllocType Alloc = No;
bool isfunc = false;
bool isreturn = false;
int indentlevel = 0;
for (const TOKEN *tok = Tok1 ; tok; tok = tok->next )
{
if (tok->str[0]=='{')
indentlevel++;
else if (tok->str[0]=='}')
{
indentlevel--;
if ( indentlevel < 0 )
{
if ( Alloc != No )
MemoryLeak( tok, varname );
return;
}
}
// Allocated..
if ( Alloc == No && Match(tok, "[(;{}] %var1% =", varnames) )
Alloc = GetAllocationType( gettok(tok, 3) );
// Deallocated..
AllocType dealloc = GetDeallocationType( tok, varnames );
if ( dealloc != No )
{
if ( Alloc != No && Alloc != dealloc )
MismatchError( tok, varname );
return;
}
if ( Match(tok,";") )
isfunc = isreturn = false;
// Assignment..
if ( Match(tok, "[=)&] %var1%", varnames) )
return;
// Assuming that it's deallocated if it's passed as parameter to a
// function
if ( Match(tok, "%var% (") &&
strcmp(tok->str,"if") &&
strcmp(tok->str,"for") &&
strcmp(tok->str,"while"))
{
isfunc = true;
}
if (isfunc && Match(tok,"[(,] %var1% [,)]", varnames))
return;
// Return variable..
if (Match(tok, "return"))
isreturn = true;
if (isreturn && Match(tok,varname))
return;
}
}
//---------------------------------------------------------------------------
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@ -455,6 +455,17 @@ static void operator_eq()
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void check_(void (chk)(),
const unsigned int line,
const char code[],
const char msg[])
{
ShowAll = false;
check( chk, line, code, msg );
ShowAll = true;
check( chk, line, code, msg );
}
static void memleak_in_function() static void memleak_in_function()
{ {
// There are 2 sections: // There are 2 sections:
@ -476,12 +487,11 @@ static void memleak_in_function()
// Simple testcases // Simple testcases
//////////////////////////////////////////////// ////////////////////////////////////////////////
code = "void f()\n" code = "void f()\n"
"{\n" "{\n"
" int *a = new int[10];\n" " int *a = new int[10];\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "[test.cpp:3]: Memory leak: a\n" ); check_( CheckMemoryLeak, __LINE__, code, "[test.cpp:4]: Memory leak: a\n" );
code = "Fred *NewFred()\n" code = "Fred *NewFred()\n"
@ -489,7 +499,7 @@ static void memleak_in_function()
" Fred *f = new Fred;\n" " Fred *f = new Fred;\n"
" return f;\n" " return f;\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "" ); check_( CheckMemoryLeak, __LINE__, code, "" );
code = "static char *f()\n" code = "static char *f()\n"
@ -497,7 +507,7 @@ static void memleak_in_function()
" char *s = new char[100];\n" " char *s = new char[100];\n"
" return (char *)s;\n" " return (char *)s;\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "" ); check_( CheckMemoryLeak, __LINE__, code, "" );
code = "static void f()\n" code = "static void f()\n"
@ -506,9 +516,7 @@ static void memleak_in_function()
" char *str2 = (char *)str;\n" " char *str2 = (char *)str;\n"
" free(str2);\n" " free(str2);\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "" ); check_( CheckMemoryLeak, __LINE__, code, "" );
@ -525,7 +533,7 @@ static void memleak_in_function()
" delete [] a;\n" " delete [] a;\n"
" }\n" " }\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "" ); check_( CheckMemoryLeak, __LINE__, code, "" );
code = "void f()\n" code = "void f()\n"
@ -549,7 +557,7 @@ static void memleak_in_function()
" return;\n" " return;\n"
" }\n" " }\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "[test.cpp:3]: Memory leak: str\n" ); check( CheckMemoryLeak, __LINE__, code, "[test.cpp:9]: Memory leak: str\n" );
code = "void f()\n" code = "void f()\n"
@ -562,7 +570,7 @@ static void memleak_in_function()
" }\n" " }\n"
" delete [] str;\n" " delete [] str;\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "" ); check_( CheckMemoryLeak, __LINE__, code, "" );
@ -581,7 +589,7 @@ static void memleak_in_function()
" }\n" " }\n"
" delete fred;\n" " delete fred;\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "" ); check_( CheckMemoryLeak, __LINE__, code, "" );
*/ */
code = "static char *f()\n" code = "static char *f()\n"
@ -605,9 +613,9 @@ static void memleak_in_function()
" }\n" " }\n"
" return s;\n" " return s;\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "" ); check_( CheckMemoryLeak, __LINE__, code, "" );
/* todo
code = "static char *f()\n" code = "static char *f()\n"
"{\n" "{\n"
" char *s = new char[10];\n" " char *s = new char[10];\n"
@ -618,7 +626,7 @@ static void memleak_in_function()
" return 0;\n" " return 0;\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "" ); check( CheckMemoryLeak, __LINE__, code, "" );
*/
@ -639,7 +647,7 @@ static void memleak_in_function()
" }\n" " }\n"
" free(str);\n" " free(str);\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "" ); check_( CheckMemoryLeak, __LINE__, code, "" );
code = "void f()\n" code = "void f()\n"
@ -674,7 +682,7 @@ static void memleak_in_function()
" };\n" " };\n"
" delete [] str;\n" " delete [] str;\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "" ); check_( CheckMemoryLeak, __LINE__, code, "" );
@ -690,7 +698,7 @@ static void memleak_in_function()
" int *a = new int[10];\n" " int *a = new int[10];\n"
" free(a);\n" " free(a);\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "[test.cpp:3]: Mismatching allocation and deallocation: a\n" ); check_( CheckMemoryLeak, __LINE__, code, "[test.cpp:4]: Mismatching allocation and deallocation: a\n" );
@ -708,7 +716,7 @@ static void memleak_in_function()
" Fred *fred = new Fred;\n" " Fred *fred = new Fred;\n"
" // fred is deleted automaticly\n" " // fred is deleted automaticly\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "" ); check_( CheckMemoryLeak, __LINE__, code, "" );
code = "struct abc\n" code = "struct abc\n"
@ -741,7 +749,7 @@ static void memleak_in_function()
" char *str[10];\n" " char *str[10];\n"
" str[0] = strdup(\"hello\");\n" " str[0] = strdup(\"hello\");\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "[test.cpp:3]: Memory leak: str[0]\n" ); check_( CheckMemoryLeak, __LINE__, code, "[test.cpp:3]: Memory leak: str[0]\n" );
*/ */
@ -756,7 +764,7 @@ static void memleak_in_function()
" Fred *fred = new Fred;\n" " Fred *fred = new Fred;\n"
" free( fred->Name );\n" " free( fred->Name );\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "[test.cpp:3]: Memory leak: fred\n" ); check_( CheckMemoryLeak, __LINE__, code, "[test.cpp:5]: Memory leak: fred\n" );
/* TODO /* TODO
@ -770,7 +778,7 @@ static void memleak_in_function()
" Fred f;\n" " Fred f;\n"
" f.str = strdup(\"aa\");\n" " f.str = strdup(\"aa\");\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "[test.cpp:9]: Memory leak: f.str\n" ); check_( CheckMemoryLeak, __LINE__, code, "[test.cpp:9]: Memory leak: f.str\n" );
*/ */
@ -793,7 +801,7 @@ static void memleak_in_function()
"{\n" "{\n"
" char *p = dmalloc();\n" " char *p = dmalloc();\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "[test.cpp:8]: Memory leak: p\n" ); check( CheckMemoryLeak, __LINE__, code, "[test.cpp:9]: Memory leak: p\n" );
code = "static char *dmalloc()\n" code = "static char *dmalloc()\n"
@ -806,7 +814,7 @@ static void memleak_in_function()
" char *p = dmalloc();\n" " char *p = dmalloc();\n"
" delete p;\n" " delete p;\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "[test.cpp:8]: Mismatching allocation and deallocation: p\n" ); check( CheckMemoryLeak, __LINE__, code, "[test.cpp:9]: Mismatching allocation and deallocation: p\n" );
code = "static void foo(const char *str)\n" code = "static void foo(const char *str)\n"
@ -817,7 +825,7 @@ static void memleak_in_function()
" char *p = new char[100];\n" " char *p = new char[100];\n"
" foo(p);\n" " foo(p);\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "[test.cpp:6]: Memory leak: p\n" ); check( CheckMemoryLeak, __LINE__, code, "[test.cpp:8]: Memory leak: p\n" );
code = "static void f()\n" code = "static void f()\n"
@ -825,7 +833,7 @@ static void memleak_in_function()
" char *p = new char[100];\n" " char *p = new char[100];\n"
" foo(p);\n" " foo(p);\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "" ); check_( CheckMemoryLeak, __LINE__, code, "" );
code = "static void f()\n" code = "static void f()\n"
@ -833,7 +841,7 @@ static void memleak_in_function()
" char *p = new char[100];\n" " char *p = new char[100];\n"
" foo.add(p);\n" " foo.add(p);\n"
"}\n"; "}\n";
check( CheckMemoryLeak, __LINE__, code, "" ); check_( CheckMemoryLeak, __LINE__, code, "" );
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------