From cc8583ec7d6fd86ca7e129475fde32b76d102e79 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 27 Sep 2016 21:37:32 +0200 Subject: Function types. --- test/libsolidity/SolidityEndToEndTest.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'test/libsolidity/SolidityEndToEndTest.cpp') diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index d8924250..c9097663 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7606,6 +7606,24 @@ BOOST_AUTO_TEST_CASE(mem_resize_is_not_paid_at_call) BOOST_CHECK(callContractFunction("f(address)", cAddrOpt) == encodeArgs(u256(7))); } +BOOST_AUTO_TEST_CASE(pass_function_types_internally) +{ + char const* sourceCode = R"( + contract C { + function f(uint x) returns (uint) { + return eval(g, x); + } + function eval(function(uint) returns (uint) x, uint a) returns (uint) { + return x(a); + } + function g(uint x) returns (uint) { return x + 1; } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("f(uint256)", 7) == encodeArgs(u256(8))); +} + BOOST_AUTO_TEST_CASE(shift_constant_left) { char const* sourceCode = R"( -- cgit v1.2.3 From dd173f83e3a6a9046d1aa7e64cb171598a73b272 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 28 Sep 2016 19:22:23 +0200 Subject: Code generator for function types. --- test/libsolidity/SolidityEndToEndTest.cpp | 49 ++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) (limited to 'test/libsolidity/SolidityEndToEndTest.cpp') diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index c9097663..76df1970 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7606,6 +7606,29 @@ BOOST_AUTO_TEST_CASE(mem_resize_is_not_paid_at_call) BOOST_CHECK(callContractFunction("f(address)", cAddrOpt) == encodeArgs(u256(7))); } +BOOST_AUTO_TEST_CASE(calling_uninitialized_function) +{ + char const* sourceCode = R"( + contract C { + function intern() returns (uint) { + function (uint) internal returns (uint) x; + x(); + return 7; + } + function extern() returns (uint) { + function (uint) external returns (uint) x; + x(); + return 7; + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + // This should throw exceptions + BOOST_CHECK(callContractFunction("intern()") == encodeArgs()); + BOOST_CHECK(callContractFunction("extern()") == encodeArgs()); +} + BOOST_AUTO_TEST_CASE(pass_function_types_internally) { char const* sourceCode = R"( @@ -7613,7 +7636,28 @@ BOOST_AUTO_TEST_CASE(pass_function_types_internally) function f(uint x) returns (uint) { return eval(g, x); } - function eval(function(uint) returns (uint) x, uint a) returns (uint) { + function eval(function(uint) returns (uint) x, uint a) internal returns (uint) { + return x(a); + } + function g(uint x) returns (uint) { return x + 1; } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("f(uint256)", 7) == encodeArgs(u256(8))); +} + +BOOST_AUTO_TEST_CASE(pass_function_types_externally) +{ + char const* sourceCode = R"( + contract C { + function f(uint x) returns (uint) { + return this.eval(this.g, x); + } + function f2(uint x) returns (uint) { + return eval(this.g, x); + } + function eval(function(uint) external returns (uint) x, uint a) returns (uint) { return x(a); } function g(uint x) returns (uint) { return x + 1; } @@ -7622,8 +7666,11 @@ BOOST_AUTO_TEST_CASE(pass_function_types_internally) compileAndRun(sourceCode, 0, "C"); BOOST_CHECK(callContractFunction("f(uint256)", 7) == encodeArgs(u256(8))); + BOOST_CHECK(callContractFunction("f2(uint256)", 7) == encodeArgs(u256(8))); } +// TODO: storage, arrays + BOOST_AUTO_TEST_CASE(shift_constant_left) { char const* sourceCode = R"( -- cgit v1.2.3 From 97a3588701edafe9112f35272b5d4c6e23e574b9 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 10 Oct 2016 23:06:44 +0200 Subject: Function type state variables. --- test/libsolidity/SolidityEndToEndTest.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'test/libsolidity/SolidityEndToEndTest.cpp') diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 76df1970..0f392cab 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7669,7 +7669,33 @@ BOOST_AUTO_TEST_CASE(pass_function_types_externally) BOOST_CHECK(callContractFunction("f2(uint256)", 7) == encodeArgs(u256(8))); } -// TODO: storage, arrays +BOOST_AUTO_TEST_CASE(store_function) +{ + char const* sourceCode = R"( + contract Other { + function addTwo(uint x) returns (uint) { return x + 2; } + } + contract C { + function (unction (uint) external returns (uint)) returns (uint) ev = eval; + function (uint) external returns (uint) x; + function store(function(uint) external returns (uint) y) { + x = y; + } + function eval(function(uint) external returns (uint) y) returns (uint) { + return y(7); + } + function t() returns (uint) { + this.store((new Other()).addTwo); + return ev(x); + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("t()") == encodeArgs(u256(9))); +} + +// TODO: public function state variables, arrays BOOST_AUTO_TEST_CASE(shift_constant_left) { -- cgit v1.2.3 From 6f19559de02e0bf2b53e743678d53a4ea0414eae Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 13 Oct 2016 17:51:46 +0200 Subject: Fix some type checks and tests for internal / external function parameters. --- test/libsolidity/SolidityEndToEndTest.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'test/libsolidity/SolidityEndToEndTest.cpp') diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 0f392cab..709e63b2 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7612,12 +7612,12 @@ BOOST_AUTO_TEST_CASE(calling_uninitialized_function) contract C { function intern() returns (uint) { function (uint) internal returns (uint) x; - x(); + x(2); return 7; } function extern() returns (uint) { function (uint) external returns (uint) x; - x(); + x(2); return 7; } } @@ -7676,7 +7676,7 @@ BOOST_AUTO_TEST_CASE(store_function) function addTwo(uint x) returns (uint) { return x + 2; } } contract C { - function (unction (uint) external returns (uint)) returns (uint) ev = eval; + function (function (uint) external returns (uint)) returns (uint) ev = eval; function (uint) external returns (uint) x; function store(function(uint) external returns (uint) y) { x = y; @@ -7695,7 +7695,7 @@ BOOST_AUTO_TEST_CASE(store_function) BOOST_CHECK(callContractFunction("t()") == encodeArgs(u256(9))); } -// TODO: public function state variables, arrays +// TODO: arrays, libraries BOOST_AUTO_TEST_CASE(shift_constant_left) { -- cgit v1.2.3 From 95d7555e3c0e8fc4826114a336e0e717fe7a1a2d Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 14 Oct 2016 12:27:46 +0200 Subject: External functions in storage. --- test/libsolidity/SolidityEndToEndTest.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'test/libsolidity/SolidityEndToEndTest.cpp') diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 709e63b2..b1529f8f 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7695,7 +7695,33 @@ BOOST_AUTO_TEST_CASE(store_function) BOOST_CHECK(callContractFunction("t()") == encodeArgs(u256(9))); } -// TODO: arrays, libraries +BOOST_AUTO_TEST_CASE(function_type_library_internal) +{ + char const* sourceCode = R"( + library Utils { + function reduce(uint[] memory array, function(uint, uint) returns (uint) f, uint init) internal returns (uint) { + for (uint i = 0; i < array.length; i++) { + init = f(array[i], init); + } + return init; + } + function sum(uint a, uint b) internal returns (uint) { + return a + b; + } + } + contract C { + function f(uint[] x) returns (uint) { + return Utils.reduce(x, Utils.sum, 0); + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("f(uint256[])", 0x20, 3, u256(1), u256(7), u256(3)) == encodeArgs(u256(11))); +} + + +// TODO: arrays, libraries with external functions BOOST_AUTO_TEST_CASE(shift_constant_left) { -- cgit v1.2.3 From ab3d1b024db6e208e4b63e2ecb07754af1540d6f Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 14 Oct 2016 17:32:13 +0200 Subject: Add tests around calling functions returning functions returning functions --- test/libsolidity/SolidityEndToEndTest.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'test/libsolidity/SolidityEndToEndTest.cpp') diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index b1529f8f..79dfd90e 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7721,6 +7721,36 @@ BOOST_AUTO_TEST_CASE(function_type_library_internal) } +BOOST_AUTO_TEST_CASE(call_function_returning_function) +{ + char const* sourceCode = R"( + contract test { + function f0() returns (uint) { + return 2; + } + function f1() returns (function() returns (uint)) { + returns f0; + } + function f2() returns (function() returns (function () returns (uint))) { + returns f1; + } + function f3() returns (function() returns (function () returns (function () returns (uint)))) + { + returns f2; + } + function f() returns (uint) { + function() returns(function() returns(function() returns(function() returns(uint)))) x; + x = f3; + return x()()()(); + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(2))); +} + + // TODO: arrays, libraries with external functions BOOST_AUTO_TEST_CASE(shift_constant_left) -- cgit v1.2.3 From 6172590b870832d7aa132209afb890125f301c15 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 14 Oct 2016 17:54:12 +0200 Subject: Add a test around storing functions in an array --- test/libsolidity/SolidityEndToEndTest.cpp | 39 +++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'test/libsolidity/SolidityEndToEndTest.cpp') diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 79dfd90e..704fc1a1 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7750,6 +7750,45 @@ BOOST_AUTO_TEST_CASE(call_function_returning_function) BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(2))); } +BOOST_AUTO_TEST_CASE(array_of_functions) +{ + char const* sourceCode = R"( + contract Flow { + bool success; + function checkSuccess() returns(bool) { + return success; + } + + mapping (address => function () internal returns()) stages; + + function stage0() internal { + stages[msg.sender] = stage1; + } + + function stage1() internal { + stages[msg.sender] = stage2; + } + + function stage2() internal { + success = true; + } + + function f () { + if (0 == steps[msg.sender]) + stages[msg.sender] = stage0; + stages[msg.sender](); + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("checkSuccess()") == encodeArgs(false)); + callContractFunction("f()"); + callContractFunction("f()"); + BOOST_CHECK(callContractFunction("checkSuccess()") == encodeArgs(false)); + callContractFunction("f()"); + BOOST_CHECK(callContractFunction("checkSuccess()") == encodeArgs(true)); +} // TODO: arrays, libraries with external functions -- cgit v1.2.3 From 87b148494bcf1dd4814fafe658dd81fef79cf8b4 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 19 Oct 2016 18:43:42 +0200 Subject: Tests. --- test/libsolidity/SolidityEndToEndTest.cpp | 198 ++++++++++++++++++++++++++---- 1 file changed, 174 insertions(+), 24 deletions(-) (limited to 'test/libsolidity/SolidityEndToEndTest.cpp') diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 704fc1a1..ef64ad5a 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7669,6 +7669,42 @@ BOOST_AUTO_TEST_CASE(pass_function_types_externally) BOOST_CHECK(callContractFunction("f2(uint256)", 7) == encodeArgs(u256(8))); } +BOOST_AUTO_TEST_CASE(receive_external_function_type) +{ + char const* sourceCode = R"( + contract C { + function g() returns (uint) { return 7; } + function f(function() external returns (uint) g) returns (uint) { + return g(); + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction( + "f(bytes24)", + FixedHash<4>(dev::keccak256("g()")).asBytes() + m_contractAddress.asBytes() + bytes(32 - 4 - 20, 0) + ) == encodeArgs(u256(7))); +} + +BOOST_AUTO_TEST_CASE(return_external_function_type) +{ + char const* sourceCode = R"( + contract C { + function g() {} + function f() returns (function() external) { + return this.g; + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK( + callContractFunction("f()") == + FixedHash<4>(dev::keccak256("g()")).asBytes() + m_contractAddress.asBytes() + bytes(32 - 4 - 20, 0) + ); +} + BOOST_AUTO_TEST_CASE(store_function) { char const* sourceCode = R"( @@ -7676,7 +7712,7 @@ BOOST_AUTO_TEST_CASE(store_function) function addTwo(uint x) returns (uint) { return x + 2; } } contract C { - function (function (uint) external returns (uint)) returns (uint) ev = eval; + function (function (uint) external returns (uint)) returns (uint) ev; function (uint) external returns (uint) x; function store(function(uint) external returns (uint) y) { x = y; @@ -7685,6 +7721,7 @@ BOOST_AUTO_TEST_CASE(store_function) return y(7); } function t() returns (uint) { + ev = eval; this.store((new Other()).addTwo); return ev(x); } @@ -7728,15 +7765,15 @@ BOOST_AUTO_TEST_CASE(call_function_returning_function) function f0() returns (uint) { return 2; } - function f1() returns (function() returns (uint)) { - returns f0; + function f1() internal returns (function() returns (uint)) { + return f0; } - function f2() returns (function() returns (function () returns (uint))) { - returns f1; + function f2() internal returns (function() returns (function () returns (uint))) { + return f1; } - function f3() returns (function() returns (function () returns (function () returns (uint)))) + function f3() internal returns (function() returns (function () returns (function () returns (uint)))) { - returns f2; + return f2; } function f() returns (uint) { function() returns(function() returns(function() returns(function() returns(uint)))) x; @@ -7746,51 +7783,164 @@ BOOST_AUTO_TEST_CASE(call_function_returning_function) } )"; - compileAndRun(sourceCode, 0, "C"); + compileAndRun(sourceCode, 0, "test"); BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(2))); } -BOOST_AUTO_TEST_CASE(array_of_functions) +BOOST_AUTO_TEST_CASE(mapping_of_functions) { char const* sourceCode = R"( contract Flow { - bool success; - function checkSuccess() returns(bool) { - return success; - } + bool public success; - mapping (address => function () internal returns()) stages; + mapping (address => function () internal) stages; function stage0() internal { - stages[msg.sender] = stage1; + stages[msg.sender] = stage1; } function stage1() internal { - stages[msg.sender] = stage2; + stages[msg.sender] = stage2; } function stage2() internal { success = true; } - function f () { - if (0 == steps[msg.sender]) - stages[msg.sender] = stage0; + function Flow() { + stages[msg.sender] = stage0; + } + + function f() { stages[msg.sender](); } } )"; - compileAndRun(sourceCode, 0, "C"); + compileAndRun(sourceCode, 0, "Flow"); BOOST_CHECK(callContractFunction("checkSuccess()") == encodeArgs(false)); - callContractFunction("f()"); - callContractFunction("f()"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs()); + BOOST_CHECK(callContractFunction("f()") == encodeArgs()); BOOST_CHECK(callContractFunction("checkSuccess()") == encodeArgs(false)); - callContractFunction("f()"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs()); BOOST_CHECK(callContractFunction("checkSuccess()") == encodeArgs(true)); } -// TODO: arrays, libraries with external functions +BOOST_AUTO_TEST_CASE(packed_functions) +{ + char const* sourceCode = R"( + contract C { + // these should take the same slot + function() returns (uint) a; + function() external returns (uint) b; + uint8 public x; + + function set() { + x = 2; + a = g; + b = h; + } + function t1() returns (uint) { + return a(); + } + function t2() returns (uint) { + return b(); + } + function g() returns (uint) { + return 7; + } + function h() returns (uint) { + return 8; + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("set()") == encodeArgs()); + BOOST_CHECK(callContractFunction("t1()") == encodeArgs(u256(7))); + BOOST_CHECK(callContractFunction("t2()") == encodeArgs(u256(8))); + BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(2))); +} + +BOOST_AUTO_TEST_CASE(function_memory_array) +{ + char const* sourceCode = R"( + contract C { + function a(uint x) returns (uint) { return x + 1; } + function b(uint x) returns (uint) { return x + 2; } + function c(uint x) returns (uint) { return x + 3; } + function d(uint x) returns (uint) { return x + 5; } + function e(uint x) returns (uint) { return x + 8; } + function test(uint x, uint i) returns (uint) { + function(uint) internal returns (uint)[] arr = + new function(uint) internal returns (uint)[](10); + arr[0] = a; + arr[1] = b; + arr[2] = c; + arr[3] = d; + arr[4] = e; + return arr[i](x); + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("test(uint256,uint256)", u256(10), u256(0)) == encodeArgs(u256(11))); + BOOST_CHECK(callContractFunction("test(uint256,uint256)", u256(10), u256(1)) == encodeArgs(u256(12))); + BOOST_CHECK(callContractFunction("test(uint256,uint256)", u256(10), u256(2)) == encodeArgs(u256(13))); + BOOST_CHECK(callContractFunction("test(uint256,uint256)", u256(10), u256(3)) == encodeArgs(u256(15))); + BOOST_CHECK(callContractFunction("test(uint256,uint256)", u256(10), u256(4)) == encodeArgs(u256(18))); + BOOST_CHECK(callContractFunction("test(uint256,uint256)", u256(10), u256(5)) == encodeArgs()); +} + +BOOST_AUTO_TEST_CASE(function_delete) +{ + char const* sourceCode = R"( + contract C { + function a() returns (uint) { return 7; } + function() internal returns (uint) y; + function set() returns (uint) { + y = a; + return y(); + } + funciton d() returns (uint) { + delete y; + return 1; + } + function ca() returns (uint) { + return y(); + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("set()") == encodeArgs(u256(7))); + BOOST_CHECK(callContractFunction("ca()") == encodeArgs(u256(7))); + BOOST_CHECK(callContractFunction("d()") == encodeArgs(u256(1))); + BOOST_CHECK(callContractFunction("ca()") == encodeArgs()); +} + +BOOST_AUTO_TEST_CASE(copy_function_storage_array) +{ + char const* sourceCode = R"( + contract C { + function() internal returns (uint)[] x; + function() internal returns (uint)[] y; + function test() returns (uint) { + x.length = 10; + x[9] = a; + y = x; + return y[9](); + } + function a() returns (uint) { + return 7; + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(7))); +} BOOST_AUTO_TEST_CASE(shift_constant_left) { -- cgit v1.2.3 From 3158a8ea7b06888472b09ac4bc5f6a5a2f7ae2ce Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 4 Nov 2016 15:23:48 +0100 Subject: test: add a test for storing an internal function in the constructor and then using the stored function in runtime --- test/libsolidity/SolidityEndToEndTest.cpp | 46 +++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'test/libsolidity/SolidityEndToEndTest.cpp') diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index ef64ad5a..7dbadc48 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7732,6 +7732,52 @@ BOOST_AUTO_TEST_CASE(store_function) BOOST_CHECK(callContractFunction("t()") == encodeArgs(u256(9))); } +BOOST_AUTO_TEST_CASE(store_function_in_constructor) +{ + char const* sourceCode = R"( + contract C { + uint result_in_constructor; + function (uint) internal returns (uint) x; + function C () { + x = double; + result_in_constructor = use(2); + } + function double(uint _arg) returns (uint _ret) { + _ret = _arg * 2; + } + function use(uint _arg) returns (uint) { + return x(_arg); + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("use(uint256)", encodeArgs(u256(3))) == encodeArgs(u256(6))); + BOOST_CHECK(callContractFunction("result_in_constructor()") == encodeArgs(u256(4))); +} + +BOOST_AUTO_TEST_CASE(same_function_in_construction_and_runtime) +{ + char const* sourceCode = R"( + contract C { + uint public initial; + function C() { + initial = double(2); + } + function double(uint _arg) returns (uint _ret) { + _ret = _arg * 2; + } + function runtime(uint _arg) returns (uint) { + return double(_arg); + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("runtime(uint256)", encodeArgs(u256(3))) == encodeArgs(u256(6))); + BOOST_CHECK(callContractFunction("initial()") == encodeArgs(u256(4))); +} + BOOST_AUTO_TEST_CASE(function_type_library_internal) { char const* sourceCode = R"( -- cgit v1.2.3 From b6992d740a849d28f7c2a52bef0ba6b3740c9179 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 7 Nov 2016 20:07:55 +0100 Subject: Tests for uninitialized storage functions. --- test/libsolidity/SolidityEndToEndTest.cpp | 54 ++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) (limited to 'test/libsolidity/SolidityEndToEndTest.cpp') diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 7dbadc48..44dba9b2 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7629,6 +7629,29 @@ BOOST_AUTO_TEST_CASE(calling_uninitialized_function) BOOST_CHECK(callContractFunction("extern()") == encodeArgs()); } +BOOST_AUTO_TEST_CASE(calling_uninitialized_function_in_detail) +{ + // Storage default value of zero would be correct jump dest, this tests that + // that is properly handled. + char const* sourceCode = R"( + contract C { + function() internal returns (uint) x; + int mutex; + function t() returns (uint) { + if (mutex > 0) + return 7; + mutex = 1; + // If this test fails, it will jump to "0" and re-execute this function. + x(); + return 2; + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("t()") == encodeArgs()); +} + BOOST_AUTO_TEST_CASE(pass_function_types_internally) { char const* sourceCode = R"( @@ -7949,7 +7972,7 @@ BOOST_AUTO_TEST_CASE(function_delete) y = a; return y(); } - funciton d() returns (uint) { + function d() returns (uint) { delete y; return 1; } @@ -7988,6 +8011,35 @@ BOOST_AUTO_TEST_CASE(copy_function_storage_array) BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(7))); } +BOOST_AUTO_TEST_CASE(copy_internal_function_array_to_storage) +{ + // This has to apply NOT to the functions because encoding in storage + // is different than encoding in memory. + char const* sourceCode = R"( + contract C { + function() internal returns (uint)[20] x; + int mutex; + function one() returns (uint) { + function() internal returns (uint)[20] xmem; + x = xmem; + return 3; + } + function two() returns (uint) { + if (mutex > 0) + return 7; + mutex = 1; + // If this test fails, it will jump to "0" and re-execute this function. + x[0](); + return 2; + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("one()") == encodeArgs(u256(3))); + BOOST_CHECK(callContractFunction("two()") == encodeArgs()); +} + BOOST_AUTO_TEST_CASE(shift_constant_left) { char const* sourceCode = R"( -- cgit v1.2.3 From 47794c1da406a28f0e8a10e3e57cd935f5cc7f3d Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 7 Nov 2016 20:08:05 +0100 Subject: Implement uninitialized storage functions. --- test/libsolidity/SolidityEndToEndTest.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'test/libsolidity/SolidityEndToEndTest.cpp') diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 44dba9b2..c665b050 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7631,8 +7631,6 @@ BOOST_AUTO_TEST_CASE(calling_uninitialized_function) BOOST_AUTO_TEST_CASE(calling_uninitialized_function_in_detail) { - // Storage default value of zero would be correct jump dest, this tests that - // that is properly handled. char const* sourceCode = R"( contract C { function() internal returns (uint) x; @@ -7641,7 +7639,7 @@ BOOST_AUTO_TEST_CASE(calling_uninitialized_function_in_detail) if (mutex > 0) return 7; mutex = 1; - // If this test fails, it will jump to "0" and re-execute this function. + // Avoid re-executing this function if we jump somewhere. x(); return 2; } -- cgit v1.2.3 From f21f794f3c380c9382ace4908c38d0f6c776ae17 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 9 Nov 2016 09:36:38 +0100 Subject: delete for function types --- test/libsolidity/SolidityEndToEndTest.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'test/libsolidity/SolidityEndToEndTest.cpp') diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index c665b050..a1236803 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7960,7 +7960,7 @@ BOOST_AUTO_TEST_CASE(function_memory_array) BOOST_CHECK(callContractFunction("test(uint256,uint256)", u256(10), u256(5)) == encodeArgs()); } -BOOST_AUTO_TEST_CASE(function_delete) +BOOST_AUTO_TEST_CASE(function_delete_storage) { char const* sourceCode = R"( contract C { @@ -7987,6 +7987,23 @@ BOOST_AUTO_TEST_CASE(function_delete) BOOST_CHECK(callContractFunction("ca()") == encodeArgs()); } +BOOST_AUTO_TEST_CASE(function_delete_stack) +{ + char const* sourceCode = R"( + contract C { + function a() returns (uint) { return 7; } + function test() returns (uint) { + y = a; + delete y; + y(); + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("test()") == encodeArgs()); +} + BOOST_AUTO_TEST_CASE(copy_function_storage_array) { char const* sourceCode = R"( -- cgit v1.2.3 From e1df3bd77f78d5564fc173474015e5d84b192824 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 9 Nov 2016 13:34:51 +0100 Subject: Fix tests. --- test/libsolidity/SolidityEndToEndTest.cpp | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'test/libsolidity/SolidityEndToEndTest.cpp') diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index a1236803..8f9edadf 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7878,19 +7878,20 @@ BOOST_AUTO_TEST_CASE(mapping_of_functions) stages[msg.sender] = stage0; } - function f() { + function f() returns (uint) { stages[msg.sender](); + return 7; } } )"; compileAndRun(sourceCode, 0, "Flow"); - BOOST_CHECK(callContractFunction("checkSuccess()") == encodeArgs(false)); - BOOST_CHECK(callContractFunction("f()") == encodeArgs()); - BOOST_CHECK(callContractFunction("f()") == encodeArgs()); - BOOST_CHECK(callContractFunction("checkSuccess()") == encodeArgs(false)); - BOOST_CHECK(callContractFunction("f()") == encodeArgs()); - BOOST_CHECK(callContractFunction("checkSuccess()") == encodeArgs(true)); + BOOST_CHECK(callContractFunction("success()") == encodeArgs(false)); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(7))); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(7))); + BOOST_CHECK(callContractFunction("success()") == encodeArgs(false)); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(7))); + BOOST_CHECK(callContractFunction("success()") == encodeArgs(true)); } BOOST_AUTO_TEST_CASE(packed_functions) @@ -7900,12 +7901,16 @@ BOOST_AUTO_TEST_CASE(packed_functions) // these should take the same slot function() returns (uint) a; function() external returns (uint) b; + function() external returns (uint) c; + function() returns (uint) d; uint8 public x; function set() { x = 2; + d = g; + c = this.h; + b = this.h; a = g; - b = h; } function t1() returns (uint) { return a(); @@ -7913,6 +7918,12 @@ BOOST_AUTO_TEST_CASE(packed_functions) function t2() returns (uint) { return b(); } + function t3() returns (uint) { + return a(); + } + function t4() returns (uint) { + return b(); + } function g() returns (uint) { return 7; } @@ -7926,6 +7937,8 @@ BOOST_AUTO_TEST_CASE(packed_functions) BOOST_CHECK(callContractFunction("set()") == encodeArgs()); BOOST_CHECK(callContractFunction("t1()") == encodeArgs(u256(7))); BOOST_CHECK(callContractFunction("t2()") == encodeArgs(u256(8))); + BOOST_CHECK(callContractFunction("t3()") == encodeArgs(u256(7))); + BOOST_CHECK(callContractFunction("t4()") == encodeArgs(u256(8))); BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(2))); } @@ -7939,7 +7952,7 @@ BOOST_AUTO_TEST_CASE(function_memory_array) function d(uint x) returns (uint) { return x + 5; } function e(uint x) returns (uint) { return x + 8; } function test(uint x, uint i) returns (uint) { - function(uint) internal returns (uint)[] arr = + function(uint) internal returns (uint)[] memory arr = new function(uint) internal returns (uint)[](10); arr[0] = a; arr[1] = b; -- cgit v1.2.3 From 08763a206d4391f94546ef32a1d0f1495eeb99e4 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 9 Nov 2016 15:58:45 +0100 Subject: Test passing functions as arrays to other contracts. --- test/libsolidity/SolidityEndToEndTest.cpp | 43 ++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) (limited to 'test/libsolidity/SolidityEndToEndTest.cpp') diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 8f9edadf..5054e275 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -8039,10 +8039,47 @@ BOOST_AUTO_TEST_CASE(copy_function_storage_array) BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(7))); } +BOOST_AUTO_TEST_CASE(function_array_cross_calls) +{ + char const* sourceCode = R"( + contract D { + function f(function() external returns (function() external returns (uint))[] x) + returns (function() external returns (uint)[3] r) + { + r[0] = x[0](); + r[1] = x[1](); + r[2] = x[2](); + } + } + contract C { + function test() returns (uint, uint, uint) { + function() external returns (function() external returns (uint))[] memory x = + new function() external returns (function() external returns (uint))[](10); + for (uint i = 0; i < x.length; i ++) + x[i] = this.h; + x[0] = this.htwo; + var y = (new D()).f(x); + return (y[0](), y[1](), y[2]()); + } + function e() returns (uint) { return 5; } + function f() returns (uint) { return 6; } + function g() returns (uint) { return 7; } + uint counter; + function h() returns (function() external returns (uint)) { + return counter++ == 0 ? this.f : this.g; + } + function htwo() returns (function() external returns (uint)) { + return this.e; + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(5), u256(6), u256(7))); +} + BOOST_AUTO_TEST_CASE(copy_internal_function_array_to_storage) { - // This has to apply NOT to the functions because encoding in storage - // is different than encoding in memory. char const* sourceCode = R"( contract C { function() internal returns (uint)[20] x; @@ -8056,7 +8093,7 @@ BOOST_AUTO_TEST_CASE(copy_internal_function_array_to_storage) if (mutex > 0) return 7; mutex = 1; - // If this test fails, it will jump to "0" and re-execute this function. + // If this test fails, it might re-execute this function. x[0](); return 2; } -- cgit v1.2.3 From ee3efa67a8d3eb4077786fd745c1925a916419f5 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 9 Nov 2016 17:51:48 +0100 Subject: Fix tests. --- test/libsolidity/SolidityEndToEndTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/libsolidity/SolidityEndToEndTest.cpp') diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 5054e275..b05316dd 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -8006,7 +8006,7 @@ BOOST_AUTO_TEST_CASE(function_delete_stack) contract C { function a() returns (uint) { return 7; } function test() returns (uint) { - y = a; + var y = a; delete y; y(); } -- cgit v1.2.3 From e543bd34c0b4884b5a27555f698f50af6a1c0b81 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 10 Nov 2016 18:16:21 +0100 Subject: Stored combined creation and runtime tags. Includes a change to Assembly to allow tags from sub-assemblies to be used. Sorry, this get a bit bigger than I thought. --- test/libsolidity/SolidityEndToEndTest.cpp | 63 +++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'test/libsolidity/SolidityEndToEndTest.cpp') diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index b05316dd..8f49b9c4 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7777,6 +7777,48 @@ BOOST_AUTO_TEST_CASE(store_function_in_constructor) BOOST_CHECK(callContractFunction("result_in_constructor()") == encodeArgs(u256(4))); } +// TODO: store bound internal library functions + +BOOST_AUTO_TEST_CASE(store_internal_unused_function_in_constructor) +{ + char const* sourceCode = R"( + contract C { + function () internal returns (uint) x; + function C () { + x = unused; + } + function unused() internal returns (uint) { + return 7; + } + function t() returns (uint) { + return x(); + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("t()") == encodeArgs(u256(7))); +} + +BOOST_AUTO_TEST_CASE(store_internal_unused_library_function_in_constructor) +{ + char const* sourceCode = R"( + library L { function x() internal returns (uint) { return 7; } } + contract C { + function () internal returns (uint) x; + function C () { + x = L.x; + } + function t() returns (uint) { + return x(); + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("t()") == encodeArgs(u256(7))); +} + BOOST_AUTO_TEST_CASE(same_function_in_construction_and_runtime) { char const* sourceCode = R"( @@ -7799,6 +7841,27 @@ BOOST_AUTO_TEST_CASE(same_function_in_construction_and_runtime) BOOST_CHECK(callContractFunction("initial()") == encodeArgs(u256(4))); } +BOOST_AUTO_TEST_CASE(same_function_in_construction_and_runtime_equality_check) +{ + char const* sourceCode = R"( + contract C { + function (uint) internal returns (uint) x; + function C() { + x = double; + } + function test() returns (bool) { + return x == double; + } + function double(uint _arg) returns (uint _ret) { + _ret = _arg * 2; + } + } + )"; + + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("test()") == encodeArgs(true)); +} + BOOST_AUTO_TEST_CASE(function_type_library_internal) { char const* sourceCode = R"( -- cgit v1.2.3 From e51f852504556f952ae1350c070409e3c4981cc0 Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 11 Nov 2016 11:41:50 +0100 Subject: Converted sub assembly to smart pointer. --- test/libsolidity/SolidityEndToEndTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/libsolidity/SolidityEndToEndTest.cpp') diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 8f49b9c4..c01d11d2 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7757,7 +7757,7 @@ BOOST_AUTO_TEST_CASE(store_function_in_constructor) { char const* sourceCode = R"( contract C { - uint result_in_constructor; + uint public result_in_constructor; function (uint) internal returns (uint) x; function C () { x = double; -- cgit v1.2.3 From ec31d08775021de0f3279dbeb115b3e688c5997e Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 14 Nov 2016 13:13:37 +0100 Subject: Change encoding to address-funid and add "function" as ABI type. --- test/libsolidity/SolidityEndToEndTest.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'test/libsolidity/SolidityEndToEndTest.cpp') diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index c01d11d2..ed95d687 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -7703,8 +7703,8 @@ BOOST_AUTO_TEST_CASE(receive_external_function_type) compileAndRun(sourceCode, 0, "C"); BOOST_CHECK(callContractFunction( - "f(bytes24)", - FixedHash<4>(dev::keccak256("g()")).asBytes() + m_contractAddress.asBytes() + bytes(32 - 4 - 20, 0) + "f(function)", + m_contractAddress.asBytes() + FixedHash<4>(dev::keccak256("g()")).asBytes() + bytes(32 - 4 - 20, 0) ) == encodeArgs(u256(7))); } @@ -7722,7 +7722,7 @@ BOOST_AUTO_TEST_CASE(return_external_function_type) compileAndRun(sourceCode, 0, "C"); BOOST_CHECK( callContractFunction("f()") == - FixedHash<4>(dev::keccak256("g()")).asBytes() + m_contractAddress.asBytes() + bytes(32 - 4 - 20, 0) + m_contractAddress.asBytes() + FixedHash<4>(dev::keccak256("g()")).asBytes() + bytes(32 - 4 - 20, 0) ); } -- cgit v1.2.3