diff --git a/Changelog.md b/Changelog.md index c51fc2a54..e88d96d2f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,7 @@ ### 0.7.6 (unreleased) Language Features: + * Code generator: Support copying dynamically encoded structs from calldata to memory. * The fallback function can now also have a single ``calldata`` argument (equaling ``msg.data``) and return ``bytes memory`` (which will not be ABI-encoded but returned as-is). Compiler Features: diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index f64b54d8e..384b61c8e 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -1106,11 +1106,22 @@ void CompilerUtils::convertType( } case DataLocation::CallData: { - solUnimplementedAssert(!typeOnStack.isDynamicallyEncoded(), ""); - m_context << Instruction::DUP1; - m_context << Instruction::CALLDATASIZE; - m_context << Instruction::SUB; - abiDecode({&targetType}, false); + if (typeOnStack.isDynamicallyEncoded()) + { + solAssert(m_context.useABICoderV2(), ""); + m_context.callYulFunction( + m_context.utilFunctions().conversionFunction(typeOnStack, targetType), + 1, + 1 + ); + } + else + { + m_context << Instruction::DUP1; + m_context << Instruction::CALLDATASIZE; + m_context << Instruction::SUB; + abiDecode({&targetType}, false); + } break; } case DataLocation::Memory: diff --git a/test/libsolidity/semanticTests/structs/calldata/calldata_nested_structs.sol b/test/libsolidity/semanticTests/structs/calldata/calldata_nested_structs.sol index ee9527236..5a5728e06 100644 --- a/test/libsolidity/semanticTests/structs/calldata/calldata_nested_structs.sol +++ b/test/libsolidity/semanticTests/structs/calldata/calldata_nested_structs.sol @@ -42,7 +42,7 @@ contract C { } } // ==== -// compileViaYul: true +// compileViaYul: also // ---- // f((uint128, (uint128, uint256[][2], uint32)), uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33 // g(((uint128, uint256[][2], uint32)[2])): 0x20, 0x20, 0x40, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 22, 1, 2, 33 diff --git a/test/libsolidity/semanticTests/structs/calldata/calldata_struct_as_argument_of_lib_function.sol b/test/libsolidity/semanticTests/structs/calldata/calldata_struct_as_argument_of_lib_function.sol index c44c5cd2a..3d82da599 100644 --- a/test/libsolidity/semanticTests/structs/calldata/calldata_struct_as_argument_of_lib_function.sol +++ b/test/libsolidity/semanticTests/structs/calldata/calldata_struct_as_argument_of_lib_function.sol @@ -23,7 +23,7 @@ contract C { } } // ==== -// compileViaYul: true +// compileViaYul: also // ---- // library: L // f((uint128, (uint128, uint256[][2], uint32)), uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33 diff --git a/test/libsolidity/semanticTests/structs/calldata/calldata_struct_as_memory_argument.sol b/test/libsolidity/semanticTests/structs/calldata/calldata_struct_as_memory_argument.sol index 71b55abf4..3361bada6 100644 --- a/test/libsolidity/semanticTests/structs/calldata/calldata_struct_as_memory_argument.sol +++ b/test/libsolidity/semanticTests/structs/calldata/calldata_struct_as_memory_argument.sol @@ -18,6 +18,6 @@ contract C { } } // ==== -// compileViaYul: true +// compileViaYul: also // ---- // f(uint32, (uint128, uint256[][2], uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88 diff --git a/test/libsolidity/semanticTests/structs/calldata/calldata_struct_to_memory_tuple_assignment.sol b/test/libsolidity/semanticTests/structs/calldata/calldata_struct_to_memory_tuple_assignment.sol index 9bf1d1f48..ed3d2e151 100644 --- a/test/libsolidity/semanticTests/structs/calldata/calldata_struct_to_memory_tuple_assignment.sol +++ b/test/libsolidity/semanticTests/structs/calldata/calldata_struct_to_memory_tuple_assignment.sol @@ -17,6 +17,6 @@ contract C { } } // ==== -// compileViaYul: true +// compileViaYul: also // ---- // f(uint32, (uint128, uint256[][2], uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88 diff --git a/test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_bytes_to_memory.sol b/test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_bytes_to_memory.sol new file mode 100644 index 000000000..79c7677c3 --- /dev/null +++ b/test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_bytes_to_memory.sol @@ -0,0 +1,23 @@ +pragma experimental ABIEncoderV2; + +contract C { + struct S { + uint256 a; + bytes b; + uint256 c; + } + + function f(S calldata c) + external + pure + returns (uint256, byte, byte, uint256) + { + S memory m = c; + return (m.a, m.b[0], m.b[1], m.c); + } +} + +// ==== +// compileViaYul: also +// ---- +// f((uint256,bytes,uint256)): 0x20, 42, 0x60, 23, 2, "ab" -> 42, "a", "b", 23 diff --git a/test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_nested_array_to_memory.sol b/test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_nested_array_to_memory.sol index 9ad5bed9c..40d14e66f 100644 --- a/test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_nested_array_to_memory.sol +++ b/test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_nested_array_to_memory.sol @@ -18,6 +18,6 @@ contract C { } } // ==== -// compileViaYul: true +// compileViaYul: also // ---- // f(uint32, (uint128, uint256[][2], uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88