From a8bf4d7e7776dfc2dbfb68f4151869a4d91f1c96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 1 Dec 2008 18:52:40 +0000 Subject: [PATCH] Memory leak: Refactoring and improvements of simplifycode etc --- CheckMemoryLeak.cpp | 71 ++++++++++++++++++++++++++++++++++++--------- testmemleak.cpp | 17 +++++------ 2 files changed, 65 insertions(+), 23 deletions(-) diff --git a/CheckMemoryLeak.cpp b/CheckMemoryLeak.cpp index c79307c0a..c99a77c00 100644 --- a/CheckMemoryLeak.cpp +++ b/CheckMemoryLeak.cpp @@ -141,14 +141,6 @@ CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetAllocationType( const T CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetDeallocationType( const TOKEN *tok, const char *varnames[] ) { - // Redundant condition.. - if ( TOKEN::Match(tok, "if ( %var1% )", varnames) ) - { - tok = tok->tokAt(4); - if (tok->str() =="{") - tok = tok->next; - } - if ( TOKEN::Match(tok, "delete %var1% ;", varnames) ) return New; @@ -336,9 +328,9 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list } else if ( tok->aaaa0() == '}' ) { + addtoken( "}" ); if ( indentlevel <= 0 ) break; - addtoken( "}" ); indentlevel--; } @@ -579,7 +571,7 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok) erase( tok2->next->next, tok2->tokAt(4) ); done = false; } - if ( TOKEN::Match(tok2->next, "{ return use ; }") ) + if ( TOKEN::Match(tok2->next, "{ %var% %var% ; }") ) { erase( tok2, tok2->tokAt(2) ); erase( tok2->next->next->next, tok2->tokAt(5) ); @@ -624,12 +616,42 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok) done = false; } + // Reduce "if(var) dealloc ;" and "if(var) use ;" that is not followed by an else.. + if ((TOKEN::Match(tok2, "[;{}] if(var) dealloc ;") || TOKEN::Match(tok2, "[;{}] if(var) use ;")) && + !TOKEN::Match(tok2->tokAt(4), "else")) + { + erase(tok2, tok2->tokAt(2)); + done = false; + } + + // Reduce "if if" => "if" + if ( TOKEN::Match(tok2, "if if") ) + { + erase(tok2, tok2->tokAt(2)); + done = false; + } + + // Reduce "else ;" => ";" + if ( TOKEN::Match(tok2->next, "else ;") ) + { + erase(tok2, tok2->tokAt(2)); + done = false; + } + // Delete if block: "alloc; if return use ;" if (TOKEN::Match(tok2,"alloc ; if return use ;") && !TOKEN::Match(tok2->tokAt(6),"else")) { erase(tok2, tok2->tokAt(5)); done = false; - } + } + + + // Reduce "if return ; alloc ;" => "alloc ;" + if (TOKEN::Match(tok2, "[;{}] if return ; alloc ;")) + { + erase(tok2, tok2->tokAt(4)); + done = false; + } // "[;{}] if alloc ; else return ;" => "[;{}] alloc ;" if (TOKEN::Match(tok2,"[;{}] if alloc ; else return ;")) @@ -718,7 +740,20 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok) erase(tok2, tok2->tokAt(4)); done = false; } - + // Delete if block: "alloc; if return use ;" + if (TOKEN::Match(tok2,"alloc ; if return use ;") && !TOKEN::Match(tok2->tokAt(6),"else")) + { + erase(tok2, tok2->tokAt(5)); + done = false; + } + + // Reduce "if return ; if return ;" => "if return ;" + if ( TOKEN::Match(tok2->next, "if return ; if return ;") ) + { + erase( tok2, tok2->tokAt(4) ); + done = false; + } + // Reduce "if(var) return use ;" => "return use ;" if ( TOKEN::Match(tok2->next, "if(var) return use ;") && !TOKEN::Match(tok2->tokAt(5),"else")) { @@ -732,6 +767,14 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok) erase( tok2, tok2->tokAt(2) ); done = false; } + + // Reduce "if* alloc ; dealloc ;" => ";" + if ( TOKEN::Match(tok2->tokAt(2), "alloc ; dealloc ;") && + tok2->next->str().find("if") == 0 ) + { + erase( tok2, tok2->tokAt(5) ); + done = false; + } // Delete second use in "use ; use ;" while (TOKEN::Match(tok2, "[;{}] use ; use ;")) @@ -837,6 +880,7 @@ void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const AllocType dealloctype = No; TOKEN *tok = getcode( Tok1, callstack, varname, alloctype, dealloctype ); + simplifycode( tok ); // If the variable is not allocated at all => no memory leak if (TOKEN::findmatch(tok, "alloc") == 0) @@ -852,8 +896,6 @@ void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const return; } - simplifycode( tok ); - if ( TOKEN::findmatch(tok, "loop alloc ;") ) { MemoryLeak(TOKEN::findmatch(tok, "loop alloc ;"), varname); @@ -923,6 +965,7 @@ void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const noerr |= TOKEN::Match( first, "if alloc ; dealloc ;" ); noerr |= TOKEN::Match( first, "if alloc ; return use ;" ); noerr |= TOKEN::Match( first, "if alloc ; use ;" ); + noerr |= TOKEN::Match( first, "alloc ; ifv return ; dealloc ;" ); // Unhandled case.. if ( ! noerr ) diff --git a/testmemleak.cpp b/testmemleak.cpp index 1cfec30bd..188ae8eef 100644 --- a/testmemleak.cpp +++ b/testmemleak.cpp @@ -58,7 +58,7 @@ private: void run() { - // TODO TEST_CASE( simple1 ); + TEST_CASE( simple1 ); TEST_CASE( simple2 ); TEST_CASE( simple3 ); TEST_CASE( simple4 ); @@ -72,7 +72,7 @@ private: TEST_CASE( ifelse1 ); TEST_CASE( ifelse2 ); - // TODO TEST_CASE( ifelse3 ); + TEST_CASE( ifelse3 ); TEST_CASE( ifelse4 ); TEST_CASE( ifelse5 ); TEST_CASE( ifelse6 ); @@ -93,13 +93,13 @@ private: TEST_CASE( forwhile3 ); TEST_CASE( forwhile4 ); TEST_CASE( forwhile5 ); - // TODO TEST_CASE( forwhile6 ); + TEST_CASE( forwhile6 ); TEST_CASE( forwhile7 ); TEST_CASE( dowhile1 ); TEST_CASE( switch1 ); - // TODO TEST_CASE( switch2 ); + TEST_CASE( switch2 ); TEST_CASE( ret1 ); TEST_CASE( ret2 ); @@ -108,10 +108,10 @@ private: TEST_CASE( func1 ); TEST_CASE( func2 ); - // TODO TEST_CASE( func3 ); + TEST_CASE( func3 ); TEST_CASE( func4 ); TEST_CASE( func5 ); - // TODO TEST_CASE( func6 ); + TEST_CASE( func6 ); // TODO TEST_CASE( func7 ); TEST_CASE( func8 ); // Using callback @@ -132,7 +132,7 @@ private: check( "void f()\n" "{\n" " int *a = new int[10];\n" - "}\n" ); + "}\n" ); ASSERT_EQUALS( std::string("[test.cpp:4]: Memory leak: a\n"), errout.str() ); } @@ -440,8 +440,7 @@ private: " if (b)\n" " free(s);\n" "}\n" ); - std::string err( errout.str() ); - ASSERT_EQUALS( std::string(""), err ); + ASSERT_EQUALS( std::string(""), errout.str() ); } void if5()