Skip to content

Commit af4e5b3

Browse files
authored
ValueFlow: delayed some code until necessary and added some early outs (#7052)
1 parent 34a6266 commit af4e5b3

2 files changed

Lines changed: 38 additions & 28 deletions

File tree

lib/programmemory.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,13 +1384,13 @@ namespace {
13841384
std::equal(conditions1.begin(), conditions1.end(), conditions2.begin(), &TokenExprIdEqual))
13851385
return value;
13861386
std::vector<const Token*> diffConditions1 = setDifference(conditions1, conditions2);
1387-
std::vector<const Token*> diffConditions2 = setDifference(conditions2, conditions1);
13881387
pruneConditions(diffConditions1, !b, condValues);
1388+
if (diffConditions1.size() == conditions1.size())
1389+
continue;
1390+
std::vector<const Token*> diffConditions2 = setDifference(conditions2, conditions1);
13891391
pruneConditions(diffConditions2, !b, executeAll(diffConditions2));
13901392
if (diffConditions1.size() != diffConditions2.size())
13911393
continue;
1392-
if (diffConditions1.size() == conditions1.size())
1393-
continue;
13941394
for (const Token* cond1 : diffConditions1) {
13951395
auto it = std::find_if(diffConditions2.begin(), diffConditions2.end(), [&](const Token* cond2) {
13961396
return evalSameCondition(*pm, cond2, cond1, settings);
@@ -1707,9 +1707,10 @@ namespace {
17071707
continue;
17081708
if (value.tokvalue->exprId() > 0 && !pm->hasValue(value.tokvalue->exprId()))
17091709
continue;
1710-
ValueFlow::Value v2 = utils::as_const(*pm).at(value.tokvalue->exprId());
1711-
if (!v2.isIntValue() && value.intvalue != 0)
1710+
const ValueFlow::Value& v_ref = utils::as_const(*pm).at(value.tokvalue->exprId());
1711+
if (!v_ref.isIntValue() && value.intvalue != 0)
17121712
continue;
1713+
ValueFlow::Value v2 = v_ref;
17131714
v2.intvalue += value.intvalue;
17141715
return v2;
17151716
}

lib/valueflow.cpp

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -294,18 +294,18 @@ static void parseCompareEachInt(
294294
value1.clear();
295295
}
296296
for (const ValueFlow::Value& v1 : value1) {
297-
ValueFlow::Value true_value = v1;
298-
ValueFlow::Value false_value = v1;
299297
if (isSaturated(v1.intvalue) || astIsFloat(tok->astOperand2(), /*unknown*/ false))
300298
continue;
299+
ValueFlow::Value true_value = v1;
300+
ValueFlow::Value false_value = v1;
301301
setConditionalValues(tok, true, v1.intvalue, true_value, false_value);
302302
each(tok->astOperand2(), std::move(true_value), std::move(false_value));
303303
}
304304
for (const ValueFlow::Value& v2 : value2) {
305-
ValueFlow::Value true_value = v2;
306-
ValueFlow::Value false_value = v2;
307305
if (isSaturated(v2.intvalue) || astIsFloat(tok->astOperand1(), /*unknown*/ false))
308306
continue;
307+
ValueFlow::Value true_value = v2;
308+
ValueFlow::Value false_value = v2;
309309
setConditionalValues(tok, false, v2.intvalue, true_value, false_value);
310310
each(tok->astOperand1(), std::move(true_value), std::move(false_value));
311311
}
@@ -856,23 +856,22 @@ static void valueFlowSameExpressions(TokenList& tokenlist, const Settings& setti
856856
if (!astIsIntegral(tok->astOperand1(), false) && !astIsIntegral(tok->astOperand2(), false))
857857
continue;
858858

859-
ValueFlow::Value val;
859+
long long val;
860860

861861
if (Token::Match(tok, "==|>=|<=|/")) {
862-
val = ValueFlow::Value(1);
863-
val.setKnown();
862+
val = 1;
864863
}
865-
866-
if (Token::Match(tok, "!=|>|<|%|-")) {
867-
val = ValueFlow::Value(0);
868-
val.setKnown();
864+
else if (Token::Match(tok, "!=|>|<|%|-")) {
865+
val = 0;
869866
}
870-
871-
if (!val.isKnown())
867+
else
872868
continue;
873869

874-
if (isSameExpression(false, tok->astOperand1(), tok->astOperand2(), settings, true, true, &val.errorPath)) {
875-
setTokenValue(tok, std::move(val), settings);
870+
ValueFlow::Value value(val);
871+
value.setKnown();
872+
873+
if (isSameExpression(false, tok->astOperand1(), tok->astOperand2(), settings, true, true, &value.errorPath)) {
874+
setTokenValue(tok, std::move(value), settings);
876875
}
877876
}
878877
}
@@ -993,9 +992,11 @@ static std::vector<MathLib::bigint> minUnsignedValue(const Token* tok, int depth
993992
result = {tok->values().front().intvalue};
994993
} else if (!Token::Match(tok, "-|%|&|^") && tok->isConstOp() && tok->astOperand1() && tok->astOperand2()) {
995994
std::vector<MathLib::bigint> op1 = minUnsignedValue(tok->astOperand1(), depth - 1);
996-
std::vector<MathLib::bigint> op2 = minUnsignedValue(tok->astOperand2(), depth - 1);
997-
if (!op1.empty() && !op2.empty()) {
998-
result = calculate<std::vector<MathLib::bigint>>(tok->str(), op1.front(), op2.front());
995+
if (!op1.empty()) {
996+
std::vector<MathLib::bigint> op2 = minUnsignedValue(tok->astOperand2(), depth - 1);
997+
if (!op2.empty()) {
998+
result = calculate<std::vector<MathLib::bigint>>(tok->str(), op1.front(), op2.front());
999+
}
9991000
}
10001001
}
10011002
if (result.empty() && astIsUnsigned(tok))
@@ -3364,6 +3365,8 @@ static void valueFlowConditionExpressions(const TokenList& tokenlist,
33643365
}
33653366

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

33683371
// Check else block
33693372
if (Token::simpleMatch(startTok->link(), "} else {")) {
@@ -4410,19 +4413,23 @@ struct ConditionHandler {
44104413
return;
44114414
}
44124415

4416+
if (cond.true_values.empty() && cond.false_values.empty())
4417+
return;
4418+
44134419
std::list<ValueFlow::Value> values = cond.true_values;
44144420
if (cond.true_values != cond.false_values)
44154421
values.insert(values.end(), cond.false_values.cbegin(), cond.false_values.cend());
44164422

44174423
// extra logic for unsigned variables 'i>=1' => possible value can also be 0
44184424
if (Token::Match(tok, "<|>|<=|>=")) {
4425+
if (cond.vartok->valueType() && cond.vartok->valueType()->sign != ValueType::Sign::UNSIGNED)
4426+
return;
4427+
44194428
values.remove_if([](const ValueFlow::Value& v) {
44204429
if (v.isIntValue())
44214430
return v.intvalue != 0;
44224431
return false;
44234432
});
4424-
if (cond.vartok->valueType() && cond.vartok->valueType()->sign != ValueType::Sign::UNSIGNED)
4425-
return;
44264433
}
44274434
if (values.empty())
44284435
return;
@@ -6024,9 +6031,9 @@ static const Token* parseBinaryIntOp(const Token* expr,
60246031
if (expr->astOperand1()->exprId() == 0 && expr->astOperand2()->exprId() == 0)
60256032
return nullptr;
60266033
std::vector<MathLib::bigint> x1 = eval(expr->astOperand1());
6027-
std::vector<MathLib::bigint> x2 = eval(expr->astOperand2());
60286034
if (expr->astOperand1()->exprId() == 0 && x1.empty())
60296035
return nullptr;
6036+
std::vector<MathLib::bigint> x2 = eval(expr->astOperand2());
60306037
if (expr->astOperand2()->exprId() == 0 && x2.empty())
60316038
return nullptr;
60326039
const Token* varTok = nullptr;
@@ -6236,12 +6243,14 @@ static void valueFlowIterators(TokenList& tokenlist, const Settings& settings)
62366243
const Library::Container::Yield yield = findIteratorYield(tok, ftok, settings);
62376244
if (!ftok)
62386245
continue;
6239-
ValueFlow::Value v(0);
6240-
v.setKnown();
62416246
if (yield == Library::Container::Yield::START_ITERATOR) {
6247+
ValueFlow::Value v(0);
6248+
v.setKnown();
62426249
v.valueType = ValueFlow::Value::ValueType::ITERATOR_START;
62436250
setTokenValue(const_cast<Token*>(ftok)->next(), std::move(v), settings);
62446251
} else if (yield == Library::Container::Yield::END_ITERATOR) {
6252+
ValueFlow::Value v(0);
6253+
v.setKnown();
62456254
v.valueType = ValueFlow::Value::ValueType::ITERATOR_END;
62466255
setTokenValue(const_cast<Token*>(ftok)->next(), std::move(v), settings);
62476256
}

0 commit comments

Comments
 (0)