diff --git a/test/libsolidity/semanticTests/array/copying/array_elements_to_mapping.sol b/test/libsolidity/semanticTests/array/copying/array_elements_to_mapping.sol new file mode 100644 index 000000000..4ee91191c --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/array_elements_to_mapping.sol @@ -0,0 +1,61 @@ +pragma abicoder v2; + +contract C { + mapping (uint => uint8[][]) m; + + uint8[][] s; + + constructor() { + s = new uint8[][](2); + + s[0] = new uint8[](2); + s[0][0] = 10; + s[0][1] = 11; + + s[1] = new uint8[](3); + s[1][0] = 12; + s[1][1] = 13; + s[1][2] = 14; + } + + function from_storage() public returns (uint8[][] memory) { + m[0] = new uint8[][](2); + m[0][0] = s[0]; + m[0][1] = s[1]; + return m[0]; + } + + + function from_storage_ptr() public returns (uint8[][] memory) { + uint8[][] storage sPtr = s; + m[0] = new uint8[][](2); + m[0][0] = sPtr[0]; + m[0][1] = sPtr[1]; + return m[0]; + } + + + function from_memory() public returns (uint8[][] memory) { + uint8[][] memory a = s; + m[0] = new uint8[][](2); + m[0][0] = a[0]; + m[0][1] = a[1]; + return m[0]; + } + + function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) { + m[0] = new uint8[][](2); + m[0][0] = _a[0]; + m[0][1] = _a[1]; + return m[0]; + } +} + +// ---- +// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 +// gas irOptimized: 150098 +// gas legacy: 150830 +// gas legacyOptimized: 148728 +// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 +// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 +// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 diff --git a/test/libsolidity/semanticTests/array/copying/array_nested_storage_to_memory.sol b/test/libsolidity/semanticTests/array/copying/array_nested_storage_to_memory.sol new file mode 100644 index 000000000..40990ba81 --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/array_nested_storage_to_memory.sol @@ -0,0 +1,45 @@ +pragma abicoder v2; + +contract C { + uint256[][] a1; + uint256[][2] a2; + uint256[2][] a3; + uint256[2][2] a4; + + constructor() { + a1 = new uint256[][](2); + a1[0] = [1, 2]; + a1[1] = [3, 4, 5]; + + a2[0] = [6, 7, 8]; + a2[1] = [9]; + + a3.push([1, 2]); + a3.push([3, 4]); + a3.push([5, 6]); + + a4 = [[10, 11], [12, 13]]; + } + + function test1() external returns (uint256[][] memory) { + return a1; + } + + function test2() external returns (uint256[][2] memory) { + return a2; + } + + function test3() external returns (uint256[2][] memory) { + return a3; + } + + function test4() external returns (uint256[2][2] memory) { + return a4; + } +} + +// ---- +// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5 +// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9 +// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6 +// test4() -> 10, 11, 12, 13 diff --git a/test/libsolidity/semanticTests/array/copying/array_to_mapping.sol b/test/libsolidity/semanticTests/array/copying/array_to_mapping.sol new file mode 100644 index 000000000..bd9444638 --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/array_to_mapping.sol @@ -0,0 +1,45 @@ +pragma abicoder v2; + +contract C { + mapping (uint => uint8[][]) m; + + uint8[][] s; + + constructor() { + s = new uint8[][](2); + + s[0] = new uint8[](2); + s[0][0] = 10; + s[0][1] = 11; + + s[1] = new uint8[](3); + s[1][0] = 12; + s[1][1] = 13; + s[1][2] = 14; + } + + function from_storage() public returns (uint8[][] memory) { + m[0] = s; + return m[0]; + } + + function from_storage_ptr() public returns (uint8[][] memory) { + uint8[][] storage sPtr = s; + m[0] = sPtr; + return m[0]; + } + + function from_memory() public returns (uint8[][] memory) { + uint8[][] memory a = s; + m[0] = a; + return m[0]; + } +} + +// ---- +// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 +// gas irOptimized: 147913 +// gas legacy: 148965 +// gas legacyOptimized: 146935 +// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 +// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 diff --git a/test/libsolidity/semanticTests/array/copying/calldata_array_to_mapping.sol b/test/libsolidity/semanticTests/array/copying/calldata_array_to_mapping.sol new file mode 100644 index 000000000..0573760eb --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/calldata_array_to_mapping.sol @@ -0,0 +1,18 @@ +pragma abicoder v2; + +contract C { + mapping (uint => uint8[][]) m; + + uint8[][] s; + + function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) { + m[0] = _a; + return m[0]; + } +} + +// ==== +// compileViaYul: true +// ---- +// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 +// gas irOptimized: 139927 diff --git a/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_calldata_to_storage.sol new file mode 100644 index 000000000..fe87b79ee --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_calldata_to_storage.sol @@ -0,0 +1,40 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8[] a; + uint8[2] b; + } + + S[][][] s1; + S[][1][] s2; + S[1][][1] s3; + + function test1(S[][][] calldata _a) public returns (S[][] memory){ + s1.push(); + s1[0] = _a[0]; + return s1[0]; + } + + function test2(S[][1][] calldata _a) public returns (S[][1] memory) { + s2.push(); + s2[0] = _a[0]; + return s2[0]; + } + + function test3(S[1][][2] calldata _a) public returns (S[1][] memory) { + s3[0] = _a[1]; + return s3[0]; + } +} + + +// ==== +// compileViaYul: true +// ---- +// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 +// gas irOptimized: 327878 +// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 +// gas irOptimized: 140894 +// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 +// gas irOptimized: 188509 diff --git a/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_memory_to_storage.sol new file mode 100644 index 000000000..9c0bb74ca --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/elements_of_nested_array_of_structs_memory_to_storage.sol @@ -0,0 +1,40 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8[] a; + uint8[2] b; + } + + S[][][] s1; + S[][1][] s2; + S[1][][1] s3; + + function test1(S[][][] memory _a) public returns (S[][] memory){ + s1.push(); + s1[0] = _a[0]; + return s1[0]; + } + + function test2(S[][1][] memory _a) public returns (S[][1] memory) { + s2.push(); + s2[0] = _a[0]; + return s2[0]; + } + + function test3(S[1][][2] memory _a) public returns (S[1][] memory) { + s3[0] = _a[1]; + return s3[0]; + } +} + + +// ==== +// compileViaYul: true +// ---- +// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 +// gas irOptimized: 332334 +// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 +// gas irOptimized: 145029 +// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 +// gas irOptimized: 192344 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_element_calldata_to_memory.sol b/test/libsolidity/semanticTests/array/copying/nested_array_element_calldata_to_memory.sol new file mode 100644 index 000000000..ee715b5b6 --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/nested_array_element_calldata_to_memory.sol @@ -0,0 +1,41 @@ +pragma abicoder v2; + +contract C { + function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) { + return _a[1]; + } + + function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) { + return _a[0]; + } + + function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) { + return _a[0]; + } + + function test4(uint16[][] calldata _a) public returns (uint16[][] memory) { + uint16[][][] memory tmp = new uint16[][][](2); + tmp[1] = _a; + return tmp[1]; + } + + function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) { + uint32[][2][] memory tmp = new uint32[][2][](1); + tmp[0] = _a; + return tmp[0]; + } + + function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) { + uint32[2][][] memory tmp = new uint32[2][][](1); + tmp[0] = _a; + return tmp[0]; + } +} + +// ---- +// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 +// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14 +// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7 +// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 +// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 +// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_element_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_element_calldata_to_storage.sol new file mode 100644 index 000000000..93c458341 --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/nested_array_element_calldata_to_storage.sol @@ -0,0 +1,30 @@ +contract C { + uint8[2][2] a; + uint8[2][2][2] a2; + + function test(uint8[2][2][2] calldata _a) public { + a = _a[0]; + require(a[0][0] == 1); + require(a[0][1] == 2); + require(a[1][0] == 3); + require(a[1][1] == 4); + } + + function test2(uint8[2][2] calldata _a) public { + a2[0] = _a; + require(a2[0][0][0] == 1); + require(a2[0][0][1] == 2); + require(a2[0][1][0] == 3); + require(a2[0][1][1] == 4); + require(a2[1][0][0] == 0); + require(a2[1][0][1] == 0); + require(a2[1][1][0] == 0); + require(a2[1][1][1] == 0); + } +} + +// ---- +// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8 +// test2(uint8[2][2]): 1, 2, 3, 4 +// gas irOptimized: 119939 +// gas legacyOptimized: 120228 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_element_memory_to_memory.sol b/test/libsolidity/semanticTests/array/copying/nested_array_element_memory_to_memory.sol new file mode 100644 index 000000000..ab3d472d6 --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/nested_array_element_memory_to_memory.sol @@ -0,0 +1,41 @@ +pragma abicoder v2; + +contract C { + function test1(uint8[][][] memory _a) public returns (uint8[][] memory) { + return _a[1]; + } + + function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) { + return _a[0]; + } + + function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) { + return _a[0]; + } + + function test4(uint16[][] memory _a) public returns (uint16[][] memory) { + uint16[][][] memory tmp = new uint16[][][](2); + tmp[1] = _a; + return tmp[1]; + } + + function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) { + uint32[][2][] memory tmp = new uint32[][2][](1); + tmp[0] = _a; + return tmp[0]; + } + + function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) { + uint32[2][][] memory tmp = new uint32[2][][](1); + tmp[0] = _a; + return tmp[0]; + } +} + +// ---- +// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 +// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14 +// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7 +// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 +// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 +// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_element_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_element_memory_to_storage.sol new file mode 100644 index 000000000..2dd2e7aa3 --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/nested_array_element_memory_to_storage.sol @@ -0,0 +1,30 @@ +contract C { + uint8[2][2] a1; + uint8[2][2][2] a2; + + function test(uint8[2][2][2] memory _a) public { + a1 = _a[0]; + require(a1[0][0] == 1); + require(a1[0][1] == 2); + require(a1[1][0] == 3); + require(a1[1][1] == 4); + } + + function test2(uint8[2][2] memory _a) public { + a2[0] = _a; + require(a2[0][0][0] == 1); + require(a2[0][0][1] == 2); + require(a2[0][1][0] == 3); + require(a2[0][1][1] == 4); + require(a2[1][0][0] == 0); + require(a2[1][0][1] == 0); + require(a2[1][1][0] == 0); + require(a2[1][1][1] == 0); + } +} + +// ---- +// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8 +// test2(uint8[2][2]): 1, 2, 3, 4 +// gas irOptimized: 119939 +// gas legacyOptimized: 120228 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_element_storage_to_memory.sol b/test/libsolidity/semanticTests/array/copying/nested_array_element_storage_to_memory.sol new file mode 100644 index 000000000..2f78042a4 --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/nested_array_element_storage_to_memory.sol @@ -0,0 +1,71 @@ +pragma abicoder v2; + +contract C { + uint8[][][] a1 = new uint8[][][](2); + uint8[][][2] a2; + uint8[][2][] a3 = new uint8[][2][](1); + uint8[2][][] a4 = new uint8[2][][](2); + + constructor() { + a1[1] = new uint8[][](2); + a1[1][0] = [3, 4]; + a1[1][1] = [5, 6]; + + a2[0] = new uint8[][](2); + a2[0][0] = [6, 7]; + a2[0][1] = [8, 9]; + a2[1] = new uint8[][](2); + a2[1][0] = [10, 11]; + + a3[0][0] = [3, 4]; + a3[0][1] = [5, 6]; + + a4[0] = new uint8[2][](1); + a4[0][0] = [17, 23]; + a4[1] = new uint8[2][](1); + a4[1][0] = [19, 31]; + } + + function test1() public returns (uint8[][] memory) { + return a1[1]; + } + + function test2() public returns (uint8[][] memory) { + return a2[0]; + } + + function test3() public returns (uint8[][2] memory) { + return a3[0]; + } + + function test4() public returns (uint8[2][] memory) { + return a4[1]; + } + + function test5() public returns (uint8[][][] memory) { + uint8[][][] memory tmp = new uint8[][][](3); + tmp[1] = a1[1]; + return tmp; + } + + function test6() public returns (uint8[][2][] memory) { + uint8[][2][] memory tmp = new uint8[][2][](2); + tmp[0] = a3[0]; + return tmp; + } + + function test7() public returns (uint8[2][][] memory) { + uint8[2][][] memory tmp = new uint8[2][][](1); + tmp[0] = a4[0]; + return tmp; + } +} + +// ---- +// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6 +// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9 +// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6 +// test4() -> 0x20, 1, 19, 31 +// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0 +// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0 +// test7() -> 0x20, 1, 0x20, 1, 17, 23 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_element_storage_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_element_storage_to_storage.sol new file mode 100644 index 000000000..0da09064c --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/nested_array_element_storage_to_storage.sol @@ -0,0 +1,85 @@ +pragma abicoder v2; + +contract C { + uint8[][][] src1 = new uint8[][][](2); + uint8[][][2] src2; + uint8[][2][] src3 = new uint8[][2][](1); + uint8[2][][] src4 = new uint8[2][][](2); + + uint8[][] dst1; + uint8[][] dst2; + uint8[][2] dst3; + uint8[][] dst4; + + constructor() { + src1[1] = new uint8[][](2); + src1[1][0] = [3, 4]; + src1[1][1] = [5, 6]; + + src2[0] = new uint8[][](2); + src2[0][0] = [6, 7]; + src2[0][1] = [8, 9]; + src2[1] = new uint8[][](2); + src2[1][0] = [10, 11]; + + src3[0][0] = [3, 4]; + src3[0][1] = [5, 6]; + + src4[0] = new uint8[2][](1); + src4[0][0] = [17, 23]; + src4[1] = new uint8[2][](1); + src4[1][0] = [19, 31]; + } + + function test1() public { + dst1 = src1[1]; + + require(dst1.length == 2); + require(dst1[0][0] == src1[1][0][0]); + require(dst1[0][1] == src1[1][0][1]); + require(dst1[1][0] == src1[1][1][0]); + require(dst1[1][1] == src1[1][1][1]); + } + + function test2() public { + dst2 = src2[0]; + + require(dst2.length == 2); + require(dst2[0][0] == src2[1][0][0]); + require(dst2[0][1] == src2[1][0][1]); + require(dst2[1][0] == src2[1][1][0]); + require(dst2[1][1] == src2[1][1][1]); + } + + function test3() public { + dst3 = src3[0]; + require(dst3[0][0] == src3[0][0][0]); + require(dst3[0][1] == src3[0][0][1]); + require(dst3[1][0] == src3[0][1][0]); + require(dst3[1][1] == src3[0][1][1]); + } + + function test4() public { + dst4 = src4[1]; + require(dst4.length == 2); + require(dst4[0][0] == src4[0][0][0]); + require(dst4[0][1] == src4[0][0][1]); + require(dst4[1][0] == src4[0][1][0]); + require(dst4[1][1] == src4[0][1][1]); + } +} + +// ---- +// test1() -> +// gas irOptimized: 150570 +// gas legacy: 151017 +// gas legacyOptimized: 150970 +// test2() -> FAILURE +// gas irOptimized: 150408 +// gas legacy: 150700 +// gas legacyOptimized: 150601 +// test3() -> +// gas irOptimized: 123810 +// gas legacy: 125381 +// gas legacyOptimized: 125160 +// test4() -> FAILURE diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_memory.sol b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_memory.sol new file mode 100644 index 000000000..159486eda --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_memory.sol @@ -0,0 +1,25 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8 x; + uint8 y; + } + + function test1(S[1][2] calldata a) public returns (S[1][2] memory) { + return a; + } + + function test2(S[1][] calldata a) public returns (S[1][] memory) { + return a; + } + + function test3(S[][2] calldata a) public returns (S[][2] memory) { + return a; + } +} + +// ---- +// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4 +// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23 +// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_storage.sol new file mode 100644 index 000000000..1f9011abd --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_calldata_to_storage.sol @@ -0,0 +1,38 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8[] a; + uint8[2] b; + } + + S[][] s1; + S[][1] s2; + S[1][] s3; + + function test1(S[][] calldata _a) public returns (S[][] memory){ + s1 = _a; + return s1; + } + + function test2(S[][1] calldata _a) public returns (S[][1] memory) { + s2 = _a; + return s2; + } + + function test3(S[1][] calldata _a) public returns (S[1][] memory) { + s3 = _a; + return s3; + } +} + + +// ==== +// compileViaYul: true +// ---- +// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 +// gas irOptimized: 304768 +// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 +// gas irOptimized: 116476 +// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 +// gas irOptimized: 187998 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_memory.sol b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_memory.sol new file mode 100644 index 000000000..55a4d6aed --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_memory.sol @@ -0,0 +1,25 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8 x; + uint8 y; + } + + function test1(S[1][2] memory a) public returns (S[1][2] memory r) { + r = a; + } + + function test2(S[1][] memory a) public returns (S[1][] memory r) { + r = a; + } + + function test3(S[][2] memory a) public returns (S[][2] memory r) { + r = a; + } +} + +// ---- +// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4 +// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23 +// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_storage.sol new file mode 100644 index 000000000..688946aae --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_memory_to_storage.sol @@ -0,0 +1,38 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8[] a; + uint8[2] b; + } + + S[][] s1; + S[][1] s2; + S[1][] s3; + + function test1(S[][] memory _a) public returns (S[][] memory){ + s1 = _a; + return s1; + } + + function test2(S[][1] memory _a) public returns (S[][1] memory) { + s2 = _a; + return s2; + } + + function test3(S[1][] memory _a) public returns (S[1][] memory) { + s3 = _a; + return s3; + } +} + + +// ==== +// compileViaYul: true +// ---- +// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 +// gas irOptimized: 308790 +// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 +// gas irOptimized: 118077 +// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 +// gas irOptimized: 190775 diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_storage_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_storage_to_storage.sol new file mode 100644 index 000000000..b4ab1cc61 --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_storage_to_storage.sol @@ -0,0 +1,70 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8 x; + uint8 y; + } + + S[][] src1; + S[][1] src2; + S[1][] src3; + + S[][] dst1; + S[][1] dst2; + S[1][] dst3; + + constructor() { + src1 = new S[][](1); + src1[0].push(S({x: 3, y: 7})); + src1[0].push(S({x: 11, y: 13})); + + src2[0].push(S({x: 3, y: 7})); + src2[0].push(S({x: 11, y: 13})); + src2[0].push(S({x: 17, y: 19})); + + src3.push([S({x: 3, y: 7})]); + src3.push([S({x: 11, y: 13})]); + } + + function test1() public { + dst1 = src1; + + require(dst1.length == 1); + require(dst1[0][0].x == src1[0][0].x); + require(dst1[0][0].y == src1[0][0].y); + require(dst1[0][1].x == src1[0][1].x); + require(dst1[0][1].y == src1[0][1].y); + } + + function test2() public { + dst2 = src2; + + require(dst2[0].length == 3); + require(dst2[0][0].x == src2[0][0].x); + require(dst2[0][0].y == src2[0][0].y); + require(dst2[0][1].x == src2[0][1].x); + require(dst2[0][1].y == src2[0][1].y); + require(dst2[0][2].x == src2[0][2].x); + require(dst2[0][2].y == src2[0][2].y); + } + + function test3() public { + dst3 = src3; + + require(dst3.length == 2); + require(dst3[0][0].x == src3[0][0].x); + require(dst3[0][0].y == src3[0][0].y); + require(dst3[1][0].x == src3[1][0].x); + require(dst3[1][0].y == src3[1][0].y); + } +} + +// ==== +// compileViaYul: true +// ---- +// test1() +// gas irOptimized: 123279 +// test2() +// gas irOptimized: 123073 +// test3() diff --git a/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_with_nested_array_from_storage_to_memory.sol b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_with_nested_array_from_storage_to_memory.sol new file mode 100644 index 000000000..58240492c --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/nested_array_of_structs_with_nested_array_from_storage_to_memory.sol @@ -0,0 +1,45 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8[] a; + uint8[2] b; + } + + uint8[] a1; + uint8[] a2; + uint8[] a3; + + S[][] s1; + S[1][1] s2; + + constructor() { + a1.push(23); + a1.push(29); + a2.push(31); + + s1 = new S[][](2); + s1[0] = new S[](2); + s1[0][0] = S({a: a1, b: [7, 11]}); + s1[0][1] = S({a: a2, b: [17, 19]}); + + s1[1] = new S[](1); + s1[1][0] = S({a: a3, b: [37, 41]}); + + s2[0][0] = S({a: a3, b: [43, 47]}); + } + + function test1() public returns (S[] memory) { + return s1[0]; + } + + function test2() public returns (S[1] memory) { + return s2[0]; + } +} + +// ==== +// compileViaYul: true +// ---- +// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31 +// test2() -> 0x20, 0x20, 0x60, 43, 47, 0 diff --git a/test/libsolidity/semanticTests/array/copying/nested_dynamic_array_element_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/nested_dynamic_array_element_calldata_to_storage.sol new file mode 100644 index 000000000..c519d11ce --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/nested_dynamic_array_element_calldata_to_storage.sol @@ -0,0 +1,37 @@ +pragma abicoder v2; + +contract C { + uint8[][] a; + uint8[][][] a2; + + function test(uint8[][][] calldata _a) public { + a = _a[1]; + require(a.length == 2); + require(a[0].length == 1); + require(a[0][0] == 7); + require(a[1].length == 2); + require(a[1][0] == 8); + require(a[1][1] == 9); + } + + function test2(uint8[][] calldata _a) public { + a2 = new uint8[][][](2); + a2[0] = _a; + require(a2[0].length == 2); + require(a2[0][0].length == 1); + require(a2[0][0][0] == 7); + require(a2[0][1].length == 2); + require(a2[0][1][0] == 8); + require(a2[0][1][1] == 9); + require(a2[1].length == 0); + } +} + +// ==== +// compileViaYul: true +// ---- +// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 +// gas irOptimized: 138083 +// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 +// gas irOptimized: 164290 +// gas legacyOptimized: 120228 diff --git a/test/libsolidity/semanticTests/structs/copy_from_mapping.sol b/test/libsolidity/semanticTests/structs/copy_from_mapping.sol new file mode 100644 index 000000000..5057b0efa --- /dev/null +++ b/test/libsolidity/semanticTests/structs/copy_from_mapping.sol @@ -0,0 +1,44 @@ +pragma abicoder v2; + +contract C { + struct S { + bytes b; + uint16[] a; + uint16 u; + } + + constructor() { + uint16[] memory a = new uint16[](2); + a[0] = 13; + a[1] = 14; + + m[7] = S({b: "foo", a: a, u: 7}); + } + + mapping (uint => S) m; + S s; + + function to_state() public returns (S memory) { + s = m[7]; + return s; + } + + function to_storage() public returns (S memory) { + S storage sLocal = s; + sLocal = m[7]; + return sLocal; + } + + function to_memory() public returns (S memory) { + return m[7]; + } + +} + +// ---- +// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// gas irOptimized: 121513 +// gas legacy: 123120 +// gas legacyOptimized: 121776 +// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 diff --git a/test/libsolidity/semanticTests/structs/copy_struct_with_nested_array_from_calldata_to_memory.sol b/test/libsolidity/semanticTests/structs/copy_struct_with_nested_array_from_calldata_to_memory.sol new file mode 100644 index 000000000..8ccc30936 --- /dev/null +++ b/test/libsolidity/semanticTests/structs/copy_struct_with_nested_array_from_calldata_to_memory.sol @@ -0,0 +1,16 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8[1] x; + uint8[] y; + } + + function test(S calldata s) public returns (S memory) { + return s; + } +} + +// ---- +// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11 +// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23 diff --git a/test/libsolidity/semanticTests/structs/copy_struct_with_nested_array_from_calldata_to_storage.sol b/test/libsolidity/semanticTests/structs/copy_struct_with_nested_array_from_calldata_to_storage.sol new file mode 100644 index 000000000..fa67deb2c --- /dev/null +++ b/test/libsolidity/semanticTests/structs/copy_struct_with_nested_array_from_calldata_to_storage.sol @@ -0,0 +1,22 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8[1] x; + uint8[] y; + } + + S s; + + function test(S calldata src) public { + s = src; + + require(s.x[0] == 3); + require(s.y.length == 2); + require(s.y[0] == 7); + require(s.y[1] == 11); + } +} + +// ---- +// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 diff --git a/test/libsolidity/semanticTests/structs/copy_struct_with_nested_array_from_memory_to_memory.sol b/test/libsolidity/semanticTests/structs/copy_struct_with_nested_array_from_memory_to_memory.sol new file mode 100644 index 000000000..c340289ad --- /dev/null +++ b/test/libsolidity/semanticTests/structs/copy_struct_with_nested_array_from_memory_to_memory.sol @@ -0,0 +1,16 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8[1] x; + uint8[] y; + } + + function test(S memory s) public returns (S memory r) { + return r; + } +} + +// ---- +// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 0, 0x40, 0 +// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 0, 0x40, 0 diff --git a/test/libsolidity/semanticTests/structs/copy_struct_with_nested_array_from_storage_to_storage.sol b/test/libsolidity/semanticTests/structs/copy_struct_with_nested_array_from_storage_to_storage.sol new file mode 100644 index 000000000..3f29790d8 --- /dev/null +++ b/test/libsolidity/semanticTests/structs/copy_struct_with_nested_array_from_storage_to_storage.sol @@ -0,0 +1,27 @@ +contract C { + struct S { + uint8[1] x; + uint8[] y; + } + + S src; + S dst; + + constructor() { + src.x = [3]; + src.y.push(7); + src.y.push(11); + } + + function test() public { + dst = src; + + require(dst.x[0] == 3); + require(dst.y.length == 2); + require(dst.y[0] == 7); + require(dst.y[1] == 11); + } +} + +// ---- +// test() diff --git a/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol b/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol new file mode 100644 index 000000000..e91fa839e --- /dev/null +++ b/test/libsolidity/semanticTests/structs/copy_substructures_from_mapping.sol @@ -0,0 +1,52 @@ +pragma abicoder v2; + +contract C { + struct S { + bytes b; + uint16[] a; + uint16 u; + } + + constructor() { + uint16[] memory a = new uint16[](2); + a[0] = 13; + a[1] = 14; + + m[7] = S({b: "foo", a: a, u: 7}); + } + + mapping (uint => S) m; + S s; + + function to_state() public returns (S memory) { + s.b = m[7].b; + s.a = m[7].a; + s.u = m[7].u; + return s; + } + + function to_storage() public returns (S memory) { + S storage sLocal = s; + sLocal.b = m[7].b; + sLocal.a = m[7].a; + sLocal.u = m[7].u; + return sLocal; + } + + function to_memory() public returns (S memory) { + S memory sLocal; + sLocal.b = m[7].b; + sLocal.a = m[7].a; + sLocal.u = m[7].u; + return sLocal; + } + +} + +// ---- +// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// gas irOptimized: 121616 +// gas legacy: 123263 +// gas legacyOptimized: 121785 +// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 diff --git a/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol b/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol new file mode 100644 index 000000000..cfec3844f --- /dev/null +++ b/test/libsolidity/semanticTests/structs/copy_substructures_to_mapping.sol @@ -0,0 +1,66 @@ +pragma abicoder v2; + +contract C { + struct S { + bytes b; + uint16[] a; + uint16 u; + } + + S s; + constructor() { + uint16[] memory a = new uint16[](2); + a[0] = 13; + a[1] = 14; + + s.b = "foo"; + s.a = a; + s.u = 21; + } + + mapping (uint => S) m; + + function from_memory() public returns (S memory) { + S memory sMemory = s; + m[0].b = sMemory.b; + m[0].a = sMemory.a; + m[0].u = sMemory.u; + return m[0]; + } + + function from_state() public returns (S memory) { + m[1].b = s.b; + m[1].a = s.a; + m[1].u = s.u; + return m[1]; + } + + function from_storage() public returns (S memory) { + S storage sLocal = s; + m[1].b = sLocal.b; + m[1].a = sLocal.a; + m[1].u = sLocal.u; + return m[1]; + } + + function from_calldata(S calldata sCalldata) public returns (S memory) { + m[2].b = sCalldata.b; + m[2].a = sCalldata.a; + m[2].u = sCalldata.u; + return m[2]; + } +} + +// ---- +// from_memory() -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// gas irOptimized: 123062 +// gas legacy: 130289 +// gas legacyOptimized: 128785 +// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// gas irOptimized: 121776 +// gas legacy: 123341 +// gas legacyOptimized: 121892 +// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// gas irOptimized: 115169 +// gas legacy: 122579 +// gas legacyOptimized: 120829 diff --git a/test/libsolidity/semanticTests/structs/copy_to_mapping.sol b/test/libsolidity/semanticTests/structs/copy_to_mapping.sol new file mode 100644 index 000000000..e575fb8f1 --- /dev/null +++ b/test/libsolidity/semanticTests/structs/copy_to_mapping.sol @@ -0,0 +1,63 @@ +pragma abicoder v2; + +contract C { + struct S { + bytes b; + uint16[] a; + uint16 u; + } + + S s; + constructor() { + uint16[] memory a = new uint16[](2); + a[0] = 13; + a[1] = 14; + + s.b = "foo"; + s.a = a; + s.u = 21; + } + + mapping (uint => S) m; + + function from_state() public returns (S memory) { + m[0] = s; + return m[0]; + } + + function from_storage() public returns (S memory) { + S storage sLocal = s; + m[1] = sLocal; + return m[1]; + } + + function from_memory() public returns (S memory) { + S memory sMemory = s; + m[2] = sMemory; + return m[2]; + } + + + function from_calldata(S calldata sCalldata) public returns (S memory) { + m[3] = sCalldata; + return m[3]; + } +} + +// ---- +// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// gas irOptimized: 121709 +// gas legacy: 123198 +// gas legacyOptimized: 121830 +// from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// gas irOptimized: 121753 +// gas legacy: 123247 +// gas legacyOptimized: 121882 +// from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// gas irOptimized: 122954 +// gas legacy: 130146 +// gas legacyOptimized: 128779 +// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// gas irOptimized: 115067 +// gas legacy: 118383 +// gas legacyOptimized: 115458 diff --git a/test/libsolidity/semanticTests/types/mapping/copy_from_mapping_to_mapping.sol b/test/libsolidity/semanticTests/types/mapping/copy_from_mapping_to_mapping.sol new file mode 100644 index 000000000..4315095ac --- /dev/null +++ b/test/libsolidity/semanticTests/types/mapping/copy_from_mapping_to_mapping.sol @@ -0,0 +1,35 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8[3] x; + uint8[][] y; + uint16 z; + } + + mapping (uint8 => S) src; + mapping (uint8 => S) dst; + + constructor() { + uint8[] memory d = new uint8[](2); + d[0] = 3; + d[1] = 4; + + uint8[][] memory y = new uint8[][](2); + y[0] = d; + y[1] = d; + + src[0] = S({x: [7, 8, 9], y: y, z: 13}); + } + + function f() public returns (S memory) { + dst[0] = src[0]; + return dst[0]; + } +} + +// ---- +// f() -> 0x20, 7, 8, 9, 0xa0, 13, 2, 0x40, 0xa0, 2, 3, 4, 2, 3, 4 +// gas irOptimized: 197113 +// gas legacy: 199986 +// gas legacyOptimized: 196847 diff --git a/test/libsolidity/semanticTests/types/mapping/copy_struct_to_array_stored_in_mapping.sol b/test/libsolidity/semanticTests/types/mapping/copy_struct_to_array_stored_in_mapping.sol new file mode 100644 index 000000000..26a33682d --- /dev/null +++ b/test/libsolidity/semanticTests/types/mapping/copy_struct_to_array_stored_in_mapping.sol @@ -0,0 +1,57 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8 x; + } + + constructor() { + s = S({x: 7}); + m2[0].push(); + } + + S s; + + mapping (uint8 => S[2]) m1; + mapping (uint8 => S[]) m2; + + function from_storage_to_static_array() public returns (S[2] memory) { + m1[0][1] = s; + return m1[0]; + } + + function from_storage_to_dynamic_array() public returns (S[] memory) { + m2[0][0] = s; + return m2[0]; + } + + function from_memory_to_static_array() public returns (S[2] memory) { + S memory sLocal = s; + m1[0][1] = sLocal; + return m1[0]; + } + + function from_memory_to_dynamic_array() public returns (S[] memory) { + S memory sLocal = s; + m2[0][0] = sLocal; + return m2[0]; + } + + function from_calldata_to_static_array(S calldata sCalldata) public returns (S[2] memory) { + m1[0][1] = sCalldata; + return m1[0]; + } + + function from_calldata_to_dynamic_array(S calldata sCalldata) public returns (S[] memory) { + m2[0][0] = sCalldata; + return m2[0]; + } +} + +// ---- +// from_storage_to_static_array() -> 0, 7 +// from_storage_to_dynamic_array() -> 0x20, 1, 7 +// from_memory_to_static_array() -> 0, 7 +// from_memory_to_dynamic_array() -> 0x20, 1, 7 +// from_calldata_to_static_array((uint8)): 8 -> 0, 8 +// from_calldata_to_dynamic_array((uint8)): 8 -> 0x20, 1, 8