|
110 | 110 | #include "vf_settokenvalue.h" |
111 | 111 |
|
112 | 112 | #include <algorithm> |
113 | | -#include <array> |
114 | 113 | #include <cassert> |
115 | 114 | #include <chrono> |
116 | 115 | #include <cstdint> |
@@ -4114,103 +4113,12 @@ static ValueFlow::Value inferCondition(const std::string& op, const Token* varTo |
4114 | 4113 | return ValueFlow::Value{}; |
4115 | 4114 | if (varTok->hasKnownIntValue()) |
4116 | 4115 | return ValueFlow::Value{}; |
4117 | | - std::vector<ValueFlow::Value> r = infer(IntegralInferModel{}, op, varTok->values(), val); |
| 4116 | + std::vector<ValueFlow::Value> r = infer(ValueFlow::makeIntegralInferModel(), op, varTok->values(), val); |
4118 | 4117 | if (r.size() == 1 && r.front().isKnown()) |
4119 | 4118 | return r.front(); |
4120 | 4119 | return ValueFlow::Value{}; |
4121 | 4120 | } |
4122 | 4121 |
|
4123 | | -struct IteratorInferModel : InferModel { |
4124 | | - virtual ValueFlow::Value::ValueType getType() const = 0; |
4125 | | - bool match(const ValueFlow::Value& value) const override { |
4126 | | - return value.valueType == getType(); |
4127 | | - } |
4128 | | - ValueFlow::Value yield(MathLib::bigint value) const override |
4129 | | - { |
4130 | | - ValueFlow::Value result(value); |
4131 | | - result.valueType = getType(); |
4132 | | - result.setKnown(); |
4133 | | - return result; |
4134 | | - } |
4135 | | -}; |
4136 | | - |
4137 | | -struct EndIteratorInferModel : IteratorInferModel { |
4138 | | - ValueFlow::Value::ValueType getType() const override { |
4139 | | - return ValueFlow::Value::ValueType::ITERATOR_END; |
4140 | | - } |
4141 | | -}; |
4142 | | - |
4143 | | -struct StartIteratorInferModel : IteratorInferModel { |
4144 | | - ValueFlow::Value::ValueType getType() const override { |
4145 | | - return ValueFlow::Value::ValueType::ITERATOR_END; |
4146 | | - } |
4147 | | -}; |
4148 | | - |
4149 | | -static bool isIntegralOnlyOperator(const Token* tok) { |
4150 | | - return Token::Match(tok, "%|<<|>>|&|^|~|%or%"); |
4151 | | -} |
4152 | | - |
4153 | | -static bool isIntegralOrPointer(const Token* tok) |
4154 | | -{ |
4155 | | - if (!tok) |
4156 | | - return false; |
4157 | | - if (astIsIntegral(tok, false)) |
4158 | | - return true; |
4159 | | - if (astIsPointer(tok)) |
4160 | | - return true; |
4161 | | - if (Token::Match(tok, "NULL|nullptr")) |
4162 | | - return true; |
4163 | | - if (tok->valueType()) |
4164 | | - return false; |
4165 | | - // These operators only work on integers |
4166 | | - if (isIntegralOnlyOperator(tok)) |
4167 | | - return true; |
4168 | | - if (isIntegralOnlyOperator(tok->astParent())) |
4169 | | - return true; |
4170 | | - if (Token::Match(tok, "+|-|*|/") && tok->isBinaryOp()) |
4171 | | - return isIntegralOrPointer(tok->astOperand1()) && isIntegralOrPointer(tok->astOperand2()); |
4172 | | - return false; |
4173 | | -} |
4174 | | - |
4175 | | -static void valueFlowInferCondition(TokenList& tokenlist, |
4176 | | - const Settings& settings) |
4177 | | -{ |
4178 | | - for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { |
4179 | | - if (!tok->astParent()) |
4180 | | - continue; |
4181 | | - if (tok->hasKnownIntValue()) |
4182 | | - continue; |
4183 | | - if (Token::Match(tok, "%comp%|-") && tok->astOperand1() && tok->astOperand2()) { |
4184 | | - if (astIsIterator(tok->astOperand1()) || astIsIterator(tok->astOperand2())) { |
4185 | | - static const std::array<ValuePtr<InferModel>, 2> iteratorModels = {EndIteratorInferModel{}, |
4186 | | - StartIteratorInferModel{}}; |
4187 | | - for (const ValuePtr<InferModel>& model : iteratorModels) { |
4188 | | - std::vector<ValueFlow::Value> result = |
4189 | | - infer(model, tok->str(), tok->astOperand1()->values(), tok->astOperand2()->values()); |
4190 | | - for (ValueFlow::Value value : result) { |
4191 | | - value.valueType = ValueFlow::Value::ValueType::INT; |
4192 | | - setTokenValue(tok, std::move(value), settings); |
4193 | | - } |
4194 | | - } |
4195 | | - } else if (isIntegralOrPointer(tok->astOperand1()) && isIntegralOrPointer(tok->astOperand2())) { |
4196 | | - std::vector<ValueFlow::Value> result = |
4197 | | - infer(IntegralInferModel{}, tok->str(), tok->astOperand1()->values(), tok->astOperand2()->values()); |
4198 | | - for (ValueFlow::Value& value : result) { |
4199 | | - setTokenValue(tok, std::move(value), settings); |
4200 | | - } |
4201 | | - } |
4202 | | - } else if (Token::Match(tok->astParent(), "?|&&|!|%oror%") || |
4203 | | - Token::Match(tok->astParent()->previous(), "if|while (") || |
4204 | | - (astIsPointer(tok) && isUsedAsBool(tok, settings))) { |
4205 | | - std::vector<ValueFlow::Value> result = infer(IntegralInferModel{}, "!=", tok->values(), 0); |
4206 | | - if (result.size() != 1) |
4207 | | - continue; |
4208 | | - ValueFlow::Value value = result.front(); |
4209 | | - setTokenValue(tok, std::move(value), settings); |
4210 | | - } |
4211 | | - } |
4212 | | -} |
4213 | | - |
4214 | 4122 | struct SymbolicConditionHandler : SimpleConditionHandler { |
4215 | 4123 |
|
4216 | 4124 | static bool isNegatedBool(const Token* tok) |
@@ -6213,7 +6121,7 @@ void ValueFlow::setValues(TokenList& tokenlist, |
6213 | 6121 | VFA(valueFlowAfterAssign(tokenlist, symboldatabase, errorLogger, settings, skippedFunctions)), |
6214 | 6122 | VFA_CPP(valueFlowAfterSwap(tokenlist, symboldatabase, errorLogger, settings)), |
6215 | 6123 | VFA(valueFlowCondition(SimpleConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions)), |
6216 | | - VFA(valueFlowInferCondition(tokenlist, settings)), |
| 6124 | + VFA(analyzeInferCondition(tokenlist, settings)), |
6217 | 6125 | VFA(valueFlowSwitchVariable(tokenlist, symboldatabase, errorLogger, settings)), |
6218 | 6126 | VFA(valueFlowForLoop(tokenlist, symboldatabase, errorLogger, settings)), |
6219 | 6127 | VFA(valueFlowSubFunction(tokenlist, symboldatabase, errorLogger, settings)), |
|
0 commit comments