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)
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue