From 6915d9d2a87b4ae2dcca0a97f138f6c11d80bf7b Mon Sep 17 00:00:00 2001 From: Djordje Mijovic Date: Tue, 3 Nov 2020 16:52:04 +0100 Subject: [PATCH] Moving some struct tests to semanticTests --- test/libsolidity/ABIDecoderTests.cpp | 182 ------------------ .../struct/struct_storage_ptr.sol | 26 +++ .../abiEncoderV2/struct/mediocre2_struct.sol | 14 ++ .../abiEncoderV2/struct/mediocre_struct.sol | 14 ++ .../abiEncoderV2/struct/struct_function.sol | 16 ++ .../abiEncoderV2/struct/struct_short.sol | 13 ++ .../abiEncoderV2/struct/struct_simple.sol | 15 ++ .../abiEncoderV2/struct/struct_validation.sol | 19 ++ ...validation_function_type_inside_struct.sol | 17 ++ 9 files changed, 134 insertions(+), 182 deletions(-) create mode 100644 test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol create mode 100644 test/libsolidity/semanticTests/abiEncoderV2/struct/mediocre2_struct.sol create mode 100644 test/libsolidity/semanticTests/abiEncoderV2/struct/mediocre_struct.sol create mode 100644 test/libsolidity/semanticTests/abiEncoderV2/struct/struct_function.sol create mode 100644 test/libsolidity/semanticTests/abiEncoderV2/struct/struct_short.sol create mode 100644 test/libsolidity/semanticTests/abiEncoderV2/struct/struct_simple.sol create mode 100644 test/libsolidity/semanticTests/abiEncoderV2/struct/struct_validation.sol create mode 100644 test/libsolidity/semanticTests/abiEncoderV2/struct/validation_function_type_inside_struct.sol diff --git a/test/libsolidity/ABIDecoderTests.cpp b/test/libsolidity/ABIDecoderTests.cpp index ef6719dce..d7c164a46 100644 --- a/test/libsolidity/ABIDecoderTests.cpp +++ b/test/libsolidity/ABIDecoderTests.cpp @@ -352,121 +352,6 @@ BOOST_AUTO_TEST_CASE(validation_function_type) ) } -BOOST_AUTO_TEST_CASE(validation_function_type_inside_struct) -{ - string sourceCode = R"( - contract C { - struct S { function () external x; } - function f(S memory) public pure returns (uint r) { r = 1; } - function g(S calldata) external pure returns (uint r) { r = 2; } - function h(S calldata s) external pure returns (uint r) { s.x; r = 3; } - } - )"; - string validFun{"01234567890123456789abcd"}; - string invalidFun{"01234567890123456789abcdX"}; - NEW_ENCODER( - compileAndRun(sourceCode); - ABI_CHECK(callContractFunction("f((function))", validFun), encodeArgs(1)); - // Error because we copy to memory - ABI_CHECK(callContractFunction("f((function))", invalidFun), encodeArgs()); - ABI_CHECK(callContractFunction("g((function))", validFun), encodeArgs(2)); - // No error because x is not accessed. - ABI_CHECK(callContractFunction("g((function))", invalidFun), encodeArgs(2)); - ABI_CHECK(callContractFunction("h((function))", validFun), encodeArgs(3)); - // Error on access. - ABI_CHECK(callContractFunction("h((function))", invalidFun), encodeArgs()); - ) -} - -BOOST_AUTO_TEST_CASE(storage_ptr) -{ - string sourceCode = R"( - library L { - struct S { uint x; uint y; } - function f(uint[] storage r, S storage s) public returns (uint, uint, uint, uint) { - r[2] = 8; - s.x = 7; - return (r[0], r[1], s.x, s.y); - } - } - contract C { - uint8 x = 3; - L.S s; - uint[] r; - function f() public returns (uint, uint, uint, uint, uint, uint) { - r = new uint[](6); - r[0] = 1; - r[1] = 2; - r[2] = 3; - s.x = 11; - s.y = 12; - (uint a, uint b, uint c, uint d) = L.f(r, s); - return (r[2], s.x, a, b, c, d); - } - } - )"; - BOTH_ENCODERS( - compileAndRun(sourceCode, 0, "L"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{"L", m_contractAddress}}); - ABI_CHECK(callContractFunction("f()"), encodeArgs(8, 7, 1, 2, 7, 12)); - ) -} - -BOOST_AUTO_TEST_CASE(struct_simple) -{ - string sourceCode = R"( - contract C { - struct S { uint a; uint8 b; uint8 c; bytes2 d; } - function f(S memory s) public pure returns (uint a, uint b, uint c, uint d) { - a = s.a; - b = s.b; - c = s.c; - d = uint16(s.d); - } - } - )"; - NEW_ENCODER( - compileAndRun(sourceCode, 0, "C"); - ABI_CHECK(callContractFunction("f((uint256,uint8,uint8,bytes2))", 1, 2, 3, "ab"), encodeArgs(1, 2, 3, 'a' * 0x100 + 'b')); - ) -} - -BOOST_AUTO_TEST_CASE(struct_validation) -{ - string sourceCode = R"( - contract C { - struct S { int16 a; uint8 b; bytes2 c; } - function f(S memory s) public pure returns (uint a, uint b, uint c) { - assembly { - a := mload(s) - b := mload(add(s, 0x20)) - c := mload(add(s, 0x40)) - } - } - } - )"; - u256 largeNeg("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01"); - NEW_ENCODER( - compileAndRun(sourceCode, 0, "C"); - ABI_CHECK( - callContractFunction("f((int16,uint8,bytes2))", largeNeg, 0xff, "ab"), - encodeArgs(largeNeg, 0xff, "ab") - ); - ABI_CHECK( - callContractFunction("f((int16,uint8,bytes2))", 0xff010, 0xff, "ab"), - encodeArgs() - ); - ABI_CHECK( - callContractFunction("f((int16,uint8,bytes2))", largeNeg, 0xff0002, "ab"), - encodeArgs() - ); - ABI_CHECK( - callContractFunction("f((int16,uint8,bytes2))", largeNeg, 0xff, "abcd"), - encodeArgs() - ); - ) -} - BOOST_AUTO_TEST_CASE(struct_short) { string sourceCode = R"( @@ -494,73 +379,6 @@ BOOST_AUTO_TEST_CASE(struct_short) ) } -BOOST_AUTO_TEST_CASE(struct_function) -{ - string sourceCode = R"( - contract C { - struct S { function () external returns (uint) f; uint b; } - function f(S memory s) public returns (uint, uint) { - return (s.f(), s.b); - } - function test() public returns (uint, uint) { - return this.f(S(this.g, 3)); - } - function g() public returns (uint) { return 7; } - } - )"; - NEW_ENCODER( - compileAndRun(sourceCode, 0, "C"); - ABI_CHECK(callContractFunction("test()"), encodeArgs(7, 3)); - ) -} - -BOOST_AUTO_TEST_CASE(mediocre_struct) -{ - string sourceCode = R"( - contract C { - struct S { C c; } - function f(uint a, S[2] memory s1, uint b) public returns (uint r1, C r2, uint r3) { - r1 = a; - r2 = s1[0].c; - r3 = b; - } - } - )"; - NEW_ENCODER( - compileAndRun(sourceCode, 0, "C"); - string sig = "f(uint256,(address)[2],uint256)"; - ABI_CHECK(callContractFunction(sig, - 7, u256(u160(m_contractAddress)), 0, 8 - ), encodeArgs(7, u256(u160(m_contractAddress)), 8)); - ) -} - -BOOST_AUTO_TEST_CASE(mediocre2_struct) -{ - string sourceCode = R"( - contract C { - struct S { C c; uint[] x; } - function f(uint a, S[2] memory s1, uint b) public returns (uint r1, C r2, uint r3) { - r1 = a; - r2 = s1[0].c; - r3 = b; - } - } - )"; - NEW_ENCODER( - compileAndRun(sourceCode, 0, "C"); - string sig = "f(uint256,(address,uint256[])[2],uint256)"; - ABI_CHECK(callContractFunction(sig, - 7, 0x60, 8, - 0x40, 7 * 0x20, - u256(u160(m_contractAddress)), 0x40, - 2, 0x11, 0x12, - 0x99, 0x40, - 4, 0x31, 0x32, 0x34, 0x35 - ), encodeArgs(7, u256(u160(m_contractAddress)), 8)); - ) -} - BOOST_AUTO_TEST_CASE(complex_struct) { string sourceCode = R"( diff --git a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol new file mode 100644 index 000000000..eb67bf38d --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol @@ -0,0 +1,26 @@ +library L { + struct S { uint x; uint y; } + function f(uint[] storage r, S storage s) public returns (uint, uint, uint, uint) { + r[2] = 8; + s.x = 7; + return (r[0], r[1], s.x, s.y); + } +} +contract C { + uint8 x = 3; + L.S s; + uint[] r; + function f() public returns (uint, uint, uint, uint, uint, uint) { + r = new uint[](6); + r[0] = 1; + r[1] = 2; + r[2] = 3; + s.x = 11; + s.y = 12; + (uint a, uint b, uint c, uint d) = L.f(r, s); + return (r[2], s.x, a, b, c, d); + } +} +// ---- +// library: L +// f() -> 8, 7, 1, 2, 7, 12 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/struct/mediocre2_struct.sol b/test/libsolidity/semanticTests/abiEncoderV2/struct/mediocre2_struct.sol new file mode 100644 index 000000000..e4ffcb422 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/struct/mediocre2_struct.sol @@ -0,0 +1,14 @@ +pragma experimental ABIEncoderV2; + +contract C { + struct S { C c; uint[] x; } + function f(uint a, S[2] memory s1, uint b) public returns (uint r1, C r2, uint r3) { + r1 = a; + r2 = s1[0].c; + r3 = b; + } +} +// ==== +// compileViaYul: also +// ---- +// f(uint256,(address,uint256[])[2],uint256): 7, 0x60, 8, 0x40, 0xE0, 0x0, 0x40, 2, 0x11, 0x12, 0x99, 0x40, 4, 0x31, 0x32, 0x34, 0x35 -> 7, 0x0, 8 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/struct/mediocre_struct.sol b/test/libsolidity/semanticTests/abiEncoderV2/struct/mediocre_struct.sol new file mode 100644 index 000000000..4f05afe9b --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/struct/mediocre_struct.sol @@ -0,0 +1,14 @@ +pragma experimental ABIEncoderV2; + +contract C { + struct S { C c; } + function f(uint a, S[2] memory s1, uint b) public returns (uint r1, C r2, uint r3) { + r1 = a; + r2 = s1[0].c; + r3 = b; + } +} +// ==== +// compileViaYul: also +// ---- +// f(uint256,(address)[2],uint256): 7, 0, 0, 8 -> 7, 0, 8 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_function.sol b/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_function.sol new file mode 100644 index 000000000..4dcf6c010 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_function.sol @@ -0,0 +1,16 @@ +pragma experimental ABIEncoderV2; + +contract C { + struct S { function () external returns (uint) f; uint b; } + function f(S memory s) public returns (uint, uint) { + return (s.f(), s.b); + } + function test() public returns (uint, uint) { + return this.f(S(this.g, 3)); + } + function g() public returns (uint) { return 7; } +} +// ==== +// compileViaYul: also +// ---- +// test() -> 7, 3 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_short.sol b/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_short.sol new file mode 100644 index 000000000..a1eae4e8b --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_short.sol @@ -0,0 +1,13 @@ +pragma experimental ABIEncoderV2; + +contract C { + struct S { int a; uint b; bytes16 c; } + function f(S memory s) public pure returns (S memory q) { + q = s; + } +} +// ==== +// compileViaYul: also +// ---- +// f((int256,uint256,bytes16)): 0xff010, 0xff0002, "abcd" -> 0xff010, 0xff0002, "abcd" +// f((int256,uint256,bytes16)): 0xff010, 0xff0002, 0x1111222233334444555566667777888800000000000000000000000000000000 -> 0xff010, 0xff0002, left(0x11112222333344445555666677778888) diff --git a/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_simple.sol b/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_simple.sol new file mode 100644 index 000000000..ccef5ddc0 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_simple.sol @@ -0,0 +1,15 @@ +pragma experimental ABIEncoderV2; + +contract C { + struct S { uint a; uint8 b; uint8 c; bytes2 d; } + function f(S memory s) public pure returns (uint a, uint b, uint c, uint d) { + a = s.a; + b = s.b; + c = s.c; + d = uint16(s.d); + } +} +// ==== +// compileViaYul: also +// ---- +// f((uint256,uint8,uint8,bytes2)): 1, 2, 3, "ab" -> 1, 2, 3, 0x6162 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_validation.sol b/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_validation.sol new file mode 100644 index 000000000..f8c77be64 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/struct/struct_validation.sol @@ -0,0 +1,19 @@ +pragma experimental ABIEncoderV2; + +contract C { + struct S { int16 a; uint8 b; bytes2 c; } + function f(S memory s) public pure returns (uint a, uint b, uint c) { + assembly { + a := mload(s) + b := mload(add(s, 0x20)) + c := mload(add(s, 0x40)) + } + } +} +// ==== +// compileViaYul: also +// ---- +// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, "ab" -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, "ab" +// f((int16,uint8,bytes2)): 0xff010, 0xff, "ab" -> FAILURE +// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff0002, "ab" -> FAILURE +// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, "abcd" -> FAILURE diff --git a/test/libsolidity/semanticTests/abiEncoderV2/struct/validation_function_type_inside_struct.sol b/test/libsolidity/semanticTests/abiEncoderV2/struct/validation_function_type_inside_struct.sol new file mode 100644 index 000000000..7944262a3 --- /dev/null +++ b/test/libsolidity/semanticTests/abiEncoderV2/struct/validation_function_type_inside_struct.sol @@ -0,0 +1,17 @@ +pragma experimental ABIEncoderV2; + +contract C { + struct S { function () external x; } + function f(S memory) public pure returns (uint r) { r = 1; } + function g(S calldata) external pure returns (uint r) { r = 2; } + function h(S calldata s) external pure returns (uint r) { s.x; r = 3; } +} +// ==== +// compileViaYul: also +// ---- +// f((function)): "01234567890123456789abcd" -> 1 +// f((function)): "01234567890123456789abcdX" -> FAILURE +// g((function)): "01234567890123456789abcd" -> 2 +// g((function)): "01234567890123456789abcdX" -> 2 +// h((function)): "01234567890123456789abcd" -> 3 +// h((function)): "01234567890123456789abcdX" -> FAILURE