mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge remote-tracking branch 'origin/develop' into breaking
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract C {
|
||||
function test(uint256[][2] calldata a) external returns (uint256) {
|
||||
return a.length;
|
||||
}
|
||||
function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {
|
||||
return a[i].length;
|
||||
}
|
||||
function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {
|
||||
return a[i][j];
|
||||
}
|
||||
function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {
|
||||
return this.test(a, i, j);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2
|
||||
// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3
|
||||
// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4
|
||||
// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01
|
||||
// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01
|
||||
// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02
|
||||
// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02
|
||||
// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03
|
||||
// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03
|
||||
// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01
|
||||
// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01
|
||||
// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02
|
||||
// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02
|
||||
// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03
|
||||
// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03
|
||||
// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04
|
||||
// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04
|
||||
// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE
|
||||
// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE
|
||||
// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE
|
||||
@@ -0,0 +1,38 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract C {
|
||||
function test(uint256[][] calldata a) external returns (uint256) {
|
||||
return a.length;
|
||||
}
|
||||
function test(uint256[][] calldata a, uint256 i) external returns (uint256) {
|
||||
return a[i].length;
|
||||
}
|
||||
function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {
|
||||
return a[i][j];
|
||||
}
|
||||
function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {
|
||||
return this.test(a, i, j);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2
|
||||
// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3
|
||||
// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4
|
||||
// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01
|
||||
// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01
|
||||
// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02
|
||||
// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02
|
||||
// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03
|
||||
// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03
|
||||
// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01
|
||||
// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01
|
||||
// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02
|
||||
// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02
|
||||
// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03
|
||||
// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03
|
||||
// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04
|
||||
// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04
|
||||
// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE
|
||||
// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE
|
||||
// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE
|
||||
@@ -0,0 +1,12 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
contract C {
|
||||
function f(bytes[] calldata a, uint256 i) external returns (uint) {
|
||||
return uint8(a[0][i]);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61
|
||||
// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62
|
||||
// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE
|
||||
@@ -0,0 +1,25 @@
|
||||
contract c {
|
||||
uint[9] m_data;
|
||||
uint[] m_data_dyn;
|
||||
uint8[][] m_byte_data;
|
||||
function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {
|
||||
m_data = a;
|
||||
m_data_dyn = a;
|
||||
m_byte_data = b;
|
||||
return b[3][1]; // note that access and declaration are reversed to each other
|
||||
}
|
||||
function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {
|
||||
a = m_data.length;
|
||||
b = m_data[7];
|
||||
c = m_data_dyn.length;
|
||||
d = m_data_dyn[7];
|
||||
e = m_byte_data.length;
|
||||
f = m_byte_data[3].length;
|
||||
g = m_byte_data[3][1];
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32
|
||||
// retrieve() -> 9, 28, 9, 28, 4, 3, 32
|
||||
@@ -0,0 +1,42 @@
|
||||
contract c {
|
||||
uint[3][90][] large;
|
||||
uint[3][3][] small;
|
||||
function test() public returns (uint r) {
|
||||
for (uint i = 0; i < 7; i++) {
|
||||
large.push();
|
||||
small.push();
|
||||
}
|
||||
large[3][2][0] = 2;
|
||||
large[1] = large[3];
|
||||
small[3][2][0] = 2;
|
||||
small[1] = small[2];
|
||||
r = ((
|
||||
small[3][2][0] * 0x100 |
|
||||
small[1][2][0]) * 0x100 |
|
||||
large[3][2][0]) * 0x100 |
|
||||
large[1][2][0];
|
||||
delete small;
|
||||
delete large;
|
||||
|
||||
}
|
||||
function clear() public returns (uint, uint) {
|
||||
for (uint i = 0; i < 7; i++) {
|
||||
large.push();
|
||||
small.push();
|
||||
}
|
||||
small[3][2][0] = 0;
|
||||
large[3][2][0] = 0;
|
||||
while (small.length > 0)
|
||||
small.pop();
|
||||
while (large.length > 0)
|
||||
large.pop();
|
||||
return (small.length, large.length);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test() -> 0x02000202
|
||||
// storage: empty
|
||||
// clear() -> 0, 0
|
||||
// storage: empty
|
||||
@@ -11,5 +11,7 @@ contract c {
|
||||
}
|
||||
}
|
||||
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
contract c {
|
||||
uint[] data1;
|
||||
uint[] data2;
|
||||
function setData1(uint length, uint index, uint value) public {
|
||||
data1 = new uint[](length);
|
||||
if (index < length)
|
||||
data1[index] = value;
|
||||
}
|
||||
function copyStorageStorage() public { data2 = data1; }
|
||||
function getData2(uint index) public returns (uint len, uint val) {
|
||||
len = data2.length; if (index < len) val = data2[index];
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// setData1(uint256,uint256,uint256): 10, 5, 4 ->
|
||||
// copyStorageStorage() ->
|
||||
// getData2(uint256): 5 -> 10, 4
|
||||
// setData1(uint256,uint256,uint256): 0, 0, 0 ->
|
||||
// copyStorageStorage() ->
|
||||
// getData2(uint256): 0 -> 0, 0
|
||||
// storage: empty
|
||||
+2
@@ -10,5 +10,7 @@ contract c {
|
||||
}
|
||||
}
|
||||
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test() -> 9, 4
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
contract c {
|
||||
struct Data { uint x; uint y; }
|
||||
Data[] data1;
|
||||
Data[] data2;
|
||||
function test() public returns (uint x, uint y) {
|
||||
while (data1.length < 9)
|
||||
data1.push();
|
||||
data1[8].x = 4;
|
||||
data1[8].y = 5;
|
||||
data2 = data1;
|
||||
x = data2[8].x;
|
||||
y = data2[8].y;
|
||||
while (data1.length > 0)
|
||||
data1.pop();
|
||||
data2 = data1;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test() -> 4, 5
|
||||
// storage: empty
|
||||
@@ -0,0 +1,19 @@
|
||||
contract c {
|
||||
byte[10] data1;
|
||||
bytes2[32] data2;
|
||||
function test() public returns (uint check, uint res1, uint res2) {
|
||||
uint i;
|
||||
for (i = 0; i < data2.length; ++i)
|
||||
data2[i] = 0xffff;
|
||||
check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));
|
||||
for (i = 0; i < data1.length; ++i)
|
||||
data1[i] = byte(uint8(1 + i));
|
||||
data2 = data1;
|
||||
for (i = 0; i < 16; ++i)
|
||||
res1 |= uint(uint16(data2[i])) * 0x10000**i;
|
||||
for (i = 0; i < 16; ++i)
|
||||
res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000
|
||||
@@ -0,0 +1,18 @@
|
||||
contract Test {
|
||||
uint24[] public data;
|
||||
function set(uint24[] memory _data) public returns (uint) {
|
||||
data = _data;
|
||||
return data.length;
|
||||
}
|
||||
function get() public returns (uint24[] memory) {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18
|
||||
// data(uint256): 7 -> 8
|
||||
// data(uint256): 15 -> 16
|
||||
// data(uint256): 18 -> FAILURE
|
||||
// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18
|
||||
@@ -0,0 +1,17 @@
|
||||
contract c {
|
||||
function set(uint key) public returns (bool) { data[key] = msg.data; return true; }
|
||||
function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }
|
||||
mapping(uint => bytes) data;
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// set(uint256): 1, 2 -> true
|
||||
// set(uint256): 2, 2, 3, 4, 5 -> true
|
||||
// storage: nonempty
|
||||
// copy(uint256,uint256): 1, 2 -> true
|
||||
// storage: nonempty
|
||||
// copy(uint256,uint256): 99, 1 -> true
|
||||
// storage: nonempty
|
||||
// copy(uint256,uint256): 99, 2 -> true
|
||||
// storage: empty
|
||||
@@ -14,5 +14,7 @@ contract C {
|
||||
}
|
||||
}
|
||||
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test() -> 7
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
contract c {
|
||||
function set() public returns (bool) { data1 = msg.data; return true; }
|
||||
function reset() public returns (bool) { data1 = data2; return true; }
|
||||
bytes data1;
|
||||
bytes data2;
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// set(): 1, 2, 3, 4, 5 -> true
|
||||
// storage: nonempty
|
||||
// reset() -> true
|
||||
// storage: empty
|
||||
@@ -0,0 +1,12 @@
|
||||
contract c {
|
||||
fallback() external { data = msg.data; }
|
||||
function del() public returns (bool) { delete data; return true; }
|
||||
bytes data;
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// (): 7 ->
|
||||
// storage: nonempty
|
||||
// del(): 7 -> true
|
||||
// storage: empty
|
||||
@@ -0,0 +1,15 @@
|
||||
contract Test {
|
||||
function del() public returns (uint24[3][4] memory) {
|
||||
uint24[3][4] memory x;
|
||||
for (uint24 i = 0; i < x.length; i ++)
|
||||
for (uint24 j = 0; j < x[i].length; j ++)
|
||||
x[i][j] = i * 0x10 + j;
|
||||
delete x[1];
|
||||
delete x[3][2];
|
||||
return x;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// del() -> 0, 1, 2, 0, 0, 0, 0x20, 0x21, 0x22, 0x30, 0x31, 0
|
||||
@@ -0,0 +1,23 @@
|
||||
contract c {
|
||||
uint[20] spacer;
|
||||
uint[] dynamic;
|
||||
function fill() public {
|
||||
for (uint i = 0; i < 21; ++i)
|
||||
dynamic.push(i + 1);
|
||||
}
|
||||
function halfClear() public {
|
||||
while (dynamic.length > 5)
|
||||
dynamic.pop();
|
||||
}
|
||||
function fullClear() public { delete dynamic; }
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// storage: empty
|
||||
// fill() ->
|
||||
// storage: nonempty
|
||||
// halfClear() ->
|
||||
// storage: nonempty
|
||||
// fullClear() ->
|
||||
// storage: empty
|
||||
@@ -0,0 +1,23 @@
|
||||
contract c {
|
||||
struct s { uint[][] d; }
|
||||
s[] data;
|
||||
function fill() public returns (uint) {
|
||||
while (data.length < 3)
|
||||
data.push();
|
||||
while (data[2].d.length < 4)
|
||||
data[2].d.push();
|
||||
while (data[2].d[3].length < 5)
|
||||
data[2].d[3].push();
|
||||
data[2].d[3][4] = 8;
|
||||
return data[2].d[3][4];
|
||||
}
|
||||
function clear() public { delete data; }
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// storage: empty
|
||||
// fill() -> 8
|
||||
// storage: nonempty
|
||||
// clear() ->
|
||||
// storage: empty
|
||||
@@ -0,0 +1,12 @@
|
||||
contract c {
|
||||
function test(uint[8] calldata a, uint[] calldata b, uint[5] calldata c, uint a_index, uint b_index, uint c_index)
|
||||
external returns (uint av, uint bv, uint cv) {
|
||||
av = a[a_index];
|
||||
bv = b[b_index];
|
||||
cv = c[c_index];
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256): 1, 2, 3, 4, 5, 6, 7, 8, 0x220, 21, 22, 23, 24, 25, 0, 1, 2, 3, 11, 12, 13 -> 1, 12, 23
|
||||
@@ -0,0 +1,17 @@
|
||||
contract c {
|
||||
uint spacer1;
|
||||
uint spacer2;
|
||||
uint[20] data;
|
||||
function fill() public {
|
||||
for (uint i = 0; i < data.length; ++i) data[i] = i+1;
|
||||
}
|
||||
function clear() public { delete data; }
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// storage: empty
|
||||
// fill() ->
|
||||
// storage: nonempty
|
||||
// clear() ->
|
||||
// storage: empty
|
||||
@@ -0,0 +1,27 @@
|
||||
contract c {
|
||||
bytes data;
|
||||
function direct(bytes calldata arg, uint index) external returns (uint) {
|
||||
return uint(uint8(arg[index]));
|
||||
}
|
||||
function storageCopyRead(bytes calldata arg, uint index) external returns (uint) {
|
||||
data = arg;
|
||||
return uint(uint8(data[index]));
|
||||
}
|
||||
function storageWrite() external returns (uint) {
|
||||
data = new bytes(35);
|
||||
data[31] = 0x77;
|
||||
data[32] = 0x14;
|
||||
|
||||
data[31] = 0x01;
|
||||
data[31] |= 0x08;
|
||||
data[30] = 0x01;
|
||||
data[32] = 0x03;
|
||||
return uint(uint8(data[30])) * 0x100 | uint(uint8(data[31])) * 0x10 | uint(uint8(data[32]));
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// direct(bytes,uint256): 0x40, 33, 34, 0x000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F, left(0x2021) -> 0x21
|
||||
// storageCopyRead(bytes,uint256): 0x40, 33, 34, 0x000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F, left(0x2021) -> 0x21
|
||||
// storageWrite() -> 0x193
|
||||
@@ -0,0 +1,17 @@
|
||||
contract Main {
|
||||
function f(bytes memory _s1, uint i1, uint i2, uint i3) public returns (byte c1, byte c2, byte c3) {
|
||||
c1 = _s1[i1];
|
||||
c2 = intern(_s1, i2);
|
||||
c3 = internIndirect(_s1)[i3];
|
||||
}
|
||||
function intern(bytes memory _s1, uint i) public returns (byte c) {
|
||||
return _s1[i];
|
||||
}
|
||||
function internIndirect(bytes memory _s1) public returns (bytes memory) {
|
||||
return _s1;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f(bytes,uint256,uint256,uint256): 0x80, 3, 4, 5, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> "d", "e", "f"
|
||||
@@ -0,0 +1,28 @@
|
||||
contract c {
|
||||
uint256 a;
|
||||
uint256 b;
|
||||
uint256 c;
|
||||
uint16[] inner = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
|
||||
uint16[][] data;
|
||||
function test() public returns (uint x, uint y, uint z) {
|
||||
for (uint i = 1; i <= 48; i++)
|
||||
data.push(inner);
|
||||
for (uint j = 1; j <= 10; j++)
|
||||
data.pop();
|
||||
x = data[data.length - 1][0];
|
||||
for (uint k = 1; k <= 10; k++)
|
||||
data.pop();
|
||||
y = data[data.length - 1][1];
|
||||
for (uint l = 1; l <= 10; l++)
|
||||
data.pop();
|
||||
z = data[data.length - 1][2];
|
||||
for (uint m = 1; m <= 18; m++)
|
||||
data.pop();
|
||||
delete inner;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test() -> 1, 2, 3
|
||||
// storage: empty
|
||||
@@ -0,0 +1,12 @@
|
||||
contract c {
|
||||
uint[] data;
|
||||
function test() public {
|
||||
data.push(7);
|
||||
data.pop();
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test() ->
|
||||
// storage: empty
|
||||
@@ -0,0 +1,23 @@
|
||||
contract c {
|
||||
uint16[] data;
|
||||
function test() public returns (uint16 x, uint16 y, uint16 z) {
|
||||
for (uint i = 1; i <= 48; i++)
|
||||
data.push(uint16(i));
|
||||
for (uint j = 1; j <= 10; j++)
|
||||
data.pop();
|
||||
x = data[data.length - 1];
|
||||
for (uint k = 1; k <= 10; k++)
|
||||
data.pop();
|
||||
y = data[data.length - 1];
|
||||
for (uint l = 1; l <= 10; l++)
|
||||
data.pop();
|
||||
z = data[data.length - 1];
|
||||
for (uint m = 1; m <= 18; m++)
|
||||
data.pop();
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test() -> 38, 28, 18
|
||||
// storage: empty
|
||||
@@ -0,0 +1,23 @@
|
||||
contract c {
|
||||
uint256 a;
|
||||
uint256 b;
|
||||
uint256 c;
|
||||
uint24[] data;
|
||||
function test() public returns (uint24 x, uint24 y) {
|
||||
for (uint i = 1; i <= 30; i++)
|
||||
data.push(uint24(i));
|
||||
for (uint j = 1; j <= 10; j++)
|
||||
data.pop();
|
||||
x = data[data.length - 1];
|
||||
for (uint k = 1; k <= 10; k++)
|
||||
data.pop();
|
||||
y = data[data.length - 1];
|
||||
for (uint l = 1; l <= 10; l++)
|
||||
data.pop();
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test() -> 20, 10
|
||||
// storage: empty
|
||||
@@ -0,0 +1,21 @@
|
||||
contract c {
|
||||
uint256 a;
|
||||
uint256 b;
|
||||
uint256 c;
|
||||
bytes data;
|
||||
function test() public returns (bool) {
|
||||
for (uint8 i = 0; i <= 40; i++)
|
||||
data.push(byte(i+1));
|
||||
for (int8 j = 40; j >= 0; j--) {
|
||||
require(data[uint8(j)] == byte(j+1));
|
||||
require(data.length == uint8(j+1));
|
||||
data.pop();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test() -> true
|
||||
// storage: empty
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
contract c {
|
||||
uint256 a;
|
||||
uint256 b;
|
||||
bytes data;
|
||||
function test() public {
|
||||
for (uint8 i = 0; i <= 40; i++)
|
||||
data.push(0x03);
|
||||
for (uint8 j = 0; j <= 40; j++) {
|
||||
assembly {
|
||||
mstore(0, "garbage")
|
||||
}
|
||||
data.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test() ->
|
||||
// storage: empty
|
||||
@@ -0,0 +1,16 @@
|
||||
contract c {
|
||||
bytes data;
|
||||
function test() public {
|
||||
data.push(0x07);
|
||||
data.push(0x05);
|
||||
data.push(0x03);
|
||||
data.pop();
|
||||
data.pop();
|
||||
data.pop();
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test() ->
|
||||
// storage: empty
|
||||
@@ -0,0 +1,17 @@
|
||||
contract c {
|
||||
uint spacer1;
|
||||
uint spacer2;
|
||||
uint[3] data;
|
||||
function fill() public {
|
||||
for (uint i = 0; i < data.length; ++i) data[i] = i+1;
|
||||
}
|
||||
function clear() public { delete data; }
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// storage: empty
|
||||
// fill() ->
|
||||
// storage: nonempty
|
||||
// clear() ->
|
||||
// storage: empty
|
||||
@@ -12,6 +12,8 @@ contract Test {
|
||||
return bytes(s).length;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f(string,uint256): 0x40, 0x02, 0x06, "abcdef" -> "c"
|
||||
// l() -> 0x06
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
contract Base {
|
||||
uint public m_x;
|
||||
address[] m_s;
|
||||
constructor(uint x, address[] memory s) {
|
||||
m_x = x;
|
||||
m_s = s;
|
||||
}
|
||||
function part(uint i) public returns (address) {
|
||||
return m_s[i];
|
||||
}
|
||||
}
|
||||
contract Main is Base {
|
||||
constructor(address[] memory s, uint x) Base(x, f(s)) {}
|
||||
function f(address[] memory s) public returns (address[] memory) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
contract Creator {
|
||||
function f(uint x, address[] memory s) public returns (uint r, address ch) {
|
||||
Main c = new Main(s, x);
|
||||
r = c.m_x();
|
||||
ch = c.part(x);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8
|
||||
@@ -0,0 +1,28 @@
|
||||
contract Base {
|
||||
uint public m_x;
|
||||
bytes m_s;
|
||||
constructor(uint x, bytes memory s) {
|
||||
m_x = x;
|
||||
m_s = s;
|
||||
}
|
||||
function part(uint i) public returns (byte) {
|
||||
return m_s[i];
|
||||
}
|
||||
}
|
||||
contract Main is Base {
|
||||
constructor(bytes memory s, uint x) Base(x, f(s)) {}
|
||||
function f(bytes memory s) public returns (bytes memory) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
contract Creator {
|
||||
function f(uint x, bytes memory s) public returns (uint r, byte ch) {
|
||||
Main c = new Main(s, x);
|
||||
r = c.m_x();
|
||||
ch = c.part(x);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h"
|
||||
@@ -0,0 +1,12 @@
|
||||
contract Test {
|
||||
uint public m_x;
|
||||
bytes public m_s;
|
||||
constructor(uint x, bytes memory s) {
|
||||
m_x = x;
|
||||
m_s = s;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// constructor(): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" ->
|
||||
// m_x() -> 7
|
||||
// m_s() -> 0x20, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz"
|
||||
@@ -32,5 +32,7 @@ contract test {
|
||||
}
|
||||
}
|
||||
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// assign() -> 2, 2, 3, 3
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
contract c {
|
||||
struct Struct { uint a; bytes data; uint b; }
|
||||
Struct data1;
|
||||
Struct data2;
|
||||
function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {
|
||||
data1.a = _a;
|
||||
data1.b = _b;
|
||||
data1.data = _data;
|
||||
return true;
|
||||
}
|
||||
function copy() public returns (bool) {
|
||||
data1 = data2;
|
||||
return true;
|
||||
}
|
||||
function del() public returns (bool) {
|
||||
delete data1;
|
||||
return true;
|
||||
}
|
||||
function test(uint256 i) public returns (byte) {
|
||||
return data1.data[i];
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// storage: empty
|
||||
// set(uint256,bytes,uint256): 12, 0x60, 13, 33, "12345678901234567890123456789012", "3" -> true
|
||||
// test(uint256): 32 -> "3"
|
||||
// storage: nonempty
|
||||
// copy() -> true
|
||||
// storage: empty
|
||||
// set(uint256,bytes,uint256): 12, 0x60, 13, 33, "12345678901234567890123456789012", "3" -> true
|
||||
// storage: nonempty
|
||||
// del() -> true
|
||||
// storage: empty
|
||||
@@ -34,6 +34,8 @@ contract c {
|
||||
}
|
||||
}
|
||||
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// set(uint256): 7 -> true
|
||||
// retrieve(uint256): 7 -> 1, 3, 4, 2
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
library L {
|
||||
struct S { uint x; }
|
||||
function integer(uint t, bool b) public view returns (uint) {
|
||||
if (b) {
|
||||
return t;
|
||||
} else {
|
||||
revert("failure");
|
||||
}
|
||||
}
|
||||
function stru(S storage t, bool b) public view returns (uint) {
|
||||
if (b) {
|
||||
return t.x;
|
||||
} else {
|
||||
revert("failure");
|
||||
}
|
||||
}
|
||||
}
|
||||
contract C {
|
||||
using L for L.S;
|
||||
L.S t;
|
||||
function f(bool b) public returns (uint, string memory) {
|
||||
uint x = 8;
|
||||
try L.integer(x, b) returns (uint _x) {
|
||||
return (_x, "");
|
||||
} catch Error(string memory message) {
|
||||
return (18, message);
|
||||
}
|
||||
}
|
||||
function g(bool b) public returns (uint, string memory) {
|
||||
t.x = 9;
|
||||
try t.stru(b) returns (uint x) {
|
||||
return (x, "");
|
||||
} catch Error(string memory message) {
|
||||
return (19, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=byzantium
|
||||
// ----
|
||||
// library: L
|
||||
// f(bool): true -> 8, 0x40, 0
|
||||
// f(bool): false -> 18, 0x40, 7, "failure"
|
||||
// g(bool): true -> 9, 0x40, 0
|
||||
// g(bool): false -> 19, 0x40, 7, "failure"
|
||||
@@ -23,6 +23,8 @@ contract c {
|
||||
}
|
||||
}
|
||||
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// x() -> 0, 0
|
||||
// y() -> 0, 0
|
||||
|
||||
Reference in New Issue
Block a user