From 11033c95361216c0e8ce4bb153465e18c3c55ecc Mon Sep 17 00:00:00 2001 From: Djordje Mijovic Date: Thu, 12 Nov 2020 15:29:08 +0100 Subject: [PATCH] Moving some bytes and array tests to semanticTests --- test/libsolidity/SolidityEndToEndTest.cpp | 398 ------------------ .../array/array_pop_array_transition.sol | 26 ++ .../array/array_pop_storage_empty.sol | 12 + .../array/array_pop_uint16_transition.sol | 23 + .../array/array_pop_uint24_transition.sol | 23 + .../array_copy_storage_storage_dyn_dyn.sol | 22 + .../array_copy_storage_storage_struct.sol | 20 + .../copying/array_copy_target_leftover.sol | 19 + .../array/copying/bytes_inside_mappings.sol | 15 + .../array/copying/copy_removes_bytes_data.sol | 12 + .../array/delete_removes_bytes_data.sol | 12 + .../array/dynamic_array_cleanup.sol | 23 + .../array/dynamic_multi_array_cleanup.sol | 23 + .../array/fixed_array_cleanup.sol | 17 + .../array/short_fixed_array_cleanup.sol | 17 + ...truct_containing_bytes_copy_and_delete.sol | 33 ++ 16 files changed, 297 insertions(+), 398 deletions(-) create mode 100644 test/libsolidity/semanticTests/array/array_pop_array_transition.sol create mode 100644 test/libsolidity/semanticTests/array/array_pop_storage_empty.sol create mode 100644 test/libsolidity/semanticTests/array/array_pop_uint16_transition.sol create mode 100644 test/libsolidity/semanticTests/array/array_pop_uint24_transition.sol create mode 100644 test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol create mode 100644 test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol create mode 100644 test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol create mode 100644 test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol create mode 100644 test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol create mode 100644 test/libsolidity/semanticTests/array/delete_removes_bytes_data.sol create mode 100644 test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol create mode 100644 test/libsolidity/semanticTests/array/dynamic_multi_array_cleanup.sol create mode 100644 test/libsolidity/semanticTests/array/fixed_array_cleanup.sol create mode 100644 test/libsolidity/semanticTests/array/short_fixed_array_cleanup.sol create mode 100644 test/libsolidity/semanticTests/structs/struct_containing_bytes_copy_and_delete.sol diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 3072d2038..f8472d191 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -2593,25 +2593,6 @@ BOOST_AUTO_TEST_CASE(copying_bytes_multiassign) ABI_CHECK(callContractFunction("val()"), encodeArgs(0x80)); } -BOOST_AUTO_TEST_CASE(delete_removes_bytes_data) -{ - char const* sourceCode = R"( - contract c { - fallback() external { data = msg.data; } - function del() public returns (bool) { delete data; return true; } - bytes data; - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - compileAndRun(sourceCode); - ABI_CHECK(callContractFunction("---", 7), bytes()); - BOOST_CHECK(!storageEmpty(m_contractAddress)); - ABI_CHECK(callContractFunction("del()", 7), encodeArgs(true)); - BOOST_CHECK(storageEmpty(m_contractAddress)); - ); -} - BOOST_AUTO_TEST_CASE(copy_from_calldata_removes_bytes_data) { char const* sourceCode = R"( @@ -2633,83 +2614,6 @@ BOOST_AUTO_TEST_CASE(copy_from_calldata_removes_bytes_data) ); } -BOOST_AUTO_TEST_CASE(copy_removes_bytes_data) -{ - char const* sourceCode = R"( - 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; - } - )"; - compileAndRun(sourceCode); - ABI_CHECK(callContractFunction("set()", 1, 2, 3, 4, 5), encodeArgs(true)); - BOOST_CHECK(!storageEmpty(m_contractAddress)); - ABI_CHECK(callContractFunction("reset()"), encodeArgs(true)); - BOOST_CHECK(storageEmpty(m_contractAddress)); -} - -BOOST_AUTO_TEST_CASE(bytes_inside_mappings) -{ - char const* sourceCode = R"( - 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; - } - )"; - compileAndRun(sourceCode); - // store a short byte array at 1 and a longer one at 2 - ABI_CHECK(callContractFunction("set(uint256)", 1, 2), encodeArgs(true)); - ABI_CHECK(callContractFunction("set(uint256)", 2, 2, 3, 4, 5), encodeArgs(true)); - BOOST_CHECK(!storageEmpty(m_contractAddress)); - // copy shorter to longer - ABI_CHECK(callContractFunction("copy(uint256,uint256)", 1, 2), encodeArgs(true)); - BOOST_CHECK(!storageEmpty(m_contractAddress)); - // copy empty to both - ABI_CHECK(callContractFunction("copy(uint256,uint256)", 99, 1), encodeArgs(true)); - BOOST_CHECK(!storageEmpty(m_contractAddress)); - ABI_CHECK(callContractFunction("copy(uint256,uint256)", 99, 2), encodeArgs(true)); - BOOST_CHECK(storageEmpty(m_contractAddress)); -} - -BOOST_AUTO_TEST_CASE(struct_containing_bytes_copy_and_delete) -{ - char const* sourceCode = R"( - 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; - } - } - )"; - compileAndRun(sourceCode); - string data = "123456789012345678901234567890123"; - BOOST_CHECK(storageEmpty(m_contractAddress)); - ABI_CHECK(callContractFunction("set(uint256,bytes,uint256)", 12, 0x60, 13, u256(data.length()), data), encodeArgs(true)); - BOOST_CHECK(!storageEmpty(m_contractAddress)); - ABI_CHECK(callContractFunction("copy()"), encodeArgs(true)); - BOOST_CHECK(storageEmpty(m_contractAddress)); - ABI_CHECK(callContractFunction("set(uint256,bytes,uint256)", 12, 0x60, 13, u256(data.length()), data), encodeArgs(true)); - BOOST_CHECK(!storageEmpty(m_contractAddress)); - ABI_CHECK(callContractFunction("del()"), encodeArgs(true)); - BOOST_CHECK(storageEmpty(m_contractAddress)); -} - BOOST_AUTO_TEST_CASE(storing_invalid_boolean) { char const* sourceCode = R"( @@ -2894,197 +2798,6 @@ BOOST_AUTO_TEST_CASE(bytes_in_arguments) ); } -BOOST_AUTO_TEST_CASE(fixed_array_cleanup) -{ - char const* sourceCode = R"( - 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; } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - - compileAndRun(sourceCode); - BOOST_CHECK(storageEmpty(m_contractAddress)); - ABI_CHECK(callContractFunction("fill()"), bytes()); - BOOST_CHECK(!storageEmpty(m_contractAddress)); - ABI_CHECK(callContractFunction("clear()"), bytes()); - BOOST_CHECK(storageEmpty(m_contractAddress)); - ); -} - -BOOST_AUTO_TEST_CASE(short_fixed_array_cleanup) -{ - char const* sourceCode = R"( - 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; } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - - compileAndRun(sourceCode); - BOOST_CHECK(storageEmpty(m_contractAddress)); - ABI_CHECK(callContractFunction("fill()"), bytes()); - BOOST_CHECK(!storageEmpty(m_contractAddress)); - ABI_CHECK(callContractFunction("clear()"), bytes()); - BOOST_CHECK(storageEmpty(m_contractAddress)); - ); -} - -BOOST_AUTO_TEST_CASE(dynamic_array_cleanup) -{ - char const* sourceCode = R"( - 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; } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - - compileAndRun(sourceCode); - BOOST_CHECK(storageEmpty(m_contractAddress)); - ABI_CHECK(callContractFunction("fill()"), bytes()); - BOOST_CHECK(!storageEmpty(m_contractAddress)); - ABI_CHECK(callContractFunction("halfClear()"), bytes()); - BOOST_CHECK(!storageEmpty(m_contractAddress)); - ABI_CHECK(callContractFunction("fullClear()"), bytes()); - BOOST_CHECK(storageEmpty(m_contractAddress)); - ); -} - -BOOST_AUTO_TEST_CASE(dynamic_multi_array_cleanup) -{ - char const* sourceCode = R"( - 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; } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - - compileAndRun(sourceCode); - BOOST_CHECK(storageEmpty(m_contractAddress)); - ABI_CHECK(callContractFunction("fill()"), encodeArgs(8)); - BOOST_CHECK(!storageEmpty(m_contractAddress)); - ABI_CHECK(callContractFunction("clear()"), bytes()); - BOOST_CHECK(storageEmpty(m_contractAddress)); - ); -} - -BOOST_AUTO_TEST_CASE(array_copy_storage_storage_dyn_dyn) -{ - char const* sourceCode = R"( - 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]; - } - } - )"; - compileAndRun(sourceCode); - ABI_CHECK(callContractFunction("setData1(uint256,uint256,uint256)", 10, 5, 4), bytes()); - ABI_CHECK(callContractFunction("copyStorageStorage()"), bytes()); - ABI_CHECK(callContractFunction("getData2(uint256)", 5), encodeArgs(10, 4)); - ABI_CHECK(callContractFunction("setData1(uint256,uint256,uint256)", 0, 0, 0), bytes()); - ABI_CHECK(callContractFunction("copyStorageStorage()"), bytes()); - ABI_CHECK(callContractFunction("getData2(uint256)", 0), encodeArgs(0, 0)); - BOOST_CHECK(storageEmpty(m_contractAddress)); -} - -BOOST_AUTO_TEST_CASE(array_copy_target_leftover) -{ - // test that leftover elements in the last slot of target are correctly cleared during assignment - char const* sourceCode = R"( - 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; - } - } - )"; - compileAndRun(sourceCode); - ABI_CHECK(callContractFunction("test()"), encodeArgs(u256("0xffffffff"), asString(fromHex("0000000000000000000000000a00090008000700060005000400030002000100")), asString(fromHex("0000000000000000000000000000000000000000000000000000000000000000")))); -} - -BOOST_AUTO_TEST_CASE(array_copy_storage_storage_struct) -{ - char const* sourceCode = R"( - 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; - } - } - )"; - compileAndRun(sourceCode); - ABI_CHECK(callContractFunction("test()"), encodeArgs(4, 5)); - BOOST_CHECK(storageEmpty(m_contractAddress)); -} - BOOST_AUTO_TEST_CASE(array_copy_storage_abi) { // NOTE: This does not really test copying from storage to ABI directly, @@ -3141,117 +2854,6 @@ BOOST_AUTO_TEST_CASE(array_copy_storage_abi) ); } -BOOST_AUTO_TEST_CASE(array_pop_uint16_transition) -{ - char const* sourceCode = R"( - 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(); - } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - compileAndRun(sourceCode); - ABI_CHECK(callContractFunction("test()"), encodeArgs(38, 28, 18)); - BOOST_CHECK(storageEmpty(m_contractAddress)); - ); -} - -BOOST_AUTO_TEST_CASE(array_pop_uint24_transition) -{ - char const* sourceCode = R"( - 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(); - } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - compileAndRun(sourceCode); - ABI_CHECK(callContractFunction("test()"), encodeArgs(20, 10)); - BOOST_CHECK(storageEmpty(m_contractAddress)); - ); -} - -BOOST_AUTO_TEST_CASE(array_pop_array_transition) -{ - char const* sourceCode = R"( - 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; - } - } - )"; - compileAndRun(sourceCode); - ABI_CHECK(callContractFunction("test()"), encodeArgs(1, 2, 3)); - BOOST_CHECK(storageEmpty(m_contractAddress)); -} - -BOOST_AUTO_TEST_CASE(array_pop_storage_empty) -{ - char const* sourceCode = R"( - contract c { - uint[] data; - function test() public { - data.push(7); - data.pop(); - } - } - )"; - ALSO_VIA_YUL( - DISABLE_EWASM_TESTRUN() - compileAndRun(sourceCode); - ABI_CHECK(callContractFunction("test()"), encodeArgs()); - BOOST_CHECK(storageEmpty(m_contractAddress)); - ); -} - BOOST_AUTO_TEST_CASE(byte_array_pop_storage_empty) { char const* sourceCode = R"( diff --git a/test/libsolidity/semanticTests/array/array_pop_array_transition.sol b/test/libsolidity/semanticTests/array/array_pop_array_transition.sol new file mode 100644 index 000000000..d826dea30 --- /dev/null +++ b/test/libsolidity/semanticTests/array/array_pop_array_transition.sol @@ -0,0 +1,26 @@ +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; + } +} +// ---- +// test() -> 1, 2, 3 +// storage: empty diff --git a/test/libsolidity/semanticTests/array/array_pop_storage_empty.sol b/test/libsolidity/semanticTests/array/array_pop_storage_empty.sol new file mode 100644 index 000000000..24f210177 --- /dev/null +++ b/test/libsolidity/semanticTests/array/array_pop_storage_empty.sol @@ -0,0 +1,12 @@ +contract c { + uint[] data; + function test() public { + data.push(7); + data.pop(); + } +} +// ==== +// compileViaYul: also +// ---- +// test() -> +// storage: empty diff --git a/test/libsolidity/semanticTests/array/array_pop_uint16_transition.sol b/test/libsolidity/semanticTests/array/array_pop_uint16_transition.sol new file mode 100644 index 000000000..8cecac615 --- /dev/null +++ b/test/libsolidity/semanticTests/array/array_pop_uint16_transition.sol @@ -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 diff --git a/test/libsolidity/semanticTests/array/array_pop_uint24_transition.sol b/test/libsolidity/semanticTests/array/array_pop_uint24_transition.sol new file mode 100644 index 000000000..467774cc2 --- /dev/null +++ b/test/libsolidity/semanticTests/array/array_pop_uint24_transition.sol @@ -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 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol new file mode 100644 index 000000000..c183d8a82 --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol @@ -0,0 +1,22 @@ + +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]; + } +} +// ---- +// 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 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol new file mode 100644 index 000000000..5c53eaa77 --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol @@ -0,0 +1,20 @@ +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; + } +} +// ---- +// test() -> 4, 5 +// storage: empty diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol new file mode 100644 index 000000000..88d741654 --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol @@ -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 diff --git a/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol b/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol new file mode 100644 index 000000000..21b5e9c5d --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol @@ -0,0 +1,15 @@ +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; +} +// ---- +// 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 diff --git a/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol b/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol new file mode 100644 index 000000000..bb97ae2c1 --- /dev/null +++ b/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol @@ -0,0 +1,12 @@ + +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; +} +// ---- +// set(): 1, 2, 3, 4, 5 -> true +// storage: nonempty +// reset() -> true +// storage: empty diff --git a/test/libsolidity/semanticTests/array/delete_removes_bytes_data.sol b/test/libsolidity/semanticTests/array/delete_removes_bytes_data.sol new file mode 100644 index 000000000..28d6e5d8f --- /dev/null +++ b/test/libsolidity/semanticTests/array/delete_removes_bytes_data.sol @@ -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 diff --git a/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol b/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol new file mode 100644 index 000000000..07c3f63aa --- /dev/null +++ b/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol @@ -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 diff --git a/test/libsolidity/semanticTests/array/dynamic_multi_array_cleanup.sol b/test/libsolidity/semanticTests/array/dynamic_multi_array_cleanup.sol new file mode 100644 index 000000000..c58abad52 --- /dev/null +++ b/test/libsolidity/semanticTests/array/dynamic_multi_array_cleanup.sol @@ -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 diff --git a/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol b/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol new file mode 100644 index 000000000..9a6f35452 --- /dev/null +++ b/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol @@ -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 diff --git a/test/libsolidity/semanticTests/array/short_fixed_array_cleanup.sol b/test/libsolidity/semanticTests/array/short_fixed_array_cleanup.sol new file mode 100644 index 000000000..8909ed48e --- /dev/null +++ b/test/libsolidity/semanticTests/array/short_fixed_array_cleanup.sol @@ -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 diff --git a/test/libsolidity/semanticTests/structs/struct_containing_bytes_copy_and_delete.sol b/test/libsolidity/semanticTests/structs/struct_containing_bytes_copy_and_delete.sol new file mode 100644 index 000000000..c6e25f9d5 --- /dev/null +++ b/test/libsolidity/semanticTests/structs/struct_containing_bytes_copy_and_delete.sol @@ -0,0 +1,33 @@ +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]; + } +} +// ---- +// 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