mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[SMTChecker] Added support for struct constructor.
This commit is contained in:
@@ -622,11 +622,7 @@ void SMTEncoder::endVisit(FunctionCall const& _funCall)
|
||||
createExpr(_funCall);
|
||||
if (functionCallKind == FunctionCallKind::StructConstructorCall)
|
||||
{
|
||||
m_errorReporter.warning(
|
||||
4639_error,
|
||||
_funCall.location(),
|
||||
"Assertion checker does not yet implement this expression."
|
||||
);
|
||||
visitStructConstructorCall(_funCall);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -861,6 +857,12 @@ void SMTEncoder::endVisit(Identifier const& _identifier)
|
||||
defineExpr(_identifier, m_context.state().thisAddress());
|
||||
m_uninterpretedTerms.insert(&_identifier);
|
||||
}
|
||||
// Ignore struct type identifiers in struct constructor calls
|
||||
else if (
|
||||
auto typetype = dynamic_cast<TypeType const*>(_identifier.annotation().type);
|
||||
typetype && typetype->actualType()->category() == Type::Category::Struct
|
||||
)
|
||||
return;
|
||||
// Ignore the builtin abi, it is handled in FunctionCall.
|
||||
// TODO: ignore MagicType in general (abi, block, msg, tx, type)
|
||||
else if (auto magicType = dynamic_cast<MagicType const*>(_identifier.annotation().type); magicType && magicType->kind() == MagicType::Kind::ABI)
|
||||
@@ -1018,6 +1020,13 @@ void SMTEncoder::visitFunctionIdentifier(Identifier const& _identifier)
|
||||
}
|
||||
}
|
||||
|
||||
void SMTEncoder::visitStructConstructorCall(FunctionCall const& _funCall)
|
||||
{
|
||||
solAssert(*_funCall.annotation().kind == FunctionCallKind::StructConstructorCall, "");
|
||||
auto& structSymbolicVar = dynamic_cast<smt::SymbolicStructVariable&>(*m_context.expression(_funCall));
|
||||
structSymbolicVar.assignAllMembers(applyMap(_funCall.sortedArguments(), [this](auto const& arg) { return expr(*arg); }));
|
||||
}
|
||||
|
||||
void SMTEncoder::endVisit(Literal const& _literal)
|
||||
{
|
||||
solAssert(_literal.annotation().type, "Expected type for AST node");
|
||||
|
||||
@@ -151,6 +151,7 @@ protected:
|
||||
virtual void visitAddMulMod(FunctionCall const& _funCall);
|
||||
void visitObjectCreation(FunctionCall const& _funCall);
|
||||
void visitTypeConversion(FunctionCall const& _funCall);
|
||||
void visitStructConstructorCall(FunctionCall const& _funCall);
|
||||
void visitFunctionIdentifier(Identifier const& _identifier);
|
||||
|
||||
/// Encodes a modifier or function body according to the modifier
|
||||
|
||||
@@ -360,7 +360,7 @@ SymbolicStructVariable::SymbolicStructVariable(
|
||||
}
|
||||
}
|
||||
|
||||
smtutil::Expression SymbolicStructVariable::member(string const& _member)
|
||||
smtutil::Expression SymbolicStructVariable::member(string const& _member) const
|
||||
{
|
||||
return smtutil::Expression::tuple_get(currentValue(), m_memberIndices.at(_member));
|
||||
}
|
||||
@@ -385,3 +385,18 @@ smtutil::Expression SymbolicStructVariable::assignMember(string const& _member,
|
||||
|
||||
return currentValue();
|
||||
}
|
||||
|
||||
smtutil::Expression SymbolicStructVariable::assignAllMembers(vector<smtutil::Expression> const& _memberValues)
|
||||
{
|
||||
auto structType = dynamic_cast<StructType const*>(m_type);
|
||||
solAssert(structType, "");
|
||||
|
||||
auto const& structDef = structType->structDefinition();
|
||||
auto const& structMembers = structDef.members();
|
||||
solAssert(_memberValues.size() == structMembers.size(), "");
|
||||
increaseIndex();
|
||||
for (unsigned i = 0; i < _memberValues.size(); ++i)
|
||||
m_context.addAssertion(_memberValues[i] == member(structMembers[i]->name()));
|
||||
|
||||
return currentValue();
|
||||
}
|
||||
@@ -282,12 +282,16 @@ public:
|
||||
);
|
||||
|
||||
/// @returns the symbolic expression representing _member.
|
||||
smtutil::Expression member(std::string const& _member);
|
||||
smtutil::Expression member(std::string const& _member) const;
|
||||
|
||||
/// @returns the symbolic expression representing this struct
|
||||
/// with field _member updated.
|
||||
smtutil::Expression assignMember(std::string const& _member, smtutil::Expression const& _memberValue);
|
||||
|
||||
/// @returns the symbolic expression representing this struct
|
||||
/// with all fields updated with the given values.
|
||||
smtutil::Expression assignAllMembers(std::vector<smtutil::Expression> const& _memberValues);
|
||||
|
||||
private:
|
||||
std::map<std::string, unsigned> m_memberIndices;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user