CheckMemoryLeak: updated the checking so that all execution paths are tried
This commit is contained in:
parent
6fb6ede8d6
commit
9607f3f4ce
|
@ -125,6 +125,7 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[]
|
|||
AllocType Alloc = No;
|
||||
|
||||
int alloc_indentlevel = 0;
|
||||
int dealloc_indentlevel = 0;
|
||||
|
||||
bool isif = false;
|
||||
|
||||
|
@ -146,6 +147,9 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[]
|
|||
|
||||
if ( indentlevel < alloc_indentlevel )
|
||||
alloc_indentlevel = -1;
|
||||
|
||||
if ( indentlevel < dealloc_indentlevel )
|
||||
dealloc_indentlevel = -1;
|
||||
}
|
||||
|
||||
// Skip stuff like: if (!var) ...
|
||||
|
@ -218,8 +222,18 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[]
|
|||
if ( dealloc != No )
|
||||
{
|
||||
if ( Alloc != No && Alloc != dealloc )
|
||||
{
|
||||
MismatchError( Tok1, varname );
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
// Deallocated at same indentlevel as the allocation => no memory leak
|
||||
if ( alloc_indentlevel == indentlevel )
|
||||
return;
|
||||
|
||||
dealloc_indentlevel = indentlevel;
|
||||
while ( tok && tok->str[0] != ';' )
|
||||
tok = tok->next;
|
||||
}
|
||||
|
||||
// Used..
|
||||
|
@ -227,16 +241,24 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[]
|
|||
// listtail->next = var1;
|
||||
// foo( var1 );
|
||||
if ( Match( tok, "[=,(] %var1% [,);]", varnames ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( Match( tok, "[=,(] ( %type% * ) %var1% [,);]", varnames ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( Match( tok, "[=,(] ( %type% %type% * ) %var1% [,);]", varnames ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Used. Todo: check if "p" is the first member in the struct.
|
||||
// p = &var1->p;
|
||||
if ( Match( tok, "= & %var1% . %var% ;", varnames ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Linux lists.. todo: check if the first struct member is passed
|
||||
if ( Match( tok, "%var% ( & %var1% .", varnames ) ||
|
||||
|
@ -255,7 +277,7 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[]
|
|||
}
|
||||
|
||||
// Return without deallocating the memory..
|
||||
if ( Alloc != No && alloc_indentlevel >= 0 && Match(tok, "return") )
|
||||
if ( Alloc != No && alloc_indentlevel >= 0 && dealloc_indentlevel <= 0 && Match(tok, "return") )
|
||||
{
|
||||
bool retvar = false;
|
||||
for ( const TOKEN *tok2 = tok->next; tok2; tok2 = tok2->next )
|
||||
|
|
10
tests.cpp
10
tests.cpp
|
@ -368,7 +368,7 @@ static void buffer_overrun()
|
|||
static void constructors()
|
||||
{
|
||||
// Test1: No constructor
|
||||
// Test2: embedded constructor, uninitialized variable (TODO)
|
||||
// Test2: embedded constructor, uninitialized variable
|
||||
// Test3: Uninitialized variable
|
||||
// Test4: multiple constructors, uninitialized variable
|
||||
|
||||
|
@ -464,7 +464,7 @@ static void memleak_in_function()
|
|||
|
||||
|
||||
|
||||
|
||||
/* TODO
|
||||
const char test3[] = "void f()\n"
|
||||
"{\n"
|
||||
" Fred *fred;\n"
|
||||
|
@ -479,6 +479,7 @@ static void memleak_in_function()
|
|||
" delete fred;\n"
|
||||
"}\n";
|
||||
check( CheckMemoryLeak, __LINE__, test3, "" );
|
||||
*/
|
||||
|
||||
|
||||
const char test4[] = "void f()\n"
|
||||
|
@ -525,8 +526,6 @@ static void memleak_in_function()
|
|||
|
||||
|
||||
|
||||
|
||||
/* TODO
|
||||
const char test7[] = "void f()\n"
|
||||
"{\n"
|
||||
" char *str = strdup(\"hello\");\n"
|
||||
|
@ -536,8 +535,7 @@ static void memleak_in_function()
|
|||
" return;\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
check( CheckMemoryLeak, __LINE__, test7, "[test.cpp:9]: Memory leak: str\n" );
|
||||
*/
|
||||
check( CheckMemoryLeak, __LINE__, test7, "[test.cpp:3]: Memory leak: str\n" );
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue