diff --git a/CheckMemoryLeak.cpp b/CheckMemoryLeak.cpp index 465409f5d..867808c71 100644 --- a/CheckMemoryLeak.cpp +++ b/CheckMemoryLeak.cpp @@ -106,6 +106,8 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] int alloc_indentlevel = 0; + bool isif = false; + int indentlevel = 0; for (const TOKEN *tok = Tok1 ; tok; tok = tok->next ) { @@ -128,6 +130,7 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] // Skip stuff like: if (!var) ... if ( Match(tok, "if ( ! %var1% )", varnames) || + Match(tok, "if ( unlikely( ! %var1% ) )", varnames) || Match(tok, "if ( %var1% == NULL )", varnames) || Match(tok, "if ( NULL == %var1% )", varnames) || Match(tok, "if ( %var1% == 0 )", varnames) ) @@ -149,6 +152,12 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] } } + // if.. + if ( Match(tok,"if") ) + isif = true; + if ( strchr(";{}", tok->str[0]) ) + isif = false; + // Allocated.. if ( Match(tok, "%var1% =", varnames) ) { @@ -157,6 +166,28 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] { Alloc = alloc; alloc_indentlevel = indentlevel; + + if ( isif ) + { + while ( tok ) + { + if ( tok->str[0] == '{' ) + { + indentlevel++; + } + else if ( tok->str[0] == '}' ) + { + indentlevel--; + if ( indentlevel <= alloc_indentlevel ) + break; + } + else if ( tok->str[0] == ';' && indentlevel == alloc_indentlevel ) + { + break; + } + tok = tok->next; + } + } } } @@ -174,8 +205,11 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] // list.push_back( var1 ); // listtail->next = var1; // foo( var1 ); - if ( Match( tok, "[=,(] %var1% [,);]", varnames ) ) + if ( Match( tok, "[=,(] %var1% [,);]", varnames ) ) return; + if ( Match( tok, "= ( %type% * ) %var1% ;", varnames ) ) + return; + // continue/break loop.. if (Alloc != No && diff --git a/tests.cpp b/tests.cpp index 3a633c4eb..46b4df0d9 100644 --- a/tests.cpp +++ b/tests.cpp @@ -627,6 +627,26 @@ static void memleak_in_function() " return NULL;\n" "}\n"; check( CheckMemoryLeak, __LINE__, test16, "[test.cpp:8]: Memory leak: s\n" ); + + + const char test17[] = "static void f()\n" + "{\n" + " char *str = strdup(\"hello\");\n" + " char *str2 = (char *)str;\n" + " free(str2);\n" + "}\n"; + check( CheckMemoryLeak, __LINE__, test17, "" ); + + + const char test18[] = "static void f()\n" + "{\n" + " char *str;\n" + " if ((str = (char *)malloc(123,33)) == NULL)\n" + " return;\n" + " free(str);\n" + "}\n"; + check( CheckMemoryLeak, __LINE__, test18, "" ); + } //---------------------------------------------------------------------------