From 70051ae965b424ef1174395897297b7ff774dd6a Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 20 Jul 2024 14:17:38 +0200 Subject: [PATCH 1/9] valueflow.cpp: only perform call `eval()` in `parseBinaryIntOp()` when result is required --- lib/valueflow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index c4ea3f7a277..c1f43358122 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -6027,9 +6027,9 @@ static const Token* parseBinaryIntOp(const Token* expr, if (expr->astOperand1()->exprId() == 0 && expr->astOperand2()->exprId() == 0) return nullptr; std::vector x1 = eval(expr->astOperand1()); - std::vector x2 = eval(expr->astOperand2()); if (expr->astOperand1()->exprId() == 0 && x1.empty()) return nullptr; + std::vector x2 = eval(expr->astOperand2()); if (expr->astOperand2()->exprId() == 0 && x2.empty()) return nullptr; const Token* varTok = nullptr; From a12f552f137990839b84490cb5258acf2e734d89 Mon Sep 17 00:00:00 2001 From: firewave Date: Mon, 22 Jul 2024 23:02:19 +0200 Subject: [PATCH 2/9] valueflow.cpp: do not copy values in `parseCompareEachInt()` until needed --- lib/valueflow.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index c1f43358122..9a36079b048 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -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)); } From 7f47e88cc26ddfacd60d792cb303289d1db31a9f Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 31 Aug 2024 16:09:31 +0200 Subject: [PATCH 3/9] valueflow.cpp: do not create value in `valueFlowIterators()` until unnecessary --- lib/valueflow.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 9a36079b048..7e5d4232934 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -6239,12 +6239,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(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(ftok)->next(), std::move(v), settings); } From 270121ce5c45d5ad37d3529bfefa9da1faec8d09 Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 31 Aug 2024 16:13:00 +0200 Subject: [PATCH 4/9] programmemory.cpp: do not copy value in `Executor::execute()` until necessary --- lib/programmemory.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 8305ab2e9f7..4eb9e4168a6 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -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; } From a4c41b554aec58f292aa01a7b0c1040914752ed6 Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 31 Aug 2024 16:21:06 +0200 Subject: [PATCH 5/9] valueflow.cpp: do not create value in `valueFlowSameExpressions()` until necessary --- lib/valueflow.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 7e5d4232934..b831a13af7a 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -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); } } } From 4b013f200a9c1dd25557578ee2a994794e2bf044 Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 31 Aug 2024 16:22:48 +0200 Subject: [PATCH 6/9] valueflow.cpp: do not perform function calls in `minUnsignedValue()` until necessary --- lib/valueflow.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index b831a13af7a..34e9ba93c01 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -992,9 +992,11 @@ static std::vector minUnsignedValue(const Token* tok, int depth result = {tok->values().front().intvalue}; } else if (!Token::Match(tok, "-|%|&|^") && tok->isConstOp() && tok->astOperand1() && tok->astOperand2()) { std::vector op1 = minUnsignedValue(tok->astOperand1(), depth - 1); - std::vector op2 = minUnsignedValue(tok->astOperand2(), depth - 1); - if (!op1.empty() && !op2.empty()) { - result = calculate>(tok->str(), op1.front(), op2.front()); + if (!op1.empty()) { + std::vector op2 = minUnsignedValue(tok->astOperand2(), depth - 1); + if (!op2.empty()) { + result = calculate>(tok->str(), op1.front(), op2.front()); + } } } if (result.empty() && astIsUnsigned(tok)) From 511c0aaaec1e0c22b710abf9481976411c9d55ea Mon Sep 17 00:00:00 2001 From: firewave Date: Sun, 1 Sep 2024 19:47:10 +0200 Subject: [PATCH 7/9] valueflow.cpp: added some early outs in `ConditionHandler::beforeCondition()` --- lib/valueflow.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 34e9ba93c01..7c2b39a5f48 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4410,19 +4410,23 @@ struct ConditionHandler { return; } + if (cond.true_values.empty() && cond.false_values.empty()) + return; + std::list 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; From 76b2aef92707a455202ad69957c269e6b58a6309 Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 14 Sep 2024 14:09:27 +0200 Subject: [PATCH 8/9] programmemory.cpp: do not perform call in `Executor::executeMultiCondition()` until necessary --- lib/programmemory.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 4eb9e4168a6..20e212b8409 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -1384,13 +1384,13 @@ namespace { std::equal(conditions1.begin(), conditions1.end(), conditions2.begin(), &TokenExprIdEqual)) return value; std::vector diffConditions1 = setDifference(conditions1, conditions2); - std::vector diffConditions2 = setDifference(conditions2, conditions1); pruneConditions(diffConditions1, !b, condValues); + if (diffConditions1.size() == conditions1.size()) + continue; + std::vector 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); From 9c2a6b442b7e528ed961daf399e7091c23697bfb Mon Sep 17 00:00:00 2001 From: firewave Date: Mon, 30 Sep 2024 01:40:33 +0200 Subject: [PATCH 9/9] valueflow.cpp: added early out in `valueFlowConditionExpressions()` --- lib/valueflow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 7c2b39a5f48..feb45c56266 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -3364,6 +3364,8 @@ static void valueFlowConditionExpressions(const TokenList& tokenlist, } std::vector conds = getConditions(condTok, "||"); + if (conds.empty()) + continue; // Check else block if (Token::simpleMatch(startTok->link(), "} else {")) {