diff --git a/CheckMemoryLeak.cpp b/CheckMemoryLeak.cpp index 0c183875b..4a179e06f 100644 --- a/CheckMemoryLeak.cpp +++ b/CheckMemoryLeak.cpp @@ -14,10 +14,24 @@ #include #endif - //--------------------------------------------------------------------------- - + enum AllocType { No, Malloc, New, NewA }; + +// Extra allocation.. +class allocfunc +{ + public: + const char *funcname; + AllocType alloctype; + + allocfunc(const char f[], AllocType a) + { + funcname = f; + alloctype = a; + } +}; +static std::list listallocfunc; static AllocType GetAllocationType( const TOKEN *tok2 ) { @@ -53,8 +67,17 @@ static AllocType GetAllocationType( const TOKEN *tok2 ) return New; if ( Match( tok2, "new %type% [" ) ) - return NewA; - + return NewA; + + // Userdefined allocation function.. + std::list::const_iterator it = listallocfunc.begin(); + while ( it != listallocfunc.end() ) + { + if ( strcmp(tok2->str, it->funcname) == 0 ) + return it->alloctype; + ++it; + } + return No; } @@ -215,7 +238,7 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] if ( Match( tok, "= & %var1% . %var% ;", varnames ) ) return; - // Linux lists.. + // Linux lists.. todo: check if the first struct member is passed if ( Match( tok, "%var% ( & %var1% .", varnames ) ) { if ( strstr(tok->str, "list_add") ) @@ -250,7 +273,37 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] } if ( ! retvar ) - MemoryLeak( tok, varname ); + MemoryLeak( tok, varname ); + + else + { + // The allocated memory is returned.. check that it is deallocated + + // Get function name.. + const char *funcname = 0; + int indentlevel = 0; + for ( const TOKEN *ftok = tokens; ftok && ftok != tok; ftok = ftok->next ) + { + if ( ftok->str[0] == '{' ) + indentlevel++; + + else if ( ftok->str[0] == '}' ) + indentlevel--; + + if ( indentlevel <= 0 ) + { + if ( Match(ftok, "[};]") ) + funcname = 0; + else if ( Match(ftok, "%var% (") ) + funcname = ftok->str; + } + } + + if ( funcname ) + { + listallocfunc.push_back( allocfunc(funcname, Alloc) ); + } + } if ( indentlevel <= alloc_indentlevel ) return; diff --git a/tests.cpp b/tests.cpp index 6f1caf601..8fb0f9f79 100644 --- a/tests.cpp +++ b/tests.cpp @@ -668,6 +668,19 @@ static void memleak_in_function() " p = &abc1->a;\n" "}\n"; check( CheckMemoryLeak, __LINE__, test19, "" ); + + + const char test20[] = "static char *dmalloc()\n" + "{\n" + " char *p = new char[100];\n" + " return p;\n" + "}\n" + "static void f()\n" + "{\n" + " char *p = dmalloc();\n" + "}\n"; + check( CheckMemoryLeak, __LINE__, test20, "[test.cpp:8]: Memory leak: p\n" ); + } //---------------------------------------------------------------------------