ValueFlow: Improved bailout when variable is reassigned

This commit is contained in:
Daniel Marjamäki 2014-05-03 12:49:07 +02:00
parent 4b7aaba159
commit 5a23b739da
4 changed files with 12 additions and 22 deletions

View File

@ -84,17 +84,8 @@ void Token::update_property_info()
_type = eString;
else if (_str.length() > 1 && _str[0] == '\'' && _str[_str.length()-1] == '\'')
_type = eChar;
else if (_str == "=" ||
_str == "+=" ||
_str == "-=" ||
_str == "*=" ||
_str == "/=" ||
_str == "%=" ||
_str == "&=" ||
_str == "^=" ||
_str == "|=" ||
_str == "<<=" ||
_str == ">>=")
else if (_str == "=" || _str == "<<=" || _str == ">>=" ||
(_str.size() == 2U && _str[1] == '=' && std::strchr("+-*/%&^|",_str[0])))
_type = eAssignmentOp;
else if (_str.size() == 1 && _str.find_first_of(",[]()?:") != std::string::npos)
_type = eExtendedOp;

View File

@ -417,14 +417,6 @@ static void compileUnaryOp(Token *&tok, void (*f)(Token *&, std::stack<Token*> &
op.push(unaryop);
}
static bool isAssignment(const Token *tok)
{
return (tok->str() == "=" ||
tok->str() == "<<=" ||
tok->str() == ">>=" ||
(tok->str().size() == 2U && tok->str()[1] == '=' && std::strchr("+-*/%&|^",tok->str()[0])));
}
static void compileBinOp(Token *&tok, void (*f)(Token *&, std::stack<Token*> &, unsigned int depth), std::stack<Token*> &op, unsigned int depth)
{
Token *binop = tok;
@ -433,7 +425,7 @@ static void compileBinOp(Token *&tok, void (*f)(Token *&, std::stack<Token*> &,
f(tok,op, depth);
// Assignment operators are executed in right-to-left order
if (tok && isAssignment(binop) && isAssignment(tok))
if (binop->isAssignmentOp() && tok && tok->isAssignmentOp())
compileBinOp(tok,f,op,depth);
// TODO: Should we check if op is empty.
@ -726,7 +718,7 @@ static void compileAssign(Token *&tok, std::stack<Token*> &op, unsigned int dept
{
compileTernaryOp(tok,op, depth);
while (tok) {
if (isAssignment(tok)) {
if (tok->isAssignmentOp()) {
compileBinOp(tok, compileTernaryOp, op, depth);
} else break;
}

View File

@ -678,7 +678,7 @@ static void valueFlowAfterAssign(TokenList *tokenlist, ErrorLogger *errorLogger,
if (tok2->varId() == varid) {
// bailout: assignment
if (Token::Match(tok2->previous(), "!!* %var% =")) {
if (Token::Match(tok2->previous(), "!!* %var% %op%") && tok2->next()->isAssignmentOp()) {
if (settings->debugwarnings)
bailout(tokenlist, errorLogger, tok2, "assignment of " + tok2->str());
break;

View File

@ -507,6 +507,13 @@ private:
"}";
ASSERT_EQUALS(false, testValueOfX(code, 4U, 9));
code = "void f() {\n"
" int x = 0;\n"
" y = x += z;\n"
" return x;\n"
"}";
ASSERT_EQUALS(false, testValueOfX(code, 4U, 0));
code = "void f() {\n"
" static int x = 2;\n"
" x++;\n"