mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[SMTChecker] Support enums
This commit is contained in:
@@ -736,9 +736,9 @@ bool SMTChecker::visit(MemberAccess const& _memberAccess)
|
||||
|
||||
auto const& exprType = _memberAccess.expression().annotation().type;
|
||||
solAssert(exprType, "");
|
||||
auto identifier = dynamic_cast<Identifier const*>(&_memberAccess.expression());
|
||||
if (exprType->category() == Type::Category::Magic)
|
||||
{
|
||||
auto identifier = dynamic_cast<Identifier const*>(&_memberAccess.expression());
|
||||
string accessedName;
|
||||
if (identifier)
|
||||
accessedName = identifier->name();
|
||||
@@ -750,12 +750,23 @@ bool SMTChecker::visit(MemberAccess const& _memberAccess)
|
||||
defineGlobalVariable(accessedName + "." + _memberAccess.memberName(), _memberAccess);
|
||||
return false;
|
||||
}
|
||||
else if (exprType->category() == Type::Category::TypeType)
|
||||
{
|
||||
if (identifier && dynamic_cast<EnumDefinition const*>(identifier->annotation().referencedDeclaration))
|
||||
{
|
||||
auto enumType = dynamic_cast<EnumType const*>(accessType.get());
|
||||
solAssert(enumType, "");
|
||||
defineExpr(_memberAccess, enumType->memberValue(_memberAccess.memberName()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
m_errorReporter.warning(
|
||||
_memberAccess.location(),
|
||||
"Assertion checker does not yet support this expression."
|
||||
);
|
||||
|
||||
createExpr(_memberAccess);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -135,6 +135,8 @@ pair<bool, shared_ptr<SymbolicVariable>> dev::solidity::newSymbolicVariable(
|
||||
}
|
||||
else if (isAddress(_type.category()))
|
||||
var = make_shared<SymbolicAddressVariable>(_uniqueName, _solver);
|
||||
else if (isEnum(_type.category()))
|
||||
var = make_shared<SymbolicEnumVariable>(type, _uniqueName, _solver);
|
||||
else if (isRational(_type.category()))
|
||||
{
|
||||
auto rational = dynamic_cast<RationalNumberType const*>(&_type);
|
||||
@@ -183,12 +185,18 @@ bool dev::solidity::isAddress(Type::Category _category)
|
||||
return _category == Type::Category::Address;
|
||||
}
|
||||
|
||||
bool dev::solidity::isEnum(Type::Category _category)
|
||||
{
|
||||
return _category == Type::Category::Enum;
|
||||
}
|
||||
|
||||
bool dev::solidity::isNumber(Type::Category _category)
|
||||
{
|
||||
return isInteger(_category) ||
|
||||
isRational(_category) ||
|
||||
isFixedBytes(_category) ||
|
||||
isAddress(_category);
|
||||
isAddress(_category) ||
|
||||
isEnum(_category);
|
||||
}
|
||||
|
||||
bool dev::solidity::isBool(Type::Category _category)
|
||||
@@ -241,7 +249,14 @@ void dev::solidity::smt::setSymbolicUnknownValue(SymbolicVariable const& _variab
|
||||
|
||||
void dev::solidity::smt::setSymbolicUnknownValue(smt::Expression _expr, TypePointer const& _type, smt::SolverInterface& _interface)
|
||||
{
|
||||
if (isInteger(_type->category()))
|
||||
if (isEnum(_type->category()))
|
||||
{
|
||||
auto enumType = dynamic_cast<EnumType const*>(_type.get());
|
||||
solAssert(enumType, "");
|
||||
_interface.addAssertion(_expr >= 0);
|
||||
_interface.addAssertion(_expr < enumType->numberOfMembers());
|
||||
}
|
||||
else if (isInteger(_type->category()))
|
||||
{
|
||||
auto intType = dynamic_cast<IntegerType const*>(_type.get());
|
||||
solAssert(intType, "");
|
||||
|
||||
@@ -44,6 +44,7 @@ bool isInteger(Type::Category _category);
|
||||
bool isRational(Type::Category _category);
|
||||
bool isFixedBytes(Type::Category _category);
|
||||
bool isAddress(Type::Category _category);
|
||||
bool isEnum(Type::Category _category);
|
||||
bool isNumber(Type::Category _category);
|
||||
bool isBool(Type::Category _category);
|
||||
bool isFunction(Type::Category _category);
|
||||
|
||||
@@ -146,3 +146,13 @@ SymbolicArrayVariable::SymbolicArrayVariable(
|
||||
{
|
||||
solAssert(isArray(m_type->category()), "");
|
||||
}
|
||||
|
||||
SymbolicEnumVariable::SymbolicEnumVariable(
|
||||
TypePointer _type,
|
||||
string const& _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
):
|
||||
SymbolicVariable(move(_type), _uniqueName, _interface)
|
||||
{
|
||||
solAssert(isEnum(m_type->category()), "");
|
||||
}
|
||||
|
||||
@@ -166,5 +166,18 @@ public:
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Specialization of SymbolicVariable for Enum
|
||||
*/
|
||||
class SymbolicEnumVariable: public SymbolicVariable
|
||||
{
|
||||
public:
|
||||
SymbolicEnumVariable(
|
||||
TypePointer _type,
|
||||
std::string const& _uniqueName,
|
||||
smt::SolverInterface& _interface
|
||||
);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user