mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #6717 from ethereum/smt_namespace
Move SMT specific code into smt namespace
This commit is contained in:
commit
01dd9ba2ae
@ -332,7 +332,7 @@ void SMTChecker::endVisit(VariableDeclarationStatement const& _varDecl)
|
||||
{
|
||||
if (auto init = _varDecl.initialValue())
|
||||
{
|
||||
auto symbTuple = dynamic_pointer_cast<SymbolicTupleVariable>(m_expressions[init]);
|
||||
auto symbTuple = dynamic_pointer_cast<smt::SymbolicTupleVariable>(m_expressions[init]);
|
||||
/// symbTuple == nullptr if it is the return of a non-inlined function call.
|
||||
if (symbTuple)
|
||||
{
|
||||
@ -375,7 +375,7 @@ void SMTChecker::endVisit(Assignment const& _assignment)
|
||||
_assignment.location(),
|
||||
"Assertion checker does not yet implement this assignment operator."
|
||||
);
|
||||
else if (!isSupportedType(_assignment.annotation().type->category()))
|
||||
else if (!smt::isSupportedType(_assignment.annotation().type->category()))
|
||||
{
|
||||
m_errorReporter.warning(
|
||||
_assignment.location(),
|
||||
@ -390,7 +390,7 @@ void SMTChecker::endVisit(Assignment const& _assignment)
|
||||
vector<smt::Expression> rightArguments;
|
||||
if (_assignment.rightHandSide().annotation().type->category() == Type::Category::Tuple)
|
||||
{
|
||||
auto symbTuple = dynamic_pointer_cast<SymbolicTupleVariable>(m_expressions[&_assignment.rightHandSide()]);
|
||||
auto symbTuple = dynamic_pointer_cast<smt::SymbolicTupleVariable>(m_expressions[&_assignment.rightHandSide()]);
|
||||
solAssert(symbTuple, "");
|
||||
for (auto const& component: symbTuple->components())
|
||||
{
|
||||
@ -426,7 +426,7 @@ void SMTChecker::endVisit(TupleExpression const& _tuple)
|
||||
else if (_tuple.annotation().type->category() == Type::Category::Tuple)
|
||||
{
|
||||
createExpr(_tuple);
|
||||
vector<shared_ptr<SymbolicVariable>> components;
|
||||
vector<shared_ptr<smt::SymbolicVariable>> components;
|
||||
for (auto const& component: _tuple.components())
|
||||
if (component)
|
||||
{
|
||||
@ -441,7 +441,7 @@ void SMTChecker::endVisit(TupleExpression const& _tuple)
|
||||
else
|
||||
components.push_back(nullptr);
|
||||
solAssert(components.size() == _tuple.components().size(), "");
|
||||
auto const& symbTuple = dynamic_pointer_cast<SymbolicTupleVariable>(m_expressions[&_tuple]);
|
||||
auto const& symbTuple = dynamic_pointer_cast<smt::SymbolicTupleVariable>(m_expressions[&_tuple]);
|
||||
solAssert(symbTuple, "");
|
||||
symbTuple->setComponents(move(components));
|
||||
}
|
||||
@ -450,7 +450,7 @@ void SMTChecker::endVisit(TupleExpression const& _tuple)
|
||||
/// Parenthesized expressions are also TupleExpression regardless their type.
|
||||
auto const& components = _tuple.components();
|
||||
solAssert(components.size() == 1, "");
|
||||
if (isSupportedType(components.front()->annotation().type->category()))
|
||||
if (smt::isSupportedType(components.front()->annotation().type->category()))
|
||||
defineExpr(_tuple, expr(*components.front()));
|
||||
}
|
||||
}
|
||||
@ -490,7 +490,7 @@ void SMTChecker::checkUnderflow(OverflowTarget& _target)
|
||||
solAssert(_target.type != OverflowTarget::Type::Overflow, "");
|
||||
auto intType = dynamic_cast<IntegerType const*>(_target.intType);
|
||||
checkCondition(
|
||||
_target.path && _target.value < minValue(*intType),
|
||||
_target.path && _target.value < smt::minValue(*intType),
|
||||
_target.location,
|
||||
"Underflow (resulting value less than " + formatNumberReadable(intType->minValue()) + ")",
|
||||
"<result>",
|
||||
@ -503,7 +503,7 @@ void SMTChecker::checkOverflow(OverflowTarget& _target)
|
||||
solAssert(_target.type != OverflowTarget::Type::Underflow, "");
|
||||
auto intType = dynamic_cast<IntegerType const*>(_target.intType);
|
||||
checkCondition(
|
||||
_target.path && _target.value > maxValue(*intType),
|
||||
_target.path && _target.value > smt::maxValue(*intType),
|
||||
_target.location,
|
||||
"Overflow (resulting value larger than " + formatNumberReadable(intType->maxValue()) + ")",
|
||||
"<result>",
|
||||
@ -520,7 +520,7 @@ void SMTChecker::endVisit(UnaryOperation const& _op)
|
||||
{
|
||||
case Token::Not: // !
|
||||
{
|
||||
solAssert(isBool(_op.annotation().type->category()), "");
|
||||
solAssert(smt::isBool(_op.annotation().type->category()), "");
|
||||
defineExpr(_op, !expr(_op.subExpression()));
|
||||
break;
|
||||
}
|
||||
@ -528,7 +528,7 @@ void SMTChecker::endVisit(UnaryOperation const& _op)
|
||||
case Token::Dec: // -- (pre- or postfix)
|
||||
{
|
||||
|
||||
solAssert(isInteger(_op.annotation().type->category()), "");
|
||||
solAssert(smt::isInteger(_op.annotation().type->category()), "");
|
||||
solAssert(_op.subExpression().annotation().lValueRequested, "");
|
||||
if (auto identifier = dynamic_cast<Identifier const*>(&_op.subExpression()))
|
||||
{
|
||||
@ -785,13 +785,13 @@ void SMTChecker::inlineFunctionCall(FunctionCall const& _funCall)
|
||||
auto const& returnParams = funDef->returnParameters();
|
||||
if (returnParams.size() > 1)
|
||||
{
|
||||
vector<shared_ptr<SymbolicVariable>> components;
|
||||
vector<shared_ptr<smt::SymbolicVariable>> components;
|
||||
for (auto param: returnParams)
|
||||
{
|
||||
solAssert(m_variables[param.get()], "");
|
||||
components.push_back(m_variables[param.get()]);
|
||||
}
|
||||
auto const& symbTuple = dynamic_pointer_cast<SymbolicTupleVariable>(m_expressions[&_funCall]);
|
||||
auto const& symbTuple = dynamic_pointer_cast<smt::SymbolicTupleVariable>(m_expressions[&_funCall]);
|
||||
solAssert(symbTuple, "");
|
||||
symbTuple->setComponents(move(components));
|
||||
}
|
||||
@ -837,7 +837,7 @@ void SMTChecker::endVisit(Identifier const& _identifier)
|
||||
}
|
||||
else if (_identifier.annotation().type->category() == Type::Category::Function)
|
||||
visitFunctionIdentifier(_identifier);
|
||||
else if (isSupportedType(_identifier.annotation().type->category()))
|
||||
else if (smt::isSupportedType(_identifier.annotation().type->category()))
|
||||
{
|
||||
if (auto decl = identifierToVariable(_identifier))
|
||||
defineExpr(_identifier, currentValue(*decl));
|
||||
@ -880,7 +880,7 @@ void SMTChecker::visitTypeConversion(FunctionCall const& _funCall)
|
||||
{
|
||||
auto const& intType = dynamic_cast<IntegerType const&>(*m_expressions.at(&_funCall)->type());
|
||||
defineExpr(_funCall, smt::Expression::ite(
|
||||
expr(*argument) >= minValue(intType) && expr(*argument) <= maxValue(intType),
|
||||
expr(*argument) >= smt::minValue(intType) && expr(*argument) <= smt::maxValue(intType),
|
||||
expr(*argument),
|
||||
expr(_funCall)
|
||||
));
|
||||
@ -908,9 +908,9 @@ void SMTChecker::endVisit(Literal const& _literal)
|
||||
{
|
||||
solAssert(_literal.annotation().type, "Expected type for AST node");
|
||||
Type const& type = *_literal.annotation().type;
|
||||
if (isNumber(type.category()))
|
||||
if (smt::isNumber(type.category()))
|
||||
defineExpr(_literal, smt::Expression(type.literalValue(&_literal)));
|
||||
else if (isBool(type.category()))
|
||||
else if (smt::isBool(type.category()))
|
||||
defineExpr(_literal, smt::Expression(_literal.token() == Token::TrueLiteral ? true : false));
|
||||
else
|
||||
{
|
||||
@ -919,7 +919,7 @@ void SMTChecker::endVisit(Literal const& _literal)
|
||||
auto stringType = TypeProvider::stringMemory();
|
||||
auto stringLit = dynamic_cast<StringLiteralType const*>(_literal.annotation().type);
|
||||
solAssert(stringLit, "");
|
||||
auto result = newSymbolicVariable(*stringType, stringLit->richIdentifier(), *m_interface);
|
||||
auto result = smt::newSymbolicVariable(*stringType, stringLit->richIdentifier(), *m_interface);
|
||||
m_expressions.emplace(&_literal, result.second);
|
||||
}
|
||||
m_errorReporter.warning(
|
||||
@ -1006,7 +1006,7 @@ bool SMTChecker::visit(MemberAccess const& _memberAccess)
|
||||
|
||||
void SMTChecker::endVisit(IndexAccess const& _indexAccess)
|
||||
{
|
||||
shared_ptr<SymbolicVariable> array;
|
||||
shared_ptr<smt::SymbolicVariable> array;
|
||||
if (auto const& id = dynamic_cast<Identifier const*>(&_indexAccess.baseExpression()))
|
||||
{
|
||||
auto varDecl = identifierToVariable(*id);
|
||||
@ -1121,7 +1121,7 @@ void SMTChecker::defineGlobalVariable(string const& _name, Expression const& _ex
|
||||
{
|
||||
if (!knownGlobalSymbol(_name))
|
||||
{
|
||||
auto result = newSymbolicVariable(*_expr.annotation().type, _name, *m_interface);
|
||||
auto result = smt::newSymbolicVariable(*_expr.annotation().type, _name, *m_interface);
|
||||
m_globalContext.emplace(_name, result.second);
|
||||
setUnknownValue(*result.second);
|
||||
if (result.first)
|
||||
@ -1134,7 +1134,7 @@ void SMTChecker::defineGlobalVariable(string const& _name, Expression const& _ex
|
||||
m_globalContext.at(_name)->increaseIndex();
|
||||
// The default behavior is not to increase the index since
|
||||
// most of the global values stay the same throughout a tx.
|
||||
if (isSupportedType(_expr.annotation().type->category()))
|
||||
if (smt::isSupportedType(_expr.annotation().type->category()))
|
||||
defineExpr(_expr, m_globalContext.at(_name)->currentValue());
|
||||
}
|
||||
|
||||
@ -1142,7 +1142,7 @@ void SMTChecker::defineGlobalFunction(string const& _name, Expression const& _ex
|
||||
{
|
||||
if (!knownGlobalSymbol(_name))
|
||||
{
|
||||
auto result = newSymbolicVariable(*_expr.annotation().type, _name, *m_interface);
|
||||
auto result = smt::newSymbolicVariable(*_expr.annotation().type, _name, *m_interface);
|
||||
m_globalContext.emplace(_name, result.second);
|
||||
if (result.first)
|
||||
m_errorReporter.warning(
|
||||
@ -1245,16 +1245,16 @@ smt::Expression SMTChecker::arithmeticOperation(
|
||||
_location
|
||||
);
|
||||
|
||||
smt::Expression intValueRange = (0 - minValue(intType)) + maxValue(intType) + 1;
|
||||
smt::Expression intValueRange = (0 - smt::minValue(intType)) + smt::maxValue(intType) + 1;
|
||||
value = smt::Expression::ite(
|
||||
value > maxValue(intType) || value < minValue(intType),
|
||||
value > smt::maxValue(intType) || value < smt::minValue(intType),
|
||||
value % intValueRange,
|
||||
value
|
||||
);
|
||||
if (intType.isSigned())
|
||||
{
|
||||
value = smt::Expression::ite(
|
||||
value > maxValue(intType),
|
||||
value > smt::maxValue(intType),
|
||||
value - intValueRange,
|
||||
value
|
||||
);
|
||||
@ -1266,13 +1266,13 @@ smt::Expression SMTChecker::arithmeticOperation(
|
||||
void SMTChecker::compareOperation(BinaryOperation const& _op)
|
||||
{
|
||||
solAssert(_op.annotation().commonType, "");
|
||||
if (isSupportedType(_op.annotation().commonType->category()))
|
||||
if (smt::isSupportedType(_op.annotation().commonType->category()))
|
||||
{
|
||||
smt::Expression left(expr(_op.leftExpression()));
|
||||
smt::Expression right(expr(_op.rightExpression()));
|
||||
Token op = _op.getOperator();
|
||||
shared_ptr<smt::Expression> value;
|
||||
if (isNumber(_op.annotation().commonType->category()))
|
||||
if (smt::isNumber(_op.annotation().commonType->category()))
|
||||
{
|
||||
value = make_shared<smt::Expression>(
|
||||
op == Token::Equal ? (left == right) :
|
||||
@ -1285,7 +1285,7 @@ void SMTChecker::compareOperation(BinaryOperation const& _op)
|
||||
}
|
||||
else // Bool
|
||||
{
|
||||
solUnimplementedAssert(isBool(_op.annotation().commonType->category()), "Operation not yet supported");
|
||||
solUnimplementedAssert(smt::isBool(_op.annotation().commonType->category()), "Operation not yet supported");
|
||||
value = make_shared<smt::Expression>(
|
||||
op == Token::Equal ? (left == right) :
|
||||
/*op == Token::NotEqual*/ (left != right)
|
||||
@ -1349,7 +1349,7 @@ void SMTChecker::assignment(
|
||||
langutil::SourceLocation const& _location
|
||||
)
|
||||
{
|
||||
if (!isSupportedType(_type->category()))
|
||||
if (!smt::isSupportedType(_type->category()))
|
||||
m_errorReporter.warning(
|
||||
_location,
|
||||
"Assertion checker does not yet implement type " + _type->toString()
|
||||
@ -1469,7 +1469,7 @@ void SMTChecker::checkCondition(
|
||||
auto const& type = var.second->type();
|
||||
if (
|
||||
type->isValueType() &&
|
||||
smtKind(type->category()) != smt::Kind::Function
|
||||
smt::smtKind(type->category()) != smt::Kind::Function
|
||||
)
|
||||
{
|
||||
expressionsToEvaluate.emplace_back(var.second->currentValue());
|
||||
@ -1766,7 +1766,7 @@ bool SMTChecker::createVariable(VariableDeclaration const& _varDecl)
|
||||
return true;
|
||||
auto const& type = _varDecl.type();
|
||||
solAssert(m_variables.count(&_varDecl) == 0, "");
|
||||
auto result = newSymbolicVariable(*type, _varDecl.name() + "_" + to_string(_varDecl.id()), *m_interface);
|
||||
auto result = smt::newSymbolicVariable(*type, _varDecl.name() + "_" + to_string(_varDecl.id()), *m_interface);
|
||||
m_variables.emplace(&_varDecl, result.second);
|
||||
if (result.first)
|
||||
{
|
||||
@ -1808,7 +1808,7 @@ void SMTChecker::setZeroValue(VariableDeclaration const& _decl)
|
||||
setZeroValue(*m_variables.at(&_decl));
|
||||
}
|
||||
|
||||
void SMTChecker::setZeroValue(SymbolicVariable& _variable)
|
||||
void SMTChecker::setZeroValue(smt::SymbolicVariable& _variable)
|
||||
{
|
||||
smt::setSymbolicZeroValue(_variable, *m_interface);
|
||||
}
|
||||
@ -1819,7 +1819,7 @@ void SMTChecker::setUnknownValue(VariableDeclaration const& _decl)
|
||||
setUnknownValue(*m_variables.at(&_decl));
|
||||
}
|
||||
|
||||
void SMTChecker::setUnknownValue(SymbolicVariable& _variable)
|
||||
void SMTChecker::setUnknownValue(smt::SymbolicVariable& _variable)
|
||||
{
|
||||
smt::setSymbolicUnknownValue(_variable, *m_interface);
|
||||
}
|
||||
@ -1851,7 +1851,7 @@ void SMTChecker::createExpr(Expression const& _e)
|
||||
m_expressions.at(&_e)->increaseIndex();
|
||||
else
|
||||
{
|
||||
auto result = newSymbolicVariable(*_e.annotation().type, "expr_" + to_string(_e.id()), *m_interface);
|
||||
auto result = smt::newSymbolicVariable(*_e.annotation().type, "expr_" + to_string(_e.id()), *m_interface);
|
||||
m_expressions.emplace(&_e, result.second);
|
||||
if (result.first)
|
||||
m_errorReporter.warning(
|
||||
@ -1864,7 +1864,7 @@ void SMTChecker::createExpr(Expression const& _e)
|
||||
void SMTChecker::defineExpr(Expression const& _e, smt::Expression _value)
|
||||
{
|
||||
createExpr(_e);
|
||||
solAssert(smtKind(_e.annotation().type->category()) != smt::Kind::Function, "Equality operator applied to type that is not fully supported");
|
||||
solAssert(smt::smtKind(_e.annotation().type->category()) != smt::Kind::Function, "Equality operator applied to type that is not fully supported");
|
||||
m_interface->addAssertion(expr(_e) == _value);
|
||||
}
|
||||
|
||||
|
@ -247,10 +247,10 @@ private:
|
||||
|
||||
/// Sets the value of the declaration to zero.
|
||||
void setZeroValue(VariableDeclaration const& _decl);
|
||||
void setZeroValue(SymbolicVariable& _variable);
|
||||
void setZeroValue(smt::SymbolicVariable& _variable);
|
||||
/// Resets the variable to an unknown value (in its range).
|
||||
void setUnknownValue(VariableDeclaration const& decl);
|
||||
void setUnknownValue(SymbolicVariable& _variable);
|
||||
void setUnknownValue(smt::SymbolicVariable& _variable);
|
||||
|
||||
/// Returns the expression corresponding to the AST node. Throws if the expression does not exist.
|
||||
smt::Expression expr(Expression const& _e);
|
||||
@ -296,7 +296,7 @@ private:
|
||||
VariableDeclaration const* identifierToVariable(Expression const& _expr);
|
||||
|
||||
std::unique_ptr<smt::SolverInterface> m_interface;
|
||||
VariableUsage m_variableUsage;
|
||||
smt::VariableUsage m_variableUsage;
|
||||
bool m_loopExecutionHappened = false;
|
||||
bool m_arrayAssignmentHappened = false;
|
||||
bool m_externalFunctionCallHappened = false;
|
||||
@ -304,9 +304,9 @@ private:
|
||||
bool m_noSolverWarning = false;
|
||||
/// An Expression may have multiple smt::Expression due to
|
||||
/// repeated calls to the same function.
|
||||
std::unordered_map<Expression const*, std::shared_ptr<SymbolicVariable>> m_expressions;
|
||||
std::unordered_map<VariableDeclaration const*, std::shared_ptr<SymbolicVariable>> m_variables;
|
||||
std::unordered_map<std::string, std::shared_ptr<SymbolicVariable>> m_globalContext;
|
||||
std::unordered_map<Expression const*, std::shared_ptr<smt::SymbolicVariable>> m_expressions;
|
||||
std::unordered_map<VariableDeclaration const*, std::shared_ptr<smt::SymbolicVariable>> m_variables;
|
||||
std::unordered_map<std::string, std::shared_ptr<smt::SymbolicVariable>> m_globalContext;
|
||||
|
||||
/// Stores the instances of an Uninterpreted Function applied to arguments.
|
||||
/// These may be direct application of UFs or Array index access.
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <libsolidity/formal/SSAVariable.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace dev::solidity;
|
||||
using namespace dev::solidity::smt;
|
||||
|
||||
SSAVariable::SSAVariable()
|
||||
{
|
||||
|
@ -23,6 +23,8 @@ namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
{
|
||||
namespace smt
|
||||
{
|
||||
|
||||
/**
|
||||
* This class represents the SSA representation of a program variable.
|
||||
@ -49,3 +51,4 @@ private:
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,79 +22,85 @@
|
||||
#include <memory>
|
||||
|
||||
using namespace std;
|
||||
using namespace dev::solidity;
|
||||
|
||||
smt::SortPointer dev::solidity::smtSort(Type const& _type)
|
||||
namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
{
|
||||
namespace smt
|
||||
{
|
||||
|
||||
SortPointer smtSort(solidity::Type const& _type)
|
||||
{
|
||||
switch (smtKind(_type.category()))
|
||||
{
|
||||
case smt::Kind::Int:
|
||||
return make_shared<smt::Sort>(smt::Kind::Int);
|
||||
case smt::Kind::Bool:
|
||||
return make_shared<smt::Sort>(smt::Kind::Bool);
|
||||
case smt::Kind::Function:
|
||||
case Kind::Int:
|
||||
return make_shared<Sort>(Kind::Int);
|
||||
case Kind::Bool:
|
||||
return make_shared<Sort>(Kind::Bool);
|
||||
case Kind::Function:
|
||||
{
|
||||
auto fType = dynamic_cast<FunctionType const*>(&_type);
|
||||
auto fType = dynamic_cast<solidity::FunctionType const*>(&_type);
|
||||
solAssert(fType, "");
|
||||
vector<smt::SortPointer> parameterSorts = smtSort(fType->parameterTypes());
|
||||
vector<SortPointer> parameterSorts = smtSort(fType->parameterTypes());
|
||||
auto returnTypes = fType->returnParameterTypes();
|
||||
smt::SortPointer returnSort;
|
||||
SortPointer returnSort;
|
||||
// TODO change this when we support tuples.
|
||||
if (returnTypes.size() == 0)
|
||||
// We cannot declare functions without a return sort, so we use the smallest.
|
||||
returnSort = make_shared<smt::Sort>(smt::Kind::Bool);
|
||||
returnSort = make_shared<Sort>(Kind::Bool);
|
||||
else if (returnTypes.size() > 1)
|
||||
// Abstract sort.
|
||||
returnSort = make_shared<smt::Sort>(smt::Kind::Int);
|
||||
returnSort = make_shared<Sort>(Kind::Int);
|
||||
else
|
||||
returnSort = smtSort(*returnTypes.front());
|
||||
return make_shared<smt::FunctionSort>(parameterSorts, returnSort);
|
||||
return make_shared<FunctionSort>(parameterSorts, returnSort);
|
||||
}
|
||||
case smt::Kind::Array:
|
||||
case Kind::Array:
|
||||
{
|
||||
if (isMapping(_type.category()))
|
||||
{
|
||||
auto mapType = dynamic_cast<MappingType const*>(&_type);
|
||||
auto mapType = dynamic_cast<solidity::MappingType const*>(&_type);
|
||||
solAssert(mapType, "");
|
||||
return make_shared<smt::ArraySort>(smtSort(*mapType->keyType()), smtSort(*mapType->valueType()));
|
||||
return make_shared<ArraySort>(smtSort(*mapType->keyType()), smtSort(*mapType->valueType()));
|
||||
}
|
||||
else
|
||||
{
|
||||
solAssert(isArray(_type.category()), "");
|
||||
auto arrayType = dynamic_cast<ArrayType const*>(&_type);
|
||||
auto arrayType = dynamic_cast<solidity::ArrayType const*>(&_type);
|
||||
solAssert(arrayType, "");
|
||||
return make_shared<smt::ArraySort>(make_shared<smt::Sort>(smt::Kind::Int), smtSort(*arrayType->baseType()));
|
||||
return make_shared<ArraySort>(make_shared<Sort>(Kind::Int), smtSort(*arrayType->baseType()));
|
||||
}
|
||||
}
|
||||
default:
|
||||
// Abstract case.
|
||||
return make_shared<smt::Sort>(smt::Kind::Int);
|
||||
return make_shared<Sort>(Kind::Int);
|
||||
}
|
||||
}
|
||||
|
||||
vector<smt::SortPointer> dev::solidity::smtSort(vector<TypePointer> const& _types)
|
||||
vector<SortPointer> smtSort(vector<solidity::TypePointer> const& _types)
|
||||
{
|
||||
vector<smt::SortPointer> sorts;
|
||||
vector<SortPointer> sorts;
|
||||
for (auto const& type: _types)
|
||||
sorts.push_back(smtSort(*type));
|
||||
return sorts;
|
||||
}
|
||||
|
||||
smt::Kind dev::solidity::smtKind(Type::Category _category)
|
||||
Kind smtKind(solidity::Type::Category _category)
|
||||
{
|
||||
if (isNumber(_category))
|
||||
return smt::Kind::Int;
|
||||
return Kind::Int;
|
||||
else if (isBool(_category))
|
||||
return smt::Kind::Bool;
|
||||
return Kind::Bool;
|
||||
else if (isFunction(_category))
|
||||
return smt::Kind::Function;
|
||||
return Kind::Function;
|
||||
else if (isMapping(_category) || isArray(_category))
|
||||
return smt::Kind::Array;
|
||||
return Kind::Array;
|
||||
// Abstract case.
|
||||
return smt::Kind::Int;
|
||||
return Kind::Int;
|
||||
}
|
||||
|
||||
bool dev::solidity::isSupportedType(Type::Category _category)
|
||||
bool isSupportedType(solidity::Type::Category _category)
|
||||
{
|
||||
return isNumber(_category) ||
|
||||
isBool(_category) ||
|
||||
@ -103,25 +109,25 @@ bool dev::solidity::isSupportedType(Type::Category _category)
|
||||
isTuple(_category);
|
||||
}
|
||||
|
||||
bool dev::solidity::isSupportedTypeDeclaration(Type::Category _category)
|
||||
bool isSupportedTypeDeclaration(solidity::Type::Category _category)
|
||||
{
|
||||
return isSupportedType(_category) ||
|
||||
isFunction(_category);
|
||||
}
|
||||
|
||||
pair<bool, shared_ptr<SymbolicVariable>> dev::solidity::newSymbolicVariable(
|
||||
Type const& _type,
|
||||
pair<bool, shared_ptr<SymbolicVariable>> newSymbolicVariable(
|
||||
solidity::Type const& _type,
|
||||
std::string const& _uniqueName,
|
||||
smt::SolverInterface& _solver
|
||||
SolverInterface& _solver
|
||||
)
|
||||
{
|
||||
bool abstract = false;
|
||||
shared_ptr<SymbolicVariable> var;
|
||||
TypePointer type = &_type;
|
||||
solidity::TypePointer type = &_type;
|
||||
if (!isSupportedTypeDeclaration(_type))
|
||||
{
|
||||
abstract = true;
|
||||
var = make_shared<SymbolicIntVariable>(TypeProvider::uint256(), _uniqueName, _solver);
|
||||
var = make_shared<SymbolicIntVariable>(solidity::TypeProvider::uint256(), _uniqueName, _solver);
|
||||
}
|
||||
else if (isBool(_type.category()))
|
||||
var = make_shared<SymbolicBoolVariable>(type, _uniqueName, _solver);
|
||||
@ -131,7 +137,7 @@ pair<bool, shared_ptr<SymbolicVariable>> dev::solidity::newSymbolicVariable(
|
||||
var = make_shared<SymbolicIntVariable>(type, _uniqueName, _solver);
|
||||
else if (isFixedBytes(_type.category()))
|
||||
{
|
||||
auto fixedBytesType = dynamic_cast<FixedBytesType const*>(type);
|
||||
auto fixedBytesType = dynamic_cast<solidity::FixedBytesType const*>(type);
|
||||
solAssert(fixedBytesType, "");
|
||||
var = make_shared<SymbolicFixedBytesVariable>(fixedBytesType->numBytes(), _uniqueName, _solver);
|
||||
}
|
||||
@ -141,10 +147,10 @@ pair<bool, shared_ptr<SymbolicVariable>> dev::solidity::newSymbolicVariable(
|
||||
var = make_shared<SymbolicEnumVariable>(type, _uniqueName, _solver);
|
||||
else if (isRational(_type.category()))
|
||||
{
|
||||
auto rational = dynamic_cast<RationalNumberType const*>(&_type);
|
||||
auto rational = dynamic_cast<solidity::RationalNumberType const*>(&_type);
|
||||
solAssert(rational, "");
|
||||
if (rational->isFractional())
|
||||
var = make_shared<SymbolicIntVariable>(TypeProvider::uint256(), _uniqueName, _solver);
|
||||
var = make_shared<SymbolicIntVariable>(solidity::TypeProvider::uint256(), _uniqueName, _solver);
|
||||
else
|
||||
var = make_shared<SymbolicIntVariable>(type, _uniqueName, _solver);
|
||||
}
|
||||
@ -159,47 +165,47 @@ pair<bool, shared_ptr<SymbolicVariable>> dev::solidity::newSymbolicVariable(
|
||||
return make_pair(abstract, var);
|
||||
}
|
||||
|
||||
bool dev::solidity::isSupportedType(Type const& _type)
|
||||
bool isSupportedType(solidity::Type const& _type)
|
||||
{
|
||||
return isSupportedType(_type.category());
|
||||
}
|
||||
|
||||
bool dev::solidity::isSupportedTypeDeclaration(Type const& _type)
|
||||
bool isSupportedTypeDeclaration(solidity::Type const& _type)
|
||||
{
|
||||
return isSupportedTypeDeclaration(_type.category());
|
||||
}
|
||||
|
||||
bool dev::solidity::isInteger(Type::Category _category)
|
||||
bool isInteger(solidity::Type::Category _category)
|
||||
{
|
||||
return _category == Type::Category::Integer;
|
||||
return _category == solidity::Type::Category::Integer;
|
||||
}
|
||||
|
||||
bool dev::solidity::isRational(Type::Category _category)
|
||||
bool isRational(solidity::Type::Category _category)
|
||||
{
|
||||
return _category == Type::Category::RationalNumber;
|
||||
return _category == solidity::Type::Category::RationalNumber;
|
||||
}
|
||||
|
||||
bool dev::solidity::isFixedBytes(Type::Category _category)
|
||||
bool isFixedBytes(solidity::Type::Category _category)
|
||||
{
|
||||
return _category == Type::Category::FixedBytes;
|
||||
return _category == solidity::Type::Category::FixedBytes;
|
||||
}
|
||||
|
||||
bool dev::solidity::isAddress(Type::Category _category)
|
||||
bool isAddress(solidity::Type::Category _category)
|
||||
{
|
||||
return _category == Type::Category::Address;
|
||||
return _category == solidity::Type::Category::Address;
|
||||
}
|
||||
|
||||
bool dev::solidity::isContract(Type::Category _category)
|
||||
bool isContract(solidity::Type::Category _category)
|
||||
{
|
||||
return _category == Type::Category::Contract;
|
||||
return _category == solidity::Type::Category::Contract;
|
||||
}
|
||||
|
||||
bool dev::solidity::isEnum(Type::Category _category)
|
||||
bool isEnum(solidity::Type::Category _category)
|
||||
{
|
||||
return _category == Type::Category::Enum;
|
||||
return _category == solidity::Type::Category::Enum;
|
||||
}
|
||||
|
||||
bool dev::solidity::isNumber(Type::Category _category)
|
||||
bool isNumber(solidity::Type::Category _category)
|
||||
{
|
||||
return isInteger(_category) ||
|
||||
isRational(_category) ||
|
||||
@ -209,75 +215,79 @@ bool dev::solidity::isNumber(Type::Category _category)
|
||||
isEnum(_category);
|
||||
}
|
||||
|
||||
bool dev::solidity::isBool(Type::Category _category)
|
||||
bool isBool(solidity::Type::Category _category)
|
||||
{
|
||||
return _category == Type::Category::Bool;
|
||||
return _category == solidity::Type::Category::Bool;
|
||||
}
|
||||
|
||||
bool dev::solidity::isFunction(Type::Category _category)
|
||||
bool isFunction(solidity::Type::Category _category)
|
||||
{
|
||||
return _category == Type::Category::Function;
|
||||
return _category == solidity::Type::Category::Function;
|
||||
}
|
||||
|
||||
bool dev::solidity::isMapping(Type::Category _category)
|
||||
bool isMapping(solidity::Type::Category _category)
|
||||
{
|
||||
return _category == Type::Category::Mapping;
|
||||
return _category == solidity::Type::Category::Mapping;
|
||||
}
|
||||
|
||||
bool dev::solidity::isArray(Type::Category _category)
|
||||
bool isArray(solidity::Type::Category _category)
|
||||
{
|
||||
return _category == Type::Category::Array;
|
||||
return _category == solidity::Type::Category::Array;
|
||||
}
|
||||
|
||||
bool dev::solidity::isTuple(Type::Category _category)
|
||||
bool isTuple(solidity::Type::Category _category)
|
||||
{
|
||||
return _category == Type::Category::Tuple;
|
||||
return _category == solidity::Type::Category::Tuple;
|
||||
}
|
||||
|
||||
smt::Expression dev::solidity::minValue(IntegerType const& _type)
|
||||
Expression minValue(solidity::IntegerType const& _type)
|
||||
{
|
||||
return smt::Expression(_type.minValue());
|
||||
return Expression(_type.minValue());
|
||||
}
|
||||
|
||||
smt::Expression dev::solidity::maxValue(IntegerType const& _type)
|
||||
Expression maxValue(solidity::IntegerType const& _type)
|
||||
{
|
||||
return smt::Expression(_type.maxValue());
|
||||
return Expression(_type.maxValue());
|
||||
}
|
||||
|
||||
void dev::solidity::smt::setSymbolicZeroValue(SymbolicVariable const& _variable, smt::SolverInterface& _interface)
|
||||
void setSymbolicZeroValue(SymbolicVariable const& _variable, SolverInterface& _interface)
|
||||
{
|
||||
setSymbolicZeroValue(_variable.currentValue(), _variable.type(), _interface);
|
||||
}
|
||||
|
||||
void dev::solidity::smt::setSymbolicZeroValue(smt::Expression _expr, TypePointer const& _type, smt::SolverInterface& _interface)
|
||||
void setSymbolicZeroValue(Expression _expr, solidity::TypePointer const& _type, SolverInterface& _interface)
|
||||
{
|
||||
solAssert(_type, "");
|
||||
if (isInteger(_type->category()))
|
||||
_interface.addAssertion(_expr == 0);
|
||||
else if (isBool(_type->category()))
|
||||
_interface.addAssertion(_expr == smt::Expression(false));
|
||||
_interface.addAssertion(_expr == Expression(false));
|
||||
}
|
||||
|
||||
void dev::solidity::smt::setSymbolicUnknownValue(SymbolicVariable const& _variable, smt::SolverInterface& _interface)
|
||||
void setSymbolicUnknownValue(SymbolicVariable const& _variable, SolverInterface& _interface)
|
||||
{
|
||||
setSymbolicUnknownValue(_variable.currentValue(), _variable.type(), _interface);
|
||||
}
|
||||
|
||||
void dev::solidity::smt::setSymbolicUnknownValue(smt::Expression _expr, TypePointer const& _type, smt::SolverInterface& _interface)
|
||||
void setSymbolicUnknownValue(Expression _expr, solidity::TypePointer const& _type, SolverInterface& _interface)
|
||||
{
|
||||
solAssert(_type, "");
|
||||
if (isEnum(_type->category()))
|
||||
{
|
||||
auto enumType = dynamic_cast<EnumType const*>(_type);
|
||||
auto enumType = dynamic_cast<solidity::EnumType const*>(_type);
|
||||
solAssert(enumType, "");
|
||||
_interface.addAssertion(_expr >= 0);
|
||||
_interface.addAssertion(_expr < enumType->numberOfMembers());
|
||||
}
|
||||
else if (isInteger(_type->category()))
|
||||
{
|
||||
auto intType = dynamic_cast<IntegerType const*>(_type);
|
||||
auto intType = dynamic_cast<solidity::IntegerType const*>(_type);
|
||||
solAssert(intType, "");
|
||||
_interface.addAssertion(_expr >= minValue(*intType));
|
||||
_interface.addAssertion(_expr <= maxValue(*intType));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,50 +26,48 @@ namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
{
|
||||
namespace smt
|
||||
{
|
||||
|
||||
/// Returns the SMT sort that models the Solidity type _type.
|
||||
smt::SortPointer smtSort(Type const& _type);
|
||||
std::vector<smt::SortPointer> smtSort(std::vector<TypePointer> const& _types);
|
||||
SortPointer smtSort(solidity::Type const& _type);
|
||||
std::vector<SortPointer> smtSort(std::vector<solidity::TypePointer> const& _types);
|
||||
/// Returns the SMT kind that models the Solidity type type category _category.
|
||||
smt::Kind smtKind(Type::Category _category);
|
||||
Kind smtKind(solidity::Type::Category _category);
|
||||
|
||||
/// Returns true if type is fully supported (declaration and operations).
|
||||
bool isSupportedType(Type::Category _category);
|
||||
bool isSupportedType(Type const& _type);
|
||||
bool isSupportedType(solidity::Type::Category _category);
|
||||
bool isSupportedType(solidity::Type const& _type);
|
||||
/// Returns true if type is partially supported (declaration).
|
||||
bool isSupportedTypeDeclaration(Type::Category _category);
|
||||
bool isSupportedTypeDeclaration(Type const& _type);
|
||||
bool isSupportedTypeDeclaration(solidity::Type::Category _category);
|
||||
bool isSupportedTypeDeclaration(solidity::Type const& _type);
|
||||
|
||||
bool isInteger(Type::Category _category);
|
||||
bool isRational(Type::Category _category);
|
||||
bool isFixedBytes(Type::Category _category);
|
||||
bool isAddress(Type::Category _category);
|
||||
bool isContract(Type::Category _category);
|
||||
bool isEnum(Type::Category _category);
|
||||
bool isNumber(Type::Category _category);
|
||||
bool isBool(Type::Category _category);
|
||||
bool isFunction(Type::Category _category);
|
||||
bool isMapping(Type::Category _category);
|
||||
bool isArray(Type::Category _category);
|
||||
bool isTuple(Type::Category _category);
|
||||
bool isInteger(solidity::Type::Category _category);
|
||||
bool isRational(solidity::Type::Category _category);
|
||||
bool isFixedBytes(solidity::Type::Category _category);
|
||||
bool isAddress(solidity::Type::Category _category);
|
||||
bool isContract(solidity::Type::Category _category);
|
||||
bool isEnum(solidity::Type::Category _category);
|
||||
bool isNumber(solidity::Type::Category _category);
|
||||
bool isBool(solidity::Type::Category _category);
|
||||
bool isFunction(solidity::Type::Category _category);
|
||||
bool isMapping(solidity::Type::Category _category);
|
||||
bool isArray(solidity::Type::Category _category);
|
||||
bool isTuple(solidity::Type::Category _category);
|
||||
|
||||
/// Returns a new symbolic variable, according to _type.
|
||||
/// Also returns whether the type is abstract or not,
|
||||
/// which is true for unsupported types.
|
||||
std::pair<bool, std::shared_ptr<SymbolicVariable>> newSymbolicVariable(Type const& _type, std::string const& _uniqueName, smt::SolverInterface& _solver);
|
||||
std::pair<bool, std::shared_ptr<SymbolicVariable>> newSymbolicVariable(solidity::Type const& _type, std::string const& _uniqueName, SolverInterface& _solver);
|
||||
|
||||
smt::Expression minValue(IntegerType const& _type);
|
||||
smt::Expression maxValue(IntegerType const& _type);
|
||||
Expression minValue(solidity::IntegerType const& _type);
|
||||
Expression maxValue(solidity::IntegerType const& _type);
|
||||
|
||||
namespace smt
|
||||
{
|
||||
|
||||
void setSymbolicZeroValue(SymbolicVariable const& _variable, smt::SolverInterface& _interface);
|
||||
void setSymbolicZeroValue(smt::Expression _expr, TypePointer const& _type, smt::SolverInterface& _interface);
|
||||
void setSymbolicUnknownValue(SymbolicVariable const& _variable, smt::SolverInterface& _interface);
|
||||
void setSymbolicUnknownValue(smt::Expression _expr, TypePointer const& _type, smt::SolverInterface& _interface);
|
||||
|
||||
}
|
||||
void setSymbolicZeroValue(SymbolicVariable const& _variable, SolverInterface& _interface);
|
||||
void setSymbolicZeroValue(Expression _expr, solidity::TypePointer const& _type, SolverInterface& _interface);
|
||||
void setSymbolicUnknownValue(SymbolicVariable const& _variable, SolverInterface& _interface);
|
||||
void setSymbolicUnknownValue(Expression _expr, solidity::TypePointer const& _type, SolverInterface& _interface);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,12 +23,12 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::solidity;
|
||||
using namespace dev::solidity::smt;
|
||||
|
||||
SymbolicVariable::SymbolicVariable(
|
||||
TypePointer _type,
|
||||
solidity::TypePointer _type,
|
||||
string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
):
|
||||
m_type(move(_type)),
|
||||
m_uniqueName(move(_uniqueName)),
|
||||
@ -41,9 +41,9 @@ SymbolicVariable::SymbolicVariable(
|
||||
}
|
||||
|
||||
SymbolicVariable::SymbolicVariable(
|
||||
smt::SortPointer _sort,
|
||||
SortPointer _sort,
|
||||
string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
):
|
||||
m_sort(move(_sort)),
|
||||
m_uniqueName(move(_uniqueName)),
|
||||
@ -53,7 +53,7 @@ SymbolicVariable::SymbolicVariable(
|
||||
solAssert(m_sort, "");
|
||||
}
|
||||
|
||||
smt::Expression SymbolicVariable::currentValue() const
|
||||
Expression SymbolicVariable::currentValue() const
|
||||
{
|
||||
return valueAtIndex(m_ssa->index());
|
||||
}
|
||||
@ -63,7 +63,7 @@ string SymbolicVariable::currentName() const
|
||||
return uniqueSymbol(m_ssa->index());
|
||||
}
|
||||
|
||||
smt::Expression SymbolicVariable::valueAtIndex(int _index) const
|
||||
Expression SymbolicVariable::valueAtIndex(int _index) const
|
||||
{
|
||||
return m_interface.newVariable(uniqueSymbol(_index), m_sort);
|
||||
}
|
||||
@ -73,26 +73,26 @@ string SymbolicVariable::uniqueSymbol(unsigned _index) const
|
||||
return m_uniqueName + "_" + to_string(_index);
|
||||
}
|
||||
|
||||
smt::Expression SymbolicVariable::increaseIndex()
|
||||
Expression SymbolicVariable::increaseIndex()
|
||||
{
|
||||
++(*m_ssa);
|
||||
return currentValue();
|
||||
}
|
||||
|
||||
SymbolicBoolVariable::SymbolicBoolVariable(
|
||||
TypePointer _type,
|
||||
solidity::TypePointer _type,
|
||||
string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
):
|
||||
SymbolicVariable(move(_type), move(_uniqueName), _interface)
|
||||
{
|
||||
solAssert(m_type->category() == Type::Category::Bool, "");
|
||||
solAssert(m_type->category() == solidity::Type::Category::Bool, "");
|
||||
}
|
||||
|
||||
SymbolicIntVariable::SymbolicIntVariable(
|
||||
TypePointer _type,
|
||||
solidity::TypePointer _type,
|
||||
string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
):
|
||||
SymbolicVariable(move(_type), move(_uniqueName), _interface)
|
||||
{
|
||||
@ -101,7 +101,7 @@ SymbolicIntVariable::SymbolicIntVariable(
|
||||
|
||||
SymbolicAddressVariable::SymbolicAddressVariable(
|
||||
string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
):
|
||||
SymbolicIntVariable(TypeProvider::uint(160), move(_uniqueName), _interface)
|
||||
{
|
||||
@ -110,21 +110,21 @@ SymbolicAddressVariable::SymbolicAddressVariable(
|
||||
SymbolicFixedBytesVariable::SymbolicFixedBytesVariable(
|
||||
unsigned _numBytes,
|
||||
string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
):
|
||||
SymbolicIntVariable(TypeProvider::uint(_numBytes * 8), move(_uniqueName), _interface)
|
||||
{
|
||||
}
|
||||
|
||||
SymbolicFunctionVariable::SymbolicFunctionVariable(
|
||||
TypePointer _type,
|
||||
solidity::TypePointer _type,
|
||||
string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
):
|
||||
SymbolicVariable(move(_type), move(_uniqueName), _interface),
|
||||
m_declaration(m_interface.newVariable(currentName(), m_sort))
|
||||
{
|
||||
solAssert(m_type->category() == Type::Category::Function, "");
|
||||
solAssert(m_type->category() == solidity::Type::Category::Function, "");
|
||||
}
|
||||
|
||||
void SymbolicFunctionVariable::resetDeclaration()
|
||||
@ -132,22 +132,22 @@ void SymbolicFunctionVariable::resetDeclaration()
|
||||
m_declaration = m_interface.newVariable(currentName(), m_sort);
|
||||
}
|
||||
|
||||
smt::Expression SymbolicFunctionVariable::increaseIndex()
|
||||
Expression SymbolicFunctionVariable::increaseIndex()
|
||||
{
|
||||
++(*m_ssa);
|
||||
resetDeclaration();
|
||||
return currentValue();
|
||||
}
|
||||
|
||||
smt::Expression SymbolicFunctionVariable::operator()(vector<smt::Expression> _arguments) const
|
||||
Expression SymbolicFunctionVariable::operator()(vector<Expression> _arguments) const
|
||||
{
|
||||
return m_declaration(_arguments);
|
||||
}
|
||||
|
||||
SymbolicMappingVariable::SymbolicMappingVariable(
|
||||
TypePointer _type,
|
||||
solidity::TypePointer _type,
|
||||
string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
):
|
||||
SymbolicVariable(move(_type), move(_uniqueName), _interface)
|
||||
{
|
||||
@ -155,9 +155,9 @@ SymbolicMappingVariable::SymbolicMappingVariable(
|
||||
}
|
||||
|
||||
SymbolicArrayVariable::SymbolicArrayVariable(
|
||||
TypePointer _type,
|
||||
solidity::TypePointer _type,
|
||||
string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
):
|
||||
SymbolicVariable(move(_type), move(_uniqueName), _interface)
|
||||
{
|
||||
@ -165,9 +165,9 @@ SymbolicArrayVariable::SymbolicArrayVariable(
|
||||
}
|
||||
|
||||
SymbolicEnumVariable::SymbolicEnumVariable(
|
||||
TypePointer _type,
|
||||
solidity::TypePointer _type,
|
||||
string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
):
|
||||
SymbolicVariable(move(_type), move(_uniqueName), _interface)
|
||||
{
|
||||
@ -175,9 +175,9 @@ SymbolicEnumVariable::SymbolicEnumVariable(
|
||||
}
|
||||
|
||||
SymbolicTupleVariable::SymbolicTupleVariable(
|
||||
TypePointer _type,
|
||||
solidity::TypePointer _type,
|
||||
string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
):
|
||||
SymbolicVariable(move(_type), move(_uniqueName), _interface)
|
||||
{
|
||||
@ -187,7 +187,7 @@ SymbolicTupleVariable::SymbolicTupleVariable(
|
||||
void SymbolicTupleVariable::setComponents(vector<shared_ptr<SymbolicVariable>> _components)
|
||||
{
|
||||
solAssert(m_components.empty(), "");
|
||||
auto const& tupleType = dynamic_cast<TupleType const*>(m_type);
|
||||
auto const& tupleType = dynamic_cast<solidity::TupleType const*>(m_type);
|
||||
solAssert(_components.size() == tupleType->components().size(), "");
|
||||
m_components = move(_components);
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
{
|
||||
namespace smt
|
||||
{
|
||||
|
||||
class Type;
|
||||
|
||||
@ -36,23 +38,23 @@ class SymbolicVariable
|
||||
{
|
||||
public:
|
||||
SymbolicVariable(
|
||||
TypePointer _type,
|
||||
solidity::TypePointer _type,
|
||||
std::string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
);
|
||||
SymbolicVariable(
|
||||
smt::SortPointer _sort,
|
||||
SortPointer _sort,
|
||||
std::string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
);
|
||||
|
||||
virtual ~SymbolicVariable() = default;
|
||||
|
||||
smt::Expression currentValue() const;
|
||||
Expression currentValue() const;
|
||||
std::string currentName() const;
|
||||
virtual smt::Expression valueAtIndex(int _index) const;
|
||||
virtual smt::Expression increaseIndex();
|
||||
virtual smt::Expression operator()(std::vector<smt::Expression> /*_arguments*/) const
|
||||
virtual Expression valueAtIndex(int _index) const;
|
||||
virtual Expression increaseIndex();
|
||||
virtual Expression operator()(std::vector<Expression> /*_arguments*/) const
|
||||
{
|
||||
solAssert(false, "Function application to non-function.");
|
||||
}
|
||||
@ -60,17 +62,17 @@ public:
|
||||
unsigned index() const { return m_ssa->index(); }
|
||||
unsigned& index() { return m_ssa->index(); }
|
||||
|
||||
TypePointer const& type() const { return m_type; }
|
||||
solidity::TypePointer const& type() const { return m_type; }
|
||||
|
||||
protected:
|
||||
std::string uniqueSymbol(unsigned _index) const;
|
||||
|
||||
/// SMT sort.
|
||||
smt::SortPointer m_sort;
|
||||
SortPointer m_sort;
|
||||
/// Solidity type, used for size and range in number types.
|
||||
TypePointer m_type;
|
||||
solidity::TypePointer m_type;
|
||||
std::string m_uniqueName;
|
||||
smt::SolverInterface& m_interface;
|
||||
SolverInterface& m_interface;
|
||||
std::unique_ptr<SSAVariable> m_ssa;
|
||||
};
|
||||
|
||||
@ -81,9 +83,9 @@ class SymbolicBoolVariable: public SymbolicVariable
|
||||
{
|
||||
public:
|
||||
SymbolicBoolVariable(
|
||||
TypePointer _type,
|
||||
solidity::TypePointer _type,
|
||||
std::string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
);
|
||||
};
|
||||
|
||||
@ -94,9 +96,9 @@ class SymbolicIntVariable: public SymbolicVariable
|
||||
{
|
||||
public:
|
||||
SymbolicIntVariable(
|
||||
TypePointer _type,
|
||||
solidity::TypePointer _type,
|
||||
std::string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
);
|
||||
};
|
||||
|
||||
@ -108,7 +110,7 @@ class SymbolicAddressVariable: public SymbolicIntVariable
|
||||
public:
|
||||
SymbolicAddressVariable(
|
||||
std::string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
);
|
||||
};
|
||||
|
||||
@ -121,7 +123,7 @@ public:
|
||||
SymbolicFixedBytesVariable(
|
||||
unsigned _numBytes,
|
||||
std::string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
);
|
||||
};
|
||||
|
||||
@ -132,20 +134,20 @@ class SymbolicFunctionVariable: public SymbolicVariable
|
||||
{
|
||||
public:
|
||||
SymbolicFunctionVariable(
|
||||
TypePointer _type,
|
||||
solidity::TypePointer _type,
|
||||
std::string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
);
|
||||
|
||||
smt::Expression increaseIndex();
|
||||
smt::Expression operator()(std::vector<smt::Expression> _arguments) const;
|
||||
Expression increaseIndex();
|
||||
Expression operator()(std::vector<Expression> _arguments) const;
|
||||
|
||||
private:
|
||||
/// Creates a new function declaration.
|
||||
void resetDeclaration();
|
||||
|
||||
/// Stores the current function declaration.
|
||||
smt::Expression m_declaration;
|
||||
Expression m_declaration;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -155,9 +157,9 @@ class SymbolicMappingVariable: public SymbolicVariable
|
||||
{
|
||||
public:
|
||||
SymbolicMappingVariable(
|
||||
TypePointer _type,
|
||||
solidity::TypePointer _type,
|
||||
std::string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
);
|
||||
};
|
||||
|
||||
@ -168,9 +170,9 @@ class SymbolicArrayVariable: public SymbolicVariable
|
||||
{
|
||||
public:
|
||||
SymbolicArrayVariable(
|
||||
TypePointer _type,
|
||||
solidity::TypePointer _type,
|
||||
std::string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
);
|
||||
};
|
||||
|
||||
@ -181,9 +183,9 @@ class SymbolicEnumVariable: public SymbolicVariable
|
||||
{
|
||||
public:
|
||||
SymbolicEnumVariable(
|
||||
TypePointer _type,
|
||||
solidity::TypePointer _type,
|
||||
std::string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
);
|
||||
};
|
||||
|
||||
@ -194,9 +196,9 @@ class SymbolicTupleVariable: public SymbolicVariable
|
||||
{
|
||||
public:
|
||||
SymbolicTupleVariable(
|
||||
TypePointer _type,
|
||||
solidity::TypePointer _type,
|
||||
std::string _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
SolverInterface& _interface
|
||||
);
|
||||
|
||||
std::vector<std::shared_ptr<SymbolicVariable>> const& components()
|
||||
@ -212,3 +214,4 @@ private:
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::solidity;
|
||||
using namespace dev::solidity::smt;
|
||||
|
||||
set<VariableDeclaration const*> VariableUsage::touchedVariables(ASTNode const& _node, vector<CallableDeclaration const*> const& _outerCallstack)
|
||||
{
|
||||
|
@ -26,6 +26,8 @@ namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
{
|
||||
namespace smt
|
||||
{
|
||||
|
||||
/**
|
||||
* This class computes information about which variables are modified in a certain subtree.
|
||||
@ -55,3 +57,4 @@ private:
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user