Fixed #2442 (False positive: Memory leak when function returns in 'if' instead of 'else if')

This commit is contained in:
Daniel Marjamäki 2011-01-10 19:35:06 +01:00
parent 03093cb8c4
commit 2d92f1ff6a
2 changed files with 25 additions and 1 deletions

View File

@ -838,6 +838,10 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
{
Token *rethead = 0, *rettail = 0;
// variables whose value depends on if(!var). If one of these variables
// is used in a if-condition then generate "ifv" instead of "if".
std::set<unsigned int> extravar;
// The first token should be ";"
rethead = new Token(0);
rethead->str(";");
@ -1084,10 +1088,22 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
else if (Token::simpleMatch(tok, "if (") && notvar(tok->tokAt(2), varid, true))
{
addtoken(&rettail, tok, "if(!var)");
// parse the if-body.
// if a variable is assigned then add variable to "extravar".
for (const Token *tok2 = tok->next()->link()->tokAt(2); tok2; tok2 = tok2->next())
{
if (tok2->str() == "{")
tok2 = tok2->link();
else if (tok2->str() == "}")
break;
else if (Token::Match(tok2, "%var% ="))
extravar.insert(tok2->varId());
}
}
else
{
// Check if the condition depends on var somehow..
// Check if the condition depends on var or extravar somehow..
bool dep = false;
int innerParlevel = 0;
for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next())
@ -1138,6 +1154,10 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
break;
}
}
if (tok2->varId() && extravar.find(tok2->varId()) != extravar.end())
{
dep = true;
}
}
if (Token::Match(tok, "if ( ! %varid% &&", varid))

View File

@ -425,6 +425,10 @@ private:
ASSERT_EQUALS(";;use;if{}", getcode("char *s; if (x(&s)) { }", "s"));
ASSERT_EQUALS(";;use;if{}", getcode("char *s; if (!s || x(&s)) { }", "s"));
// if (ticket #2442)
ASSERT_EQUALS(";;;;if(!var){;}ifv{}", getcode("char *s; int x = 0; if (!s) { x = 2; } if (x) { }", "s"));
ASSERT_EQUALS(";;;;if(!var){;}if{}", getcode("char *s; int x = 0; if (!s) { x = 2; } if (y) { }", "s"));
// switch..
ASSERT_EQUALS(";;switch{case;;break;};", getcode("char *s; switch(a){case 1: break;};", "s"));