From 51009c005d0934f6e32e77fa0277ad847defb69e Mon Sep 17 00:00:00 2001 From: hrkrshnn Date: Tue, 26 Oct 2021 18:31:13 +0200 Subject: [PATCH] Moved a canBeStored assert for struct members to TypeChecker This is to avoid a assert from failing for forward declared user defined value types. --- libsolidity/analysis/DeclarationTypeChecker.cpp | 1 - libsolidity/analysis/TypeChecker.cpp | 10 ++++++++++ libsolidity/analysis/TypeChecker.h | 1 + .../userDefinedValueType/forward_reference_struct.sol | 3 +++ 4 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/syntaxTests/userDefinedValueType/forward_reference_struct.sol diff --git a/libsolidity/analysis/DeclarationTypeChecker.cpp b/libsolidity/analysis/DeclarationTypeChecker.cpp index d531fd77f..d5392ef84 100644 --- a/libsolidity/analysis/DeclarationTypeChecker.cpp +++ b/libsolidity/analysis/DeclarationTypeChecker.cpp @@ -100,7 +100,6 @@ bool DeclarationTypeChecker::visit(StructDefinition const& _struct) m_recursiveStructSeen = false; member->accept(*this); solAssert(member->annotation().type, ""); - solAssert(member->annotation().type->canBeStored(), "Type cannot be used in struct."); if (m_recursiveStructSeen) hasRecursiveChild = true; } diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 0b5f97719..83a9da55c 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -621,6 +621,16 @@ bool TypeChecker::visit(VariableDeclaration const& _variable) return false; } +void TypeChecker::endVisit(StructDefinition const& _struct) +{ + for (auto const& member: _struct.members()) + solAssert( + member->annotation().type && + member->annotation().type->canBeStored(), + "Type cannot be used in struct." + ); +} + void TypeChecker::visitManually( ModifierInvocation const& _modifier, vector const& _bases diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h index f0820d930..ba445ffbb 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -121,6 +121,7 @@ private: bool visit(FunctionDefinition const& _function) override; void endVisit(ArrayTypeName const& _typeName) override; bool visit(VariableDeclaration const& _variable) override; + void endVisit(StructDefinition const& _struct) override; /// We need to do this manually because we want to pass the bases of the current contract in /// case this is a base constructor call. void visitManually(ModifierInvocation const& _modifier, std::vector const& _bases); diff --git a/test/libsolidity/syntaxTests/userDefinedValueType/forward_reference_struct.sol b/test/libsolidity/syntaxTests/userDefinedValueType/forward_reference_struct.sol new file mode 100644 index 000000000..b99cff215 --- /dev/null +++ b/test/libsolidity/syntaxTests/userDefinedValueType/forward_reference_struct.sol @@ -0,0 +1,3 @@ +struct S { U u; } +contract C { S s; } +type U is address;