Adjusts semantic tests to read-only array length.

This commit is contained in:
Erik Kundt 2019-09-18 15:38:38 +02:00
parent d05afb34d6
commit 7d6c0a50c2
11 changed files with 146 additions and 137 deletions

View File

@ -3,7 +3,8 @@ contract test {
mapping(uint => uint[]) public dynamicData; mapping(uint => uint[]) public dynamicData;
constructor() public { constructor() public {
data[2][2] = 8; data[2][2] = 8;
dynamicData[2].length = 3; for (uint i = 0; i < 3; i++)
dynamicData[2].push();
dynamicData[2][2] = 8; dynamicData[2][2] = 8;
} }
} }

View File

@ -7,13 +7,18 @@ contract test {
constructor() public { constructor() public {
data[0] = 8; data[0] = 8;
dynamicData.length = 3;
dynamicData[2] = 8; dynamicData.push();
smallTypeData.length = 128; dynamicData.push();
dynamicData.push(8);
smallTypeData = new uint24[](128);
smallTypeData[1] = 22; smallTypeData[1] = 22;
smallTypeData[127] = 2; smallTypeData[127] = 2;
multiple_map[2][1][2].a = 3; multiple_map[2][1][2].a = 3;
multiple_map[2][1][2].finalArray.length = 4; for (uint i = 0; i < 4; i++)
multiple_map[2][1][2].finalArray.push();
multiple_map[2][1][2].finalArray[3] = 5; multiple_map[2][1][2].finalArray[3] = 5;
} }
} }

View File

