Memory leak: Added check "TestMemoryLeak::throw2" (no false positive upon throw)
This commit is contained in:
parent
801f2c246d
commit
a01ebc819f
|
@ -566,8 +566,8 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list<const TOKEN *>
|
||||||
}
|
}
|
||||||
|
|
||||||
// throw..
|
// throw..
|
||||||
if ( tok->str() == "throw" )
|
if ( TOKEN::Match(tok, "try|throw|catch") )
|
||||||
addtoken("throw");
|
addtoken(tok->strAt(0));
|
||||||
|
|
||||||
// Assignment..
|
// Assignment..
|
||||||
if ( TOKEN::Match(tok,"[)=] %var1% [+;)]", varnames) ||
|
if ( TOKEN::Match(tok,"[)=] %var1% [+;)]", varnames) ||
|
||||||
|
@ -616,6 +616,25 @@ void CheckMemoryLeakClass::erase(TOKEN *begin, const TOKEN *end)
|
||||||
|
|
||||||
void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
||||||
{
|
{
|
||||||
|
// Replace "throw" that is not in a try block with "return"
|
||||||
|
int indentlevel = 0;
|
||||||
|
int trylevel = -1;
|
||||||
|
for (TOKEN *tok2 = tok; tok2; tok2 = tok2->next())
|
||||||
|
{
|
||||||
|
if ( tok2->str() == "{" )
|
||||||
|
++indentlevel;
|
||||||
|
else if ( tok2->str() == "}" )
|
||||||
|
{
|
||||||
|
--indentlevel;
|
||||||
|
if ( indentlevel <= trylevel )
|
||||||
|
trylevel = -1;
|
||||||
|
}
|
||||||
|
else if ( trylevel == -1 && tok2->str() == "try" )
|
||||||
|
trylevel = indentlevel;
|
||||||
|
else if ( trylevel == -1 && tok2->str() == "throw" )
|
||||||
|
tok2->setstr("return");
|
||||||
|
}
|
||||||
|
|
||||||
// reduce the code..
|
// reduce the code..
|
||||||
bool done = false;
|
bool done = false;
|
||||||
while ( ! done )
|
while ( ! done )
|
||||||
|
@ -779,6 +798,12 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
||||||
done = false;
|
done = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove "catch ;"
|
||||||
|
if ( TOKEN::simpleMatch(tok2->next(), "catch ;") )
|
||||||
|
{
|
||||||
|
erase(tok2, tok2->tokAt(3));
|
||||||
|
done = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Reduce "if* ;" that is not followed by an else..
|
// Reduce "if* ;" that is not followed by an else..
|
||||||
if (TOKEN::Match(tok2->next(), "if(var)|if(!var)|if(true)|if(false)|ifv ; !!else") )
|
if (TOKEN::Match(tok2->next(), "if(var)|if(!var)|if(true)|if(false)|ifv ; !!else") )
|
||||||
|
@ -1032,12 +1057,6 @@ void CheckMemoryLeakClass::simplifycode(TOKEN *tok)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( TOKEN::Match(tok2, "throw") )
|
|
||||||
{
|
|
||||||
tok2->setstr( "return" );
|
|
||||||
done = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,6 +131,7 @@ private:
|
||||||
// TODO TEST_CASE( class3 );
|
// TODO TEST_CASE( class3 );
|
||||||
|
|
||||||
TEST_CASE( throw1 );
|
TEST_CASE( throw1 );
|
||||||
|
TEST_CASE( throw2 );
|
||||||
|
|
||||||
TEST_CASE( linux_list_1 );
|
TEST_CASE( linux_list_1 );
|
||||||
|
|
||||||
|
@ -1138,6 +1139,27 @@ private:
|
||||||
ASSERT_EQUALS( std::string("[test.cpp:5]: Memory leak: str\n"), errout.str() );
|
ASSERT_EQUALS( std::string("[test.cpp:5]: Memory leak: str\n"), errout.str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void throw2()
|
||||||
|
{
|
||||||
|
check( "void foo()\n"
|
||||||
|
"{\n"
|
||||||
|
" char *str = 0;\n"
|
||||||
|
" try\n"
|
||||||
|
" {\n"
|
||||||
|
" str = new char[100];\n"
|
||||||
|
" if ( somecondition )\n"
|
||||||
|
" throw exception;\n"
|
||||||
|
" delete [] str;\n"
|
||||||
|
" }\n"
|
||||||
|
" catch ( ... )\n"
|
||||||
|
" {\n"
|
||||||
|
" delete [] str;\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n" );
|
||||||
|
|
||||||
|
ASSERT_EQUALS( std::string(""), errout.str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue