From ee5e20ed1fc6b6cf2a42e3b2bbcb116f77fc6051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 17 Dec 2008 19:21:39 +0000 Subject: [PATCH] memory leak : fixed 2 bugs related to the testcases TestMemleak::if7 and TestMemleak::simple9 --- checkmemoryleak.cpp | 56 ++++++++++++++++++++++++++------------------- testmemleak.cpp | 48 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 78 insertions(+), 26 deletions(-) diff --git a/checkmemoryleak.cpp b/checkmemoryleak.cpp index 7f89e53d3..39d7abcda 100644 --- a/checkmemoryleak.cpp +++ b/checkmemoryleak.cpp @@ -357,7 +357,6 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list // The first token should be ";" addtoken(";"); - bool isloop = false; int indentlevel = 0; @@ -440,16 +439,20 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list addtoken( (rhs ? "use" : "assign") ); } } - - AllocType dealloc = GetDeallocationType(tok, varnames); - if ( dealloc != No ) + + if ( TOKEN::Match(tok->previous(), "[;{})] %var%") ) { - addtoken("dealloc"); - if (alloctype!=No && alloctype!=dealloc) - MismatchError(tok, callstack, varname); - if (dealloctype!=No && dealloctype!=dealloc) - MismatchError(tok, callstack, varname); - dealloctype = dealloc; + AllocType dealloc = GetDeallocationType(tok, varnames); + if ( dealloc != No ) + { + addtoken("dealloc"); + if (alloctype!=No && alloctype!=dealloc) + MismatchError(tok, callstack, varname); + if (dealloctype!=No && dealloctype!=dealloc) + MismatchError(tok, callstack, varname); + dealloctype = dealloc; + continue; + } } // if else switch @@ -665,7 +668,7 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok) done = false; } - + // TODO Make this more generic. Delete "if ; else use ; use" if ( TOKEN::Match(tok2, "; if ; else assign|use ; assign|use") || TOKEN::Match(tok2, "; if assign|use ; else ; assign|use") ) @@ -675,9 +678,9 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok) } - // Reduce "if dealloc ;" and "if use ;" that is not followed by an else.. + // Reduce "if assign|dealloc|use ;" that is not followed by an else.. // If "--all" has been given these are deleted - // Otherwise, ony the "if" will be deleted + // Otherwise, only the "if" will be deleted if (TOKEN::Match(tok2, "[;{}] if assign|dealloc|use ; !!else") ) { if ( _settings._showAll ) @@ -745,17 +748,20 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok) done = false; } - // Reducing if.. - if (TOKEN::Match(tok2,"if assign|dealloc|use ; else")) + // Reducing if.. + if ( _settings._showAll ) { - erase(tok2, tok2->tokAt(2)); - done = false; - } - if (TOKEN::Match(tok2,"[;{}] if { assign|dealloc|use ; return ; } !!else") ) - { - erase(tok2,tok2->tokAt(8)); - done = false; - } + if (TOKEN::Match(tok2,"if assign|dealloc|use ; else")) + { + erase(tok2, tok2->tokAt(2)); + done = false; + } + if (TOKEN::Match(tok2,"[;{}] if { assign|dealloc|use ; return ; } !!else") ) + { + erase(tok2,tok2->tokAt(8)); + done = false; + } + } // Reduce "if ; else %var% ;" => "if %var% ;" if ( TOKEN::Match(tok2, "if ; else %var% ;") ) @@ -1016,7 +1022,10 @@ void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const AllocType dealloctype = No; TOKEN *tok = getcode( Tok1, callstack, varname, alloctype, dealloctype ); + //tok->printOut( "getcode result" ); + simplifycode( tok ); + //tok->printOut( "simplifycode result" ); // If the variable is not allocated at all => no memory leak if (TOKEN::findmatch(tok, "alloc") == 0) @@ -1040,7 +1049,6 @@ void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const else if ( (result = TOKEN::findmatch(tok, "alloc ; if break|continue|return ;")) != NULL ) { - // MemoryLeak(Tokenizer::gettok(TOKEN::findmatch(tok, "alloc ; if continue ;"), 3), varname); MemoryLeak(result->tokAt(3), varname, alloctype); } diff --git a/testmemleak.cpp b/testmemleak.cpp index ee5d9503f..36c8bd37c 100644 --- a/testmemleak.cpp +++ b/testmemleak.cpp @@ -66,7 +66,8 @@ private: TEST_CASE( simple5 ); TEST_CASE( simple6 ); TEST_CASE( simple7 ); - TEST_CASE( simple8 ); + TEST_CASE( simple8 ); + TEST_CASE( simple9 ); // Bug 2435468 - member function "free" TEST_CASE( use1 ); TEST_CASE( use2 ); @@ -86,7 +87,8 @@ private: TEST_CASE( if3 ); TEST_CASE( if4 ); TEST_CASE( if5 ); - TEST_CASE( if6 ); // Bug 2432631 + TEST_CASE( if6 ); // Bug 2432631 + TEST_CASE( if7 ); // Bug 2401436 TEST_CASE( alwaysTrue ); @@ -236,6 +238,20 @@ private: ASSERT_EQUALS( std::string(""), errout.str() ); } + + void simple9() + { + check( "void foo()\n" + "{\n" + " MyClass *c = new MyClass();\n" + " c->free(c);\n" + " delete c;\n" + "}\n" ); + ASSERT_EQUALS( std::string(""), errout.str() ); + } + + + @@ -312,6 +328,17 @@ private: " return;\n" " }\n" "}\n" ); + ASSERT_EQUALS( std::string(""), errout.str() ); + + check( "void f()\n" + "{\n" + " char *str = strdup(\"hello\");\n" + " if (a==b)\n" + " {\n" + " free(str);\n" + " return;\n" + " }\n" + "}\n", true ); ASSERT_EQUALS( std::string("[test.cpp:9]: Memory leak: str\n"), errout.str() ); } @@ -491,6 +518,23 @@ private: ASSERT_EQUALS( std::string(""), errout.str() ); } + void if7() + { + check( "void f( bool b )\n" + "{\n" + " int *a=0;\n" + " if( b )\n" + " {\n" + " a = new int[10];\n" + " }\n" + "\n" + " if( b )\n" + " delete [] a;\n" + " else {}\n" + "}\n" ); + ASSERT_EQUALS( std::string(""), errout.str() ); + } +