ValueFlowForward: Refactoring handling of compound assignments

This commit is contained in:
Daniel Marjamäki 2017-09-20 11:45:28 +02:00
parent 6c2ed41e12
commit 87c35cd60e
1 changed files with 49 additions and 52 deletions

View File

@ -1340,6 +1340,50 @@ static void handleKnownValuesInLoop(const Token *startToken,
}
}
static bool evalAssignment(ValueFlow::Value &lhsValue, const std::string &assign, const ValueFlow::Value &rhsValue)
{
if (lhsValue.isIntValue()) {
if (assign == "+=")
lhsValue.intvalue += rhsValue.intvalue;
else if (assign == "-=")
lhsValue.intvalue -= rhsValue.intvalue;
else if (assign == "*=")
lhsValue.intvalue *= rhsValue.intvalue;
else if (assign == "/=") {
if (rhsValue.intvalue == 0)
return false;
else
lhsValue.intvalue /= rhsValue.intvalue;
} else if (assign == "%=") {
if (rhsValue.intvalue == 0)
return false;
else
lhsValue.intvalue %= rhsValue.intvalue;
} else if (assign == "&=")
lhsValue.intvalue &= rhsValue.intvalue;
else if (assign == "|=")
lhsValue.intvalue |= rhsValue.intvalue;
else if (assign == "^=")
lhsValue.intvalue ^= rhsValue.intvalue;
else
return false;
} else if (lhsValue.isFloatValue()) {
if (assign == "+=")
lhsValue.floatValue += rhsValue.intvalue;
else if (assign == "-=")
lhsValue.floatValue -= rhsValue.intvalue;
else if (assign == "*=")
lhsValue.floatValue *= rhsValue.intvalue;
else if (assign == "/=")
lhsValue.floatValue /= rhsValue.intvalue;
else
return false;
} else {
return false;
}
return true;
}
static bool valueFlowForward(Token * const startToken,
const Token * const endToken,
const Variable * const var,
@ -1805,62 +1849,15 @@ static bool valueFlowForward(Token * const startToken,
std::list<ValueFlow::Value>::iterator it;
// Erase values that are not int values..
for (it = values.begin(); it != values.end();) {
if (it->isIntValue()) {
bool ub = false;
if (assign == "+=")
it->intvalue += rhsValue.intvalue;
else if (assign == "-=")
it->intvalue -= rhsValue.intvalue;
else if (assign == "*=")
it->intvalue *= rhsValue.intvalue;
else if (assign == "/=") {
if (rhsValue.intvalue == 0)
ub = true;
else
it->intvalue /= rhsValue.intvalue;
} else if (assign == "%=") {
if (rhsValue.intvalue == 0)
ub = true;
else
it->intvalue %= rhsValue.intvalue;
} else if (assign == "&=")
it->intvalue &= rhsValue.intvalue;
else if (assign == "|=")
it->intvalue |= rhsValue.intvalue;
else if (assign == "^=")
it->intvalue ^= rhsValue.intvalue;
else {
values.clear();
break;
}
if (ub)
it = values.erase(it);
else {
const std::string info("Compound assignment '" + assign + "', assigned value is " + it->infoString());
it->errorPath.push_back(ErrorPathItem(tok2, info));
++it;
}
} else if (it->isFloatValue()) {
if (assign == "+=")
it->floatValue += rhsValue.intvalue;
else if (assign == "-=")
it->floatValue -= rhsValue.intvalue;
else if (assign == "*=")
it->floatValue *= rhsValue.intvalue;
else if (assign == "/=")
it->floatValue /= rhsValue.intvalue;
else {
values.clear();
break;
}
if (!evalAssignment(*it, assign, rhsValue)) {
it = values.erase(it);
} else {
const std::string info("Compound assignment '" + assign + "', assigned value is " + it->infoString());
it->errorPath.push_back(ErrorPathItem(tok2, info));
++it;
} else {
it = values.erase(it);
}
}
if (values.empty()) {
if (settings->debugwarnings)