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