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 +++++++++++++++++++++- test/libsolidity/SolidityNameAndTypeResolution.cpp | 33 +++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) (limited to 'test/libsolidity') 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"( diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 7f12cd86..2d469cdc 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -4180,6 +4180,39 @@ BOOST_AUTO_TEST_CASE(public_function_type) BOOST_CHECK(expectError(text) == Error::Type::TypeError); } +BOOST_AUTO_TEST_CASE(internal_function_as_external_parameter) +{ + // It should not be possible to give internal functions + // as parameters to external functions. + char const* text = R"( + contract C { + function f(function(uint) returns (uint) x) { + } + } + )"; + BOOST_CHECK(expectError(text) == Error::Type::TypeError); +} + +BOOST_AUTO_TEST_CASE(internal_function_as_external_parameter_in_library_internal) +{ + char const* text = R"( + library L { + function f(function(uint) returns (uint) x) internal { + } + } + )"; + BOOST_CHECK(success(text)); +} +BOOST_AUTO_TEST_CASE(internal_function_as_external_parameter_in_library_external) +{ + char const* text = R"( + library L { + function f(function(uint) returns (uint) x) { + } + } + )"; + BOOST_CHECK(expectError(text) == Error::Type::TypeError); +} BOOST_AUTO_TEST_CASE(invalid_fixed_point_literal) { -- cgit