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; _type = eString;
else if (_str.length() > 1 && _str[0] == '\'' && _str[_str.length()-1] == '\'') else if (_str.length() > 1 && _str[0] == '\'' && _str[_str.length()-1] == '\'')
_type = eChar; _type = eChar;
else if (_str == "=" || else if (_str == "=" || _str == "<<=" || _str == ">>=" ||
_str == "+=" || (_str.size() == 2U && _str[1] == '=' && std::strchr("+-*/%&^|",_str[0])))
_str == "-=" ||
_str == "*=" ||
_str == "/=" ||
_str == "%=" ||
_str == "&=" ||
_str == "^=" ||
_str == "|=" ||
_str == "<<=" ||
_str == ">>=")
_type = eAssignmentOp; _type = eAssignmentOp;
else if (_str.size() == 1 && _str.find_first_of(",[]()?:") != std::string::npos) else if (_str.size() == 1 && _str.find_first_of(",[]()?:") != std::string::npos)
_type = eExtendedOp; _type = eExtendedOp;

View File

@ -417,14 +417,6 @@ static void compileUnaryOp(Token *&tok, void (*f)(Token *&, std::stack<Token*> &
op.push(unaryop); 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) static void compileBinOp(Token *&tok, void (*f)(Token *&, std::stack<Token*> &, unsigned int depth), std::stack<Token*> &op, unsigned int depth)
{ {
Token *binop = tok; Token *binop = tok;
@ -433,7 +425,7 @@ static void compileBinOp(Token *&tok, void (*f)(Token *&, std::stack<Token*> &,
f(tok,op, depth); f(tok,op, depth);
// Assignment operators are executed in right-to-left order // 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); compileBinOp(tok,f,op,depth);
// TODO: Should we check if op is empty. // 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); compileTernaryOp(tok,op, depth);
while (tok) { while (tok) {
if (isAssignment(tok)) { if (tok->isAssignmentOp()) {
compileBinOp(tok, compileTernaryOp, op, depth); compileBinOp(tok, compileTernaryOp, op, depth);
} else break; } else break;
} }

View File

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

View File

@ -507,6 +507,13 @@ private:
"}"; "}";
ASSERT_EQUALS(false, testValueOfX(code, 4U, 9)); 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" code = "void f() {\n"
" static int x = 2;\n" " static int x = 2;\n"
" x++;\n" " x++;\n"