From 7202ebb5b22f867fb0c598ff4dfa92c8faf613b6 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 1 Oct 2019 16:40:39 +0200 Subject: [PATCH] Fix internal compiler error for arrays of recursive structs. --- Changelog.md | 1 + libsolidity/ast/Types.cpp | 2 ++ .../structs/array_of_recursive_struct.sol | 12 ++++++++++++ .../recursion/static_array_of_recursive_structs.sol | 10 ++++++++++ 4 files changed, 25 insertions(+) create mode 100644 test/libsolidity/semanticTests/structs/array_of_recursive_struct.sol create mode 100644 test/libsolidity/syntaxTests/structs/recursion/static_array_of_recursive_structs.sol diff --git a/Changelog.md b/Changelog.md index 64fe627f3..f184c0568 100644 --- a/Changelog.md +++ b/Changelog.md @@ -16,6 +16,7 @@ Bugfixes: * Code Generator: Fix internal error when popping a dynamic storage array of mappings. * Name Resolver: Fix wrong source location when warning on shadowed aliases in import declarations. * Scanner: Fix multi-line natspec comment parsing with triple slashes when file is encoded with CRLF instead of LF. + * Type System: Fix arrays of recursive structs. * Yul Optimizer: Fix reordering bug in connection with shifted one and mul/div-instructions in for loop conditions. diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 556347980..25d31a857 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -2050,6 +2050,8 @@ unsigned StructType::calldataOffsetOfMember(std::string const& _member) const bool StructType::isDynamicallyEncoded() const { + if (recursive()) + return true; solAssert(interfaceType(false).get(), ""); for (auto t: memoryMemberTypes()) { diff --git a/test/libsolidity/semanticTests/structs/array_of_recursive_struct.sol b/test/libsolidity/semanticTests/structs/array_of_recursive_struct.sol new file mode 100644 index 000000000..16ee9d59b --- /dev/null +++ b/test/libsolidity/semanticTests/structs/array_of_recursive_struct.sol @@ -0,0 +1,12 @@ +contract Test { + struct RecursiveStruct { + RecursiveStruct[] vals; + } + + function func() public pure { + RecursiveStruct[1] memory val = [ RecursiveStruct(new RecursiveStruct[](42)) ]; + assert(val[0].vals.length == 42); + } +} +// ----- +// func() -> diff --git a/test/libsolidity/syntaxTests/structs/recursion/static_array_of_recursive_structs.sol b/test/libsolidity/syntaxTests/structs/recursion/static_array_of_recursive_structs.sol new file mode 100644 index 000000000..4268317b3 --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/recursion/static_array_of_recursive_structs.sol @@ -0,0 +1,10 @@ +contract Test { + struct RecursiveStruct { + RecursiveStruct[] vals; + } + + function func() private pure { + RecursiveStruct[1] memory val; + val; + } +}