Fixed #7968 (valueFlowBeforeCondition: better handling of compound assignments)
This commit is contained in:
parent
537045b176
commit
89532cf8b9
|
@ -940,6 +940,29 @@ static void valueFlowReverse(TokenList *tokenlist,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// compound assignment
|
||||||
|
if (Token::Match(tok2->previous(), "[;{}] %var% %assign%") && tok2->next()->str() != "=") {
|
||||||
|
const Token * const assignToken = tok2->next();
|
||||||
|
const Token * const rhsToken = assignToken->astOperand2();
|
||||||
|
if (!rhsToken || !rhsToken->hasKnownIntValue()) {
|
||||||
|
if (settings->debugwarnings)
|
||||||
|
bailout(tokenlist, errorLogger, tok2, "compound assignment, rhs value is not known");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const MathLib::bigint rhsValue = rhsToken->values().front().intvalue;
|
||||||
|
if (assignToken->str() == "+=")
|
||||||
|
val.intvalue -= rhsValue;
|
||||||
|
else if (assignToken->str() == "-=")
|
||||||
|
val.intvalue += rhsValue;
|
||||||
|
else if (assignToken->str() == "*=")
|
||||||
|
val.intvalue /= rhsValue;
|
||||||
|
else {
|
||||||
|
if (settings->debugwarnings)
|
||||||
|
bailout(tokenlist, errorLogger, tok2, "compound assignment " + tok2->str());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// bailout: variable is used in rhs in assignment to itself
|
// bailout: variable is used in rhs in assignment to itself
|
||||||
if (bailoutSelfAssignment(tok2)) {
|
if (bailoutSelfAssignment(tok2)) {
|
||||||
if (settings->debugwarnings)
|
if (settings->debugwarnings)
|
||||||
|
|
|
@ -628,6 +628,35 @@ private:
|
||||||
"}";
|
"}";
|
||||||
ASSERT_EQUALS(true, testValueOfX(code, 2U, 3));
|
ASSERT_EQUALS(true, testValueOfX(code, 2U, 3));
|
||||||
|
|
||||||
|
// compound assignment += , -= , ...
|
||||||
|
code = "void f(int x) {\n"
|
||||||
|
" a = x;\n"
|
||||||
|
" x += 2;\n"
|
||||||
|
" if (x == 4);\n"
|
||||||
|
"}";
|
||||||
|
ASSERT_EQUALS(true, testValueOfX(code, 2U, 2));
|
||||||
|
|
||||||
|
code = "void f(int x) {\n"
|
||||||
|
" a = x;\n"
|
||||||
|
" x -= 2;\n"
|
||||||
|
" if (x == 4);\n"
|
||||||
|
"}";
|
||||||
|
ASSERT_EQUALS(true, testValueOfX(code, 2U, 6));
|
||||||
|
|
||||||
|
code = "void f(int x) {\n"
|
||||||
|
" a = x;\n"
|
||||||
|
" x *= 2;\n"
|
||||||
|
" if (x == 42);\n"
|
||||||
|
"}";
|
||||||
|
ASSERT_EQUALS(true, testValueOfX(code, 2U, 21));
|
||||||
|
|
||||||
|
code = "void f(int x) {\n"
|
||||||
|
" a = x;\n"
|
||||||
|
" x /= 5;\n"
|
||||||
|
" if (x == 42);\n"
|
||||||
|
"}";
|
||||||
|
ASSERT(tokenValues(code, "x ;").empty());
|
||||||
|
|
||||||
// bailout: assignment
|
// bailout: assignment
|
||||||
bailout("void f(int x) {\n"
|
bailout("void f(int x) {\n"
|
||||||
" x = y;\n"
|
" x = y;\n"
|
||||||
|
|
Loading…
Reference in New Issue