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/semanticTests/abiencodedecode/contract_array.sol b/test/libsolidity/semanticTests/abiencodedecode/contract_array.sol new file mode 100644 index 000000000..c26aea83a --- /dev/null +++ b/test/libsolidity/semanticTests/abiencodedecode/contract_array.sol @@ -0,0 +1,17 @@ +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 new file mode 100644 index 000000000..1d2625be0 --- /dev/null +++ b/test/libsolidity/semanticTests/abiencodedecode/contract_array_v2.sol @@ -0,0 +1,20 @@ +pragma experimental ABIEncoderV2; +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 +// 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 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