From 2e2278ccc2c0926d26c4cb30842b17751d6b0efe 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 cad0761f68b..3c99e942bcd 100644 --- a/lib/infer.cpp +++ b/lib/infer.cpp @@ -409,6 +409,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 8d66d7da016..0a105ad43e9 100644 --- a/lib/infer.h +++ b/lib/infer.h @@ -63,6 +63,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 81e65c8347f..735da0c704c 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -3877,25 +3877,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) { @@ -3923,11 +3904,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 5765f6683c498db787757e7b45aa4383f2510b62 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 3c99e942bcd..d264d30054f 100644 --- a/lib/infer.cpp +++ b/lib/infer.cpp @@ -435,6 +435,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 0a105ad43e9..cb1e595295a 100644 --- a/lib/infer.h +++ b/lib/infer.h @@ -65,6 +65,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 735da0c704c..a411abb5f69 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -5113,32 +5113,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%"); } @@ -5174,8 +5148,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());