Memory leaks : Minor updates and refactoring
This commit is contained in:
parent
41aa2f8810
commit
8bd4c4278a
|
@ -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;
|
||||||
|
|
|
@ -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() );
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue