Memory leaks : Minor updates and refactoring

This commit is contained in:
Daniel Marjamäki 2008-12-10 19:15:41 +00:00
parent 41aa2f8810
commit 8bd4c4278a
2 changed files with 57 additions and 58 deletions

View File

@ -1,4 +1,4 @@
/* /*
* c++check - c/c++ syntax checking * c++check - c/c++ syntax checking
* Copyright (C) 2007 Daniel Marjamäki * Copyright (C) 2007 Daniel Marjamäki
* *
@ -287,8 +287,8 @@ void CheckMemoryLeakClass::MemoryLeak( const TOKEN *tok, const char varname[] )
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void CheckMemoryLeakClass::instoken(TOKEN *tok, const char str[]) void CheckMemoryLeakClass::instoken(TOKEN *tok, const char str[])
{ {
tok->insertToken( str ); tok->insertToken( str );
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -310,18 +310,18 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list<const TOKEN *>
TOKEN *rethead = 0, *rettail = 0; TOKEN *rethead = 0, *rettail = 0;
#define addtoken(_str) \ #define addtoken(_str) \
{ \ { \
if (rettail) \ if (rettail) \
{ \ { \
rettail->insertToken(_str); \ rettail->insertToken(_str); \
rettail = rettail->next(); \ rettail = rettail->next(); \
} \ } \
else \ else \
{ \ { \
rethead = new TOKEN; \ rethead = new TOKEN; \
rettail = rethead; \ rettail = rethead; \
rettail->setstr(_str); \ rettail->setstr(_str); \
} \ } \
\ \
rettail->linenr( tok->linenr() ); \ rettail->linenr( tok->linenr() ); \
rettail->fileIndex( tok->fileIndex() ); \ rettail->fileIndex( tok->fileIndex() ); \
@ -554,8 +554,8 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list<const TOKEN *>
} }
void CheckMemoryLeakClass::erase(TOKEN *begin, const TOKEN *end) void CheckMemoryLeakClass::erase(TOKEN *begin, const TOKEN *end)
{ {
TOKEN::eraseTokens( begin, end ); TOKEN::eraseTokens( begin, end );
} }
void CheckMemoryLeakClass::simplifycode(TOKEN *tok) void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
@ -599,8 +599,7 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
// Delete empty if that is not followed by an else // Delete empty if that is not followed by an else
if (tok2->tokAt(2) && if (tok2->tokAt(2) &&
(tok2->next()->str().find("if") == 0) && TOKEN::Match(tok2->next(), "if ;") &&
TOKEN::Match(tok2->tokAt(2), ";") &&
!TOKEN::Match(tok2->tokAt(3), "else")) !TOKEN::Match(tok2->tokAt(3), "else"))
{ {
erase(tok2, tok2->tokAt(2)); erase(tok2, tok2->tokAt(2));
@ -615,8 +614,8 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
} }
// TODO Make this more generic. Delete "if ; else use ; use" // TODO Make this more generic. Delete "if ; else use ; use"
if ( TOKEN::Match(tok2, "; if ; else use ; use") || if ( TOKEN::Match(tok2, "; if ; else assign|use ; assign|use") ||
TOKEN::Match(tok2, "; if use ; else ; use") ) TOKEN::Match(tok2, "; if assign|use ; else ; assign|use") )
{ {
erase( tok2, tok2->tokAt(4) ); erase( tok2, tok2->tokAt(4) );
done = false; done = false;
@ -626,7 +625,7 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
// Reduce "if dealloc ;" and "if use ;" that is not followed by an else.. // Reduce "if dealloc ;" and "if use ;" that is not followed by an else..
// If "--all" has been given these are deleted // If "--all" has been given these are deleted
// Otherwise, ony the "if" will be deleted // Otherwise, ony the "if" will be deleted
if ((TOKEN::Match(tok2, "[;{}] if dealloc ;") || TOKEN::Match(tok2, "[;{}] if use ;")) && if (TOKEN::Match(tok2, "[;{}] if assign|dealloc|use ;") &&
!TOKEN::Match(tok2->tokAt(4), "else")) !TOKEN::Match(tok2->tokAt(4), "else"))
{ {
if ( _settings._showAll ) if ( _settings._showAll )
@ -637,7 +636,7 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
} }
// Reduce "if(var) dealloc ;" and "if(var) use ;" that is not followed by an else.. // 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 ;")) && if (TOKEN::Match(tok2, "[;{}] if(var) assign|dealloc|use ;") &&
!TOKEN::Match(tok2->tokAt(4), "else")) !TOKEN::Match(tok2->tokAt(4), "else"))
{ {
erase(tok2, tok2->tokAt(2)); erase(tok2, tok2->tokAt(2));
@ -689,12 +688,12 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
} }
// Reducing if.. // Reducing if..
if (TOKEN::Match(tok2,"if dealloc ; else") || TOKEN::Match(tok2,"if use ; else")) if (TOKEN::Match(tok2,"if assign|dealloc|use ; else"))
{ {
erase(tok2, tok2->tokAt(2)); erase(tok2, tok2->tokAt(2));
done = false; done = false;
} }
if (TOKEN::Match(tok2,"[;{}] if { dealloc ; return ; }") && !TOKEN::Match(tok2->tokAt(8),"else")) if (TOKEN::Match(tok2,"[;{}] if { assign|dealloc|use ; return ; }") && !TOKEN::Match(tok2->tokAt(8),"else"))
{ {
erase(tok2,tok2->tokAt(8)); erase(tok2,tok2->tokAt(8));
done = false; done = false;
@ -715,18 +714,18 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
} }
// Reduce "do { alloc ; } " => "alloc ;" // Reduce "do { alloc ; } " => "alloc ;"
/* TODO : This could hide memory leaks
if ( TOKEN::Match(tok2->next(), "do { alloc ; }") ) if ( TOKEN::Match(tok2->next(), "do { alloc ; }") )
{ {
erase(tok2, tok2->tokAt(3)); erase(tok2, tok2->tokAt(3));
erase(tok2->next()->next(), tok2->tokAt(4)); erase(tok2->next()->next(), tok2->tokAt(4));
done = false; done = false;
} }
*/
// Reduce "loop if break ; => ";" // Reduce "loop if break ; => ";"
if ( TOKEN::Match( tok2->next(), "loop %var%" ) && if ( TOKEN::Match( tok2->next(), "loop if break|continue ; ") &&
tok2->tokAt(2)->str().find("if") == 0 && !TOKEN::Match(tok2->tokAt(5), "else") )
(TOKEN::Match( tok2->tokAt(3), "break ; ") || TOKEN::Match( tok2->tokAt(3), "continue ;")) &&
!TOKEN::Match(tok2->tokAt(5),"else") )
{ {
erase( tok2, tok2->tokAt(4) ); erase( tok2, tok2->tokAt(4) );
done = false; done = false;
@ -810,8 +809,8 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
done = false; done = false;
} }
// Reduce "if(var) use ;" => "use ;" // Reduce "if(var) assign|dealloc|use ;" => "assign|dealloc|use ;"
if ( TOKEN::Match(tok2->next(), "if(var) use ;") && !TOKEN::Match(tok2->tokAt(4),"else")) if ( TOKEN::Match(tok2->next(), "if(var) assign|dealloc|use ;") && !TOKEN::Match(tok2->tokAt(4),"else"))
{ {
erase( tok2, tok2->tokAt(2) ); erase( tok2, tok2->tokAt(2) );
done = false; done = false;
@ -839,14 +838,14 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
done = false; done = false;
} }
// Delete second use in "use ; use ;" // Delete first part in "use ; dealloc ;"
if (TOKEN::Match(tok2, "[;{}] use ; dealloc ;")) if (TOKEN::Match(tok2, "[;{}] use ; dealloc ;"))
{ {
erase(tok2, tok2->tokAt(3)); erase(tok2, tok2->tokAt(3));
done = false; done = false;
} }
// Delete first use in "use ; return use ;" // Delete first part in "use ; return use ;"
if (TOKEN::Match(tok2, "[;{}] use ; return use ;")) if (TOKEN::Match(tok2, "[;{}] use ; return use ;"))
{ {
erase(tok2, tok2->tokAt(2)); erase(tok2, tok2->tokAt(2));
@ -1164,7 +1163,7 @@ void CheckMemoryLeakClass::CheckMemoryLeak_ClassMembers_Variable( const std::vec
{ {
destructor << classname[i] << " :: "; destructor << classname[i] << " :: ";
} }
destructor << " ~" << classname.back() << " ("; destructor << " ~ " << classname.back() << " (";
// Pattern used in member function. "Var = ..." // Pattern used in member function. "Var = ..."
std::ostringstream varname_eq; std::ostringstream varname_eq;

View File

@ -1,4 +1,4 @@
/* /*
* c++check - c/c++ syntax checking * c++check - c/c++ syntax checking
* Copyright (C) 2007 Daniel Marjamäki * Copyright (C) 2007 Daniel Marjamäki
* *
@ -36,12 +36,12 @@ public:
{ } { }
private: private:
void check( const char code[] ) void check( const char code[], bool showAll = false )
{ {
// Tokenize.. // Tokenize..
Tokenizer tokenizer; Tokenizer tokenizer;
std::istringstream istr(code); std::istringstream istr(code);
tokenizer.tokenize( istr, "test.cpp" ); tokenizer.tokenize( istr, "test.cpp" );
tokenizer.setVarId(); tokenizer.setVarId();
tokenizer.simplifyTokenList(); tokenizer.simplifyTokenList();
@ -51,7 +51,7 @@ private:
// Check for memory leaks.. // Check for memory leaks..
Settings settings; Settings settings;
settings._debug = true; settings._debug = true;
settings._showAll = false; settings._showAll = showAll;
tokenizer.fillFunctionList(); tokenizer.fillFunctionList();
CheckMemoryLeakClass checkMemoryLeak( &tokenizer, settings, this ); CheckMemoryLeakClass checkMemoryLeak( &tokenizer, settings, this );
checkMemoryLeak.CheckMemoryLeak(); checkMemoryLeak.CheckMemoryLeak();
@ -116,8 +116,8 @@ private:
// TODO TEST_CASE( func7 ); // TODO TEST_CASE( func7 );
TEST_CASE( func8 ); // Using callback TEST_CASE( func8 ); // Using callback
// TODO TEST_CASE( class1 ); TEST_CASE( class1 );
// TODO TEST_CASE( class2 ); TEST_CASE( class2 );
TEST_CASE( throw1 ); TEST_CASE( throw1 );
@ -128,8 +128,8 @@ private:
TEST_CASE( realloc1 ); TEST_CASE( realloc1 );
TEST_CASE( realloc2 ); TEST_CASE( realloc2 );
TEST_CASE( assign ); TEST_CASE( assign );
// TODO TEST_CASE( varid ); // TODO TEST_CASE( varid );
} }
@ -881,7 +881,7 @@ private:
"Fred::~Fred()\n" "Fred::~Fred()\n"
"{\n" "{\n"
" delete [] str2;\n" " delete [] str2;\n"
"}\n" ); "}\n", true );
ASSERT_EQUALS( std::string("[test.cpp:1]: Memory leak: Fred::str1\n"), errout.str() ); ASSERT_EQUALS( std::string("[test.cpp:1]: Memory leak: Fred::str1\n"), errout.str() );
} }
@ -906,7 +906,7 @@ private:
"Fred::~Fred()\n" "Fred::~Fred()\n"
"{\n" "{\n"
" free(str1);\n" " free(str1);\n"
"}\n" ); "}\n", true );
ASSERT_EQUALS( std::string("[test.cpp:17]: Mismatching allocation and deallocation: Fred::str1\n"), errout.str() ); ASSERT_EQUALS( std::string("[test.cpp:17]: Mismatching allocation and deallocation: Fred::str1\n"), errout.str() );
} }
@ -1027,21 +1027,21 @@ private:
ASSERT_EQUALS( std::string(""), errout.str() ); ASSERT_EQUALS( std::string(""), errout.str() );
} }
void varid() void varid()
{ {
check( "void foo()\n" check( "void foo()\n"
"{\n" "{\n"
" char *p = malloc(100);\n" " char *p = malloc(100);\n"
" {\n" " {\n"
" char *p = 0;\n" " char *p = 0;\n"
" delete p;\n" " delete p;\n"
" }\n" " }\n"
" free(p);\n" " free(p);\n"
"}\n" ); "}\n" );
ASSERT_EQUALS( std::string(""), errout.str() ); ASSERT_EQUALS( std::string(""), errout.str() );
} }
}; };