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;
|
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[] )
|
CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetDeallocationType( const TOKEN *tok, const char *varnames[] )
|
||||||
{
|
{
|
||||||
if ( TOKEN::Match(tok, "delete %var1% ;", 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"))
|
if (TOKEN::Match(tok,"if") || TOKEN::Match(tok,"for") || TOKEN::Match(tok,"while"))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (GetAllocationType(tok)!=No || GetDeallocationType(tok,varnames)!=No)
|
if (GetAllocationType(tok)!=No || GetReallocationType(tok)!=No || GetDeallocationType(tok,varnames)!=No)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ( callstack.size() > 2 )
|
if ( callstack.size() > 2 )
|
||||||
|
@ -337,6 +363,16 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list<const TOKEN *>
|
||||||
{
|
{
|
||||||
AllocType alloc = GetAllocationType(tok->tokAt(3));
|
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 "--all" hasn't been given, don't check classes..
|
||||||
if ( alloc == New && ! _settings._showAll )
|
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 );
|
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 GetDeallocationType( const TOKEN *tok, const char *varnames[]);
|
||||||
AllocType GetAllocationType( const TOKEN *tok2 );
|
AllocType GetAllocationType( const TOKEN *tok2 );
|
||||||
|
AllocType GetReallocationType( const TOKEN *tok2 );
|
||||||
bool isclass( const TOKEN *typestr );
|
bool isclass( const TOKEN *typestr );
|
||||||
|
|
||||||
const Tokenizer *_tokenizer;
|
const Tokenizer *_tokenizer;
|
||||||
|
|
|
@ -123,6 +123,9 @@ private:
|
||||||
TEST_CASE( linux_list_1 );
|
TEST_CASE( linux_list_1 );
|
||||||
|
|
||||||
TEST_CASE( sizeof1 );
|
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 );
|
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 )
|
REGISTER_TEST( TestMemleak )
|
||||||
|
|
Loading…
Reference in New Issue