From bd27ce0e25d298e075de6c77318e7a8df2e27f6d Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 16 Mar 2018 11:20:06 +0100 Subject: [PATCH] Extract function type tests. --- .../SolidityNameAndTypeResolution.cpp | 313 ------------------ ...all_value_on_non_payable_function_type.sol | 6 + .../call_value_on_payable_function_type.sol | 6 + .../delete_external_function_type_invalid.sol | 5 + .../functionTypes/delete_function_type.sol | 14 + .../delete_function_type_invalid.sol | 5 + ...on_to_function_type_calldata_parameter.sol | 7 + ...ernal_function_type_returning_internal.sol | 3 + ...external_function_type_taking_internal.sol | 3 + .../external_function_type_to_address.sol | 5 + .../external_function_type_to_uint.sol | 5 + .../functionTypes/function_type.sol | 5 + .../functionTypes/function_type_arrays.sol | 11 + .../functionTypes/function_type_parameter.sol | 5 + .../functionTypes/function_type_returned.sol | 5 + ...nternal_function_as_external_parameter.sol | 4 + ...external_parameter_in_library_external.sol | 4 + ...external_parameter_in_library_internal.sol | 4 + ...function_returned_from_public_function.sol | 4 + .../internal_function_type_to_address.sol | 5 + .../payable_internal_function_type.sol | 3 + ...le_internal_function_type_is_not_fatal.sol | 7 + .../functionTypes/private_function_type.sol | 5 + .../functionTypes/public_function_type.sol | 5 + ...rn_function_type_parameters_with_names.sol | 3 + ...tion_type_return_parameters_with_names.sol | 3 + 26 files changed, 132 insertions(+), 313 deletions(-) create mode 100644 test/libsolidity/syntaxTests/functionTypes/call_value_on_non_payable_function_type.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/call_value_on_payable_function_type.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/delete_external_function_type_invalid.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/delete_function_type.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/delete_function_type_invalid.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/external_function_to_function_type_calldata_parameter.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/external_function_type_returning_internal.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/external_function_type_taking_internal.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/external_function_type_to_uint.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/function_type.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/function_type_arrays.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/function_type_parameter.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/function_type_returned.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_external.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_internal.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/internal_function_returned_from_public_function.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/internal_function_type_to_address.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type_is_not_fatal.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/private_function_type.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/public_function_type.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/warn_function_type_parameters_with_names.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/warn_function_type_return_parameters_with_names.sol diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 293f5f44e..e5e5e246d 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -5264,319 +5264,6 @@ BOOST_AUTO_TEST_CASE(using_directive_for_missing_selftype) CHECK_ERROR(text, TypeError, "Member \"b\" not found or not visible after argument-dependent lookup in bytes memory"); } -BOOST_AUTO_TEST_CASE(function_type) -{ - char const* text = R"( - contract C { - function f() public { - function(uint) returns (uint) x; - } - } - )"; - CHECK_SUCCESS(text); -} - -BOOST_AUTO_TEST_CASE(function_type_parameter) -{ - char const* text = R"( - contract C { - function f(function(uint) external returns (uint) g) public returns (function(uint) external returns (uint)) { - return g; - } - } - )"; - CHECK_SUCCESS(text); -} - -BOOST_AUTO_TEST_CASE(function_type_returned) -{ - char const* text = R"( - contract C { - function f() public returns (function(uint) external returns (uint) g) { - return g; - } - } - )"; - CHECK_SUCCESS(text); -} - -BOOST_AUTO_TEST_CASE(private_function_type) -{ - char const* text = R"( - contract C { - function f() public { - function(uint) private returns (uint) x; - } - } - )"; - CHECK_ERROR(text, TypeError, "Invalid visibility, can only be \"external\" or \"internal\"."); -} - -BOOST_AUTO_TEST_CASE(public_function_type) -{ - char const* text = R"( - contract C { - function f() public { - function(uint) public returns (uint) x; - } - } - )"; - CHECK_ERROR(text, TypeError, "Invalid visibility, can only be \"external\" or \"internal\"."); -} - -BOOST_AUTO_TEST_CASE(payable_internal_function_type) -{ - char const* text = R"( - contract C { - function (uint) internal payable returns (uint) x; - } - )"; - CHECK_ERROR(text, TypeError, "Only external function types can be payable."); -} - -BOOST_AUTO_TEST_CASE(payable_internal_function_type_is_not_fatal) -{ - char const* text = R"( - contract C { - function (uint) internal payable returns (uint) x; - - function g() { - x = g; - } - } - )"; - CHECK_ERROR_ALLOW_MULTI(text, TypeError, (std::vector{"Only external function types can be payable."})); -} - -BOOST_AUTO_TEST_CASE(call_value_on_non_payable_function_type) -{ - char const* text = R"( - contract C { - function (uint) external returns (uint) x; - function f() public { - x.value(2)(); - } - } - )"; - CHECK_ERROR(text, TypeError, "Member \"value\" not found or not visible after argument-dependent lookup in function (uint256) external returns (uint256) - did you forget the \"payable\" modifier?"); -} - -BOOST_AUTO_TEST_CASE(external_function_type_returning_internal) -{ - char const* text = R"( - contract C { - function() external returns (function () internal) x; - } - )"; - CHECK_ERROR(text, TypeError, "Internal type cannot be used for external function type."); -} - -BOOST_AUTO_TEST_CASE(external_function_type_taking_internal) -{ - char const* text = R"( - contract C { - function(function () internal) external x; - } - )"; - CHECK_ERROR(text, TypeError, "Internal type cannot be used for external function type."); -} - -BOOST_AUTO_TEST_CASE(call_value_on_payable_function_type) -{ - char const* text = R"( - contract C { - function (uint) external payable returns (uint) x; - function f() public { - x.value(2)(1); - } - } - )"; - CHECK_SUCCESS(text); -} - -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) internal returns (uint) x) public { - } - } - )"; - CHECK_ERROR(text, TypeError, "Internal or recursive type is not allowed for public or external functions."); -} - -BOOST_AUTO_TEST_CASE(internal_function_returned_from_public_function) -{ - // It should not be possible to return internal functions from external functions. - char const* text = R"( - contract C { - function f() public returns (function(uint) internal returns (uint) x) { - } - } - )"; - CHECK_ERROR(text, TypeError, "Internal or recursive type is not allowed for public or external functions."); -} - -BOOST_AUTO_TEST_CASE(internal_function_as_external_parameter_in_library_internal) -{ - char const* text = R"( - library L { - function f(function(uint) internal returns (uint) x) internal { - } - } - )"; - 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) internal returns (uint) x) public { - } - } - )"; - CHECK_ERROR(text, TypeError, "Internal or recursive type is not allowed for public or external functions."); -} - -BOOST_AUTO_TEST_CASE(function_type_arrays) -{ - char const* text = R"( - contract C { - function(uint) external returns (uint)[] public x; - function(uint) internal returns (uint)[10] y; - function f() public { - function(uint) returns (uint)[10] memory a; - function(uint) returns (uint)[10] storage b = y; - function(uint) external returns (uint)[] memory c; - c = new function(uint) external returns (uint)[](200); - a; b; - } - } - )"; - CHECK_SUCCESS(text); -} - -BOOST_AUTO_TEST_CASE(delete_function_type) -{ - char const* text = R"( - contract C { - function(uint) external returns (uint) x; - function(uint) internal returns (uint) y; - function f() public { - delete x; - var a = y; - delete a; - delete y; - var c = f; - delete c; - function(uint) internal returns (uint) g; - delete g; - } - } - )"; - CHECK_SUCCESS(text); -} - -BOOST_AUTO_TEST_CASE(delete_function_type_invalid) -{ - char const* text = R"( - contract C { - function f() public { - delete f; - } - } - )"; - CHECK_ERROR(text, TypeError, "Expression has to be an lvalue."); -} - -BOOST_AUTO_TEST_CASE(delete_external_function_type_invalid) -{ - char const* text = R"( - contract C { - function f() public { - delete this.f; - } - } - )"; - CHECK_ERROR(text, TypeError, "Expression has to be an lvalue."); -} - -BOOST_AUTO_TEST_CASE(external_function_to_function_type_calldata_parameter) -{ - // This is a test that checks that the type of the `bytes` parameter is - // correctly changed from its own type `bytes calldata` to `bytes memory` - // when converting to a function type. - char const* text = R"( - contract C { - function f(function(bytes memory) external g) public { } - function callback(bytes) external {} - function g() public { - f(this.callback); - } - } - )"; - CHECK_SUCCESS(text); -} - -BOOST_AUTO_TEST_CASE(external_function_type_to_address) -{ - char const* text = R"( - contract C { - function f() public returns (address) { - return address(this.f); - } - } - )"; - CHECK_SUCCESS(text); -} - -BOOST_AUTO_TEST_CASE(internal_function_type_to_address) -{ - char const* text = R"( - contract C { - function f() public returns (address) { - return address(f); - } - } - )"; - CHECK_ERROR(text, TypeError, "Explicit type conversion not allowed"); -} - -BOOST_AUTO_TEST_CASE(external_function_type_to_uint) -{ - char const* text = R"( - contract C { - function f() public returns (uint) { - return uint(this.f); - } - } - )"; - CHECK_ERROR(text, TypeError, "Explicit type conversion not allowed"); -} - -BOOST_AUTO_TEST_CASE(warn_function_type_parameters_with_names) -{ - char const* text = R"( - contract C { - function(uint a) f; - } - )"; - CHECK_WARNING(text, "Naming function type parameters is deprecated."); -} - -BOOST_AUTO_TEST_CASE(warn_function_type_return_parameters_with_names) -{ - char const* text = R"( - contract C { - function(uint) returns (bool ret) f; - } - )"; - CHECK_WARNING(text, "Naming function type return parameters is deprecated."); -} - BOOST_AUTO_TEST_CASE(shift_constant_left_negative_rvalue) { char const* text = R"( diff --git a/test/libsolidity/syntaxTests/functionTypes/call_value_on_non_payable_function_type.sol b/test/libsolidity/syntaxTests/functionTypes/call_value_on_non_payable_function_type.sol new file mode 100644 index 000000000..dac7908fe --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/call_value_on_non_payable_function_type.sol @@ -0,0 +1,6 @@ +contract C { + function (uint) external returns (uint) x; + function f() public { + x.value(2)(); + } +} diff --git a/test/libsolidity/syntaxTests/functionTypes/call_value_on_payable_function_type.sol b/test/libsolidity/syntaxTests/functionTypes/call_value_on_payable_function_type.sol new file mode 100644 index 000000000..ca2a01964 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/call_value_on_payable_function_type.sol @@ -0,0 +1,6 @@ +contract C { + function (uint) external payable returns (uint) x; + function f() public { + x.value(2)(1); + } +} diff --git a/test/libsolidity/syntaxTests/functionTypes/delete_external_function_type_invalid.sol b/test/libsolidity/syntaxTests/functionTypes/delete_external_function_type_invalid.sol new file mode 100644 index 000000000..e3bf2dee9 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/delete_external_function_type_invalid.sol @@ -0,0 +1,5 @@ +contract C { + function f() public { + delete this.f; + } +} diff --git a/test/libsolidity/syntaxTests/functionTypes/delete_function_type.sol b/test/libsolidity/syntaxTests/functionTypes/delete_function_type.sol new file mode 100644 index 000000000..40c0c86f8 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/delete_function_type.sol @@ -0,0 +1,14 @@ +contract C { + function(uint) external returns (uint) x; + function(uint) internal returns (uint) y; + function f() public { + delete x; + var a = y; + delete a; + delete y; + var c = f; + delete c; + function(uint) internal returns (uint) g; + delete g; + } +} diff --git a/test/libsolidity/syntaxTests/functionTypes/delete_function_type_invalid.sol b/test/libsolidity/syntaxTests/functionTypes/delete_function_type_invalid.sol new file mode 100644 index 000000000..c2c77be0e --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/delete_function_type_invalid.sol @@ -0,0 +1,5 @@ +contract C { + function f() public { + delete f; + } +} diff --git a/test/libsolidity/syntaxTests/functionTypes/external_function_to_function_type_calldata_parameter.sol b/test/libsolidity/syntaxTests/functionTypes/external_function_to_function_type_calldata_parameter.sol new file mode 100644 index 000000000..cbf90e403 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/external_function_to_function_type_calldata_parameter.sol @@ -0,0 +1,7 @@ +contract C { + function f(function(bytes memory) external g) public { } + function callback(bytes) external {} + function g() public { + f(this.callback); + } +} diff --git a/test/libsolidity/syntaxTests/functionTypes/external_function_type_returning_internal.sol b/test/libsolidity/syntaxTests/functionTypes/external_function_type_returning_internal.sol new file mode 100644 index 000000000..c4f56b41d --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/external_function_type_returning_internal.sol @@ -0,0 +1,3 @@ +contract C { + function() external returns (function () internal) x; +} diff --git a/test/libsolidity/syntaxTests/functionTypes/external_function_type_taking_internal.sol b/test/libsolidity/syntaxTests/functionTypes/external_function_type_taking_internal.sol new file mode 100644 index 000000000..c3ba80a3b --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/external_function_type_taking_internal.sol @@ -0,0 +1,3 @@ +contract C { + function(function () internal) external x; +} diff --git a/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address.sol b/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address.sol new file mode 100644 index 000000000..5f4d40650 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address.sol @@ -0,0 +1,5 @@ +contract C { + function f() public returns (address) { + return address(this.f); + } +} diff --git a/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_uint.sol b/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_uint.sol new file mode 100644 index 000000000..e47abefbf --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_uint.sol @@ -0,0 +1,5 @@ +contract C { + function f() public returns (uint) { + return uint(this.f); + } +} diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type.sol b/test/libsolidity/syntaxTests/functionTypes/function_type.sol new file mode 100644 index 000000000..a879e351c --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/function_type.sol @@ -0,0 +1,5 @@ +contract C { + function f() public { + function(uint) returns (uint) x; + } +} diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_arrays.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_arrays.sol new file mode 100644 index 000000000..c402dbff2 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/function_type_arrays.sol @@ -0,0 +1,11 @@ +contract C { + function(uint) external returns (uint)[] public x; + function(uint) internal returns (uint)[10] y; + function f() public { + function(uint) returns (uint)[10] memory a; + function(uint) returns (uint)[10] storage b = y; + function(uint) external returns (uint)[] memory c; + c = new function(uint) external returns (uint)[](200); + a; b; + } +} diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_parameter.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_parameter.sol new file mode 100644 index 000000000..c787e6f07 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/function_type_parameter.sol @@ -0,0 +1,5 @@ +contract C { + function f(function(uint) external returns (uint) g) public returns (function(uint) external returns (uint)) { + return g; + } +} diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_returned.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_returned.sol new file mode 100644 index 000000000..0590fad4d --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/function_type_returned.sol @@ -0,0 +1,5 @@ +contract C { + function f() public returns (function(uint) external returns (uint) g) { + return g; + } +} diff --git a/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter.sol b/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter.sol new file mode 100644 index 000000000..3103001d2 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter.sol @@ -0,0 +1,4 @@ +contract C { + function f(function(uint) internal returns (uint) x) public { + } +} diff --git a/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_external.sol b/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_external.sol new file mode 100644 index 000000000..7856d62d2 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_external.sol @@ -0,0 +1,4 @@ +library L { + function f(function(uint) internal returns (uint) x) public { + } +} diff --git a/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_internal.sol b/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_internal.sol new file mode 100644 index 000000000..13d6d03d8 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_internal.sol @@ -0,0 +1,4 @@ +library L { + function f(function(uint) internal returns (uint) x) internal { + } +} diff --git a/test/libsolidity/syntaxTests/functionTypes/internal_function_returned_from_public_function.sol b/test/libsolidity/syntaxTests/functionTypes/internal_function_returned_from_public_function.sol new file mode 100644 index 000000000..e836a6cc6 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/internal_function_returned_from_public_function.sol @@ -0,0 +1,4 @@ +contract C { + function f() public returns (function(uint) internal returns (uint) x) { + } +} diff --git a/test/libsolidity/syntaxTests/functionTypes/internal_function_type_to_address.sol b/test/libsolidity/syntaxTests/functionTypes/internal_function_type_to_address.sol new file mode 100644 index 000000000..4a3f02c1f --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/internal_function_type_to_address.sol @@ -0,0 +1,5 @@ +contract C { + function f() public returns (address) { + return address(f); + } +} diff --git a/test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type.sol b/test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type.sol new file mode 100644 index 000000000..69efaad4b --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type.sol @@ -0,0 +1,3 @@ +contract C { + function (uint) internal payable returns (uint) x; +} diff --git a/test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type_is_not_fatal.sol b/test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type_is_not_fatal.sol new file mode 100644 index 000000000..fb84f9ca4 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type_is_not_fatal.sol @@ -0,0 +1,7 @@ +contract C { + function (uint) internal payable returns (uint) x; + + function g() { + x = g; + } +} diff --git a/test/libsolidity/syntaxTests/functionTypes/private_function_type.sol b/test/libsolidity/syntaxTests/functionTypes/private_function_type.sol new file mode 100644 index 000000000..d15430d23 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/private_function_type.sol @@ -0,0 +1,5 @@ +contract C { + function f() public { + function(uint) private returns (uint) x; + } +} diff --git a/test/libsolidity/syntaxTests/functionTypes/public_function_type.sol b/test/libsolidity/syntaxTests/functionTypes/public_function_type.sol new file mode 100644 index 000000000..ecc2493ad --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/public_function_type.sol @@ -0,0 +1,5 @@ +contract C { + function f() public { + function(uint) public returns (uint) x; + } +} diff --git a/test/libsolidity/syntaxTests/functionTypes/warn_function_type_parameters_with_names.sol b/test/libsolidity/syntaxTests/functionTypes/warn_function_type_parameters_with_names.sol new file mode 100644 index 000000000..44417f256 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/warn_function_type_parameters_with_names.sol @@ -0,0 +1,3 @@ +contract C { + function(uint a) f; +} diff --git a/test/libsolidity/syntaxTests/functionTypes/warn_function_type_return_parameters_with_names.sol b/test/libsolidity/syntaxTests/functionTypes/warn_function_type_return_parameters_with_names.sol new file mode 100644 index 000000000..f8c21fa80 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/warn_function_type_return_parameters_with_names.sol @@ -0,0 +1,3 @@ +contract C { + function(uint) returns (bool ret) f; +}