Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

moved *InferModel classes to infer.{cpp|h} #6922

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions lib/infer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,70 @@ ValuePtr<InferModel> 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<InferModel> 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<InferModel> makeEndIteratorInferModel()
{
return EndIteratorInferModel{};
}

ValuePtr<InferModel> makeStartIteratorInferModel()
{
return StartIteratorInferModel{};
}

ValueFlow::Value inferCondition(const std::string& op, const Token* varTok, MathLib::bigint val)
{
if (!varTok)
Expand Down
5 changes: 5 additions & 0 deletions lib/infer.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ std::vector<MathLib::bigint> getMaxValue(const ValuePtr<InferModel>& model, cons

ValuePtr<InferModel> makeIntegralInferModel();

ValuePtr<InferModel> makeSymbolicInferModel(const Token* token);

ValuePtr<InferModel> makeEndIteratorInferModel();
ValuePtr<InferModel> makeStartIteratorInferModel();

ValueFlow::Value inferCondition(const std::string& op, const Token* varTok, MathLib::bigint val);

#endif
53 changes: 4 additions & 49 deletions lib/valueflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -3710,11 +3691,11 @@ static void valueFlowSymbolicInfer(const SymbolDatabase& symboldatabase, const S

std::vector<ValueFlow::Value> 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) {
Expand Down Expand Up @@ -4919,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%");
}
Expand Down Expand Up @@ -4980,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<ValuePtr<InferModel>, 2> iteratorModels = {EndIteratorInferModel{},
StartIteratorInferModel{}};
static const std::array<ValuePtr<InferModel>, 2> iteratorModels = {makeEndIteratorInferModel(),
makeStartIteratorInferModel()};
for (const ValuePtr<InferModel>& model : iteratorModels) {
std::vector<ValueFlow::Value> result =
infer(model, tok->str(), tok->astOperand1()->values(), tok->astOperand2()->values());
Expand Down
Loading