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

View File

@ -62,11 +62,13 @@ public:
* bail out all execution paths * bail out all execution paths
* @param checks the execution paths to bail out on * @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; while (!checks.empty())
for (it = checks.begin(); it != checks.end(); ++it) {
(*it)->bailout_ = true; delete checks.back();
checks.pop_back();
}
} }
/** /**
@ -74,11 +76,24 @@ public:
* @param checks the execution paths to bail out on * @param checks the execution paths to bail out on
* @param varid the specific variable id * @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; if (varid == 0)
for (it = checks.begin(); it != checks.end(); ++it) return;
(*it)->bailout_ |= ((*it)->varId == varid);
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" " p->abcd();\n"
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str()); 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() void nullpointer7()