From 0ca5c586c29cc6d5e0d81fcf61f285ec36f531e4 Mon Sep 17 00:00:00 2001 From: firewave Date: Mon, 30 Sep 2024 18:49:25 +0200 Subject: [PATCH 1/2] moved `SymbolicInferModel` to `infer.{cpp|h}` --- lib/infer.cpp | 26 ++++++++++++++++++++++++++ lib/infer.h | 2 ++ lib/valueflow.cpp | 23 ++--------------------- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/lib/infer.cpp b/lib/infer.cpp index 798c99ff6f5..8762e16cbcc 100644 --- a/lib/infer.cpp +++ b/lib/infer.cpp @@ -408,6 +408,32 @@ ValuePtr makeIntegralInferModel() return IntegralInferModel{}; } +namespace { + struct SymbolicInferModel : InferModel { + const Token* expr; + explicit SymbolicInferModel(const Token* tok) : expr(tok) { + assert(expr->exprId() != 0); + } + bool match(const ValueFlow::Value& value) const override + { + return value.isSymbolicValue() && value.tokvalue && value.tokvalue->exprId() == expr->exprId(); + } + ValueFlow::Value yield(MathLib::bigint value) const override + { + ValueFlow::Value result(value); + result.valueType = ValueFlow::Value::ValueType::SYMBOLIC; + result.tokvalue = expr; + result.setKnown(); + return result; + } + }; +} + +ValuePtr makeSymbolicInferModel(const Token* token) +{ + return SymbolicInferModel{token}; +} + ValueFlow::Value inferCondition(const std::string& op, const Token* varTok, MathLib::bigint val) { if (!varTok) diff --git a/lib/infer.h b/lib/infer.h index ed21d48a6c4..0b5761b8ed1 100644 --- a/lib/infer.h +++ b/lib/infer.h @@ -59,6 +59,8 @@ std::vector getMaxValue(const ValuePtr& model, cons ValuePtr makeIntegralInferModel(); +ValuePtr makeSymbolicInferModel(const Token* token); + ValueFlow::Value inferCondition(const std::string& op, const Token* varTok, MathLib::bigint val); #endif diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 6186b90d4e6..e07b8e5e19d 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -3664,25 +3664,6 @@ static void valueFlowSymbolicOperators(const SymbolDatabase& symboldatabase, con } } -struct SymbolicInferModel : InferModel { - const Token* expr; - explicit SymbolicInferModel(const Token* tok) : expr(tok) { - assert(expr->exprId() != 0); - } - bool match(const ValueFlow::Value& value) const override - { - return value.isSymbolicValue() && value.tokvalue && value.tokvalue->exprId() == expr->exprId(); - } - ValueFlow::Value yield(MathLib::bigint value) const override - { - ValueFlow::Value result(value); - result.valueType = ValueFlow::Value::ValueType::SYMBOLIC; - result.tokvalue = expr; - result.setKnown(); - return result; - } -}; - static void valueFlowSymbolicInfer(const SymbolDatabase& symboldatabase, const Settings& settings) { for (const Scope* scope : symboldatabase.functionScopes) { @@ -3710,11 +3691,11 @@ static void valueFlowSymbolicInfer(const SymbolDatabase& symboldatabase, const S std::vector values; { - SymbolicInferModel leftModel{tok->astOperand1()}; + auto leftModel = makeSymbolicInferModel(tok->astOperand1()); values = infer(leftModel, tok->str(), 0, tok->astOperand2()->values()); } if (values.empty()) { - SymbolicInferModel rightModel{tok->astOperand2()}; + auto rightModel = makeSymbolicInferModel(tok->astOperand2()); values = infer(rightModel, tok->str(), tok->astOperand1()->values(), 0); } for (ValueFlow::Value& value : values) { From 10cf643a167b858fd97eec0572aabae95276b514 Mon Sep 17 00:00:00 2001 From: firewave Date: Mon, 30 Sep 2024 18:57:00 +0200 Subject: [PATCH 2/2] moved `IteratorInferModel` and related classes to `infer.{cpp|h}` --- lib/infer.cpp | 38 ++++++++++++++++++++++++++++++++++++++ lib/infer.h | 3 +++ lib/valueflow.cpp | 30 ++---------------------------- 3 files changed, 43 insertions(+), 28 deletions(-) diff --git a/lib/infer.cpp b/lib/infer.cpp index 8762e16cbcc..278237a2c66 100644 --- a/lib/infer.cpp +++ b/lib/infer.cpp @@ -434,6 +434,44 @@ ValuePtr makeSymbolicInferModel(const Token* token) return SymbolicInferModel{token}; } +namespace { + struct IteratorInferModel : InferModel { + virtual ValueFlow::Value::ValueType getType() const = 0; + bool match(const ValueFlow::Value& value) const override { + return value.valueType == getType(); + } + ValueFlow::Value yield(MathLib::bigint value) const override + { + ValueFlow::Value result(value); + result.valueType = getType(); + result.setKnown(); + return result; + } + }; + + struct EndIteratorInferModel : IteratorInferModel { + ValueFlow::Value::ValueType getType() const override { + return ValueFlow::Value::ValueType::ITERATOR_END; + } + }; + + struct StartIteratorInferModel : IteratorInferModel { + ValueFlow::Value::ValueType getType() const override { + return ValueFlow::Value::ValueType::ITERATOR_END; + } + }; +} + +ValuePtr makeEndIteratorInferModel() +{ + return EndIteratorInferModel{}; +} + +ValuePtr makeStartIteratorInferModel() +{ + return StartIteratorInferModel{}; +} + ValueFlow::Value inferCondition(const std::string& op, const Token* varTok, MathLib::bigint val) { if (!varTok) diff --git a/lib/infer.h b/lib/infer.h index 0b5761b8ed1..436ee95eb14 100644 --- a/lib/infer.h +++ b/lib/infer.h @@ -61,6 +61,9 @@ ValuePtr makeIntegralInferModel(); ValuePtr makeSymbolicInferModel(const Token* token); +ValuePtr makeEndIteratorInferModel(); +ValuePtr makeStartIteratorInferModel(); + ValueFlow::Value inferCondition(const std::string& op, const Token* varTok, MathLib::bigint val); #endif diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index e07b8e5e19d..e81d8030354 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -4900,32 +4900,6 @@ struct SimpleConditionHandler : ConditionHandler { } }; -struct IteratorInferModel : InferModel { - virtual ValueFlow::Value::ValueType getType() const = 0; - bool match(const ValueFlow::Value& value) const override { - return value.valueType == getType(); - } - ValueFlow::Value yield(MathLib::bigint value) const override - { - ValueFlow::Value result(value); - result.valueType = getType(); - result.setKnown(); - return result; - } -}; - -struct EndIteratorInferModel : IteratorInferModel { - ValueFlow::Value::ValueType getType() const override { - return ValueFlow::Value::ValueType::ITERATOR_END; - } -}; - -struct StartIteratorInferModel : IteratorInferModel { - ValueFlow::Value::ValueType getType() const override { - return ValueFlow::Value::ValueType::ITERATOR_END; - } -}; - static bool isIntegralOnlyOperator(const Token* tok) { return Token::Match(tok, "%|<<|>>|&|^|~|%or%"); } @@ -4961,8 +4935,8 @@ static void valueFlowInferCondition(TokenList& tokenlist, const Settings& settin continue; if (Token::Match(tok, "%comp%|-") && tok->astOperand1() && tok->astOperand2()) { if (astIsIterator(tok->astOperand1()) || astIsIterator(tok->astOperand2())) { - static const std::array, 2> iteratorModels = {EndIteratorInferModel{}, - StartIteratorInferModel{}}; + static const std::array, 2> iteratorModels = {makeEndIteratorInferModel(), + makeStartIteratorInferModel()}; for (const ValuePtr& model : iteratorModels) { std::vector result = infer(model, tok->str(), tok->astOperand1()->values(), tok->astOperand2()->values());