Fixed #1160 (Null pointer dereference vs. goto)

This commit is contained in:
Daniel Marjamäki 2009-12-29 09:17:07 +01:00
parent 58e85d55e3
commit cfdf2b8cfe
3 changed files with 43 additions and 30 deletions

View File

@ -56,16 +56,6 @@ bool ExecutionPath::parseCondition(const Token &tok, std::list<ExecutionPath *>
}
static void dealloc_checks(std::list<ExecutionPath *> &checks)
{
while (!checks.empty())
{
delete checks.back();
checks.pop_back();
}
}
static const Token *checkExecutionPaths_(const Token *tok, std::list<ExecutionPath *> &checks)
{
const std::auto_ptr<ExecutionPath> check(checks.front()->copy());
@ -110,8 +100,8 @@ static const Token *checkExecutionPaths_(const Token *tok, std::list<ExecutionPa
// parse condition
if (checks.size() > 10 || check->parseCondition(*tok->next(), checks))
{
dealloc_checks(checks);
dealloc_checks(newchecks);
ExecutionPath::bailOut(checks);
ExecutionPath::bailOut(newchecks);
return 0;
}
@ -123,8 +113,8 @@ static const Token *checkExecutionPaths_(const Token *tok, std::list<ExecutionPa
if (!Token::simpleMatch(tok, "{"))
{
dealloc_checks(checks);
dealloc_checks(newchecks);
ExecutionPath::bailOut(checks);
ExecutionPath::bailOut(newchecks);
return 0;
}
@ -137,8 +127,8 @@ static const Token *checkExecutionPaths_(const Token *tok, std::list<ExecutionPa
const Token *tokerr = checkExecutionPaths_(tok->next(), c);
if (tokerr)
{
dealloc_checks(c);
dealloc_checks(newchecks);
ExecutionPath::bailOut(c);
ExecutionPath::bailOut(newchecks);
return tokerr;
}
while (!c.empty())
@ -164,14 +154,14 @@ static const Token *checkExecutionPaths_(const Token *tok, std::list<ExecutionPa
const Token *tokerr = checkExecutionPaths_(tok->next(), checks);
if (tokerr)
{
dealloc_checks(newchecks);
ExecutionPath::bailOut(newchecks);
return tokerr;
}
tok = tok->link();
if (!tok)
{
dealloc_checks(newchecks);
ExecutionPath::bailOut(newchecks);
return 0;
}
}

View File

@ -62,11 +62,13 @@ public:
* bail out all execution paths
* @param checks the execution paths to bail out on
**/
static void bailOut(const std::list<ExecutionPath *> &checks)
static void bailOut(std::list<ExecutionPath *> &checks)
{
std::list<ExecutionPath *>::const_iterator it;
for (it = checks.begin(); it != checks.end(); ++it)
(*it)->bailout_ = true;
while (!checks.empty())
{
delete checks.back();
checks.pop_back();
}
}
/**
@ -74,11 +76,24 @@ public:
* @param checks the execution paths to bail out on
* @param varid the specific variable id
**/
static void bailOutVar(const std::list<ExecutionPath *> &checks, const unsigned int varid)
static void bailOutVar(std::list<ExecutionPath *> &checks, const unsigned int varid)
{
std::list<ExecutionPath *>::const_iterator it;
for (it = checks.begin(); it != checks.end(); ++it)
(*it)->bailout_ |= ((*it)->varId == varid);
if (varid == 0)
return;
std::list<ExecutionPath *>::iterator it = checks.begin();
while (it != checks.end())
{
if ((*it)->varId == varid)
{
delete *it;
checks.erase(it++);
}
else
{
++it;
}
}
}
/**

View File

@ -932,6 +932,14 @@ private:
" p->abcd();\n"
"}\n");
ASSERT_EQUALS("", errout.str());
checkNullPointer("static void foo(int a)\n"
"{\n"
" Foo *p = 0;\n"
" if (a && p)\n"
" p->do_something();\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void nullpointer7()