Memory leak: Added test case that failed. And fixed it.
This commit is contained in:
parent
0a638a57d0
commit
d11e93f475
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 )
|
||||||
|
|
Loading…
Reference in New Issue