diff --git a/CheckMemoryLeak.cpp b/CheckMemoryLeak.cpp index 22fa6a71c..3fa975c03 100644 --- a/CheckMemoryLeak.cpp +++ b/CheckMemoryLeak.cpp @@ -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 2 ) @@ -335,7 +361,17 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list if (TOKEN::Match(tok, "[(;{}] %var1% =", varnames)) { - 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 ( alloc == New && ! _settings._showAll ) diff --git a/CheckMemoryLeak.h b/CheckMemoryLeak.h index 4f34c3e62..fdcb425c8 100644 --- a/CheckMemoryLeak.h +++ b/CheckMemoryLeak.h @@ -95,6 +95,7 @@ private: const char * call_func( const TOKEN *tok, std::list 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; diff --git a/testmemleak.cpp b/testmemleak.cpp index 188ae8eef..8ac60fe30 100644 --- a/testmemleak.cpp +++ b/testmemleak.cpp @@ -122,7 +122,10 @@ private: TEST_CASE( linux_list_1 ); - TEST_CASE( sizeof1 ); + TEST_CASE( sizeof1 ); + + TEST_CASE( realloc1 ); + TEST_CASE( realloc2 ); } @@ -964,6 +967,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() ); + } + };