Memory leak: Added test case that failed. And fixed it.

This commit is contained in:
Daniel Marjamäki 2008-11-16 05:57:41 +00:00
parent 0a638a57d0
commit d11e93f475
2 changed files with 73 additions and 60 deletions

View File

@ -40,16 +40,16 @@
#endif #endif
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
CheckMemoryLeakClass::CheckMemoryLeakClass( Tokenizer *tokenizer ) CheckMemoryLeakClass::CheckMemoryLeakClass( Tokenizer *tokenizer )
{ {
_tokenizer = tokenizer; _tokenizer = tokenizer;
} }
CheckMemoryLeakClass::~CheckMemoryLeakClass() CheckMemoryLeakClass::~CheckMemoryLeakClass()
{ {
} }
bool CheckMemoryLeakClass::isclass( const std::string &typestr ) bool CheckMemoryLeakClass::isclass( const std::string &typestr )
{ {
@ -276,9 +276,8 @@ bool CheckMemoryLeakClass::notvar(const TOKEN *tok, const char *varnames[])
return bool( Match(tok, "! %var1% [;)&|]", varnames) || return bool( Match(tok, "! %var1% [;)&|]", varnames) ||
Match(tok, "! ( %var1% )", varnames) || Match(tok, "! ( %var1% )", varnames) ||
Match(tok, "unlikely ( ! %var1% )", varnames) || Match(tok, "unlikely ( ! %var1% )", varnames) ||
Match(tok, "unlikely ( %var1% == NULL )", varnames) || Match(tok, "unlikely ( %var1% == 0 )", varnames) ||
Match(tok, "%var1% == NULL", varnames) || Match(tok, "0 == %var1% [;)&|]", varnames) ||
Match(tok, "NULL == %var1% [;)&|]", varnames) ||
Match(tok, "%var1% == 0", varnames) ); Match(tok, "%var1% == 0", varnames) );
} }
@ -461,19 +460,19 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, const char typestr[], con
// Linux lists.. // Linux lists..
if ( Match( tok, "[=(,] & %var1% [.[]", varnames ) ) if ( Match( tok, "[=(,] & %var1% [.[]", varnames ) )
{ {
// Linux list -> the first member of the struct // Linux list -> the first member of the struct
std::string pattern("struct " + std::string(typestr) + " {"); std::string pattern("struct " + std::string(typestr) + " {");
const TOKEN *tok2 = findmatch(tokens, pattern.c_str()); const TOKEN *tok2 = findmatch(tokens, pattern.c_str());
if ( ! tok2 ) if ( ! tok2 )
{ {
addtoken("use"); addtoken("use");
} }
else else
{ {
tok2 = findmatch(tok2, "%var% [;,]"); tok2 = findmatch(tok2, "%var% [;,]");
if ( !tok2 || Match(tok2, Tokenizer::getstr(tok, 4)) ) if ( !tok2 || Match(tok2, Tokenizer::getstr(tok, 4)) )
addtoken("use"); addtoken("use");
} }
} }
} }

View File

@ -39,8 +39,8 @@ private:
void check( const char code[] ) void check( const char code[] )
{ {
// Tokenize.. // Tokenize..
Tokenizer tokenizer; Tokenizer tokenizer;
tokenizer.getFiles()->push_back( "test.cpp" ); tokenizer.getFiles()->push_back( "test.cpp" );
std::istringstream istr(code); std::istringstream istr(code);
tokenizer.TokenizeCode( istr ); tokenizer.TokenizeCode( istr );
tokenizer.SimplifyTokenList(); tokenizer.SimplifyTokenList();
@ -49,9 +49,9 @@ private:
errout.str(""); errout.str("");
// Check for memory leaks.. // Check for memory leaks..
ShowAll = false; ShowAll = false;
Settings settings; Settings settings;
settings._checkCodingStyle = true; settings._checkCodingStyle = true;
tokenizer.settings( settings ); tokenizer.settings( settings );
tokenizer.FillFunctionList(0); tokenizer.FillFunctionList(0);
CheckMemoryLeakClass checkMemoryLeak( &tokenizer ); CheckMemoryLeakClass checkMemoryLeak( &tokenizer );
@ -85,6 +85,7 @@ private:
TEST_CASE( ifelse9 ); TEST_CASE( ifelse9 );
TEST_CASE( if1 ); TEST_CASE( if1 );
TEST_CASE( if2 );
TEST_CASE( forwhile1 ); TEST_CASE( forwhile1 );
TEST_CASE( forwhile2 ); TEST_CASE( forwhile2 );
@ -116,8 +117,8 @@ private:
TEST_CASE( throw1 ); TEST_CASE( throw1 );
TEST_CASE( linux_list_1 ); TEST_CASE( linux_list_1 );
TEST_CASE( linux_list_2 ); TEST_CASE( linux_list_2 );
TEST_CASE( sizeof1 ); TEST_CASE( sizeof1 );
} }
@ -399,6 +400,19 @@ private:
ASSERT_EQUALS( std::string("[test.cpp:6]: Memory leak: p\n"), errout.str() ); ASSERT_EQUALS( std::string("[test.cpp:6]: Memory leak: p\n"), errout.str() );
} }
void if2()
{
check( "void f()\n"
"{\n"
" struct smp_alt_module *smp;\n"
" smp = kzalloc(sizeof(*smp), GFP_KERNEL);\n"
" if (NULL == smp)\n"
" return;\n"
" kfree( smp );\n"
"}\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
}
@ -860,34 +874,34 @@ private:
ASSERT_EQUALS( std::string("[test.cpp:10]: Memory leak: ab\n"), errout.str() ); ASSERT_EQUALS( std::string("[test.cpp:10]: Memory leak: ab\n"), errout.str() );
} }
void sizeof1() void sizeof1()
{ {
check( "void f()\n" check( "void f()\n"
"{\n" "{\n"
" struct s_t s1;\n" " struct s_t s1;\n"
" struct s_t cont *p = &s1;\n" " struct s_t cont *p = &s1;\n"
" struct s_t *s2;\n" " struct s_t *s2;\n"
"\n" "\n"
" memset(p, 0, sizeof(*p));\n" " memset(p, 0, sizeof(*p));\n"
"\n" "\n"
" s2 = (struct s_t *) malloc(sizeof(*s2));\n" " s2 = (struct s_t *) malloc(sizeof(*s2));\n"
"\n" "\n"
" if (s2->value != 0)\n" " if (s2->value != 0)\n"
" return;\n" " return;\n"
"\n" "\n"
" free(s2);\n" " free(s2);\n"
"\n" "\n"
" return;\n" " return;\n"
"}\n" ); "}\n" );
std::string err( errout.str() ); std::string err( errout.str() );
ASSERT_EQUALS( std::string("[test.cpp:12]: Memory leak: s2\n"), err ); ASSERT_EQUALS( std::string("[test.cpp:12]: Memory leak: s2\n"), err );
} }
}; };
REGISTER_TEST( TestMemleak ) REGISTER_TEST( TestMemleak )