Fixed #1160 (Null pointer dereference vs. goto)
This commit is contained in:
parent
58e85d55e3
commit
cfdf2b8cfe
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue