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;
|
||||
}
|
||||
|
||||
// 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
|
||||
if (bailoutSelfAssignment(tok2)) {
|
||||
if (settings->debugwarnings)
|
||||
|
|
|
@ -628,6 +628,35 @@ private:
|
|||
"}";
|
||||
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("void f(int x) {\n"
|
||||
" x = y;\n"
|
||||
|
|
Loading…
Reference in New Issue