@ -2,16 +2,16 @@ contract C {
mapping (uint => uint)[][] a; mapping (uint => uint)[][] a;
function n1(uint key, uint value) public { function n1(uint key, uint value) public {
a.length++; a.push();
mapping (uint => uint)[] storage b = a[a.length - 1]; mapping (uint => uint)[] storage b = a[a.length - 1];
b.length++; b.push();
b[b.length - 1][key] = value; b[b.length - 1][key] = value;
} }
function n2() public { function n2() public {
a.length++; a.push();
mapping (uint => uint)[] storage b = a[a.length - 1]; mapping (uint => uint)[] storage b = a[a.length - 1];
b.length++; b.push();
} }
function map(uint key) public view returns (uint) { function map(uint key) public view returns (uint) {

View File

@ -2,12 +2,12 @@ contract C {
mapping (uint => uint)[] a; mapping (uint => uint)[] a;
function n1(uint key, uint value) public { function n1(uint key, uint value) public {
a.length++; a.push();
a[a.length - 1][key] = value; a[a.length - 1][key] = value;
} }
function n2() public { function n2() public {
a.length++; a.push();
} }
function map(uint key) public view returns (uint) { function map(uint key) public view returns (uint) {

View File

@ -20,8 +20,10 @@ contract Test {
storageA.m[1] = 2; storageA.m[1] = 2;
storageB.m[3] = 4; storageB.m[3] = 4;
storageB.x = 5; storageB.x = 5;
storageC.ma.length = 6; for (uint i = 0; i < 6; i++)
storageD.a.length = 7; storageC.ma.push();
for (uint i = 0; i < 7; i++)
storageD.a.push();
} }
function run() public returns (uint, uint, uint, uint, uint, uint) { function run() public returns (uint, uint, uint, uint, uint, uint) {
A memory memoryA = A(); A memory memoryA = A();

View File

@ -1,20 +1,25 @@
contract CopyTest { contract CopyTest {
struct Tree { struct Tree {
Tree[] children; Tree[] children;
} }
Tree storageTree;
constructor() public { Tree storageTree;
storageTree.children.length = 2; Tree[] children;
storageTree.children[0].children.length = 23;
storageTree.children[1].children.length = 42;
}
function run() public returns (uint256, uint256, uint256) { constructor() public {
Tree memory memoryTree; for (uint i = 0; i < 2; i++)
memoryTree = storageTree; storageTree.children.push();
return (memoryTree.children.length, memoryTree.children[0].children.length, memoryTree.children[1].children.length); for (uint i = 0; i < 23; i++)
} storageTree.children[0].children.push();
for (uint i = 0; i < 42; i++)
storageTree.children[1].children.push();
}
function run() public returns (uint256, uint256, uint256) {
Tree memory memoryTree;
memoryTree = storageTree;
return (memoryTree.children.length, memoryTree.children[0].children.length, memoryTree.children[1].children.length);
}
} }
// ---- // ----
// run() -> 2, 23, 42 // run() -> 2, 23, 42

View File

@ -1,46 +1,50 @@
contract CopyTest { contract CopyTest {
struct Tree { struct Tree {
uint256 data; uint256 data;
Tree[] children; Tree[] children;
} }
Tree storageTree; Tree storageTree;
Tree childStorageTree;
constructor() public { constructor() public {
storageTree.data = 0x42; storageTree.data = 0x42;
storageTree.children.length = 2; for (uint i = 0; i < 2; i++)
storageTree.children[0].data = 0x4200; storageTree.children.push(childStorageTree);
storageTree.children[1].data = 0x4201; storageTree.children[0].data = 0x4200;
storageTree.children[0].children.length = 3; storageTree.children[1].data = 0x4201;
for (uint i = 0; i < 3; i++) for (uint i = 0; i < 3; i++)
storageTree.children[0].children[i].data = 0x420000 + i; storageTree.children[0].children.push(childStorageTree);
storageTree.children[1].children.length = 4; for (uint i = 0; i < 3; i++)
for (uint i = 0; i < 4; i++) storageTree.children[0].children[i].data = 0x420000 + i;
storageTree.children[1].children[i].data = 0x420100 + i; for (uint i = 0; i < 4; i++)
} storageTree.children[1].children.push(childStorageTree);
for (uint i = 0; i < 4; i++)
storageTree.children[1].children[i].data = 0x420100 + i;
}
function countData(Tree memory tree) internal returns (uint256 c) { function countData(Tree memory tree) internal returns (uint256 c) {
c = 1; c = 1;
for (uint i = 0; i < tree.children.length; i++) { for (uint i = 0; i < tree.children.length; i++) {
c += countData(tree.children[i]); c += countData(tree.children[i]);
} }
} }
function copyFromTree(Tree memory tree, uint256[] memory data, uint256 offset) internal returns (uint256) { function copyFromTree(Tree memory tree, uint256[] memory data, uint256 offset) internal returns (uint256) {
data[offset++] = tree.data; data[offset++] = tree.data;
for (uint i = 0; i < tree.children.length; i++) { for (uint i = 0; i < tree.children.length; i++) {
offset = copyFromTree(tree.children[i], data, offset); offset = copyFromTree(tree.children[i], data, offset);
} }
return offset; return offset;
} }
function run() public returns (uint256[] memory) { function run() public returns (uint256[] memory) {
Tree memory memoryTree; Tree memory memoryTree;
memoryTree = storageTree; memoryTree = storageTree;
uint256 length = countData(memoryTree); uint256 length = countData(memoryTree);
uint256[] memory result = new uint256[](length); uint256[] memory result = new uint256[](length);
copyFromTree(memoryTree, result, 0); copyFromTree(memoryTree, result, 0);
return result; return result;
} }
} }
// ---- // ----
// run() -> 0x20, 10, 0x42, 0x4200, 0x420000, 0x420001, 0x420002, 0x4201, 0x420100, 0x420101, 0x420102, 0x420103 // run() -> 0x20, 10, 0x42, 0x4200, 0x420000, 0x420001, 0x420002, 0x4201, 0x420100, 0x420101, 0x420102, 0x420103

View File

@ -1,26 +1,23 @@
contract C { contract C {
uint[] storageArray; uint[] storageArray;
function test_indicies(uint256 len) public function test_indices(uint256 len) public
{ {
storageArray.length = len; storageArray = new uint[](len);
for (uint i = 0; i < len; i++)
storageArray[i] = i + 1;
for (uint i = 0; i < len; i++) for (uint i = 0; i < len; i++)
storageArray[i] = i + 1; require(storageArray[i] == i + 1);
}
for (uint i = 0; i < len; i++)
require(storageArray[i] == i + 1);
}
} }
// ====
// compileViaYul: true
// ---- // ----
// test_indicies(uint256): 1 -> // test_indices(uint256): 1 ->
// test_indicies(uint256): 129 -> // test_indices(uint256): 129 ->
// test_indicies(uint256): 5 -> // test_indices(uint256): 5 ->
// test_indicies(uint256): 10 -> // test_indices(uint256): 10 ->
// test_indicies(uint256): 15 -> // test_indices(uint256): 15 ->
// test_indicies(uint256): 0xFF -> // test_indices(uint256): 0xFF ->
// test_indicies(uint256): 1000 -> // test_indices(uint256): 1000 ->
// test_indicies(uint256): 129 -> // test_indices(uint256): 129 ->
// test_indicies(uint256): 128 -> // test_indices(uint256): 128 ->
// test_indicies(uint256): 1 -> // test_indices(uint256): 1 ->

View File

@ -1,14 +1,11 @@
contract C { contract C {
uint[] storageArray; uint[] storageArray;
function test_boundery_check(uint256 len, uint256 access) public returns function test_boundery_check(uint256 len, uint256 access) public returns (uint256)
(uint256) {
{ storageArray = new uint[](len);
storageArray.length = len; return storageArray[access];
return storageArray[access]; }
}
} }
// ====
// compileViaYul: true
// ---- // ----
// test_boundery_check(uint256, uint256): 10, 11 -> FAILURE // test_boundery_check(uint256, uint256): 10, 11 -> FAILURE
// test_boundery_check(uint256, uint256): 10, 9 -> 0 // test_boundery_check(uint256, uint256): 10, 9 -> 0

View File

@ -1,48 +1,46 @@
contract C { contract C {
uint[] storageArray; uint[] storageArray;
function test_zeroed_indicies(uint256 len) public function test_zeroed_indicies(uint256 len) public
{ {
storageArray.length = len; storageArray = new uint[](len);
for (uint i = 0; i < len; i++) for (uint i = 0; i < len; i++)
storageArray[i] = i + 1; storageArray[i] = i + 1;
if (len > 3) if (len > 3)
{ {
storageArray.length = 3; storageArray = new uint[](3);
for (uint i = 3; i < len; i++) for (uint i = 3; i < len; i++)
{ {
assembly { assembly {
mstore(0, storageArray_slot) mstore(0, storageArray_slot)
let pos := add(keccak256(0, 0x20), i) let pos := add(keccak256(0, 0x20), i)
if iszero(eq(sload(pos), 0)) { if iszero(eq(sload(pos), 0)) {
revert(0, 0) revert(0, 0)
} }
} }
} }
} }
storageArray.length = 0; storageArray = new uint[](0);
storageArray.length = len; storageArray = new uint[](len);
for (uint i = 0; i < len; i++) for (uint i = 0; i < len; i++)
{ {
require(storageArray[i] == 0); require(storageArray[i] == 0);
uint256 val = storageArray[i]; uint256 val = storageArray[i];
uint256 check; uint256 check;
assembly { check := iszero(val) } assembly { check := iszero(val) }
require(check == 1); require(check == 1);
} }
} }
} }
// ====
// compileViaYul: true
// ---- // ----
// test_zeroed_indicies(uint256): 1 -> // test_zeroed_indicies(uint256): 1 ->
// test_zeroed_indicies(uint256): 5 -> // test_zeroed_indicies(uint256): 5 ->

View File

@ -1,11 +1,10 @@
contract C { contract C {
uint[] storageArray; uint[] storageArray;
function set_get_length(uint256 len) public returns (uint256) function set_get_length(uint256 len) public returns (uint256)
{ {
storageArray.length = len; storageArray = new uint[](len);
return storageArray.length; return storageArray.length;
} }
} }
// ==== // ====
// compileViaYul: true // compileViaYul: true
@ -16,4 +15,5 @@ contract C {
// set_get_length(uint256): 20 -> 20 // set_get_length(uint256): 20 -> 20
// set_get_length(uint256): 0 -> 0 // set_get_length(uint256): 0 -> 0
// set_get_length(uint256): 0xFF -> 0xFF // set_get_length(uint256): 0xFF -> 0xFF
// set_get_length(uint256): 0xFFFF -> 0xFFFF // set_get_length(uint256): 0xFFF -> 0xFFF
// set_get_length(uint256): 0xFFFF -> FAILURE # Out-of-gas #