Fixed #683 (wrong usage of strcmp)

This commit is contained in:
Daniel Marjamäki 2009-12-25 19:45:21 +01:00
parent 9b851a2a11
commit b5291825ce
4 changed files with 82 additions and 17 deletions

View File

@ -1277,6 +1277,20 @@ private:
return &tok;
}
bool parseCondition(const Token &tok, std::list<ExecutionPath *> &checks) const
{
if (Token::Match(&tok, "!| %var% ("))
{
bool foundError = false;
std::list<const Token *> var;
parseFunctionCall(tok.str() == "!" ? *tok.next() : tok, var, 0);
for (std::list<const Token *>::const_iterator it = var.begin(); it != var.end(); ++it)
dereference(foundError, checks, *it);
}
return ExecutionPath::parseCondition(tok, checks);
}
};
@ -1592,6 +1606,24 @@ private:
}
return &tok;
}
bool parseCondition(const Token &tok, std::list<ExecutionPath *> &checks) const
{
bool foundError = false;
if (tok.varId() && Token::Match(&tok, "%var% <|<=|==|!=|)|["))
use(foundError, checks, &tok);
else if (Token::Match(&tok, "!| %var% ("))
{
std::list<const Token *> var;
parseFunctionCall(tok.str() == "!" ? *tok.next() : tok, var, 1);
for (std::list<const Token *>::const_iterator it = var.begin(); it != var.end(); ++it)
use_array(foundError, checks, *it);
}
return ExecutionPath::parseCondition(tok, checks);
}
};

View File

@ -22,6 +22,32 @@
#include <memory>
// default : bail out if the condition is has variable handling
bool ExecutionPath::parseCondition(const Token &tok, std::list<ExecutionPath *> & /*checks*/) const
{
unsigned int parlevel = 0;
for (const Token *tok2 = &tok; tok2; tok2 = tok2->next())
{
if (tok2->str() == "(")
++parlevel;
else if (tok2->str() == ")")
{
if (parlevel == 0)
break;
--parlevel;
}
else if (Token::Match(tok2, ";{}"))
break;
if (tok2->varId() != 0)
{
return true;
}
}
return false;
}
const Token *checkExecutionPaths(const Token *tok, std::list<ExecutionPath *> &checks)
{
const std::auto_ptr<ExecutionPath> check(checks.front()->copy());
@ -70,24 +96,16 @@ const Token *checkExecutionPaths(const Token *tok, std::list<ExecutionPath *> &c
// goto "("
tok = tok->next();
// parse condition
if (check->parseCondition(*tok->next(), checks))
{
ExecutionPath::bailOut(checks);
return 0;
}
// goto ")"
tok = tok ? tok->link() : 0;
// Check if the condition contains the variable
if (tok)
{
for (const Token *tok2 = tok->link(); tok2 && tok2 != tok; tok2 = tok2->next())
{
// The variable may be initialized..
// if (someFunction(&var)) ..
if (tok2->varId())
{
ExecutionPath::bailOut(checks);
return 0;
}
}
}
// goto "{"
tok = tok ? tok->next() : 0;

View File

@ -80,11 +80,19 @@ public:
/**
* Parse tokens at given location
* @param tok token to parse
* @param foundError If an error is found this is set to true and the return token is the error token
* @param foundError If an error is found this is set to true
* @param checks The execution paths. All execution paths in the list are executed in the current scope.
* @return if error is found => error token. if you want to skip tokens, return the last skipped token. otherwise return tok.
* @return the token before the "next" token.
**/
virtual const Token *parse(const Token &tok, bool &foundError, std::list<ExecutionPath *> &checks) const = 0;
/**
* Parse condition
* @param tok first token in condition.
* @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;
};

View File

@ -998,6 +998,13 @@ private:
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: ret\n", errout.str());
checkUninitVar("static void foo()\n"
"{\n"
" int i;\n"
" if (i);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: i\n", errout.str());
checkUninitVar("static void foo()\n"
"{\n"
" int x, y;\n"