Fixed #493 (Memory leak: False positive when using the exit(0))

This commit is contained in:
Daniel Marjamäki 2009-07-23 16:30:30 +02:00
parent d0f1d885ed
commit 565ac2fca6
2 changed files with 56 additions and 30 deletions

View File

@ -895,7 +895,10 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
// exit.. // exit..
if (Token::Match(tok->previous(), "[{};] exit ( %any% ) ;")) if (Token::Match(tok->previous(), "[{};] exit ( %any% ) ;"))
{
addtoken("exit"); addtoken("exit");
tok = tok->tokAt(3);
}
// Assignment.. // Assignment..
if (Token::Match(tok, std::string("[)=] " + varnameStr + " [+;)]").c_str()) || if (Token::Match(tok, std::string("[)=] " + varnameStr + " [+;)]").c_str()) ||
@ -1006,36 +1009,6 @@ void CheckMemoryLeakInFunction::simplifycode(Token *tok, bool &all)
tok2->str("return"); tok2->str("return");
} }
// simplify "exit".. remove everything in its execution path
for (Token *tok2 = tok; tok2; tok2 = tok2->next())
{
if (tok2->str() != "exit")
continue;
// Found an "exit".. try to remove everything before it
Token *tokEnd = tok2->next();
int indentlevel = 0;
while (tok2->previous())
{
tok2 = tok2->previous();
if (tok2->str() == "}")
{
indentlevel--;
}
else if (tok2->str() == "{")
{
if (indentlevel == 0)
break;
indentlevel++;
}
}
Token::eraseTokens(tok2, tokEnd);
tok2 = tokEnd;
}
// If "--all" is given, remove all "callfunc".. // If "--all" is given, remove all "callfunc"..
if (_settings->_showAll) if (_settings->_showAll)
{ {
@ -1257,6 +1230,27 @@ void CheckMemoryLeakInFunction::simplifycode(Token *tok, bool &all)
done = false; done = false;
} }
// Reduce "alloc|dealloc|use ; exit ;" => "; exit ;"
if (Token::Match(tok2, "alloc|dealloc|use ; exit ;"))
{
tok2->deleteThis();
done = false;
}
// Reduce "alloc|dealloc|use ; if(var) exit ;"
if (Token::Match(tok2, "alloc|dealloc|use ; if(var) exit ;"))
{
tok2->deleteThis();
done = false;
}
// Remove "if exit ;"
if (Token::simpleMatch(tok2, "if exit ;"))
{
tok2->deleteThis();
tok2->deleteThis();
done = false;
}
// Replace "dealloc use ;" with "dealloc ;" // Replace "dealloc use ;" with "dealloc ;"
if (Token::simpleMatch(tok2, "dealloc use ;")) if (Token::simpleMatch(tok2, "dealloc use ;"))
@ -1485,6 +1479,8 @@ void CheckMemoryLeakInFunction::simplifycode(Token *tok, bool &all)
} }
} }
} }
} }

View File

@ -265,6 +265,8 @@ private:
// Using the function "exit" // Using the function "exit"
TEST_CASE(exit1); TEST_CASE(exit1);
TEST_CASE(exit2); TEST_CASE(exit2);
TEST_CASE(exit3);
TEST_CASE(exit4);
TEST_CASE(stdstring); TEST_CASE(stdstring);
TEST_CASE(strndup_function); TEST_CASE(strndup_function);
@ -2118,6 +2120,34 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void exit3()
{
check("void f()\n"
"{\n"
" char *p = malloc(100);\n"
" if (p)\n"
" {\n"
" exit(0);\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void exit4()
{
check("void f()\n"
"{\n"
" char *p = malloc(100);\n"
" if (x)\n"
" {\n"
" exit(0);\n"
" }\n"
"}\n");
ASSERT_EQUALS("[test.cpp:8]: (error) Memory leak: p\n", errout.str());
}
void stdstring() void stdstring()
{ {
check("void f(std::string foo)\n" check("void f(std::string foo)\n"