ExecutionPath: Refactoring if-handling

This commit is contained in:
Daniel Marjamäki 2009-12-25 20:50:23 +01:00
parent 7bf0622ae0
commit 9819b75e17
4 changed files with 34 additions and 15 deletions

View File

@ -1278,7 +1278,7 @@ private:
return &tok;
}
bool parseCondition(const Token &tok, std::list<ExecutionPath *> &checks) const
bool parseCondition(const Token &tok, std::list<ExecutionPath *> &checks)
{
if (Token::Match(&tok, "!| %var% ("))
{
@ -1607,7 +1607,7 @@ private:
return &tok;
}
bool parseCondition(const Token &tok, std::list<ExecutionPath *> &checks) const
bool parseCondition(const Token &tok, std::list<ExecutionPath *> &checks)
{
bool foundError = false;

View File

@ -23,8 +23,13 @@
// default : bail out if the condition is has variable handling
bool ExecutionPath::parseCondition(const Token &tok, std::list<ExecutionPath *> & /*checks*/) const
bool ExecutionPath::parseCondition(const Token &tok, std::list<ExecutionPath *> & checks)
{
if (Token::Match(tok.tokAt(-3), "!!else if ("))
{
++ifinfo;
}
unsigned int parlevel = 0;
for (const Token *tok2 = &tok; tok2; tok2 = tok2->next())
{
@ -40,7 +45,10 @@ bool ExecutionPath::parseCondition(const Token &tok, std::list<ExecutionPath *>
break;
if (tok2->varId() != 0)
{
return true;
if (ifinfo > 1)
return true;
else
bailOutVar(checks, tok2->varId());
}
}
@ -52,9 +60,6 @@ static const Token *checkExecutionPaths_(const Token *tok, std::list<ExecutionPa
{
const std::auto_ptr<ExecutionPath> check(checks.front()->copy());
// Number of "if" blocks in current scope
unsigned int numberOfIf = 0;
for (; tok; tok = tok->next())
{
if (tok->str() == "}")
@ -86,10 +91,6 @@ static const Token *checkExecutionPaths_(const Token *tok, std::list<ExecutionPa
if (tok->str() == "if")
{
++numberOfIf;
if (numberOfIf > 1)
return 0;
std::list<ExecutionPath *> newchecks;
while (tok->str() == "if")
{
@ -99,7 +100,12 @@ static const Token *checkExecutionPaths_(const Token *tok, std::list<ExecutionPa
// parse condition
if (check->parseCondition(*tok->next(), checks))
{
ExecutionPath::bailOut(checks);
while (!checks.empty())
{
delete checks.back();
checks.pop_back();
}
return 0;
}

View File

@ -41,14 +41,18 @@ protected:
Check * const owner;
public:
ExecutionPath(Check *c, unsigned int id) : bailout_(false), varId(id), owner(c)
ExecutionPath(Check *c, unsigned int id) : bailout_(false), varId(id), owner(c), ifinfo(0)
{ }
virtual ~ExecutionPath()
{ }
/** Implement this in each derived class. This function must create a copy of the current instance */
virtual ExecutionPath *copy() = 0;
/** Some kind of if-information */
unsigned int ifinfo;
bool bailOut() const
{
return bailout_;
@ -92,7 +96,7 @@ public:
* @param checks The execution paths. All execution paths in the list are executed in the current scope
* @return true => bail out all checking
**/
virtual bool parseCondition(const Token &tok, std::list<ExecutionPath *> &checks) const;
virtual bool parseCondition(const Token &tok, std::list<ExecutionPath *> &checks);
/** going out of scope - all execution paths end */
virtual void end(const std::list<ExecutionPath *> & /*checks*/, const Token * /*tok*/) const

View File

@ -1005,6 +1005,15 @@ private:
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: i\n", errout.str());
checkUninitVar("static int foo(int x)\n"
"{\n"
" int i;\n"
" if (x)\n"
" i = 0;\n"
" return i;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: i\n", errout.str());
checkUninitVar("static void foo()\n"
"{\n"
" int x, y;\n"
@ -1139,7 +1148,7 @@ private:
"}\n");
ASSERT_EQUALS("", errout.str());
checkUninitVar("static void foo()\n"
checkUninitVar("static void foo(int x)\n"
"{\n"
" Foo *p;\n"
" if (x)\n"