Skip to content

Commit

Permalink
ValueFlow: delayed some code until necessary and added some early outs (
Browse files Browse the repository at this point in the history
  • Loading branch information
firewave authored Dec 5, 2024
1 parent 34a6266 commit af4e5b3
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 28 deletions.
11 changes: 6 additions & 5 deletions lib/programmemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1384,13 +1384,13 @@ namespace {
std::equal(conditions1.begin(), conditions1.end(), conditions2.begin(), &TokenExprIdEqual))
return value;
std::vector<const Token*> diffConditions1 = setDifference(conditions1, conditions2);
std::vector<const Token*> diffConditions2 = setDifference(conditions2, conditions1);
pruneConditions(diffConditions1, !b, condValues);
if (diffConditions1.size() == conditions1.size())
continue;
std::vector<const Token*> diffConditions2 = setDifference(conditions2, conditions1);
pruneConditions(diffConditions2, !b, executeAll(diffConditions2));
if (diffConditions1.size() != diffConditions2.size())
continue;
if (diffConditions1.size() == conditions1.size())
continue;
for (const Token* cond1 : diffConditions1) {
auto it = std::find_if(diffConditions2.begin(), diffConditions2.end(), [&](const Token* cond2) {
return evalSameCondition(*pm, cond2, cond1, settings);
Expand Down Expand Up @@ -1707,9 +1707,10 @@ namespace {
continue;
if (value.tokvalue->exprId() > 0 && !pm->hasValue(value.tokvalue->exprId()))
continue;
ValueFlow::Value v2 = utils::as_const(*pm).at(value.tokvalue->exprId());
if (!v2.isIntValue() && value.intvalue != 0)
const ValueFlow::Value& v_ref = utils::as_const(*pm).at(value.tokvalue->exprId());
if (!v_ref.isIntValue() && value.intvalue != 0)
continue;
ValueFlow::Value v2 = v_ref;
v2.intvalue += value.intvalue;
return v2;
}
Expand Down
55 changes: 32 additions & 23 deletions lib/valueflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,18 +294,18 @@ static void parseCompareEachInt(
value1.clear();
}
for (const ValueFlow::Value& v1 : value1) {
ValueFlow::Value true_value = v1;
ValueFlow::Value false_value = v1;
if (isSaturated(v1.intvalue) || astIsFloat(tok->astOperand2(), /*unknown*/ false))
continue;
ValueFlow::Value true_value = v1;
ValueFlow::Value false_value = v1;
setConditionalValues(tok, true, v1.intvalue, true_value, false_value);
each(tok->astOperand2(), std::move(true_value), std::move(false_value));
}
for (const ValueFlow::Value& v2 : value2) {
ValueFlow::Value true_value = v2;
ValueFlow::Value false_value = v2;
if (isSaturated(v2.intvalue) || astIsFloat(tok->astOperand1(), /*unknown*/ false))
continue;
ValueFlow::Value true_value = v2;
ValueFlow::Value false_value = v2;
setConditionalValues(tok, false, v2.intvalue, true_value, false_value);
each(tok->astOperand1(), std::move(true_value), std::move(false_value));
}
Expand Down Expand Up @@ -856,23 +856,22 @@ static void valueFlowSameExpressions(TokenList& tokenlist, const Settings& setti
if (!astIsIntegral(tok->astOperand1(), false) && !astIsIntegral(tok->astOperand2(), false))
continue;

ValueFlow::Value val;
long long val;

if (Token::Match(tok, "==|>=|<=|/")) {
val = ValueFlow::Value(1);
val.setKnown();
val = 1;
}

if (Token::Match(tok, "!=|>|<|%|-")) {
val = ValueFlow::Value(0);
val.setKnown();
else if (Token::Match(tok, "!=|>|<|%|-")) {
val = 0;
}

if (!val.isKnown())
else
continue;

if (isSameExpression(false, tok->astOperand1(), tok->astOperand2(), settings, true, true, &val.errorPath)) {
setTokenValue(tok, std::move(val), settings);
ValueFlow::Value value(val);
value.setKnown();

if (isSameExpression(false, tok->astOperand1(), tok->astOperand2(), settings, true, true, &value.errorPath)) {
setTokenValue(tok, std::move(value), settings);
}
}
}
Expand Down Expand Up @@ -993,9 +992,11 @@ static std::vector<MathLib::bigint> minUnsignedValue(const Token* tok, int depth
result = {tok->values().front().intvalue};
} else if (!Token::Match(tok, "-|%|&|^") && tok->isConstOp() && tok->astOperand1() && tok->astOperand2()) {
std::vector<MathLib::bigint> op1 = minUnsignedValue(tok->astOperand1(), depth - 1);
std::vector<MathLib::bigint> op2 = minUnsignedValue(tok->astOperand2(), depth - 1);
if (!op1.empty() && !op2.empty()) {
result = calculate<std::vector<MathLib::bigint>>(tok->str(), op1.front(), op2.front());
if (!op1.empty()) {
std::vector<MathLib::bigint> op2 = minUnsignedValue(tok->astOperand2(), depth - 1);
if (!op2.empty()) {
result = calculate<std::vector<MathLib::bigint>>(tok->str(), op1.front(), op2.front());
}
}
}
if (result.empty() && astIsUnsigned(tok))
Expand Down Expand Up @@ -3364,6 +3365,8 @@ static void valueFlowConditionExpressions(const TokenList& tokenlist,
}

std::vector<const Token*> conds = getConditions(condTok, "||");
if (conds.empty())
continue;

// Check else block
if (Token::simpleMatch(startTok->link(), "} else {")) {
Expand Down Expand Up @@ -4410,19 +4413,23 @@ struct ConditionHandler {
return;
}

if (cond.true_values.empty() && cond.false_values.empty())
return;

std::list<ValueFlow::Value> values = cond.true_values;
if (cond.true_values != cond.false_values)
values.insert(values.end(), cond.false_values.cbegin(), cond.false_values.cend());

// extra logic for unsigned variables 'i>=1' => possible value can also be 0
if (Token::Match(tok, "<|>|<=|>=")) {
if (cond.vartok->valueType() && cond.vartok->valueType()->sign != ValueType::Sign::UNSIGNED)
return;

values.remove_if([](const ValueFlow::Value& v) {
if (v.isIntValue())
return v.intvalue != 0;
return false;
});
if (cond.vartok->valueType() && cond.vartok->valueType()->sign != ValueType::Sign::UNSIGNED)
return;
}
if (values.empty())
return;
Expand Down Expand Up @@ -6024,9 +6031,9 @@ static const Token* parseBinaryIntOp(const Token* expr,
if (expr->astOperand1()->exprId() == 0 && expr->astOperand2()->exprId() == 0)
return nullptr;
std::vector<MathLib::bigint> x1 = eval(expr->astOperand1());
std::vector<MathLib::bigint> x2 = eval(expr->astOperand2());
if (expr->astOperand1()->exprId() == 0 && x1.empty())
return nullptr;
std::vector<MathLib::bigint> x2 = eval(expr->astOperand2());
if (expr->astOperand2()->exprId() == 0 && x2.empty())
return nullptr;
const Token* varTok = nullptr;
Expand Down Expand Up @@ -6236,12 +6243,14 @@ static void valueFlowIterators(TokenList& tokenlist, const Settings& settings)
const Library::Container::Yield yield = findIteratorYield(tok, ftok, settings);
if (!ftok)
continue;
ValueFlow::Value v(0);
v.setKnown();
if (yield == Library::Container::Yield::START_ITERATOR) {
ValueFlow::Value v(0);
v.setKnown();
v.valueType = ValueFlow::Value::ValueType::ITERATOR_START;
setTokenValue(const_cast<Token*>(ftok)->next(), std::move(v), settings);
} else if (yield == Library::Container::Yield::END_ITERATOR) {
ValueFlow::Value v(0);
v.setKnown();
v.valueType = ValueFlow::Value::ValueType::ITERATOR_END;
setTokenValue(const_cast<Token*>(ftok)->next(), std::move(v), settings);
}
Expand Down

0 comments on commit af4e5b3

Please sign in to comment.