mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Extract function type tests.
This commit is contained in:
parent
7626c8ab72
commit
bd27ce0e25
@ -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<std::string>{"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"(
|
||||
|
@ -0,0 +1,6 @@
|
||||
contract C {
|
||||
function (uint) external returns (uint) x;
|
||||
function f() public {
|
||||
x.value(2)();
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
contract C {
|
||||
function (uint) external payable returns (uint) x;
|
||||
function f() public {
|
||||
x.value(2)(1);
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
contract C {
|
||||
function f() public {
|
||||
delete this.f;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
contract C {
|
||||
function f() public {
|
||||
delete f;
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
contract C {
|
||||
function f(function(bytes memory) external g) public { }
|
||||
function callback(bytes) external {}
|
||||
function g() public {
|
||||
f(this.callback);
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
contract C {
|
||||
function() external returns (function () internal) x;
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
contract C {
|
||||
function(function () internal) external x;
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
contract C {
|
||||
function f() public returns (address) {
|
||||
return address(this.f);
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
contract C {
|
||||
function f() public returns (uint) {
|
||||
return uint(this.f);
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
contract C {
|
||||
function f() public {
|
||||
function(uint) returns (uint) x;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
contract C {
|
||||
function f(function(uint) external returns (uint) g) public returns (function(uint) external returns (uint)) {
|
||||
return g;
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
contract C {
|
||||
function f() public returns (function(uint) external returns (uint) g) {
|
||||
return g;
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
contract C {
|
||||
function f(function(uint) internal returns (uint) x) public {
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
library L {
|
||||
function f(function(uint) internal returns (uint) x) public {
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
library L {
|
||||
function f(function(uint) internal returns (uint) x) internal {
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
contract C {
|
||||
function f() public returns (function(uint) internal returns (uint) x) {
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
contract C {
|
||||
function f() public returns (address) {
|
||||
return address(f);
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
contract C {
|
||||
function (uint) internal payable returns (uint) x;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
contract C {
|
||||
function (uint) internal payable returns (uint) x;
|
||||
|
||||
function g() {
|
||||
x = g;
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
contract C {
|
||||
function f() public {
|
||||
function(uint) private returns (uint) x;
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
contract C {
|
||||
function f() public {
|
||||
function(uint) public returns (uint) x;
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
contract C {
|
||||
function(uint a) f;
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
contract C {
|
||||
function(uint) returns (bool ret) f;
|
||||
}
|
Loading…
Reference in New Issue
Block a user