mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #13464 from ethereum/copying_reference_types
Add tests for copying reference types between data locations
This commit is contained in:
commit
1fbee8259a
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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()
|
@ -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
|
@ -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
|
44
test/libsolidity/semanticTests/structs/copy_from_mapping.sol
Normal file
44
test/libsolidity/semanticTests/structs/copy_from_mapping.sol
Normal file
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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()
|
@ -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
|
@ -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
|
63
test/libsolidity/semanticTests/structs/copy_to_mapping.sol
Normal file
63
test/libsolidity/semanticTests/structs/copy_to_mapping.sol
Normal file
@ -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
|
@ -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
|
@ -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
|
Loading…
Reference in New Issue
Block a user