Moving some struct tests to semanticTests

This commit is contained in:
Djordje Mijovic 2020-11-03 16:52:04 +01:00
parent 490064590a
commit 6915d9d2a8
9 changed files with 134 additions and 182 deletions

View File

@ -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<string, Address>{{"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"(

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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