diff --git a/CheckMemoryLeak.cpp b/CheckMemoryLeak.cpp index f1955d14a..952dac9e9 100644 --- a/CheckMemoryLeak.cpp +++ b/CheckMemoryLeak.cpp @@ -188,7 +188,7 @@ AllocType CheckMemoryLeakClass::GetDeallocationType( const TOKEN *tok, const cha static std::list callstack; -const char * CheckMemoryLeakClass::call_func( const TOKEN *tok, const char *varnames[] ) +const char * CheckMemoryLeakClass::call_func( const TOKEN *tok, const char typestr[], const char *varnames[] ) { if (Match(tok,"if") || Match(tok,"for") || Match(tok,"while")) return 0; @@ -227,7 +227,7 @@ const char * CheckMemoryLeakClass::call_func( const TOKEN *tok, const char *varn // Check if the function deallocates the variable.. while ( ftok && ! Match(ftok,"{") ) ftok = ftok->next; - TOKEN *func = getcode( Tokenizer::gettok(ftok,1), parname ); + TOKEN *func = getcode( Tokenizer::gettok(ftok,1), typestr, parname ); simplifycode( func ); const char *ret = 0; if (findmatch(func, "goto")) @@ -291,7 +291,7 @@ extern bool ShowAll; * varname - name of variable */ -TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, const char varname[]) +TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, const char typestr[], const char varname[]) { const char *varnames[2]; varnames[0] = varname; @@ -454,16 +454,27 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, const char varname[]) // Investigate function calls.. if ( Match(tok, "%var% (") ) { - const char *str = call_func(tok, varnames); + const char *str = call_func(tok, typestr, varnames); if ( str ) addtoken( str ); } // Linux lists.. if ( Match( tok, "[=(,] & %var1% [.[]", varnames ) ) - { - // todo: better checking - addtoken("use"); + { + // Linux list -> the first member of the struct + std::string pattern("struct " + std::string(typestr) + " {"); + const TOKEN *tok2 = findmatch(tokens, pattern.c_str()); + if ( ! tok2 ) + { + addtoken("use"); + } + else + { + tok2 = findmatch(tok2, "%var% [;,]"); + if ( !tok2 || Match(tok2, Tokenizer::getstr(tok, 4)) ) + addtoken("use"); + } } } @@ -766,11 +777,11 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok) // Simpler but less powerful than "CheckMemoryLeak_CheckScope_All" -void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] ) +void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char typestr[], const char varname[] ) { callstack.clear(); - TOKEN *tok = getcode( Tok1, varname ); + TOKEN *tok = getcode( Tok1, typestr, varname ); // If the variable is not allocated at all => no memory leak if (findmatch(tok, "alloc") == 0) @@ -866,10 +877,10 @@ void CheckMemoryLeakClass::CheckMemoryLeak_InFunction() if (indentlevel>0 && infunc) { if ( Match(tok, "[{};] %type% * %var% [;=]") ) - CheckMemoryLeak_CheckScope( tok->next, Tokenizer::getstr(tok, 3) ); + CheckMemoryLeak_CheckScope( tok->next, Tokenizer::getstr(tok, 1), Tokenizer::getstr(tok, 3) ); else if ( Match(tok, "[{};] %type% %type% * %var% [;=]") ) - CheckMemoryLeak_CheckScope( tok->next, Tokenizer::getstr(tok, 4) ); + CheckMemoryLeak_CheckScope( tok->next, Tokenizer::getstr(tok, 2), Tokenizer::getstr(tok, 4) ); } } } diff --git a/CheckMemoryLeak.h b/CheckMemoryLeak.h index 8a3192f4a..27557cc44 100644 --- a/CheckMemoryLeak.h +++ b/CheckMemoryLeak.h @@ -42,16 +42,16 @@ private: void CheckMemoryLeak_ClassMembers_ParseClass( const TOKEN *tok1, std::vector &classname ); void CheckMemoryLeak_ClassMembers(); void CheckMemoryLeak_InFunction(); - void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] ); + void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char typestr[], const char varname[] ); void simplifycode(TOKEN *tok); void erase(TOKEN *begin, const TOKEN *end); - TOKEN *getcode(const TOKEN *tok, const char varname[]); + TOKEN *getcode(const TOKEN *tok, const char typestr[], const char varname[]); bool notvar(const TOKEN *tok, const char *varnames[]); void instoken(TOKEN *tok, const char str[]); void MemoryLeak( const TOKEN *tok, const char varname[] ); void MismatchError( const TOKEN *Tok1, const char varname[] ); - const char * call_func( const TOKEN *tok, const char *varnames[] ); + const char * call_func( const TOKEN *tok, const char typestr[], const char *varnames[] ); AllocType GetDeallocationType( const TOKEN *tok, const char *varnames[] ); AllocType GetAllocationType( const TOKEN *tok2 ); bool isclass( const std::string &typestr ); diff --git a/testmemleak.cpp b/testmemleak.cpp index 8526e4bb9..1807167a5 100644 --- a/testmemleak.cpp +++ b/testmemleak.cpp @@ -113,7 +113,7 @@ private: TEST_CASE( throw1 ); TEST_CASE( linux_list_1 ); - // TODO: TEST_CASE( linux_list_2 ); + TEST_CASE( linux_list_2 ); TEST_CASE( sizeof1 ); }