diff options
Merge branch 'develop' into rlpx
Diffstat (limited to 'libsolidity/SolidityEndToEndTest.cpp')
-rw-r--r-- | libsolidity/SolidityEndToEndTest.cpp | 265 |
1 files changed, 264 insertions, 1 deletions
diff --git a/libsolidity/SolidityEndToEndTest.cpp b/libsolidity/SolidityEndToEndTest.cpp index a01e98cf..3ddb0552 100644 --- a/libsolidity/SolidityEndToEndTest.cpp +++ b/libsolidity/SolidityEndToEndTest.cpp @@ -4493,7 +4493,7 @@ BOOST_AUTO_TEST_CASE(bytes_in_constructors_packer) } } contract Main is Base { - function Main(bytes s, uint x) Base(x, s){}//f(s)) {} + function Main(bytes s, uint x) Base(x, f(s)) {} function f(bytes s) returns (bytes) { return s; } @@ -4517,6 +4517,45 @@ BOOST_AUTO_TEST_CASE(bytes_in_constructors_packer) ); } +BOOST_AUTO_TEST_CASE(arrays_in_constructors) +{ + char const* sourceCode = R"( + contract Base { + uint public m_x; + address[] m_s; + function Base(uint x, address[] s) { + m_x = x; + m_s = s; + } + function part(uint i) returns (address) { + return m_s[i]; + } + } + contract Main is Base { + function Main(address[] s, uint x) Base(x, f(s)) {} + function f(address[] s) returns (address[]) { + return s; + } + } + contract Creator { + function f(uint x, address[] s) returns (uint r, address ch) { + var c = new Main(s, x); + r = c.m_x(); + ch = c.part(x); + } + } + )"; + compileAndRun(sourceCode, 0, "Creator"); + vector<u256> s1{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + bytes dyn1 = encodeArgs(u256(s1.size()), s1); + u256 x = 7; + bytes args1 = encodeArgs(x, u256(0x40)) + dyn1; + BOOST_REQUIRE( + callContractFunction("f(uint256,address[])", asString(args1)) == + encodeArgs(x, s1[unsigned(x)]) + ); +} + BOOST_AUTO_TEST_CASE(arrays_from_and_to_storage) { char const* sourceCode = R"( @@ -4691,6 +4730,35 @@ BOOST_AUTO_TEST_CASE(memory_types_initialisation) BOOST_CHECK(callContractFunction("nestedStat()") == encodeArgs(vector<u256>(3 * 7))); } +BOOST_AUTO_TEST_CASE(memory_arrays_delete) +{ + char const* sourceCode = R"( + contract Test { + function del() returns (uint24[3][4]) { + 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; + } + } + )"; + compileAndRun(sourceCode, 0, "Test"); + + vector<u256> data(3 * 4); + for (unsigned i = 0; i < 4; i++) + for (unsigned j = 0; j < 3; j++) + { + u256 v = 0; + if (!(i == 1 || (i == 3 && j == 2))) + v = i * 0x10 + j; + data[i * 3 + j] = v; + } + BOOST_CHECK(callContractFunction("del()") == encodeArgs(data)); +} + BOOST_AUTO_TEST_CASE(memory_arrays_index_access_write) { char const* sourceCode = R"( @@ -4738,6 +4806,201 @@ BOOST_AUTO_TEST_CASE(memory_arrays_dynamic_index_access_write) BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(0x20), u256(4), data)); } +BOOST_AUTO_TEST_CASE(memory_structs_read_write) +{ + char const* sourceCode = R"( + contract Test { + struct S { uint8 x; uint16 y; uint z; uint8[2] a; } + S[5] data; + function testInit() returns (uint8 x, uint16 y, uint z, uint8 a, bool flag) { + S[2] memory d; + x = d[0].x; + y = d[0].y; + z = d[0].z; + a = d[0].a[1]; + flag = true; + } + function testCopyRead() returns (uint8 x, uint16 y, uint z, uint8 a) { + data[2].x = 1; + data[2].y = 2; + data[2].z = 3; + data[2].a[1] = 4; + S memory s = data[2]; + x = s.x; + y = s.y; + z = s.z; + a = s.a[1]; + } + function testAssign() returns (uint8 x, uint16 y, uint z, uint8 a) { + S memory s; + s.x = 1; + s.y = 2; + s.z = 3; + s.a[1] = 4; + x = s.x; + y = s.y; + z = s.z; + a = s.a[1]; + } + } + )"; + compileAndRun(sourceCode, 0, "Test"); + + BOOST_CHECK(callContractFunction("testInit()") == encodeArgs(u256(0), u256(0), u256(0), u256(0), true)); + BOOST_CHECK(callContractFunction("testCopyRead()") == encodeArgs(u256(1), u256(2), u256(3), u256(4))); + BOOST_CHECK(callContractFunction("testAssign()") == encodeArgs(u256(1), u256(2), u256(3), u256(4))); +} + +BOOST_AUTO_TEST_CASE(memory_structs_as_function_args) +{ + char const* sourceCode = R"( + contract Test { + struct S { uint8 x; uint16 y; uint z; } + function test() returns (uint x, uint y, uint z) { + S memory data = combine(1, 2, 3); + x = extract(data, 0); + y = extract(data, 1); + z = extract(data, 2); + } + function extract(S s, uint which) internal returns (uint x) { + if (which == 0) return s.x; + else if (which == 1) return s.y; + else return s.z; + } + function combine(uint8 x, uint16 y, uint z) internal returns (S s) { + s.x = x; + s.y = y; + s.z = z; + } + } + )"; + compileAndRun(sourceCode, 0, "Test"); + + BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(1), u256(2), u256(3))); +} + +BOOST_AUTO_TEST_CASE(memory_structs_nested) +{ + char const* sourceCode = R"( + contract Test { + struct S { uint8 x; uint16 y; uint z; } + struct X { uint8 x; S s; } + function test() returns (uint a, uint x, uint y, uint z) { + X memory d = combine(1, 2, 3, 4); + a = extract(d, 0); + x = extract(d, 1); + y = extract(d, 2); + z = extract(d, 3); + } + function extract(X s, uint which) internal returns (uint x) { + if (which == 0) return s.x; + else if (which == 1) return s.s.x; + else if (which == 2) return s.s.y; + else return s.s.z; + } + function combine(uint8 a, uint8 x, uint16 y, uint z) internal returns (X s) { + s.x = a; + s.s.x = x; + s.s.y = y; + s.s.z = z; + } + } + )"; + compileAndRun(sourceCode, 0, "Test"); + + BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(1), u256(2), u256(3), u256(4))); +} + +BOOST_AUTO_TEST_CASE(memory_structs_nested_load) +{ + char const* sourceCode = R"( + contract Test { + struct S { uint8 x; uint16 y; uint z; } + struct X { uint8 x; S s; uint8[2] a; } + X m_x; + function load() returns (uint a, uint x, uint y, uint z, uint a1, uint a2) { + m_x.x = 1; + m_x.s.x = 2; + m_x.s.y = 3; + m_x.s.z = 4; + m_x.a[0] = 5; + m_x.a[1] = 6; + X memory d = m_x; + a = d.x; + x = d.s.x; + y = d.s.y; + z = d.s.z; + a1 = d.a[0]; + a2 = d.a[1]; + } + function store() returns (uint a, uint x, uint y, uint z, uint a1, uint a2) { + X memory d; + d.x = 1; + d.s.x = 2; + d.s.y = 3; + d.s.z = 4; + d.a[0] = 5; + d.a[1] = 6; + m_x = d; + a = m_x.x; + x = m_x.s.x; + y = m_x.s.y; + z = m_x.s.z; + a1 = m_x.a[0]; + a2 = m_x.a[1]; + } + } + )"; + compileAndRun(sourceCode, 0, "Test"); + + auto out = encodeArgs(u256(1), u256(2), u256(3), u256(4), u256(5), u256(6)); + BOOST_CHECK(callContractFunction("load()") == out); + BOOST_CHECK(callContractFunction("store()") == out); +} + +BOOST_AUTO_TEST_CASE(struct_constructor_nested) +{ + char const* sourceCode = R"( + contract C { + struct X { uint x1; uint x2; } + struct S { uint s1; uint[3] s2; X s3; } + S s; + function C() { + uint[3] memory s2; + s2[1] = 9; + s = S(1, s2, X(4, 5)); + } + function get() returns (uint s1, uint[3] s2, uint x1, uint x2) + { + s1 = s.s1; + s2 = s.s2; + x1 = s.s3.x1; + x2 = s.s3.x2; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + + auto out = encodeArgs(u256(1), u256(0), u256(9), u256(0), u256(4), u256(5)); + BOOST_CHECK(callContractFunction("get()") == out); +} + +BOOST_AUTO_TEST_CASE(struct_named_constructor) +{ + char const* sourceCode = R"( + contract C { + struct S { uint a; bool x; } + S public s; + function C() { + s = S({a: 1, x: true}); + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + + BOOST_CHECK(callContractFunction("s()") == encodeArgs(u256(1), true)); +} + BOOST_AUTO_TEST_SUITE_END() } |