From 34f44e3c04aeb6945ff5dcf236d10deff48c22b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 7 Nov 2008 16:19:55 +0000 Subject: [PATCH] Memory Leaks: Convert "do-while" blocks to "while" blocks to make the handling for that the same. --- CheckMemoryLeak.cpp | 84 ++++++++++++++++++++++++++++++++++++++++----- testmemleak.cpp | 19 ++++++++++ testrunner.cbproj | 17 +++++---- 3 files changed, 104 insertions(+), 16 deletions(-) diff --git a/CheckMemoryLeak.cpp b/CheckMemoryLeak.cpp index d8a7edb6e..071a935b0 100644 --- a/CheckMemoryLeak.cpp +++ b/CheckMemoryLeak.cpp @@ -201,6 +201,16 @@ static void instoken(TOKEN *tok, const char str[]) } //--------------------------------------------------------------------------- +static bool notvar(const TOKEN *tok, const char *varnames[]) +{ + return bool( Match(tok, "! %var1%", varnames) || + Match(tok, "unlikely ( ! %var1% )", varnames) || + Match(tok, "unlikely ( %var1% == NULL )", varnames) || + Match(tok, "%var1% == NULL", varnames) || + Match(tok, "NULL == %var1%", varnames) || + Match(tok, "%var1% == 0", varnames) ); +} + extern bool ShowAll; @@ -305,12 +315,7 @@ static TOKEN *getcode(const TOKEN *tok, const char varname[]) addtoken("if(var)"); tok = gettok(tok, 3); // Make sure the "use" will not be added } - else if ( Match(tok, "if ( ! %var1% )", varnames) || - Match(tok, "if ( unlikely ( ! %var1% ) )", varnames) || - Match(tok, "if ( unlikely ( %var1% == NULL ) )", varnames) || - Match(tok, "if ( %var1% == NULL )", varnames) || - Match(tok, "if ( NULL == %var1% )", varnames) || - Match(tok, "if ( %var1% == 0 )", varnames) ) + else if ( Match(tok, "if (") && notvar(gettok(tok,2), varnames) ) { addtoken("if(!var)"); } @@ -334,12 +339,16 @@ static TOKEN *getcode(const TOKEN *tok, const char varname[]) } // Loops.. - if (Match(tok, "for") || Match(tok, "while") || Match(tok, "do") ) + if (Match(tok, "for") || Match(tok, "while") ) { addtoken("loop"); - isloop = Match(tok, "%var% ("); + isloop = true; } - if ( isloop && Match(tok,"%var1%",varnames) ) + if ( Match(tok, "do") ) + { + addtoken("do"); + } + if ( isloop && notvar(tok,varnames) ) addtoken("!var"); // continue / break.. @@ -407,6 +416,58 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] } + // Remove "do"... + // do { x } while (y); + // => + // { x } while(y) { x }" + for ( TOKEN *tok2 = tok; tok2; tok2 = tok2->next ) + { + if ( ! Match(tok2->next, "do") ) + continue; + + // Remove the next token "do" + erase( tok2, gettok(tok2, 2) ); + tok2 = tok2->next; + + // Find the end of the "do" block.. + TOKEN *tok2_; + int indentlevel = 0; + for ( tok2_ = tok2; tok2_ && indentlevel>=0; tok2_ = tok2_->next ) + { + if ( Match(tok2_, "{") ) + ++indentlevel; + + else if ( Match(tok2_, "}") ) + --indentlevel; + + else if ( indentlevel == 0 && Match(tok2_->next, ";") ) + break; + } + + // End not found? + if ( ! tok2_ ) + continue; + + // Copy code.. + indentlevel = 0; + do + { + if ( Match( tok2, "{" ) ) + ++indentlevel; + else if ( Match(tok2, "}") ) + --indentlevel; + + // Copy token.. + instoken( tok2_, tok2->str ); + + // Next token.. + tok2 = tok2->next; + tok2_ = tok2_->next; + } + while ( tok2 && indentlevel > 0 ); + } + + // reduce the code.. bool done = false; while ( ! done ) @@ -624,6 +685,11 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] MemoryLeak(gettok(findmatch(tok,"alloc ; return ;"),2), varname); } + else if ( findmatch(tok, "alloc ; alloc") ) + { + MemoryLeak(gettok(findmatch(tok,"alloc ; alloc"),2), varname); + } + else if ( ! findmatch(tok,"dealloc") && ! findmatch(tok,"use") && ! findmatch(tok,"return use ;") ) diff --git a/testmemleak.cpp b/testmemleak.cpp index 56cc51c55..a210f663a 100644 --- a/testmemleak.cpp +++ b/testmemleak.cpp @@ -77,6 +77,8 @@ private: TEST_CASE( forwhile5 ); TEST_CASE( forwhile6 ); + TEST_CASE( dowhile1 ); + TEST_CASE( switch1 ); TEST_CASE( switch2 ); @@ -407,6 +409,23 @@ private: + void dowhile1() + { + check( "void f()\n" + "{\n" + " char *str = strdup(\"abc\");\n" + " do\n" + " {\n" + " str = strdup(\"def\");\n" + " }\n" + " while (!str);\n" + " return str;\n" + "}\n" ); + ASSERT_EQUALS( std::string("[test.cpp:5]: Memory leak: str\n"), errout.str() ); + } + + + void switch1() { check("void f()\n" diff --git a/testrunner.cbproj b/testrunner.cbproj index d59845d63..d04d16c6f 100644 --- a/testrunner.cbproj +++ b/testrunner.cbproj @@ -18,15 +18,15 @@ Base - true exe - NO_STRICT + true JPHNE + NO_STRICT true - true C:\cppcheck - CppConsoleApplication + true true + CppConsoleApplication . vclx.bpi;vcl.bpi;rtl.bpi;vclactnband.bpi false @@ -34,10 +34,10 @@ $(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;C:\cppcheck - false false - _DEBUG;$(Defines) + false true + _DEBUG;$(Defines) true false true @@ -48,8 +48,8 @@ bcb_Debug true true - $(BDS)\lib\debug;$(ILINK_LibraryPath) true + $(BDS)\lib\debug;$(ILINK_LibraryPath) Full true @@ -125,6 +125,9 @@ 15 + + 17 + tokenize.h 0