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;
|
_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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue