ValueFlow: Improved bailout when variable is reassigned
This commit is contained in:
parent
4b7aaba159
commit
5a23b739da
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue