Merge pull request #7063 from ethereum/EndToEndTest-extractions-2

Extracting more end-to-end tests.
This commit is contained in:
chriseth 2019-07-08 16:15:22 +02:00 committed by GitHub
commit 04bad01ab1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 452 additions and 641 deletions

View File

@ -126,40 +126,6 @@ BOOST_AUTO_TEST_CASE(recursive_calls)
)
}
BOOST_AUTO_TEST_CASE(multiple_functions)
{
char const* sourceCode = R"(
contract test {
function a() public returns(uint n) { return 0; }
function b() public returns(uint n) { return 1; }
function c() public returns(uint n) { return 2; }
function f() public returns(uint n) { return 3; }
}
)";
ALSO_VIA_YUL(
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("a()", bytes()), toBigEndian(u256(0)));
ABI_CHECK(callContractFunction("b()", bytes()), toBigEndian(u256(1)));
ABI_CHECK(callContractFunction("c()", bytes()), toBigEndian(u256(2)));
ABI_CHECK(callContractFunction("f()", bytes()), toBigEndian(u256(3)));
ABI_CHECK(callContractFunction("i_am_not_there()", bytes()), bytes());
)
}
BOOST_AUTO_TEST_CASE(disorder_named_args)
{
char const* sourceCode = R"(
contract test {
function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }
function b() public returns (uint r) { r = a({c: 3, a: 1, b: 2}); }
}
)";
ALSO_VIA_YUL(
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("b()", bytes()), toBigEndian(u256(123)));
)
}
BOOST_AUTO_TEST_CASE(while_loop)
{
char const* sourceCode = R"(
@ -220,68 +186,6 @@ BOOST_AUTO_TEST_CASE(do_while_loop)
)
}
BOOST_AUTO_TEST_CASE(do_while_loop_continue)
{
char const* sourceCode = R"(
contract test {
function f() public pure returns(uint r) {
uint i = 0;
do
{
if (i > 0) return 0;
i++;
continue;
} while (false);
return 42;
}
}
)";
ALSO_VIA_YUL(
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("f()"), encodeArgs(42));
)
}
BOOST_AUTO_TEST_CASE(array_multiple_local_vars)
{
char const* sourceCode = R"(
contract test {
function f(uint256[] calldata seq) external pure returns (uint256) {
uint i = 0;
uint sum = 0;
while (i < seq.length)
{
uint idx = i;
if (idx >= 10) break;
uint x = seq[idx];
if (x >= 1000) {
uint n = i + 1;
i = n;
continue;
}
else {
uint y = sum + x;
sum = y;
}
if (sum >= 500) return sum;
i++;
}
return sum;
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("f(uint256[])", 32, 3, u256(1000), u256(1), u256(2)), encodeArgs(3));
ABI_CHECK(callContractFunction("f(uint256[])", 32, 3, u256(100), u256(500), u256(300)), encodeArgs(600));
ABI_CHECK(callContractFunction(
"f(uint256[])", 32, 11,
u256(1), u256(2), u256(3), u256(4), u256(5), u256(6), u256(7), u256(8), u256(9), u256(10), u256(111)
), encodeArgs(55));
}
BOOST_AUTO_TEST_CASE(do_while_loop_multiple_local_vars)
{
char const* sourceCode = R"(
@ -773,58 +677,6 @@ BOOST_AUTO_TEST_CASE(many_local_variables)
)
}
BOOST_AUTO_TEST_CASE(packing_unpacking_types)
{
char const* sourceCode = R"(
contract test {
function run(bool a, uint32 b, uint64 c) public returns(uint256 y) {
if (a) y = 1;
y = y * 0x100000000 | ~b;
y = y * 0x10000000000000000 | ~c;
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(
callContractFunction("run(bool,uint32,uint64)", true, fromHex("0f0f0f0f"), fromHex("f0f0f0f0f0f0f0f0")),
fromHex("00000000000000000000000000000000000000""01""f0f0f0f0""0f0f0f0f0f0f0f0f")
);
}
BOOST_AUTO_TEST_CASE(packing_signed_types)
{
char const* sourceCode = R"(
contract test {
function run() public returns(int8 y) {
uint8 x = 0xfa;
return int8(x);
}
}
)";
ALSO_VIA_YUL(
compileAndRun(sourceCode);
ABI_CHECK(
callContractFunction("run()"),
fromHex("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa")
);
)
}
BOOST_AUTO_TEST_CASE(multiple_return_values)
{
char const* sourceCode = R"(
contract test {
function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {
y1 = x2; y2 = x1;
}
}
)";
ALSO_VIA_YUL(
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("run(bool,uint256)", true, 0xcd), encodeArgs(0xcd, true, 0));
)
}
BOOST_AUTO_TEST_CASE(short_circuiting)
{
char const* sourceCode = R"(
@ -952,76 +804,6 @@ BOOST_AUTO_TEST_CASE(strings)
)
}
BOOST_AUTO_TEST_CASE(inc_dec_operators)
{
char const* sourceCode = R"(
contract test {
uint8 x;
uint v;
function f() public returns (uint r) {
uint a = 6;
r = a;
r += (a++) * 0x10;
r += (++a) * 0x100;
v = 3;
r += (v++) * 0x1000;
r += (++v) * 0x10000;
}
}
)";
ALSO_VIA_YUL(
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("f()"), encodeArgs(0x53866));
)
}
BOOST_AUTO_TEST_CASE(bytes_comparison)
{
char const* sourceCode = R"(
contract test {
function f() public returns (bool) {
bytes2 a = "a";
bytes2 x = "aa";
bytes2 b = "b";
return a < x && x < b;
}
}
)";
ALSO_VIA_YUL(
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("f()"), encodeArgs(true));
)
}
BOOST_AUTO_TEST_CASE(state_smoke_test)
{
char const* sourceCode = R"(
contract test {
uint256 value1;
uint256 value2;
function get(uint8 which) public returns (uint256 value) {
if (which == 0) return value1;
else return value2;
}
function set(uint8 which, uint256 value) public {
if (which == 0) value1 = value;
else value2 = value;
}
}
)";
ALSO_VIA_YUL(
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x00)), encodeArgs(0));
ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x01)), encodeArgs(0));
ABI_CHECK(callContractFunction("set(uint8,uint256)", uint8_t(0x00), 0x1234), encodeArgs());
ABI_CHECK(callContractFunction("set(uint8,uint256)", uint8_t(0x01), 0x8765), encodeArgs());
ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x00)), encodeArgs(0x1234));
ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x01)), encodeArgs(0x8765));
ABI_CHECK(callContractFunction("set(uint8,uint256)", uint8_t(0x00), 0x3), encodeArgs());
ABI_CHECK(callContractFunction("get(uint8)", uint8_t(0x00)), encodeArgs(0x3));
)
}
BOOST_AUTO_TEST_CASE(compound_assign)
{
char const* sourceCode = R"(
@ -1247,320 +1029,6 @@ BOOST_AUTO_TEST_CASE(multi_level_mapping)
)
}
BOOST_AUTO_TEST_CASE(mapping_local_assignment)
{
char const* sourceCode = R"(
contract test {
mapping(uint8 => uint8) m1;
mapping(uint8 => uint8) m2;
function f() public returns (uint8, uint8, uint8, uint8) {
mapping(uint8 => uint8) storage m = m1;
m[1] = 42;
m = m2;
m[2] = 21;
return (m1[1], m1[2], m2[1], m2[2]);
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("f()"), encodeArgs(uint8_t(42), uint8_t(0), uint8_t(0), uint8_t(21)));
}
BOOST_AUTO_TEST_CASE(mapping_local_tuple_assignment)
{
char const* sourceCode = R"(
contract test {
mapping(uint8 => uint8) m1;
mapping(uint8 => uint8) m2;
function f() public returns (uint8, uint8, uint8, uint8) {
mapping(uint8 => uint8) storage m = m1;
m[1] = 42;
uint8 v;
(m, v) = (m2, 21);
m[2] = v;
return (m1[1], m1[2], m2[1], m2[2]);
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("f()"), encodeArgs(uint8_t(42), uint8_t(0), uint8_t(0), uint8_t(21)));
}
BOOST_AUTO_TEST_CASE(mapping_local_compound_assignment)
{
char const* sourceCode = R"(
contract test {
mapping(uint8 => uint8) m1;
mapping(uint8 => uint8) m2;
function f() public returns (uint8, uint8, uint8, uint8) {
mapping(uint8 => uint8) storage m = m1;
m[1] = 42;
(m = m2)[2] = 21;
return (m1[1], m1[2], m2[1], m2[2]);
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("f()"), encodeArgs(uint8_t(42), uint8_t(0), uint8_t(0), uint8_t(21)));
}
BOOST_AUTO_TEST_CASE(mapping_internal_argument)
{
char const* sourceCode = R"(
contract test {
mapping(uint8 => uint8) a;
mapping(uint8 => uint8) b;
function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {
uint8 oldValue = m[key];
m[key] = value;
return oldValue;
}
function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {
old_a = set_internal(a, key, value_a);
old_b = set_internal(b, key, value_b);
}
function get(uint8 key) public returns (uint8, uint8) {
return (a[key], b[key]);
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("set(uint8,uint8,uint8)", uint8_t(1), uint8_t(21), uint8_t(42)), encodeArgs(uint8_t(0), uint8_t(0)));
ABI_CHECK(callContractFunction("get(uint8)", uint8_t(1)), encodeArgs(uint8_t(21), uint8_t(42)));
ABI_CHECK(callContractFunction("set(uint8,uint8,uint8)", uint8_t(1), uint8_t(10), uint8_t(11)), encodeArgs(uint8_t(21), uint8_t(42)));
ABI_CHECK(callContractFunction("get(uint8)", uint8_t(1)), encodeArgs(uint8_t(10), uint8_t(11)));
}
BOOST_AUTO_TEST_CASE(mapping_array_internal_argument)
{
char const* sourceCode = R"(
contract test {
mapping(uint8 => uint8)[2] a;
mapping(uint8 => uint8)[2] b;
function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {
uint8 oldValue1 = m[0][key];
uint8 oldValue2 = m[1][key];
m[0][key] = value1;
m[1][key] = value2;
return (oldValue1, oldValue2);
}
function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {
(old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);
(old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);
}
function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {
return (a[0][key], a[1][key], b[0][key], b[1][key]);
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("set(uint8,uint8,uint8,uint8,uint8)", uint8_t(1), uint8_t(21), uint8_t(22), uint8_t(42), uint8_t(43)), encodeArgs(uint8_t(0), uint8_t(0), uint8_t(0), uint8_t(0)));
ABI_CHECK(callContractFunction("get(uint8)", uint8_t(1)), encodeArgs(uint8_t(21), uint8_t(22), uint8_t(42), uint8_t(43)));
ABI_CHECK(callContractFunction("set(uint8,uint8,uint8,uint8,uint8)", uint8_t(1), uint8_t(10), uint8_t(30), uint8_t(11), uint8_t(31)), encodeArgs(uint8_t(21), uint8_t(22), uint8_t(42), uint8_t(43)));
ABI_CHECK(callContractFunction("get(uint8)", uint8_t(1)), encodeArgs(uint8_t(10), uint8_t(30), uint8_t(11), uint8_t(31)));
}
BOOST_AUTO_TEST_CASE(mapping_internal_return)
{
char const* sourceCode = R"(
contract test {
mapping(uint8 => uint8) a;
mapping(uint8 => uint8) b;
function f() internal returns (mapping(uint8 => uint8) storage r) {
r = a;
r[1] = 42;
r = b;
r[1] = 84;
}
function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {
f()[2] = 21;
return (a[0], a[1], a[2], b[0], b[1], b[2]);
}
function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {
mapping(uint8 => uint8) storage m = f();
m[2] = 17;
return (a[0], a[1], a[2], b[0], b[1], b[2]);
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("g()"), encodeArgs(uint8_t(0), uint8_t(42), uint8_t(0), uint8_t(0), uint8_t(84), uint8_t (21)));
ABI_CHECK(callContractFunction("h()"), encodeArgs(uint8_t(0), uint8_t(42), uint8_t(0), uint8_t(0), uint8_t(84), uint8_t (17)));
}
BOOST_AUTO_TEST_CASE(structs)
{
char const* sourceCode = R"(
contract test {
struct s1 {
uint8 x;
bool y;
}
struct s2 {
uint32 z;
s1 s1data;
mapping(uint8 => s2) recursive;
}
s2 data;
function check() public returns (bool ok) {
return data.z == 1 && data.s1data.x == 2 &&
data.s1data.y == true &&
data.recursive[3].recursive[4].z == 5 &&
data.recursive[4].recursive[3].z == 6 &&
data.recursive[0].s1data.y == false &&
data.recursive[4].z == 9;
}
function set() public {
data.z = 1;
data.s1data.x = 2;
data.s1data.y = true;
data.recursive[3].recursive[4].z = 5;
data.recursive[4].recursive[3].z = 6;
data.recursive[0].s1data.y = false;
data.recursive[4].z = 9;
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("check()"), encodeArgs(false));
ABI_CHECK(callContractFunction("set()"), bytes());
ABI_CHECK(callContractFunction("check()"), encodeArgs(true));
}
BOOST_AUTO_TEST_CASE(struct_reference)
{
char const* sourceCode = R"(
contract test {
struct s2 {
uint32 z;
mapping(uint8 => s2) recursive;
}
s2 data;
function check() public returns (bool ok) {
return data.z == 2 &&
data.recursive[0].z == 3 &&
data.recursive[0].recursive[1].z == 0 &&
data.recursive[0].recursive[0].z == 1;
}
function set() public {
data.z = 2;
mapping(uint8 => s2) storage map = data.recursive;
s2 storage inner = map[0];
inner.z = 3;
inner.recursive[0].z = inner.recursive[1].z + 1;
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("check()"), encodeArgs(false));
ABI_CHECK(callContractFunction("set()"), bytes());
ABI_CHECK(callContractFunction("check()"), encodeArgs(true));
}
BOOST_AUTO_TEST_CASE(deleteStruct)
{
char const* sourceCode = R"(
contract test {
struct topStruct {
nestedStruct nstr;
uint topValue;
mapping (uint => uint) topMapping;
}
uint toDelete;
topStruct str;
struct nestedStruct {
uint nestedValue;
mapping (uint => bool) nestedMapping;
}
constructor() public {
toDelete = 5;
str.topValue = 1;
str.topMapping[0] = 1;
str.topMapping[1] = 2;
str.nstr.nestedValue = 2;
str.nstr.nestedMapping[0] = true;
str.nstr.nestedMapping[1] = false;
delete str;
delete toDelete;
}
function getToDelete() public returns (uint res){
res = toDelete;
}
function getTopValue() public returns(uint topValue){
topValue = str.topValue;
}
function getNestedValue() public returns(uint nestedValue){
nestedValue = str.nstr.nestedValue;
}
function getTopMapping(uint index) public returns(uint ret) {
ret = str.topMapping[index];
}
function getNestedMapping(uint index) public returns(bool ret) {
return str.nstr.nestedMapping[index];
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("getToDelete()"), encodeArgs(0));
ABI_CHECK(callContractFunction("getTopValue()"), encodeArgs(0));
ABI_CHECK(callContractFunction("getNestedValue()"), encodeArgs(0));
// mapping values should be the same
ABI_CHECK(callContractFunction("getTopMapping(uint256)", 0), encodeArgs(1));
ABI_CHECK(callContractFunction("getTopMapping(uint256)", 1), encodeArgs(2));
ABI_CHECK(callContractFunction("getNestedMapping(uint256)", 0), encodeArgs(true));
ABI_CHECK(callContractFunction("getNestedMapping(uint256)", 1), encodeArgs(false));
}
BOOST_AUTO_TEST_CASE(deleteLocal)
{
char const* sourceCode = R"(
contract test {
function delLocal() public returns (uint res){
uint v = 5;
delete v;
res = v;
}
}
)";
ALSO_VIA_YUL(
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("delLocal()"), encodeArgs(0));
)
}
BOOST_AUTO_TEST_CASE(deleteLocals)
{
char const* sourceCode = R"(
contract test {
function delLocal() public returns (uint res1, uint res2){
uint v = 5;
uint w = 6;
uint x = 7;
delete v;
res1 = w;
res2 = x;
}
}
)";
ALSO_VIA_YUL(
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("delLocal()"), encodeArgs(6, 7));
)
}
BOOST_AUTO_TEST_CASE(deleteLength)
{
char const* sourceCode = R"(
@ -1609,74 +1077,6 @@ BOOST_AUTO_TEST_CASE(constructor)
)
}
BOOST_AUTO_TEST_CASE(simple_accessor)
{
char const* sourceCode = R"(
contract test {
uint256 public data;
constructor() public {
data = 8;
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("data()"), encodeArgs(8));
}
BOOST_AUTO_TEST_CASE(array_accessor)
{
char const* sourceCode = R"(
contract test {
uint[8] public data;
uint[] public dynamicData;
uint24[] public smallTypeData;
struct st { uint a; uint[] finalArray; }
mapping(uint256 => mapping(uint256 => st[5])) public multiple_map;
constructor() public {
data[0] = 8;
dynamicData.length = 3;
dynamicData[2] = 8;
smallTypeData.length = 128;
smallTypeData[1] = 22;
smallTypeData[127] = 2;
multiple_map[2][1][2].a = 3;
multiple_map[2][1][2].finalArray.length = 4;
multiple_map[2][1][2].finalArray[3] = 5;
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("data(uint256)", 0), encodeArgs(8));
ABI_CHECK(callContractFunction("data(uint256)", 8), encodeArgs());
ABI_CHECK(callContractFunction("dynamicData(uint256)", 2), encodeArgs(8));
ABI_CHECK(callContractFunction("dynamicData(uint256)", 8), encodeArgs());
ABI_CHECK(callContractFunction("smallTypeData(uint256)", 1), encodeArgs(22));
ABI_CHECK(callContractFunction("smallTypeData(uint256)", 127), encodeArgs(2));
ABI_CHECK(callContractFunction("smallTypeData(uint256)", 128), encodeArgs());
ABI_CHECK(callContractFunction("multiple_map(uint256,uint256,uint256)", 2, 1, 2), encodeArgs(3));
}
BOOST_AUTO_TEST_CASE(accessors_mapping_for_array)
{
char const* sourceCode = R"(
contract test {
mapping(uint => uint[8]) public data;
mapping(uint => uint[]) public dynamicData;
constructor() public {
data[2][2] = 8;
dynamicData[2].length = 3;
dynamicData[2][2] = 8;
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("data(uint256,uint256)", 2, 2), encodeArgs(8));
ABI_CHECK(callContractFunction("data(uint256, 256)", 2, 8), encodeArgs());
ABI_CHECK(callContractFunction("dynamicData(uint256,uint256)", 2, 2), encodeArgs(8));
ABI_CHECK(callContractFunction("dynamicData(uint256,uint256)", 2, 8), encodeArgs());
}
BOOST_AUTO_TEST_CASE(multiple_elementary_accessors)
{
char const* sourceCode = R"(
@ -1703,47 +1103,6 @@ BOOST_AUTO_TEST_CASE(multiple_elementary_accessors)
ABI_CHECK(callContractFunction("super_secret_data()"), bytes());
}
BOOST_AUTO_TEST_CASE(complex_accessors)
{
char const* sourceCode = R"(
contract test {
mapping(uint256 => bytes4) public to_string_map;
mapping(uint256 => bool) public to_bool_map;
mapping(uint256 => uint256) public to_uint_map;
mapping(uint256 => mapping(uint256 => uint256)) public to_multiple_map;
constructor() public {
to_string_map[42] = "24";
to_bool_map[42] = false;
to_uint_map[42] = 12;
to_multiple_map[42][23] = 31;
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("to_string_map(uint256)", 42), encodeArgs("24"));
ABI_CHECK(callContractFunction("to_bool_map(uint256)", 42), encodeArgs(false));
ABI_CHECK(callContractFunction("to_uint_map(uint256)", 42), encodeArgs(12));
ABI_CHECK(callContractFunction("to_multiple_map(uint256,uint256)", 42, 23), encodeArgs(31));
}
BOOST_AUTO_TEST_CASE(struct_accessor)
{
char const* sourceCode = R"(
contract test {
struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }
mapping(uint => Data) public data;
constructor() public {
data[7].a = 1;
data[7].b = 2;
data[7].c[0] = 3;
data[7].d = true;
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("data(uint256)", 7), encodeArgs(1, 2, true));
}
BOOST_AUTO_TEST_CASE(balance)
{
char const* sourceCode = R"(

View File

@ -0,0 +1,12 @@
contract test {
function f() public returns (bool) {
bytes2 a = "a";
bytes2 x = "aa";
bytes2 b = "b";
return a < x && x < b;
}
}
// ====
// compileViaYul: also
// ----
// f() -> true

View File

@ -0,0 +1,17 @@
contract test {
uint8 x;
uint v;
function f() public returns (uint r) {
uint a = 6;
r = a;
r += (a++) * 0x10;
r += (++a) * 0x100;
v = 3;
r += (v++) * 0x1000;
r += (++v) * 0x10000;
}
}
// ====
// compileViaYul: also
// ----
// f() -> 0x053866

View File

@ -0,0 +1,28 @@
contract test {
function f(uint256[] calldata seq) external pure returns (uint256) {
uint i = 0;
uint sum = 0;
while (i < seq.length)
{
uint idx = i;
if (idx >= 10) break;
uint x = seq[idx];
if (x >= 1000) {
uint n = i + 1;
i = n;
continue;
}
else {
uint y = sum + x;
sum = y;
}
if (sum >= 500) return sum;
i++;
}
return sum;
}
}
// ----
// f(uint256[]): 32, 3, 1000, 1, 2 -> 3
// f(uint256[]): 32, 3, 100, 500, 300 -> 600
// f(uint256[]): 32, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 111 -> 55

View File

@ -0,0 +1,8 @@
contract test {
function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }
function b() public returns (uint r) { r = a({c: 3, a: 1, b: 2}); }
}
// ====
// compileViaYul: also
// ----
// b() -> 123

View File

@ -0,0 +1,23 @@
contract test {
mapping(uint8 => uint8)[2] a;
mapping(uint8 => uint8)[2] b;
function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {
uint8 oldValue1 = m[0][key];
uint8 oldValue2 = m[1][key];
m[0][key] = value1;
m[1][key] = value2;
return (oldValue1, oldValue2);
}
function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {
(old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);
(old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);
}
function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {
return (a[0][key], a[1][key], b[0][key], b[1][key]);
}
}
// ----
// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0
// get(uint8): 1 -> 21, 22, 42, 43
// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43
// get(uint8): 1 -> 10, 30, 11, 31

View File

@ -0,0 +1,21 @@
contract test {
mapping(uint8 => uint8) a;
mapping(uint8 => uint8) b;
function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {
uint8 oldValue = m[key];
m[key] = value;
return oldValue;
}
function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {
old_a = set_internal(a, key, value_a);
old_b = set_internal(b, key, value_b);
}
function get(uint8 key) public returns (uint8, uint8) {
return (a[key], b[key]);
}
}
// ----
// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0
// get(uint8): 1 -> 21, 42
// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42
// get(uint8): 1 -> 10, 11

View File

@ -0,0 +1,22 @@
contract test {
mapping(uint8 => uint8) a;
mapping(uint8 => uint8) b;
function f() internal returns (mapping(uint8 => uint8) storage r) {
r = a;
r[1] = 42;
r = b;
r[1] = 84;
}
function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {
f()[2] = 21;
return (a[0], a[1], a[2], b[0], b[1], b[2]);
}
function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {
mapping(uint8 => uint8) storage m = f();
m[2] = 17;
return (a[0], a[1], a[2], b[0], b[1], b[2]);
}
}
// ----
// g() -> 0, 42, 0, 0, 84, 21
// h() -> 0, 42, 0, 0, 84, 17

View File

@ -0,0 +1,9 @@
contract test {
function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {
y1 = x2; y2 = x1;
}
}
// ====
// compileViaYul: also
// ----
// run(bool,uint256): true, 0xcd -> 0xcd, true, 0

View File

@ -0,0 +1,16 @@
contract test {
function f() public pure returns(uint r) {
uint i = 0;
do
{
if (i > 0) return 0;
i++;
continue;
} while (false);
return 42;
}
}
// ====
// compileViaYul: also
// ----
// f() -> 42

View File

@ -0,0 +1,14 @@
contract test {
mapping(uint => uint[8]) public data;
mapping(uint => uint[]) public dynamicData;
constructor() public {
data[2][2] = 8;
dynamicData[2].length = 3;
dynamicData[2][2] = 8;
}
}
// ----
// data(uint256,uint256): 2, 2 -> 8
// data(uint256,uint256): 2, 8 -> FAILURE # NB: the original code contained a bug here #
// dynamicData(uint256,uint256): 2, 2 -> 8
// dynamicData(uint256,uint256): 2, 8 -> FAILURE

View File

@ -0,0 +1,28 @@
contract test {
uint[8] public data;
uint[] public dynamicData;
uint24[] public smallTypeData;
struct st { uint a; uint[] finalArray; }
mapping(uint256 => mapping(uint256 => st[5])) public multiple_map;
constructor() public {
data[0] = 8;
dynamicData.length = 3;
dynamicData[2] = 8;
smallTypeData.length = 128;
smallTypeData[1] = 22;
smallTypeData[127] = 2;
multiple_map[2][1][2].a = 3;
multiple_map[2][1][2].finalArray.length = 4;
multiple_map[2][1][2].finalArray[3] = 5;
}
}
// ----
// data(uint256): 0 -> 8
// data(uint256): 8 -> FAILURE
// dynamicData(uint256): 2 -> 8
// dynamicData(uint256): 8 -> FAILURE
// smallTypeData(uint256): 1 -> 22
// smallTypeData(uint256): 127 -> 2
// smallTypeData(uint256): 128 -> FAILURE
// multiple_map(uint256,uint256,uint256): 2, 1, 2 -> 3

View File

@ -0,0 +1,17 @@
contract test {
mapping(uint256 => bytes4) public to_string_map;
mapping(uint256 => bool) public to_bool_map;
mapping(uint256 => uint256) public to_uint_map;
mapping(uint256 => mapping(uint256 => uint256)) public to_multiple_map;
constructor() public {
to_string_map[42] = "24";
to_bool_map[42] = false;
to_uint_map[42] = 12;
to_multiple_map[42][23] = 31;
}
}
// ----
// to_string_map(uint256): 42 -> "24"
// to_bool_map(uint256): 42 -> false
// to_uint_map(uint256): 42 -> 12
// to_multiple_map(uint256,uint256): 42, 23 -> 31

View File

@ -0,0 +1,8 @@
contract test {
uint256 public data;
constructor() public {
data = 8;
}
}
// ----
// data() -> 8

View File

@ -0,0 +1,23 @@
contract test {
uint256 value1;
uint256 value2;
function get(uint8 which) public returns (uint256 value) {
if (which == 0) return value1;
else return value2;
}
function set(uint8 which, uint256 value) public {
if (which == 0) value1 = value;
else value2 = value;
}
}
// ====
// compileViaYul: also
// ----
// get(uint8): 0x00 -> 0
// get(uint8): 0x01 -> 0
// set(uint8,uint256): 0x00, 0x1234 ->
// set(uint8,uint256): 0x01, 0x8765 ->
// get(uint8): 0x00 -> 0x1234
// get(uint8): 0x01 -> 0x8765
// set(uint8,uint256): 0x00, 0x03 ->
// get(uint8): 0x00 -> 0x03

View File

@ -0,0 +1,12 @@
contract test {
struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }
mapping(uint => Data) public data;
constructor() public {
data[7].a = 1;
data[7].b = 2;
data[7].c[0] = 3;
data[7].d = true;
}
}
// ----
// data(uint256): 7 -> 1, 2, true

View File

@ -0,0 +1,49 @@
contract test {
struct topStruct {
nestedStruct nstr;
uint topValue;
mapping (uint => uint) topMapping;
}
uint toDelete;
topStruct str;
struct nestedStruct {
uint nestedValue;
mapping (uint => bool) nestedMapping;
}
constructor() public {
toDelete = 5;
str.topValue = 1;
str.topMapping[0] = 1;
str.topMapping[1] = 2;
str.nstr.nestedValue = 2;
str.nstr.nestedMapping[0] = true;
str.nstr.nestedMapping[1] = false;
delete str;
delete toDelete;
}
function getToDelete() public returns (uint res){
res = toDelete;
}
function getTopValue() public returns(uint topValue){
topValue = str.topValue;
}
function getNestedValue() public returns(uint nestedValue){
nestedValue = str.nstr.nestedValue;
}
function getTopMapping(uint index) public returns(uint ret) {
ret = str.topMapping[index];
}
function getNestedMapping(uint index) public returns(bool ret) {
return str.nstr.nestedMapping[index];
}
}
// ----
// getToDelete() -> 0
// getTopValue() -> 0
// getNestedValue() -> 0
// #mapping values should be the same#
// getTopMapping(uint256): 0 -> 1
// getTopMapping(uint256): 1 -> 2
// getNestedMapping(uint256): 0 -> true
// getNestedMapping(uint256): 1 -> false

View File

@ -0,0 +1,24 @@
contract test {
struct s2 {
uint32 z;
mapping(uint8 => s2) recursive;
}
s2 data;
function check() public returns (bool ok) {
return data.z == 2 &&
data.recursive[0].z == 3 &&
data.recursive[0].recursive[1].z == 0 &&
data.recursive[0].recursive[0].z == 1;
}
function set() public {
data.z = 2;
mapping(uint8 => s2) storage map = data.recursive;
s2 storage inner = map[0];
inner.z = 3;
inner.recursive[0].z = inner.recursive[1].z + 1;
}
}
// ----
// check() -> false
// set() ->
// check() -> true

View File

@ -0,0 +1,33 @@
contract test {
struct s1 {
uint8 x;
bool y;
}
struct s2 {
uint32 z;
s1 s1data;
mapping(uint8 => s2) recursive;
}
s2 data;
function check() public returns (bool ok) {
return data.z == 1 && data.s1data.x == 2 &&
data.s1data.y == true &&
data.recursive[3].recursive[4].z == 5 &&
data.recursive[4].recursive[3].z == 6 &&
data.recursive[0].s1data.y == false &&
data.recursive[4].z == 9;
}
function set() public {
data.z = 1;
data.s1data.x = 2;
data.s1data.y = true;
data.recursive[3].recursive[4].z = 5;
data.recursive[4].recursive[3].z = 6;
data.recursive[0].s1data.y = false;
data.recursive[4].z = 9;
}
}
// ----
// check() -> false
// set() ->
// check() -> true

View File

@ -0,0 +1,8 @@
contract test {
function run() public returns(int8 y) {
uint8 x = 0xfa;
return int8(x);
}
}
// ----
// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa

View File

@ -0,0 +1,10 @@
contract test {
function run(bool a, uint32 b, uint64 c) public returns(uint256 y) {
if (a) y = 1;
y = y * 0x100000000 | ~b;
y = y * 0x10000000000000000 | ~c;
}
}
// ----
// run(bool,uint32,uint64): true, 0x0f0f0f0f, 0xf0f0f0f0f0f0f0f0
// -> 0x0000000000000000000000000000000000000001f0f0f0f00f0f0f0f0f0f0f0f

View File

@ -0,0 +1,11 @@
contract test {
function delLocal() public returns (uint res){
uint v = 5;
delete v;
res = v;
}
}
// ====
// compileViaYul: also
// ----
// delLocal() -> 0

View File

@ -0,0 +1,14 @@
contract test {
function delLocal() public returns (uint res1, uint res2){
uint v = 5;
uint w = 6;
uint x = 7;
delete v;
res1 = w;
res2 = x;
}
}
// ====
// compileViaYul: also
// ----
// delLocal() -> 6, 7

View File

@ -0,0 +1,15 @@
contract test {
mapping(uint8 => uint8) m1;
mapping(uint8 => uint8) m2;
function f() public returns (uint8, uint8, uint8, uint8) {
mapping(uint8 => uint8) storage m = m1;
m[1] = 42;
m = m2;
m[2] = 21;
return (m1[1], m1[2], m2[1], m2[2]);
}
}
// ----
// f() -> 42, 0, 0, 21

View File

@ -0,0 +1,14 @@
contract test {
mapping(uint8 => uint8) m1;
mapping(uint8 => uint8) m2;
function f() public returns (uint8, uint8, uint8, uint8) {
mapping(uint8 => uint8) storage m = m1;
m[1] = 42;
(m = m2)[2] = 21;
return (m1[1], m1[2], m2[1], m2[2]);
}
}
// ----
// f() -> 42, 0, 0, 21

View File

@ -0,0 +1,16 @@
contract test {
mapping(uint8 => uint8) m1;
mapping(uint8 => uint8) m2;
function f() public returns (uint8, uint8, uint8, uint8) {
mapping(uint8 => uint8) storage m = m1;
m[1] = 42;
uint8 v;
(m, v) = (m2, 21);
m[2] = v;
return (m1[1], m1[2], m2[1], m2[2]);
}
}
// ----
// f() -> 42, 0, 0, 21