Memory leaks: Better handling of "realloc". Fixing bug [ 2395262 ]
This commit is contained in:
parent
202c613e70
commit
7c32b7b2bb
|
@ -135,6 +135,32 @@ CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetAllocationType( const T
|
|||
return No;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetReallocationType( const TOKEN *tok2 )
|
||||
{
|
||||
// What we may have...
|
||||
// * var = (char *)realloc(..;
|
||||
if ( tok2 && tok2->str() == "(" )
|
||||
{
|
||||
while ( tok2 && tok2->str() != ")" )
|
||||
tok2 = tok2->next;
|
||||
tok2 = tok2 ? tok2->next : NULL;
|
||||
}
|
||||
if ( ! tok2 )
|
||||
return No;
|
||||
|
||||
if ( TOKEN::Match(tok2, "realloc") )
|
||||
return Malloc;
|
||||
|
||||
// GTK memory reallocation..
|
||||
if ( TOKEN::Match(tok2, "g_realloc|g_try_realloc|g_renew|g_try_renew") )
|
||||
return gMalloc;
|
||||
|
||||
return No;
|
||||
}
|
||||
|
||||
|
||||
CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetDeallocationType( const TOKEN *tok, const char *varnames[] )
|
||||
{
|
||||
if ( TOKEN::Match(tok, "delete %var1% ;", varnames) )
|
||||
|
@ -167,7 +193,7 @@ const char * CheckMemoryLeakClass::call_func( const TOKEN *tok, std::list<const
|
|||
if (TOKEN::Match(tok,"if") || TOKEN::Match(tok,"for") || TOKEN::Match(tok,"while"))
|
||||
return 0;
|
||||
|
||||
if (GetAllocationType(tok)!=No || GetDeallocationType(tok,varnames)!=No)
|
||||
if (GetAllocationType(tok)!=No || GetReallocationType(tok)!=No || GetDeallocationType(tok,varnames)!=No)
|
||||
return 0;
|
||||
|
||||
if ( callstack.size() > 2 )
|
||||
|
@ -337,6 +363,16 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list<const TOKEN *>
|
|||
{
|
||||
AllocType alloc = GetAllocationType(tok->tokAt(3));
|
||||
|
||||
if ( alloc == No )
|
||||
{
|
||||
alloc = GetReallocationType( tok->tokAt(3) );
|
||||
if ( alloc != No )
|
||||
{
|
||||
addtoken( "dealloc" );
|
||||
addtoken( ";" );
|
||||
}
|
||||
}
|
||||
|
||||
// If "--all" hasn't been given, don't check classes..
|
||||
if ( alloc == New && ! _settings._showAll )
|
||||
{
|
||||
|
|
|
@ -95,6 +95,7 @@ private:
|
|||
const char * call_func( const TOKEN *tok, std::list<const TOKEN *> callstack, const char *varnames[], AllocType &alloctype, AllocType &dealloctype );
|
||||
AllocType GetDeallocationType( const TOKEN *tok, const char *varnames[]);
|
||||
AllocType GetAllocationType( const TOKEN *tok2 );
|
||||
AllocType GetReallocationType( const TOKEN *tok2 );
|
||||
bool isclass( const TOKEN *typestr );
|
||||
|
||||
const Tokenizer *_tokenizer;
|
||||
|
|
|
@ -123,6 +123,9 @@ private:
|
|||
TEST_CASE( linux_list_1 );
|
||||
|
||||
TEST_CASE( sizeof1 );
|
||||
|
||||
TEST_CASE( realloc1 );
|
||||
TEST_CASE( realloc2 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -965,6 +968,31 @@ private:
|
|||
ASSERT_EQUALS( std::string("[test.cpp:12]: Memory leak: s2\n"), err );
|
||||
}
|
||||
|
||||
|
||||
void realloc1()
|
||||
{
|
||||
check( "void foo()\n"
|
||||
"{\n"
|
||||
" char *a = (char *)malloc(10);\n"
|
||||
" a = realloc(a, 100);\n"
|
||||
"}\n" );
|
||||
|
||||
ASSERT_EQUALS( std::string("[test.cpp:5]: Memory leak: a\n"), errout.str() );
|
||||
}
|
||||
|
||||
void realloc2()
|
||||
{
|
||||
check( "void foo()\n"
|
||||
"{\n"
|
||||
" char *a = (char *)malloc(10);\n"
|
||||
" a = (char *)realloc(a, 100);\n"
|
||||
" free(a);\n"
|
||||
"}\n" );
|
||||
|
||||
ASSERT_EQUALS( std::string(""), errout.str() );
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
REGISTER_TEST( TestMemleak )
|
||||
|
|
Loading…
Reference in New Issue