From d45bb2aa07677a53a0219b93cde0414e3a1ab937 Mon Sep 17 00:00:00 2001 From: Mathias Baumann Date: Tue, 19 May 2020 13:12:07 +0200 Subject: [PATCH] Add proper unipmlemented errors for array copying --- Changelog.md | 2 +- libsolidity/codegen/ArrayUtils.cpp | 7 +++++++ libsolidity/codegen/CompilerUtils.cpp | 8 ++++++++ .../syntaxTests/array/nested_calldata_memory.sol | 13 +++++++++++++ .../syntaxTests/array/nested_calldata_memory2.sol | 13 +++++++++++++ .../syntaxTests/array/nested_calldata_memory3.sol | 13 +++++++++++++ .../syntaxTests/array/nested_calldata_storage.sol | 9 +++++++++ .../syntaxTests/array/nested_calldata_storage2.sol | 9 +++++++++ 8 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/syntaxTests/array/nested_calldata_memory.sol create mode 100644 test/libsolidity/syntaxTests/array/nested_calldata_memory2.sol create mode 100644 test/libsolidity/syntaxTests/array/nested_calldata_memory3.sol create mode 100644 test/libsolidity/syntaxTests/array/nested_calldata_storage.sol create mode 100644 test/libsolidity/syntaxTests/array/nested_calldata_storage2.sol diff --git a/Changelog.md b/Changelog.md index 4e0e677d7..518c78963 100644 --- a/Changelog.md +++ b/Changelog.md @@ -14,7 +14,7 @@ Bugfixes: * Type Checker: Disallow assignments to storage variables of type ``mapping``. * NatSpec: DocString block is terminated when encountering an empty line. * Scanner: Fix bug when two empty NatSpec comments lead to scanning past EOL. - + * Code Generator: Trigger proper unimplemented errors on certain array copy operations. ### 0.6.8 (2020-05-14) diff --git a/libsolidity/codegen/ArrayUtils.cpp b/libsolidity/codegen/ArrayUtils.cpp index 089d0f5cf..732deca6f 100644 --- a/libsolidity/codegen/ArrayUtils.cpp +++ b/libsolidity/codegen/ArrayUtils.cpp @@ -185,6 +185,13 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons { solAssert(byteOffsetSize == 0, "Byte offset for array as base type."); auto const& sourceBaseArrayType = dynamic_cast(*sourceBaseType); + + solUnimplementedAssert( + _sourceType.location() != DataLocation::CallData || + !_sourceType.isDynamicallyEncoded() || + !sourceBaseArrayType.isDynamicallySized(), + "Copying nested calldata dynamic arrays to storage is not implemented in the old code generator." + ); _context << Instruction::DUP3; if (sourceBaseArrayType.location() == DataLocation::Memory) _context << Instruction::MLOAD; diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 8bf0a21e2..25c91f0a3 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -974,6 +974,14 @@ void CompilerUtils::convertType( } else { + if (auto baseType = dynamic_cast(typeOnStack.baseType())) + solUnimplementedAssert( + typeOnStack.location() != DataLocation::CallData || + !typeOnStack.isDynamicallyEncoded() || + !baseType->isDynamicallySized(), + "Copying nested dynamic calldata arrays to memory is not implemented in the old code generator." + ); + m_context << u256(0) << Instruction::SWAP1; // stack: (variably sized) auto repeat = m_context.newTag(); diff --git a/test/libsolidity/syntaxTests/array/nested_calldata_memory.sol b/test/libsolidity/syntaxTests/array/nested_calldata_memory.sol new file mode 100644 index 000000000..b8361e115 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/nested_calldata_memory.sol @@ -0,0 +1,13 @@ +pragma experimental ABIEncoderV2; + +contract Test { + struct shouldBug { + bytes[2] deadly; + } + function killer(bytes[2] calldata weapon) pure external { + shouldBug(weapon); + } +} + +// ---- +// UnimplementedFeatureError: Copying nested dynamic calldata arrays to memory is not implemented in the old code generator. diff --git a/test/libsolidity/syntaxTests/array/nested_calldata_memory2.sol b/test/libsolidity/syntaxTests/array/nested_calldata_memory2.sol new file mode 100644 index 000000000..c886c8eee --- /dev/null +++ b/test/libsolidity/syntaxTests/array/nested_calldata_memory2.sol @@ -0,0 +1,13 @@ +pragma experimental ABIEncoderV2; + +contract Test { + struct shouldBug { + uint256[][2] deadly; + } + function killer(uint256[][2] calldata weapon) pure external { + shouldBug(weapon); + } +} + +// ---- +// UnimplementedFeatureError: Copying nested dynamic calldata arrays to memory is not implemented in the old code generator. diff --git a/test/libsolidity/syntaxTests/array/nested_calldata_memory3.sol b/test/libsolidity/syntaxTests/array/nested_calldata_memory3.sol new file mode 100644 index 000000000..d8716d18e --- /dev/null +++ b/test/libsolidity/syntaxTests/array/nested_calldata_memory3.sol @@ -0,0 +1,13 @@ +pragma experimental ABIEncoderV2; + +contract Test { + struct shouldBug { + uint256[][] deadly; + } + function killer(uint256[][] calldata weapon) pure external { + shouldBug(weapon); + } +} + +// ---- +// UnimplementedFeatureError: Copying nested dynamic calldata arrays to memory is not implemented in the old code generator. diff --git a/test/libsolidity/syntaxTests/array/nested_calldata_storage.sol b/test/libsolidity/syntaxTests/array/nested_calldata_storage.sol new file mode 100644 index 000000000..bae103321 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/nested_calldata_storage.sol @@ -0,0 +1,9 @@ +pragma experimental ABIEncoderV2; + +contract C { + uint[][2] tmp_i; + function i(uint[][2] calldata s) external { tmp_i = s; } +} + +// ---- +// UnimplementedFeatureError: Copying nested calldata dynamic arrays to storage is not implemented in the old code generator. diff --git a/test/libsolidity/syntaxTests/array/nested_calldata_storage2.sol b/test/libsolidity/syntaxTests/array/nested_calldata_storage2.sol new file mode 100644 index 000000000..d922d717f --- /dev/null +++ b/test/libsolidity/syntaxTests/array/nested_calldata_storage2.sol @@ -0,0 +1,9 @@ +pragma experimental ABIEncoderV2; + +contract C { + uint[][] tmp_i; + function i(uint[][] calldata s) external { tmp_i = s; } +} + +// ---- +// UnimplementedFeatureError: Copying nested calldata dynamic arrays to storage is not implemented in the old code generator.