Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -3363,6 +3364,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 @@ -4409,19 +4412,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 @@ -6027,9 +6034,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 @@ -6239,12 +6246,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