Memory Leak: Handling Linux lists better => Detect more leaks
This commit is contained in:
parent
43dcf6efd6
commit
2cbfa6b60b
|
@ -188,7 +188,7 @@ AllocType CheckMemoryLeakClass::GetDeallocationType( const TOKEN *tok, const cha
|
||||||
|
|
||||||
static std::list<std::string> callstack;
|
static std::list<std::string> callstack;
|
||||||
|
|
||||||
const char * CheckMemoryLeakClass::call_func( const TOKEN *tok, const char *varnames[] )
|
const char * CheckMemoryLeakClass::call_func( const TOKEN *tok, const char typestr[], const char *varnames[] )
|
||||||
{
|
{
|
||||||
if (Match(tok,"if") || Match(tok,"for") || Match(tok,"while"))
|
if (Match(tok,"if") || Match(tok,"for") || Match(tok,"while"))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -227,7 +227,7 @@ const char * CheckMemoryLeakClass::call_func( const TOKEN *tok, const char *varn
|
||||||
// Check if the function deallocates the variable..
|
// Check if the function deallocates the variable..
|
||||||
while ( ftok && ! Match(ftok,"{") )
|
while ( ftok && ! Match(ftok,"{") )
|
||||||
ftok = ftok->next;
|
ftok = ftok->next;
|
||||||
TOKEN *func = getcode( Tokenizer::gettok(ftok,1), parname );
|
TOKEN *func = getcode( Tokenizer::gettok(ftok,1), typestr, parname );
|
||||||
simplifycode( func );
|
simplifycode( func );
|
||||||
const char *ret = 0;
|
const char *ret = 0;
|
||||||
if (findmatch(func, "goto"))
|
if (findmatch(func, "goto"))
|
||||||
|
@ -291,7 +291,7 @@ extern bool ShowAll;
|
||||||
* varname - name of variable
|
* varname - name of variable
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, const char varname[])
|
TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, const char typestr[], const char varname[])
|
||||||
{
|
{
|
||||||
const char *varnames[2];
|
const char *varnames[2];
|
||||||
varnames[0] = varname;
|
varnames[0] = varname;
|
||||||
|
@ -454,7 +454,7 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, const char varname[])
|
||||||
// Investigate function calls..
|
// Investigate function calls..
|
||||||
if ( Match(tok, "%var% (") )
|
if ( Match(tok, "%var% (") )
|
||||||
{
|
{
|
||||||
const char *str = call_func(tok, varnames);
|
const char *str = call_func(tok, typestr, varnames);
|
||||||
if ( str )
|
if ( str )
|
||||||
addtoken( str );
|
addtoken( str );
|
||||||
}
|
}
|
||||||
|
@ -462,8 +462,19 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, const char varname[])
|
||||||
// Linux lists..
|
// Linux lists..
|
||||||
if ( Match( tok, "[=(,] & %var1% [.[]", varnames ) )
|
if ( Match( tok, "[=(,] & %var1% [.[]", varnames ) )
|
||||||
{
|
{
|
||||||
// todo: better checking
|
// Linux list -> the first member of the struct
|
||||||
addtoken("use");
|
std::string pattern("struct " + std::string(typestr) + " {");
|
||||||
|
const TOKEN *tok2 = findmatch(tokens, pattern.c_str());
|
||||||
|
if ( ! tok2 )
|
||||||
|
{
|
||||||
|
addtoken("use");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tok2 = findmatch(tok2, "%var% [;,]");
|
||||||
|
if ( !tok2 || Match(tok2, Tokenizer::getstr(tok, 4)) )
|
||||||
|
addtoken("use");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -766,11 +777,11 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
||||||
|
|
||||||
|
|
||||||
// Simpler but less powerful than "CheckMemoryLeak_CheckScope_All"
|
// Simpler but less powerful than "CheckMemoryLeak_CheckScope_All"
|
||||||
void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] )
|
void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char typestr[], const char varname[] )
|
||||||
{
|
{
|
||||||
callstack.clear();
|
callstack.clear();
|
||||||
|
|
||||||
TOKEN *tok = getcode( Tok1, varname );
|
TOKEN *tok = getcode( Tok1, typestr, varname );
|
||||||
|
|
||||||
// If the variable is not allocated at all => no memory leak
|
// If the variable is not allocated at all => no memory leak
|
||||||
if (findmatch(tok, "alloc") == 0)
|
if (findmatch(tok, "alloc") == 0)
|
||||||
|
@ -866,10 +877,10 @@ void CheckMemoryLeakClass::CheckMemoryLeak_InFunction()
|
||||||
if (indentlevel>0 && infunc)
|
if (indentlevel>0 && infunc)
|
||||||
{
|
{
|
||||||
if ( Match(tok, "[{};] %type% * %var% [;=]") )
|
if ( Match(tok, "[{};] %type% * %var% [;=]") )
|
||||||
CheckMemoryLeak_CheckScope( tok->next, Tokenizer::getstr(tok, 3) );
|
CheckMemoryLeak_CheckScope( tok->next, Tokenizer::getstr(tok, 1), Tokenizer::getstr(tok, 3) );
|
||||||
|
|
||||||
else if ( Match(tok, "[{};] %type% %type% * %var% [;=]") )
|
else if ( Match(tok, "[{};] %type% %type% * %var% [;=]") )
|
||||||
CheckMemoryLeak_CheckScope( tok->next, Tokenizer::getstr(tok, 4) );
|
CheckMemoryLeak_CheckScope( tok->next, Tokenizer::getstr(tok, 2), Tokenizer::getstr(tok, 4) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,16 +42,16 @@ private:
|
||||||
void CheckMemoryLeak_ClassMembers_ParseClass( const TOKEN *tok1, std::vector<const char *> &classname );
|
void CheckMemoryLeak_ClassMembers_ParseClass( const TOKEN *tok1, std::vector<const char *> &classname );
|
||||||
void CheckMemoryLeak_ClassMembers();
|
void CheckMemoryLeak_ClassMembers();
|
||||||
void CheckMemoryLeak_InFunction();
|
void CheckMemoryLeak_InFunction();
|
||||||
void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] );
|
void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char typestr[], const char varname[] );
|
||||||
void simplifycode(TOKEN *tok);
|
void simplifycode(TOKEN *tok);
|
||||||
void erase(TOKEN *begin, const TOKEN *end);
|
void erase(TOKEN *begin, const TOKEN *end);
|
||||||
|
|
||||||
TOKEN *getcode(const TOKEN *tok, const char varname[]);
|
TOKEN *getcode(const TOKEN *tok, const char typestr[], const char varname[]);
|
||||||
bool notvar(const TOKEN *tok, const char *varnames[]);
|
bool notvar(const TOKEN *tok, const char *varnames[]);
|
||||||
void instoken(TOKEN *tok, const char str[]);
|
void instoken(TOKEN *tok, const char str[]);
|
||||||
void MemoryLeak( const TOKEN *tok, const char varname[] );
|
void MemoryLeak( const TOKEN *tok, const char varname[] );
|
||||||
void MismatchError( const TOKEN *Tok1, const char varname[] );
|
void MismatchError( const TOKEN *Tok1, const char varname[] );
|
||||||
const char * call_func( const TOKEN *tok, const char *varnames[] );
|
const char * call_func( const TOKEN *tok, const char typestr[], const char *varnames[] );
|
||||||
AllocType GetDeallocationType( const TOKEN *tok, const char *varnames[] );
|
AllocType GetDeallocationType( const TOKEN *tok, const char *varnames[] );
|
||||||
AllocType GetAllocationType( const TOKEN *tok2 );
|
AllocType GetAllocationType( const TOKEN *tok2 );
|
||||||
bool isclass( const std::string &typestr );
|
bool isclass( const std::string &typestr );
|
||||||
|
|
|
@ -113,7 +113,7 @@ private:
|
||||||
TEST_CASE( throw1 );
|
TEST_CASE( throw1 );
|
||||||
|
|
||||||
TEST_CASE( linux_list_1 );
|
TEST_CASE( linux_list_1 );
|
||||||
// TODO: TEST_CASE( linux_list_2 );
|
TEST_CASE( linux_list_2 );
|
||||||
|
|
||||||
TEST_CASE( sizeof1 );
|
TEST_CASE( sizeof1 );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue