diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 7457f9c6b..69e8a7131 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -2406,6 +2406,29 @@ string YulUtilFunctions::conversionFunctionSpecial(Type const& _from, Type const .render(); } + if (_from.category() == Type::Category::Array && _to.category() == Type::Category::Array) + { + auto const& fromArrayType = dynamic_cast(_from); + auto const& toArrayType = dynamic_cast(_to); + + solAssert(!fromArrayType.baseType()->isDynamicallyEncoded(), ""); + solUnimplementedAssert(fromArrayType.isByteArray() && toArrayType.isByteArray(), ""); + solUnimplementedAssert(toArrayType.location() == DataLocation::Memory, ""); + solUnimplementedAssert(fromArrayType.location() == DataLocation::CallData, ""); + solUnimplementedAssert(toArrayType.isDynamicallySized(), ""); + + Whiskers templ(R"( + function (offset, length) -> converted { + converted := (length) + (offset, add(converted, 0x20), length) + } + )"); + templ("functionName", functionName); + templ("allocateMemoryArray", allocateMemoryArrayFunction(toArrayType)); + templ("copyToMemory", copyToMemoryFunction(fromArrayType.location() == DataLocation::CallData)); + return templ.render(); + } + solUnimplementedAssert( _from.category() == Type::Category::StringLiteral, "Type conversion " + _from.toString() + " -> " + _to.toString() + " not yet implemented." diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array_dynamic_static_dynamic.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array_dynamic_static_dynamic.sol index 6bb10c143..46d1122a9 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array_dynamic_static_dynamic.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array_dynamic_static_dynamic.sol @@ -43,6 +43,7 @@ contract C { } } // ==== +// compileViaYul: also // EVMVersion: >homestead // ---- // g() -> 32, 196, hex"eccb829a", 32, 1, 32, 32, 1, 42, hex"00000000000000000000000000000000000000000000000000000000" diff --git a/test/libsolidity/semanticTests/abiEncoderV2/cleanup/dynamic_array.sol b/test/libsolidity/semanticTests/abiEncoderV2/cleanup/dynamic_array.sol index 2302a3a38..e56ff257b 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/cleanup/dynamic_array.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/cleanup/dynamic_array.sol @@ -14,6 +14,7 @@ contract C { } } // ==== +// compileViaYul: also // EVMVersion: >homestead // ---- // f(uint256[]): 0x20, 2, 1, 1 -> 0x20, 0x84, hex"304a4c23", 0x20, 2, 1, 1, hex"00000000000000000000000000000000000000000000000000000000" diff --git a/test/libsolidity/semanticTests/abiEncoderV2/cleanup/simple_struct.sol b/test/libsolidity/semanticTests/abiEncoderV2/cleanup/simple_struct.sol index e36a600b2..2a2327c08 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/cleanup/simple_struct.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/cleanup/simple_struct.sol @@ -16,6 +16,7 @@ contract C { } } // ==== +// compileViaYul: also // EVMVersion: >homestead // ---- // f(uint256,bytes32): 1, left(0x01) -> 0x20, 0x44, hex"b63240b0", 1, left(0x01), hex"00000000000000000000000000000000000000000000000000000000" diff --git a/test/libsolidity/semanticTests/abiEncoderV2/cleanup/static_array.sol b/test/libsolidity/semanticTests/abiEncoderV2/cleanup/static_array.sol index 35a5ed9de..d353fda95 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/cleanup/static_array.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/cleanup/static_array.sol @@ -15,6 +15,7 @@ contract C { } } // ==== +// compileViaYul: also // EVMVersion: >homestead // ---- // f(uint256,uint256): 1, 1 -> 0x20, 0x44, hex"78b86ac6", 1, 1, hex"00000000000000000000000000000000000000000000000000000000" diff --git a/test/libsolidity/semanticTests/calldata/calldata_bytes_array_to_memory.sol b/test/libsolidity/semanticTests/calldata/calldata_bytes_array_to_memory.sol index 04b2ed15d..d67a24741 100644 --- a/test/libsolidity/semanticTests/calldata/calldata_bytes_array_to_memory.sol +++ b/test/libsolidity/semanticTests/calldata/calldata_bytes_array_to_memory.sol @@ -10,6 +10,8 @@ contract C { return (a.length, m.length, m); } } +// ==== +// compileViaYul: also // ---- // f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex"6162000000000000000000000000000000000000000000000000000000000000" -> 0x1, 0x2, 0x60, 0x2, hex"6162000000000000000000000000000000000000000000000000000000000000" // f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex"7878787878787878787878787878787878787878787878787878787878787878" -> 0x1, 0x20, 0x60, 0x20, hex"7878787878787878787878787878787878787878787878787878787878787878" diff --git a/test/libsolidity/semanticTests/calldata/calldata_bytes_to_memory.sol b/test/libsolidity/semanticTests/calldata/calldata_bytes_to_memory.sol new file mode 100644 index 000000000..ca6a444d8 --- /dev/null +++ b/test/libsolidity/semanticTests/calldata/calldata_bytes_to_memory.sol @@ -0,0 +1,9 @@ +contract C { + function f(bytes calldata data) external returns (bytes32) { + return keccak256(bytes(data)); + } +} +// ==== +// compileViaYul: also +// ---- +// f(bytes): 0x20, 0x08, "abcdefgh" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d diff --git a/test/libsolidity/semanticTests/calldata/calldata_bytes_to_memory_encode.sol b/test/libsolidity/semanticTests/calldata/calldata_bytes_to_memory_encode.sol new file mode 100644 index 000000000..4bb97779c --- /dev/null +++ b/test/libsolidity/semanticTests/calldata/calldata_bytes_to_memory_encode.sol @@ -0,0 +1,9 @@ +contract C { + function f(bytes calldata data) external returns (bytes memory) { + return abi.encode(bytes(data)); + } +} +// ==== +// compileViaYul: also +// ---- +// f(bytes): 0x20, 0x08, "abcdefgh" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744 diff --git a/test/libsolidity/semanticTests/calldata/calldata_string_array.sol b/test/libsolidity/semanticTests/calldata/calldata_string_array.sol index ae7d1e2ef..62459505b 100644 --- a/test/libsolidity/semanticTests/calldata/calldata_string_array.sol +++ b/test/libsolidity/semanticTests/calldata/calldata_string_array.sol @@ -11,5 +11,7 @@ contract C { return (a.length, m1.length, uint8(m1[0]), s1); } } +// ==== +// compileViaYul: also // ---- // f(string[]): 0x20, 0x1, 0x20, 0x2, hex"6162000000000000000000000000000000000000000000000000000000000000" -> 1, 2, 97, 0x80, 2, "ab" diff --git a/test/libsolidity/semanticTests/libraries/bound_returning_calldata.sol b/test/libsolidity/semanticTests/libraries/bound_returning_calldata.sol index 7451e9dc4..867fb7e8c 100644 --- a/test/libsolidity/semanticTests/libraries/bound_returning_calldata.sol +++ b/test/libsolidity/semanticTests/libraries/bound_returning_calldata.sol @@ -13,5 +13,7 @@ contract C { return (_x.f()[0], _x.g()[0]); } } +// ==== +// compileViaYul: also // ---- // f(bytes): 0x20, 4, "abcd" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/libraries/bound_to_calldata.sol b/test/libsolidity/semanticTests/libraries/bound_to_calldata.sol index 0e9bb811b..300fa8812 100644 --- a/test/libsolidity/semanticTests/libraries/bound_to_calldata.sol +++ b/test/libsolidity/semanticTests/libraries/bound_to_calldata.sol @@ -13,5 +13,7 @@ contract C { return (_x.f(), _x.g()); } } +// ==== +// compileViaYul: also // ---- // f(bytes): 0x20, 4, "abcd" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000