From 909ce9164a7a5144190a1cbc7615efbcbe7101b3 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 15 Oct 2020 20:00:22 +0200 Subject: [PATCH 1/3] Allow arrays of contract types as type expressions e.g. for abi.decode. --- Changelog.md | 1 + libsolidity/analysis/TypeChecker.cpp | 5 +++-- .../syntaxTests/array/contract_index_access.sol | 8 ++++++++ .../syntaxTests/array/invalid/contract_index_access.sol | 7 ------- .../syntaxTests/array/invalid/library_index_access.sol | 2 +- .../syntaxTests/indexing/index_range_access_assert.sol | 1 - .../specialFunctions/abidecode/contract_array.sol | 5 +++++ 7 files changed, 18 insertions(+), 11 deletions(-) create mode 100644 test/libsolidity/syntaxTests/array/contract_index_access.sol delete mode 100644 test/libsolidity/syntaxTests/array/invalid/contract_index_access.sol create mode 100644 test/libsolidity/syntaxTests/specialFunctions/abidecode/contract_array.sol diff --git a/Changelog.md b/Changelog.md index 400312c23..837f912a7 100644 --- a/Changelog.md +++ b/Changelog.md @@ -22,6 +22,7 @@ Bugfixes: * Code generator: Fix internal compiler error when referencing members via module name but not using the reference. * Code generator: Fix ``ABIEncoderV2`` pragma from the current module affecting inherited functions and applied modifiers. * Code generator: Use revert instead of invalid opcode for out-of-bounds array index access in getter. + * Type Checker: Allow arrays of contract types as type expressions and as arguments for ``abi.decode``. * Type Checker: Disallow invalid use of library names as type name. * Type Checker: Fix internal compiler error caused by storage parameters with nested mappings in libraries. * Name Resolver: Fix shadowing/same-name warnings for later declarations. diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index ec50cbb46..ff31eb8bc 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -2915,8 +2915,9 @@ bool TypeChecker::visit(IndexAccess const& _access) case Type::Category::TypeType: { TypeType const& typeType = dynamic_cast(*baseType); - if (dynamic_cast(typeType.actualType())) - m_errorReporter.typeError(2876_error, _access.location(), "Index access for contracts or libraries is not possible."); + if (auto const* contractType = dynamic_cast(typeType.actualType())) + if (contractType->contractDefinition().isLibrary()) + m_errorReporter.typeError(2876_error, _access.location(), "Index access for library types and arrays of libraries are not possible."); if (!index) resultType = TypeProvider::typeType(TypeProvider::array(DataLocation::Memory, typeType.actualType())); else diff --git a/test/libsolidity/syntaxTests/array/contract_index_access.sol b/test/libsolidity/syntaxTests/array/contract_index_access.sol new file mode 100644 index 000000000..50fbfd41b --- /dev/null +++ b/test/libsolidity/syntaxTests/array/contract_index_access.sol @@ -0,0 +1,8 @@ +contract C { + function f() view public { + C[0]; + } +} +// ---- +// Warning 6133: (52-56): Statement has no effect. +// Warning 2018: (17-63): Function state mutability can be restricted to pure diff --git a/test/libsolidity/syntaxTests/array/invalid/contract_index_access.sol b/test/libsolidity/syntaxTests/array/invalid/contract_index_access.sol deleted file mode 100644 index efa8679be..000000000 --- a/test/libsolidity/syntaxTests/array/invalid/contract_index_access.sol +++ /dev/null @@ -1,7 +0,0 @@ -contract C { - function f() view public { - C[0]; - } -} -// ---- -// TypeError 2876: (52-56): Index access for contracts or libraries is not possible. diff --git a/test/libsolidity/syntaxTests/array/invalid/library_index_access.sol b/test/libsolidity/syntaxTests/array/invalid/library_index_access.sol index d81e36bab..885a114b0 100644 --- a/test/libsolidity/syntaxTests/array/invalid/library_index_access.sol +++ b/test/libsolidity/syntaxTests/array/invalid/library_index_access.sol @@ -4,4 +4,4 @@ library C { } } // ---- -// TypeError 2876: (51-55): Index access for contracts or libraries is not possible. +// TypeError 2876: (51-55): Index access for library types and arrays of libraries are not possible. diff --git a/test/libsolidity/syntaxTests/indexing/index_range_access_assert.sol b/test/libsolidity/syntaxTests/indexing/index_range_access_assert.sol index 346cdd973..acce33091 100644 --- a/test/libsolidity/syntaxTests/indexing/index_range_access_assert.sol +++ b/test/libsolidity/syntaxTests/indexing/index_range_access_assert.sol @@ -3,4 +3,3 @@ contract s{} function f() {s[:][];} // ---- // TypeError 1760: (53-57): Types cannot be sliced. -// TypeError 2876: (53-59): Index access for contracts or libraries is not possible. diff --git a/test/libsolidity/syntaxTests/specialFunctions/abidecode/contract_array.sol b/test/libsolidity/syntaxTests/specialFunctions/abidecode/contract_array.sol new file mode 100644 index 000000000..601def4b5 --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/abidecode/contract_array.sol @@ -0,0 +1,5 @@ +contract C { + function f(bytes calldata x) public pure returns (C[] memory c) { + c = abi.decode(x, (C[])); + } +} \ No newline at end of file From e06d4303fb8f741123237a8a54c1fc0d40758605 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Fri, 16 Oct 2020 18:08:01 +0200 Subject: [PATCH 2/3] Semantic tests. --- .../semanticTests/abiencodedecode/contract_array.sol | 9 +++++++++ .../abiencodedecode/contract_array_v2.sol | 12 ++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 test/libsolidity/semanticTests/abiencodedecode/contract_array.sol create mode 100644 test/libsolidity/semanticTests/abiencodedecode/contract_array_v2.sol diff --git a/test/libsolidity/semanticTests/abiencodedecode/contract_array.sol b/test/libsolidity/semanticTests/abiencodedecode/contract_array.sol new file mode 100644 index 000000000..015f23075 --- /dev/null +++ b/test/libsolidity/semanticTests/abiencodedecode/contract_array.sol @@ -0,0 +1,9 @@ +contract C { + function f(bytes calldata x) public returns (C[] memory) { + return abi.decode(x, (C[])); + } +} +// ==== +// compileViaYul: also +// ---- +// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03 diff --git a/test/libsolidity/semanticTests/abiencodedecode/contract_array_v2.sol b/test/libsolidity/semanticTests/abiencodedecode/contract_array_v2.sol new file mode 100644 index 000000000..f838d674e --- /dev/null +++ b/test/libsolidity/semanticTests/abiencodedecode/contract_array_v2.sol @@ -0,0 +1,12 @@ +pragma experimental ABIEncoderV2; +contract C { + function f(bytes calldata x) public returns (C[] memory) { + return abi.decode(x, (C[])); + } +} +// ==== +// compileViaYul: also +// ---- +// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03 +// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 -> 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 +// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f101112131415 -> FAILURE From 79d9a1ca81d53c92f47649eca6bd782825dbf142 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Fri, 16 Oct 2020 20:24:43 +0200 Subject: [PATCH 3/3] Tests for abi.encode. --- .../semanticTests/abiencodedecode/contract_array.sol | 8 ++++++++ .../semanticTests/abiencodedecode/contract_array_v2.sol | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/test/libsolidity/semanticTests/abiencodedecode/contract_array.sol b/test/libsolidity/semanticTests/abiencodedecode/contract_array.sol index 015f23075..c26aea83a 100644 --- a/test/libsolidity/semanticTests/abiencodedecode/contract_array.sol +++ b/test/libsolidity/semanticTests/abiencodedecode/contract_array.sol @@ -2,8 +2,16 @@ contract C { function f(bytes calldata x) public returns (C[] memory) { return abi.decode(x, (C[])); } + function g() public returns (bytes memory) { + C[] memory c = new C[](3); + c[0] = C(address(0x42)); + c[1] = C(address(0x21)); + c[2] = C(address(0x23)); + return abi.encode(c); + } } // ==== // compileViaYul: also // ---- // f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03 +// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23 diff --git a/test/libsolidity/semanticTests/abiencodedecode/contract_array_v2.sol b/test/libsolidity/semanticTests/abiencodedecode/contract_array_v2.sol index f838d674e..1d2625be0 100644 --- a/test/libsolidity/semanticTests/abiencodedecode/contract_array_v2.sol +++ b/test/libsolidity/semanticTests/abiencodedecode/contract_array_v2.sol @@ -3,6 +3,13 @@ contract C { function f(bytes calldata x) public returns (C[] memory) { return abi.decode(x, (C[])); } + function g() public returns (bytes memory) { + C[] memory c = new C[](3); + c[0] = C(address(0x42)); + c[1] = C(address(0x21)); + c[2] = C(address(0x23)); + return abi.encode(c); + } } // ==== // compileViaYul: also @@ -10,3 +17,4 @@ contract C { // f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03 // f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 -> 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 // f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f101112131415 -> FAILURE +// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23