From aba5ac5e2a90477b4d69cb7e7eb4eb24407257ae Mon Sep 17 00:00:00 2001 From: wechman Date: Thu, 28 Jul 2022 08:39:10 +0200 Subject: [PATCH] User-defined operators: Tests --- .../ASTJSON/user_defined_operator.json | 663 +++++++++++++++++ .../ASTJSON/user_defined_operator.sol | 11 + .../analysis/FunctionCallGraph.cpp | 66 ++ .../userDefined/all_possible_operators.sol | 92 +++ ...ser_defined_value_types_with_operators.sol | 670 ++++++++++++++++++ ...d_defining_operator_with_same_function.sol | 20 + .../userDefined/checked_operators.sol | 22 + .../consecutive_operator_invocations.sol | 18 + .../fixed_point_udvt_with_operators.sol | 22 + ...ifferent_functions_separate_directives.sol | 26 + ...same_type_same_function_same_directive.sol | 20 + ...definition_shadowing_builtin_keccak256.sol | 15 + .../userDefined/operator_evaluation_order.sol | 83 +++ .../operator_making_pure_external_call.sol | 61 ++ .../operator_making_view_external_call.sol | 67 ++ .../operator_parameter_cleanup.sol | 40 ++ .../userDefined/operator_precendence.sol | 71 ++ .../operator_return_parameter_cleanup.sol | 58 ++ .../userDefined/recursive_operator.sol | 41 ++ .../userDefined/unchecked_operators.sol | 25 + .../user_defined_division_same_as_builtin.sol | 16 + ...ed_division_with_safe_division_by_zero.sol | 19 + .../user_defined_operations_on_constants.sol | 104 +++ ...r_defined_operations_on_constants_fail.sol | 104 +++ ...rator_matches_equivalent_function_call.sol | 105 +++ .../userDefined/user_defined_overflow.sol | 23 + .../constant_cyclic_via_user_operators.sol | 10 + .../binary_operator_udvt.sol | 17 + .../unary_operator_udvt.sol | 17 + ...203_struct_reference_compare_operators.sol | 2 +- ...ator_binary_user_defined_not_available.sol | 11 + ...rator_unary_user_defined_not_available.sol | 11 + .../userDefined/calling_operator.sol | 11 + ...as_attached_function_via_function_name.sol | 12 + ...as_attached_function_via_operator_name.sol | 12 + ..._operator_defined_separately_from_type.sol | 23 + ...fined_separately_from_type_and_binding.sol | 30 + .../userDefined/calling_operator_imported.sol | 17 + .../calling_operator_imported_non_global.sol | 22 + ...calling_operator_imported_transitively.sol | 35 + ...rator_imported_transitively_non_global.sol | 35 + ...ng_operator_in_constant_initialization.sol | 24 + .../calling_operator_non_global.sol | 14 + ...calling_operator_that_deploys_contract.sol | 24 + ...ling_operator_that_makes_external_call.sol | 20 + ...operator_that_makes_pure_external_call.sol | 17 + ...operator_that_makes_view_external_call.sol | 20 + ...ling_operator_with_implicit_conversion.sol | 32 + .../defining_operator_for_builtin_types.sol | 18 + .../defining_operator_for_contract.sol | 13 + .../defining_operator_for_enum.sol | 10 + .../defining_operator_for_error.sol | 10 + .../defining_operator_for_event.sol | 10 + .../defining_operator_for_interface.sol | 8 + .../defining_operator_for_library.sol | 6 + .../defining_operator_for_struct.sol | 9 + ...or_for_wildcard_type_at_contract_level.sol | 16 + ...erator_for_wildcard_type_at_file_level.sol | 6 + ...g_operator_with_attached_free_function.sol | 9 + ...nting_operator_with_builtin_abi_encode.sol | 8 + ...enting_operator_with_builtin_keccak256.sol | 5 + ...lementing_operator_with_builtin_revert.sol | 5 + ...th_contract_function_at_contract_level.sol | 9 + ...r_with_contract_function_at_file_level.sol | 11 + .../implementing_operator_with_error.sol | 7 + .../implementing_operator_with_event.sol | 9 + ...menting_operator_with_function_pointer.sol | 8 + ...h_function_shadowing_builtin_keccak256.sol | 9 + .../implementing_operator_with_library.sol | 7 + ...ith_library_function_at_contract_level.sol | 113 +++ ...or_with_library_function_at_file_level.sol | 39 + ...ry_function_private_outside_of_library.sol | 36 + ...enting_operator_with_non_pure_function.sol | 12 + ...e_function_on_built_in_type_non_global.sol | 8 + ...ting_operator_with_overloaded_function.sol | 10 + ...tor_with_privately_overloaded_function.sol | 12 + ...alified_library_function_at_file_level.sol | 9 + ...nqualified_library_function_in_library.sol | 22 + ..._global_and_non_global_different_files.sol | 20 + ..._different_functions_global_non_global.sol | 26 + ..._non_global_and_global_different_files.sol | 20 + ...ons_different_functions_same_directive.sol | 13 + ...tions_same_directive_operator_not_used.sol | 15 + ...definitions_on_file_and_contract_level.sol | 23 + ...unction_different_levels_free_function.sol | 19 + ...tion_different_levels_library_function.sol | 38 + ...finitions_same_function_same_directive.sol | 9 + ...ions_same_function_separate_directives.sol | 10 + .../userDefined/operator_overloading.sol | 14 + ...operator_parsing_function_name_missing.sol | 3 + .../userDefined/operator_parsing_no_brace.sol | 3 + .../operator_parsing_non_user_definable.sol | 45 ++ .../operator_parsing_not_an_operator.sol | 14 + ...operator_parsing_operator_name_missing.sol | 4 + .../operator_parsing_operator_named_as.sol | 3 + .../operator_returning_wrong_types.sol | 33 + ...returning_types_not_matching_using_for.sol | 26 + .../operator_taking_no_parameters_binary.sol | 11 + .../operator_taking_no_parameters_unary.sol | 11 + ...or_taking_or_returning_different_types.sol | 20 + .../operator_taking_two_parameters_unary.sol | 14 + ..._and_defining_operators_same_directive.sol | 10 + ...contract_level_for_contract_level_type.sol | 19 + ...with_operator_at_contract_level_global.sol | 13 + ...t_contract_level_global_different_file.sol | 13 + ...tor_at_contract_level_in_base_contract.sol | 30 + ...perator_at_contract_level_in_interface.sol | 10 + ..._at_file_level_for_contract_level_type.sol | 27 + ...vel_for_contract_level_type_non_global.sol | 30 + ...or_at_file_level_global_and_non_global.sol | 23 + ...or_at_file_level_global_different_file.sol | 11 + ..._unary_and_non_global_binary_same_file.sol | 20 + .../syntaxTests/using/using_for_enum.sol | 5 + ...r_with_pure_modifier_can_be_restricted.sol | 20 + 114 files changed, 3956 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/ASTJSON/user_defined_operator.json create mode 100644 test/libsolidity/ASTJSON/user_defined_operator.sol create mode 100644 test/libsolidity/semanticTests/operators/userDefined/all_possible_operators.sol create mode 100644 test/libsolidity/semanticTests/operators/userDefined/all_possible_user_defined_value_types_with_operators.sol create mode 100644 test/libsolidity/semanticTests/operators/userDefined/attaching_and_defining_operator_with_same_function.sol create mode 100644 test/libsolidity/semanticTests/operators/userDefined/checked_operators.sol create mode 100644 test/libsolidity/semanticTests/operators/userDefined/consecutive_operator_invocations.sol create mode 100644 test/libsolidity/semanticTests/operators/userDefined/fixed_point_udvt_with_operators.sol create mode 100644 test/libsolidity/semanticTests/operators/userDefined/multiple_operator_definitions_different_types_different_functions_separate_directives.sol create mode 100644 test/libsolidity/semanticTests/operators/userDefined/multiple_operator_definitions_same_type_same_function_same_directive.sol create mode 100644 test/libsolidity/semanticTests/operators/userDefined/operator_definition_shadowing_builtin_keccak256.sol create mode 100644 test/libsolidity/semanticTests/operators/userDefined/operator_evaluation_order.sol create mode 100644 test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol create mode 100644 test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol create mode 100644 test/libsolidity/semanticTests/operators/userDefined/operator_parameter_cleanup.sol create mode 100644 test/libsolidity/semanticTests/operators/userDefined/operator_precendence.sol create mode 100644 test/libsolidity/semanticTests/operators/userDefined/operator_return_parameter_cleanup.sol create mode 100644 test/libsolidity/semanticTests/operators/userDefined/recursive_operator.sol create mode 100644 test/libsolidity/semanticTests/operators/userDefined/unchecked_operators.sol create mode 100644 test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_division_same_as_builtin.sol create mode 100644 test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_division_with_safe_division_by_zero.sol create mode 100644 test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants.sol create mode 100644 test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants_fail.sol create mode 100644 test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol create mode 100644 test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_overflow.sol create mode 100644 test/libsolidity/syntaxTests/constants/constant_cyclic_via_user_operators.sol create mode 100644 test/libsolidity/syntaxTests/controlFlow/userDefinedOperators/binary_operator_udvt.sol create mode 100644 test/libsolidity/syntaxTests/controlFlow/userDefinedOperators/unary_operator_udvt.sol create mode 100644 test/libsolidity/syntaxTests/operators/calling_operator_binary_user_defined_not_available.sol create mode 100644 test/libsolidity/syntaxTests/operators/calling_operator_unary_user_defined_not_available.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/calling_operator.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/calling_operator_as_attached_function_via_function_name.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/calling_operator_as_attached_function_via_operator_name.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/calling_operator_defined_separately_from_type.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/calling_operator_defined_separately_from_type_and_binding.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/calling_operator_imported.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/calling_operator_imported_non_global.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/calling_operator_imported_transitively.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/calling_operator_imported_transitively_non_global.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/calling_operator_in_constant_initialization.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/calling_operator_non_global.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/calling_operator_that_deploys_contract.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/calling_operator_that_makes_external_call.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/calling_operator_that_makes_pure_external_call.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/calling_operator_that_makes_view_external_call.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/calling_operator_with_implicit_conversion.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_builtin_types.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_contract.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_enum.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_error.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_event.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_interface.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_library.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_struct.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_wildcard_type_at_contract_level.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_wildcard_type_at_file_level.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_attached_free_function.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_builtin_abi_encode.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_builtin_keccak256.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_builtin_revert.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_contract_function_at_contract_level.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_contract_function_at_file_level.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_error.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_event.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_function_pointer.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_function_shadowing_builtin_keccak256.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_library.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_library_function_at_contract_level.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_library_function_at_file_level.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_library_function_private_outside_of_library.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_non_pure_function.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_non_pure_function_on_built_in_type_non_global.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_overloaded_function.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_privately_overloaded_function.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_unqualified_library_function_at_file_level.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_unqualified_library_function_in_library.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_global_and_non_global_different_files.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_global_non_global.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_non_global_and_global_different_files.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_same_directive.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_same_directive_operator_not_used.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_on_file_and_contract_level.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_same_function_different_levels_free_function.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_same_function_different_levels_library_function.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_same_function_same_directive.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_same_function_separate_directives.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/operator_overloading.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_function_name_missing.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_no_brace.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_non_user_definable.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_not_an_operator.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_operator_name_missing.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_operator_named_as.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/operator_returning_wrong_types.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/operator_taking_and_returning_types_not_matching_using_for.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/operator_taking_no_parameters_binary.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/operator_taking_no_parameters_unary.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/operator_taking_or_returning_different_types.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/operator_taking_two_parameters_unary.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/using_for_attaching_functions_and_defining_operators_same_directive.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_for_contract_level_type.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_global.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_global_different_file.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_in_base_contract.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_in_interface.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_for_contract_level_type.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_for_contract_level_type_non_global.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_global_and_non_global.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_global_different_file.sol create mode 100644 test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_global_unary_and_non_global_binary_same_file.sol create mode 100644 test/libsolidity/syntaxTests/using/using_for_enum.sol create mode 100644 test/libsolidity/syntaxTests/viewPureChecker/user_operator_with_pure_modifier_can_be_restricted.sol diff --git a/test/libsolidity/ASTJSON/user_defined_operator.json b/test/libsolidity/ASTJSON/user_defined_operator.json new file mode 100644 index 000000000..dd1c0d941 --- /dev/null +++ b/test/libsolidity/ASTJSON/user_defined_operator.json @@ -0,0 +1,663 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 49 + ], + "I8": + [ + 2 + ], + "sub": + [ + 20 + ], + "unsub": + [ + 30 + ] + }, + "id": 50, + "nodeType": "SourceUnit", + "nodes": + [ + { + "canonicalName": "I8", + "id": 2, + "name": "I8", + "nameLocation": "5:2:1", + "nodeType": "UserDefinedValueTypeDefinition", + "src": "0:16:1", + "underlyingType": + { + "id": 1, + "name": "int8", + "nodeType": "ElementaryTypeName", + "src": "11:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_int8", + "typeString": "int8" + } + } + }, + { + "functionList": + [ + { + "definition": + { + "id": 3, + "name": "sub", + "nameLocations": + [ + "24:3:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 20, + "src": "24:3:1" + }, + "operator": "-" + }, + { + "definition": + { + "id": 4, + "name": "unsub", + "nameLocations": + [ + "34:5:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 30, + "src": "34:5:1" + }, + "operator": "-" + } + ], + "global": true, + "id": 7, + "nodeType": "UsingForDirective", + "src": "17:43:1", + "typeName": + { + "id": 6, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 5, + "name": "I8", + "nameLocations": + [ + "50:2:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2, + "src": "50:2:1" + }, + "referencedDeclaration": 2, + "src": "50:2:1", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + } + } + }, + { + "body": + { + "id": 19, + "nodeType": "Block", + "src": "100:2:1", + "statements": [] + }, + "id": 20, + "implemented": true, + "kind": "freeFunction", + "modifiers": [], + "name": "sub", + "nameLocation": "70:3:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 14, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 10, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 20, + "src": "74:2:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + }, + "typeName": + { + "id": 9, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 8, + "name": "I8", + "nameLocations": + [ + "74:2:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2, + "src": "74:2:1" + }, + "referencedDeclaration": 2, + "src": "74:2:1", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 13, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 20, + "src": "78:2:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + }, + "typeName": + { + "id": 12, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 11, + "name": "I8", + "nameLocations": + [ + "78:2:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2, + "src": "78:2:1" + }, + "referencedDeclaration": 2, + "src": "78:2:1", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + } + }, + "visibility": "internal" + } + ], + "src": "73:8:1" + }, + "returnParameters": + { + "id": 18, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 17, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 20, + "src": "96:2:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + }, + "typeName": + { + "id": 16, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 15, + "name": "I8", + "nameLocations": + [ + "96:2:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2, + "src": "96:2:1" + }, + "referencedDeclaration": 2, + "src": "96:2:1", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + } + }, + "visibility": "internal" + } + ], + "src": "95:4:1" + }, + "scope": 50, + "src": "61:41:1", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 29, + "nodeType": "Block", + "src": "140:2:1", + "statements": [] + }, + "id": 30, + "implemented": true, + "kind": "freeFunction", + "modifiers": [], + "name": "unsub", + "nameLocation": "112:5:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 24, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 23, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 30, + "src": "118:2:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + }, + "typeName": + { + "id": 22, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 21, + "name": "I8", + "nameLocations": + [ + "118:2:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2, + "src": "118:2:1" + }, + "referencedDeclaration": 2, + "src": "118:2:1", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + } + }, + "visibility": "internal" + } + ], + "src": "117:4:1" + }, + "returnParameters": + { + "id": 28, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 27, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 30, + "src": "136:2:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + }, + "typeName": + { + "id": 26, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 25, + "name": "I8", + "nameLocations": + [ + "136:2:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2, + "src": "136:2:1" + }, + "referencedDeclaration": 2, + "src": "136:2:1", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + } + }, + "visibility": "internal" + } + ], + "src": "135:4:1" + }, + "scope": 50, + "src": "103:39:1", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 49, + "linearizedBaseContracts": + [ + 49 + ], + "name": "C", + "nameLocation": "152:1:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 47, + "nodeType": "Block", + "src": "208:30:1", + "statements": + [ + { + "expression": + { + "commonType": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + }, + "function": 20, + "id": 45, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": + { + "function": 30, + "id": 43, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "-", + "prefix": true, + "src": "225:2:1", + "subExpression": + { + "id": 42, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 33, + "src": "226:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": + { + "id": 44, + "name": "b", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 36, + "src": "230:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + } + }, + "src": "225:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + } + }, + "functionReturnParameters": 41, + "id": 46, + "nodeType": "Return", + "src": "218:13:1" + } + ] + }, + "functionSelector": "ac9fe858", + "id": 48, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "169:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 37, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 33, + "mutability": "mutable", + "name": "a", + "nameLocation": "174:1:1", + "nodeType": "VariableDeclaration", + "scope": 48, + "src": "171:4:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + }, + "typeName": + { + "id": 32, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 31, + "name": "I8", + "nameLocations": + [ + "171:2:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2, + "src": "171:2:1" + }, + "referencedDeclaration": 2, + "src": "171:2:1", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 36, + "mutability": "mutable", + "name": "b", + "nameLocation": "180:1:1", + "nodeType": "VariableDeclaration", + "scope": 48, + "src": "177:4:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + }, + "typeName": + { + "id": 35, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 34, + "name": "I8", + "nameLocations": + [ + "177:2:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2, + "src": "177:2:1" + }, + "referencedDeclaration": 2, + "src": "177:2:1", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + } + }, + "visibility": "internal" + } + ], + "src": "170:12:1" + }, + "returnParameters": + { + "id": 41, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 40, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 48, + "src": "204:2:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + }, + "typeName": + { + "id": 39, + "nodeType": "UserDefinedTypeName", + "pathNode": + { + "id": 38, + "name": "I8", + "nameLocations": + [ + "204:2:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2, + "src": "204:2:1" + }, + "referencedDeclaration": 2, + "src": "204:2:1", + "typeDescriptions": + { + "typeIdentifier": "t_userDefinedValueType$_I8_$2", + "typeString": "I8" + } + }, + "visibility": "internal" + } + ], + "src": "203:4:1" + }, + "scope": 49, + "src": "160:78:1", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + } + ], + "scope": 50, + "src": "143:97:1", + "usedErrors": [] + } + ], + "src": "0:241:1" +} diff --git a/test/libsolidity/ASTJSON/user_defined_operator.sol b/test/libsolidity/ASTJSON/user_defined_operator.sol new file mode 100644 index 000000000..df5d0ed32 --- /dev/null +++ b/test/libsolidity/ASTJSON/user_defined_operator.sol @@ -0,0 +1,11 @@ +type I8 is int8; +using {sub as -, unsub as -} for I8 global; +function sub(I8, I8) pure returns (I8) {} +function unsub(I8) pure returns (I8) {} +contract C { + function f(I8 a, I8 b) public pure returns (I8) { + return -a - b; + } +} + +// ---- diff --git a/test/libsolidity/analysis/FunctionCallGraph.cpp b/test/libsolidity/analysis/FunctionCallGraph.cpp index fcc8d1423..da17fc433 100644 --- a/test/libsolidity/analysis/FunctionCallGraph.cpp +++ b/test/libsolidity/analysis/FunctionCallGraph.cpp @@ -1702,6 +1702,72 @@ BOOST_AUTO_TEST_CASE(using_for) checkCallGraphExpectations(get<1>(graphs), expectedDeployedEdges); } +BOOST_AUTO_TEST_CASE(user_defined_binary_operator) +{ + unique_ptr compilerStack = parseAndAnalyzeContracts(R"( + type Int is int128; + using {add as +} for Int global; + + function add(Int, Int) pure returns (Int) { + return Int.wrap(0); + } + + contract C { + function pub() public { + Int.wrap(0) + Int.wrap(1); + } + } + )"s); + tuple graphs = collectGraphs(*compilerStack); + + map expectedCreationEdges = { + {"C", {}}, + }; + + map expectedDeployedEdges = { + {"C", { + {"Entry", "function C.pub()"}, + {"function C.pub()", "function add(Int,Int)"}, + }}, + }; + + checkCallGraphExpectations(get<0>(graphs), expectedCreationEdges); + checkCallGraphExpectations(get<1>(graphs), expectedDeployedEdges); +} + +BOOST_AUTO_TEST_CASE(user_defined_unary_operator) +{ + unique_ptr compilerStack = parseAndAnalyzeContracts(R"( + type Int is int128; + using {sub as -} for Int global; + + function sub(Int) pure returns (Int) { + return Int.wrap(0); + } + + contract C { + function pub() public { + -Int.wrap(1); + } + } + )"s); + tuple graphs = collectGraphs(*compilerStack); + + map expectedCreationEdges = { + {"C", {}}, + }; + + map expectedDeployedEdges = { + {"C", { + {"Entry", "function C.pub()"}, + {"function C.pub()", "function sub(Int)"}, + }}, + }; + + checkCallGraphExpectations(get<0>(graphs), expectedCreationEdges); + checkCallGraphExpectations(get<1>(graphs), expectedDeployedEdges); +} + BOOST_AUTO_TEST_CASE(getters) { unique_ptr compilerStack = parseAndAnalyzeContracts(R"( diff --git a/test/libsolidity/semanticTests/operators/userDefined/all_possible_operators.sol b/test/libsolidity/semanticTests/operators/userDefined/all_possible_operators.sol new file mode 100644 index 000000000..315356b6c --- /dev/null +++ b/test/libsolidity/semanticTests/operators/userDefined/all_possible_operators.sol @@ -0,0 +1,92 @@ +type Int is int8; +using { + bitor as |, bitand as &, bitxor as ^, bitnot as ~, + add as +, sub as -, unsub as -, mul as *, div as /, mod as %, + eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >= +} for Int global; + +function bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); } +function bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); } +function bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); } +function bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); } + +function add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); } +function sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); } +function unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); } +function mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); } +function div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); } +function mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); } + +function eq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) == Int.unwrap(y); } +function noteq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) != Int.unwrap(y); } +function lt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) < Int.unwrap(y); } +function gt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) > Int.unwrap(y); } +function leq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) <= Int.unwrap(y); } +function geq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) >= Int.unwrap(y); } + +contract C { + Int constant ZERO = Int.wrap(0); + Int constant ONE = Int.wrap(1); + Int constant TWO = Int.wrap(2); + Int constant THREE = Int.wrap(3); + Int constant SIX = Int.wrap(6); + + function testBitwise() public pure { + assert(Int.unwrap(ONE | TWO) == 3); + assert(Int.unwrap(ONE | ZERO) == 1); + + assert(Int.unwrap(ONE & THREE) == 1); + assert(Int.unwrap(ONE & ONE) == 1); + + assert(Int.unwrap(TWO ^ TWO) == 0); + assert(Int.unwrap(TWO ^ ONE) == 3); + + assert(Int.unwrap(~ZERO) == -1); + assert(Int.unwrap(~ONE) == -2); + assert(Int.unwrap(~TWO) == -3); + } + + function testArithmetic() public pure { + assert(Int.unwrap(ONE + TWO) == 3); + assert(Int.unwrap(ONE + ZERO) == 1); + + assert(Int.unwrap(TWO - ONE) == 1); + assert(Int.unwrap(THREE - THREE) == 0); + + assert(Int.unwrap(-TWO) == -2); + assert(Int.unwrap(-ZERO) == 0); + + assert(Int.unwrap(ONE * ONE) == 1); + assert(Int.unwrap(THREE * TWO) == 6); + + assert(Int.unwrap(SIX / TWO) == 3); + assert(Int.unwrap(THREE / TWO) == 1); + + assert(Int.unwrap(SIX % TWO) == 0); + assert(Int.unwrap(THREE % TWO) == 1); + } + + function testComparison() public pure { + assert((ONE == ONE) == true); + assert((ONE == TWO) == false); + + assert((ONE != ONE) == false); + assert((ONE != TWO) == true); + + assert((ONE < TWO) == true); + assert((TWO < ONE) == false); + + assert((ONE <= TWO) == true); + assert((TWO <= ONE) == false); + + assert((ONE > TWO) == false); + assert((TWO > ONE) == true); + + assert((ONE >= TWO) == false); + assert((TWO >= ONE) == true); + } +} +// ---- +// testBitwise() -> +// testArithmetic() -> +// testComparison() -> diff --git a/test/libsolidity/semanticTests/operators/userDefined/all_possible_user_defined_value_types_with_operators.sol b/test/libsolidity/semanticTests/operators/userDefined/all_possible_user_defined_value_types_with_operators.sol new file mode 100644 index 000000000..868a53967 --- /dev/null +++ b/test/libsolidity/semanticTests/operators/userDefined/all_possible_user_defined_value_types_with_operators.sol @@ -0,0 +1,670 @@ +type Int8 is int8; +type Int16 is int16; +type Int24 is int24; +type Int32 is int32; +type Int40 is int40; +type Int48 is int48; +type Int56 is int56; +type Int64 is int64; +type Int72 is int72; +type Int80 is int80; +type Int88 is int88; +type Int96 is int96; +type Int104 is int104; +type Int112 is int112; +type Int120 is int120; +type Int128 is int128; +type Int136 is int136; +type Int144 is int144; +type Int152 is int152; +type Int160 is int160; +type Int168 is int168; +type Int176 is int176; +type Int184 is int184; +type Int192 is int192; +type Int200 is int200; +type Int208 is int208; +type Int216 is int216; +type Int224 is int224; +type Int232 is int232; +type Int240 is int240; +type Int248 is int248; +type Int256 is int256; +type Int is int; + +type Uint8 is uint8; +type Uint16 is uint16; +type Uint24 is uint24; +type Uint32 is uint32; +type Uint40 is uint40; +type Uint48 is uint48; +type Uint56 is uint56; +type Uint64 is uint64; +type Uint72 is uint72; +type Uint80 is uint80; +type Uint88 is uint88; +type Uint96 is uint96; +type Uint104 is uint104; +type Uint112 is uint112; +type Uint120 is uint120; +type Uint128 is uint128; +type Uint136 is uint136; +type Uint144 is uint144; +type Uint152 is uint152; +type Uint160 is uint160; +type Uint168 is uint168; +type Uint176 is uint176; +type Uint184 is uint184; +type Uint192 is uint192; +type Uint200 is uint200; +type Uint208 is uint208; +type Uint216 is uint216; +type Uint224 is uint224; +type Uint232 is uint232; +type Uint240 is uint240; +type Uint248 is uint248; +type Uint256 is uint256; +type Uint is uint; + +type Bytes1 is bytes1; +type Bytes2 is bytes2; +type Bytes3 is bytes3; +type Bytes4 is bytes4; +type Bytes5 is bytes5; +type Bytes6 is bytes6; +type Bytes7 is bytes7; +type Bytes8 is bytes8; +type Bytes9 is bytes9; +type Bytes10 is bytes10; +type Bytes11 is bytes11; +type Bytes12 is bytes12; +type Bytes13 is bytes13; +type Bytes14 is bytes14; +type Bytes15 is bytes15; +type Bytes16 is bytes16; +type Bytes17 is bytes17; +type Bytes18 is bytes18; +type Bytes19 is bytes19; +type Bytes20 is bytes20; +type Bytes21 is bytes21; +type Bytes22 is bytes22; +type Bytes23 is bytes23; +type Bytes24 is bytes24; +type Bytes25 is bytes25; +type Bytes26 is bytes26; +type Bytes27 is bytes27; +type Bytes28 is bytes28; +type Bytes29 is bytes29; +type Bytes30 is bytes30; +type Bytes31 is bytes31; +type Bytes32 is bytes32; + +type Address is address; +type AddressPayable is address payable; + +type Bool is bool; + +using {bitorInt8 as |, unsubInt8 as -} for Int8 global; +using {bitorInt16 as |, unsubInt16 as -} for Int16 global; +using {bitorInt24 as |, unsubInt24 as -} for Int24 global; +using {bitorInt32 as |, unsubInt32 as -} for Int32 global; +using {bitorInt40 as |, unsubInt40 as -} for Int40 global; +using {bitorInt48 as |, unsubInt48 as -} for Int48 global; +using {bitorInt56 as |, unsubInt56 as -} for Int56 global; +using {bitorInt64 as |, unsubInt64 as -} for Int64 global; +using {bitorInt72 as |, unsubInt72 as -} for Int72 global; +using {bitorInt80 as |, unsubInt80 as -} for Int80 global; +using {bitorInt88 as |, unsubInt88 as -} for Int88 global; +using {bitorInt96 as |, unsubInt96 as -} for Int96 global; +using {bitorInt104 as |, unsubInt104 as -} for Int104 global; +using {bitorInt112 as |, unsubInt112 as -} for Int112 global; +using {bitorInt120 as |, unsubInt120 as -} for Int120 global; +using {bitorInt128 as |, unsubInt128 as -} for Int128 global; +using {bitorInt136 as |, unsubInt136 as -} for Int136 global; +using {bitorInt144 as |, unsubInt144 as -} for Int144 global; +using {bitorInt152 as |, unsubInt152 as -} for Int152 global; +using {bitorInt160 as |, unsubInt160 as -} for Int160 global; +using {bitorInt168 as |, unsubInt168 as -} for Int168 global; +using {bitorInt176 as |, unsubInt176 as -} for Int176 global; +using {bitorInt184 as |, unsubInt184 as -} for Int184 global; +using {bitorInt192 as |, unsubInt192 as -} for Int192 global; +using {bitorInt200 as |, unsubInt200 as -} for Int200 global; +using {bitorInt208 as |, unsubInt208 as -} for Int208 global; +using {bitorInt216 as |, unsubInt216 as -} for Int216 global; +using {bitorInt224 as |, unsubInt224 as -} for Int224 global; +using {bitorInt232 as |, unsubInt232 as -} for Int232 global; +using {bitorInt240 as |, unsubInt240 as -} for Int240 global; +using {bitorInt248 as |, unsubInt248 as -} for Int248 global; +using {bitorInt256 as |, unsubInt256 as -} for Int256 global; +using {bitorInt as |, unsubInt as -} for Int global; + +using {bitorUint8 as |, bitnotUint8 as ~} for Uint8 global; +using {bitorUint16 as |, bitnotUint16 as ~} for Uint16 global; +using {bitorUint24 as |, bitnotUint24 as ~} for Uint24 global; +using {bitorUint32 as |, bitnotUint32 as ~} for Uint32 global; +using {bitorUint40 as |, bitnotUint40 as ~} for Uint40 global; +using {bitorUint48 as |, bitnotUint48 as ~} for Uint48 global; +using {bitorUint56 as |, bitnotUint56 as ~} for Uint56 global; +using {bitorUint64 as |, bitnotUint64 as ~} for Uint64 global; +using {bitorUint72 as |, bitnotUint72 as ~} for Uint72 global; +using {bitorUint80 as |, bitnotUint80 as ~} for Uint80 global; +using {bitorUint88 as |, bitnotUint88 as ~} for Uint88 global; +using {bitorUint96 as |, bitnotUint96 as ~} for Uint96 global; +using {bitorUint104 as |, bitnotUint104 as ~} for Uint104 global; +using {bitorUint112 as |, bitnotUint112 as ~} for Uint112 global; +using {bitorUint120 as |, bitnotUint120 as ~} for Uint120 global; +using {bitorUint128 as |, bitnotUint128 as ~} for Uint128 global; +using {bitorUint136 as |, bitnotUint136 as ~} for Uint136 global; +using {bitorUint144 as |, bitnotUint144 as ~} for Uint144 global; +using {bitorUint152 as |, bitnotUint152 as ~} for Uint152 global; +using {bitorUint160 as |, bitnotUint160 as ~} for Uint160 global; +using {bitorUint168 as |, bitnotUint168 as ~} for Uint168 global; +using {bitorUint176 as |, bitnotUint176 as ~} for Uint176 global; +using {bitorUint184 as |, bitnotUint184 as ~} for Uint184 global; +using {bitorUint192 as |, bitnotUint192 as ~} for Uint192 global; +using {bitorUint200 as |, bitnotUint200 as ~} for Uint200 global; +using {bitorUint208 as |, bitnotUint208 as ~} for Uint208 global; +using {bitorUint216 as |, bitnotUint216 as ~} for Uint216 global; +using {bitorUint224 as |, bitnotUint224 as ~} for Uint224 global; +using {bitorUint232 as |, bitnotUint232 as ~} for Uint232 global; +using {bitorUint240 as |, bitnotUint240 as ~} for Uint240 global; +using {bitorUint248 as |, bitnotUint248 as ~} for Uint248 global; +using {bitorUint256 as |, bitnotUint256 as ~} for Uint256 global; +using {bitorUint as |, bitnotUint as ~} for Uint global; + +using {bitorBytes1 as |, bitnotBytes1 as ~} for Bytes1 global; +using {bitorBytes2 as |, bitnotBytes2 as ~} for Bytes2 global; +using {bitorBytes3 as |, bitnotBytes3 as ~} for Bytes3 global; +using {bitorBytes4 as |, bitnotBytes4 as ~} for Bytes4 global; +using {bitorBytes5 as |, bitnotBytes5 as ~} for Bytes5 global; +using {bitorBytes6 as |, bitnotBytes6 as ~} for Bytes6 global; +using {bitorBytes7 as |, bitnotBytes7 as ~} for Bytes7 global; +using {bitorBytes8 as |, bitnotBytes8 as ~} for Bytes8 global; +using {bitorBytes9 as |, bitnotBytes9 as ~} for Bytes9 global; +using {bitorBytes10 as |, bitnotBytes10 as ~} for Bytes10 global; +using {bitorBytes11 as |, bitnotBytes11 as ~} for Bytes11 global; +using {bitorBytes12 as |, bitnotBytes12 as ~} for Bytes12 global; +using {bitorBytes13 as |, bitnotBytes13 as ~} for Bytes13 global; +using {bitorBytes14 as |, bitnotBytes14 as ~} for Bytes14 global; +using {bitorBytes15 as |, bitnotBytes15 as ~} for Bytes15 global; +using {bitorBytes16 as |, bitnotBytes16 as ~} for Bytes16 global; +using {bitorBytes17 as |, bitnotBytes17 as ~} for Bytes17 global; +using {bitorBytes18 as |, bitnotBytes18 as ~} for Bytes18 global; +using {bitorBytes19 as |, bitnotBytes19 as ~} for Bytes19 global; +using {bitorBytes20 as |, bitnotBytes20 as ~} for Bytes20 global; +using {bitorBytes21 as |, bitnotBytes21 as ~} for Bytes21 global; +using {bitorBytes22 as |, bitnotBytes22 as ~} for Bytes22 global; +using {bitorBytes23 as |, bitnotBytes23 as ~} for Bytes23 global; +using {bitorBytes24 as |, bitnotBytes24 as ~} for Bytes24 global; +using {bitorBytes25 as |, bitnotBytes25 as ~} for Bytes25 global; +using {bitorBytes26 as |, bitnotBytes26 as ~} for Bytes26 global; +using {bitorBytes27 as |, bitnotBytes27 as ~} for Bytes27 global; +using {bitorBytes28 as |, bitnotBytes28 as ~} for Bytes28 global; +using {bitorBytes29 as |, bitnotBytes29 as ~} for Bytes29 global; +using {bitorBytes30 as |, bitnotBytes30 as ~} for Bytes30 global; +using {bitorBytes31 as |, bitnotBytes31 as ~} for Bytes31 global; +using {bitorBytes32 as |, bitnotBytes32 as ~} for Bytes32 global; + +function bitorInt8(Int8 x, Int8 y) pure returns (Int8) { return Int8.wrap(Int8.unwrap(x) | Int8.unwrap(y)); } +function bitorInt16(Int16 x, Int16 y) pure returns (Int16) { return Int16.wrap(Int16.unwrap(x) | Int16.unwrap(y)); } +function bitorInt24(Int24 x, Int24 y) pure returns (Int24) { return Int24.wrap(Int24.unwrap(x) | Int24.unwrap(y)); } +function bitorInt32(Int32 x, Int32 y) pure returns (Int32) { return Int32.wrap(Int32.unwrap(x) | Int32.unwrap(y)); } +function bitorInt40(Int40 x, Int40 y) pure returns (Int40) { return Int40.wrap(Int40.unwrap(x) | Int40.unwrap(y)); } +function bitorInt48(Int48 x, Int48 y) pure returns (Int48) { return Int48.wrap(Int48.unwrap(x) | Int48.unwrap(y)); } +function bitorInt56(Int56 x, Int56 y) pure returns (Int56) { return Int56.wrap(Int56.unwrap(x) | Int56.unwrap(y)); } +function bitorInt64(Int64 x, Int64 y) pure returns (Int64) { return Int64.wrap(Int64.unwrap(x) | Int64.unwrap(y)); } +function bitorInt72(Int72 x, Int72 y) pure returns (Int72) { return Int72.wrap(Int72.unwrap(x) | Int72.unwrap(y)); } +function bitorInt80(Int80 x, Int80 y) pure returns (Int80) { return Int80.wrap(Int80.unwrap(x) | Int80.unwrap(y)); } +function bitorInt88(Int88 x, Int88 y) pure returns (Int88) { return Int88.wrap(Int88.unwrap(x) | Int88.unwrap(y)); } +function bitorInt96(Int96 x, Int96 y) pure returns (Int96) { return Int96.wrap(Int96.unwrap(x) | Int96.unwrap(y)); } +function bitorInt104(Int104 x, Int104 y) pure returns (Int104) { return Int104.wrap(Int104.unwrap(x) | Int104.unwrap(y)); } +function bitorInt112(Int112 x, Int112 y) pure returns (Int112) { return Int112.wrap(Int112.unwrap(x) | Int112.unwrap(y)); } +function bitorInt120(Int120 x, Int120 y) pure returns (Int120) { return Int120.wrap(Int120.unwrap(x) | Int120.unwrap(y)); } +function bitorInt128(Int128 x, Int128 y) pure returns (Int128) { return Int128.wrap(Int128.unwrap(x) | Int128.unwrap(y)); } +function bitorInt136(Int136 x, Int136 y) pure returns (Int136) { return Int136.wrap(Int136.unwrap(x) | Int136.unwrap(y)); } +function bitorInt144(Int144 x, Int144 y) pure returns (Int144) { return Int144.wrap(Int144.unwrap(x) | Int144.unwrap(y)); } +function bitorInt152(Int152 x, Int152 y) pure returns (Int152) { return Int152.wrap(Int152.unwrap(x) | Int152.unwrap(y)); } +function bitorInt160(Int160 x, Int160 y) pure returns (Int160) { return Int160.wrap(Int160.unwrap(x) | Int160.unwrap(y)); } +function bitorInt168(Int168 x, Int168 y) pure returns (Int168) { return Int168.wrap(Int168.unwrap(x) | Int168.unwrap(y)); } +function bitorInt176(Int176 x, Int176 y) pure returns (Int176) { return Int176.wrap(Int176.unwrap(x) | Int176.unwrap(y)); } +function bitorInt184(Int184 x, Int184 y) pure returns (Int184) { return Int184.wrap(Int184.unwrap(x) | Int184.unwrap(y)); } +function bitorInt192(Int192 x, Int192 y) pure returns (Int192) { return Int192.wrap(Int192.unwrap(x) | Int192.unwrap(y)); } +function bitorInt200(Int200 x, Int200 y) pure returns (Int200) { return Int200.wrap(Int200.unwrap(x) | Int200.unwrap(y)); } +function bitorInt208(Int208 x, Int208 y) pure returns (Int208) { return Int208.wrap(Int208.unwrap(x) | Int208.unwrap(y)); } +function bitorInt216(Int216 x, Int216 y) pure returns (Int216) { return Int216.wrap(Int216.unwrap(x) | Int216.unwrap(y)); } +function bitorInt224(Int224 x, Int224 y) pure returns (Int224) { return Int224.wrap(Int224.unwrap(x) | Int224.unwrap(y)); } +function bitorInt232(Int232 x, Int232 y) pure returns (Int232) { return Int232.wrap(Int232.unwrap(x) | Int232.unwrap(y)); } +function bitorInt240(Int240 x, Int240 y) pure returns (Int240) { return Int240.wrap(Int240.unwrap(x) | Int240.unwrap(y)); } +function bitorInt248(Int248 x, Int248 y) pure returns (Int248) { return Int248.wrap(Int248.unwrap(x) | Int248.unwrap(y)); } +function bitorInt256(Int256 x, Int256 y) pure returns (Int256) { return Int256.wrap(Int256.unwrap(x) | Int256.unwrap(y)); } +function bitorInt(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); } + +function unsubInt8(Int8 x) pure returns (Int8) { return Int8.wrap(-Int8.unwrap(x)); } +function unsubInt16(Int16 x) pure returns (Int16) { return Int16.wrap(-Int16.unwrap(x)); } +function unsubInt24(Int24 x) pure returns (Int24) { return Int24.wrap(-Int24.unwrap(x)); } +function unsubInt32(Int32 x) pure returns (Int32) { return Int32.wrap(-Int32.unwrap(x)); } +function unsubInt40(Int40 x) pure returns (Int40) { return Int40.wrap(-Int40.unwrap(x)); } +function unsubInt48(Int48 x) pure returns (Int48) { return Int48.wrap(-Int48.unwrap(x)); } +function unsubInt56(Int56 x) pure returns (Int56) { return Int56.wrap(-Int56.unwrap(x)); } +function unsubInt64(Int64 x) pure returns (Int64) { return Int64.wrap(-Int64.unwrap(x)); } +function unsubInt72(Int72 x) pure returns (Int72) { return Int72.wrap(-Int72.unwrap(x)); } +function unsubInt80(Int80 x) pure returns (Int80) { return Int80.wrap(-Int80.unwrap(x)); } +function unsubInt88(Int88 x) pure returns (Int88) { return Int88.wrap(-Int88.unwrap(x)); } +function unsubInt96(Int96 x) pure returns (Int96) { return Int96.wrap(-Int96.unwrap(x)); } +function unsubInt104(Int104 x) pure returns (Int104) { return Int104.wrap(-Int104.unwrap(x)); } +function unsubInt112(Int112 x) pure returns (Int112) { return Int112.wrap(-Int112.unwrap(x)); } +function unsubInt120(Int120 x) pure returns (Int120) { return Int120.wrap(-Int120.unwrap(x)); } +function unsubInt128(Int128 x) pure returns (Int128) { return Int128.wrap(-Int128.unwrap(x)); } +function unsubInt136(Int136 x) pure returns (Int136) { return Int136.wrap(-Int136.unwrap(x)); } +function unsubInt144(Int144 x) pure returns (Int144) { return Int144.wrap(-Int144.unwrap(x)); } +function unsubInt152(Int152 x) pure returns (Int152) { return Int152.wrap(-Int152.unwrap(x)); } +function unsubInt160(Int160 x) pure returns (Int160) { return Int160.wrap(-Int160.unwrap(x)); } +function unsubInt168(Int168 x) pure returns (Int168) { return Int168.wrap(-Int168.unwrap(x)); } +function unsubInt176(Int176 x) pure returns (Int176) { return Int176.wrap(-Int176.unwrap(x)); } +function unsubInt184(Int184 x) pure returns (Int184) { return Int184.wrap(-Int184.unwrap(x)); } +function unsubInt192(Int192 x) pure returns (Int192) { return Int192.wrap(-Int192.unwrap(x)); } +function unsubInt200(Int200 x) pure returns (Int200) { return Int200.wrap(-Int200.unwrap(x)); } +function unsubInt208(Int208 x) pure returns (Int208) { return Int208.wrap(-Int208.unwrap(x)); } +function unsubInt216(Int216 x) pure returns (Int216) { return Int216.wrap(-Int216.unwrap(x)); } +function unsubInt224(Int224 x) pure returns (Int224) { return Int224.wrap(-Int224.unwrap(x)); } +function unsubInt232(Int232 x) pure returns (Int232) { return Int232.wrap(-Int232.unwrap(x)); } +function unsubInt240(Int240 x) pure returns (Int240) { return Int240.wrap(-Int240.unwrap(x)); } +function unsubInt248(Int248 x) pure returns (Int248) { return Int248.wrap(-Int248.unwrap(x)); } +function unsubInt256(Int256 x) pure returns (Int256) { return Int256.wrap(-Int256.unwrap(x)); } +function unsubInt(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); } + +function bitorUint8(Uint8 x, Uint8 y) pure returns (Uint8) { return Uint8.wrap(Uint8.unwrap(x) | Uint8.unwrap(y)); } +function bitorUint16(Uint16 x, Uint16 y) pure returns (Uint16) { return Uint16.wrap(Uint16.unwrap(x) | Uint16.unwrap(y)); } +function bitorUint24(Uint24 x, Uint24 y) pure returns (Uint24) { return Uint24.wrap(Uint24.unwrap(x) | Uint24.unwrap(y)); } +function bitorUint32(Uint32 x, Uint32 y) pure returns (Uint32) { return Uint32.wrap(Uint32.unwrap(x) | Uint32.unwrap(y)); } +function bitorUint40(Uint40 x, Uint40 y) pure returns (Uint40) { return Uint40.wrap(Uint40.unwrap(x) | Uint40.unwrap(y)); } +function bitorUint48(Uint48 x, Uint48 y) pure returns (Uint48) { return Uint48.wrap(Uint48.unwrap(x) | Uint48.unwrap(y)); } +function bitorUint56(Uint56 x, Uint56 y) pure returns (Uint56) { return Uint56.wrap(Uint56.unwrap(x) | Uint56.unwrap(y)); } +function bitorUint64(Uint64 x, Uint64 y) pure returns (Uint64) { return Uint64.wrap(Uint64.unwrap(x) | Uint64.unwrap(y)); } +function bitorUint72(Uint72 x, Uint72 y) pure returns (Uint72) { return Uint72.wrap(Uint72.unwrap(x) | Uint72.unwrap(y)); } +function bitorUint80(Uint80 x, Uint80 y) pure returns (Uint80) { return Uint80.wrap(Uint80.unwrap(x) | Uint80.unwrap(y)); } +function bitorUint88(Uint88 x, Uint88 y) pure returns (Uint88) { return Uint88.wrap(Uint88.unwrap(x) | Uint88.unwrap(y)); } +function bitorUint96(Uint96 x, Uint96 y) pure returns (Uint96) { return Uint96.wrap(Uint96.unwrap(x) | Uint96.unwrap(y)); } +function bitorUint104(Uint104 x, Uint104 y) pure returns (Uint104) { return Uint104.wrap(Uint104.unwrap(x) | Uint104.unwrap(y)); } +function bitorUint112(Uint112 x, Uint112 y) pure returns (Uint112) { return Uint112.wrap(Uint112.unwrap(x) | Uint112.unwrap(y)); } +function bitorUint120(Uint120 x, Uint120 y) pure returns (Uint120) { return Uint120.wrap(Uint120.unwrap(x) | Uint120.unwrap(y)); } +function bitorUint128(Uint128 x, Uint128 y) pure returns (Uint128) { return Uint128.wrap(Uint128.unwrap(x) | Uint128.unwrap(y)); } +function bitorUint136(Uint136 x, Uint136 y) pure returns (Uint136) { return Uint136.wrap(Uint136.unwrap(x) | Uint136.unwrap(y)); } +function bitorUint144(Uint144 x, Uint144 y) pure returns (Uint144) { return Uint144.wrap(Uint144.unwrap(x) | Uint144.unwrap(y)); } +function bitorUint152(Uint152 x, Uint152 y) pure returns (Uint152) { return Uint152.wrap(Uint152.unwrap(x) | Uint152.unwrap(y)); } +function bitorUint160(Uint160 x, Uint160 y) pure returns (Uint160) { return Uint160.wrap(Uint160.unwrap(x) | Uint160.unwrap(y)); } +function bitorUint168(Uint168 x, Uint168 y) pure returns (Uint168) { return Uint168.wrap(Uint168.unwrap(x) | Uint168.unwrap(y)); } +function bitorUint176(Uint176 x, Uint176 y) pure returns (Uint176) { return Uint176.wrap(Uint176.unwrap(x) | Uint176.unwrap(y)); } +function bitorUint184(Uint184 x, Uint184 y) pure returns (Uint184) { return Uint184.wrap(Uint184.unwrap(x) | Uint184.unwrap(y)); } +function bitorUint192(Uint192 x, Uint192 y) pure returns (Uint192) { return Uint192.wrap(Uint192.unwrap(x) | Uint192.unwrap(y)); } +function bitorUint200(Uint200 x, Uint200 y) pure returns (Uint200) { return Uint200.wrap(Uint200.unwrap(x) | Uint200.unwrap(y)); } +function bitorUint208(Uint208 x, Uint208 y) pure returns (Uint208) { return Uint208.wrap(Uint208.unwrap(x) | Uint208.unwrap(y)); } +function bitorUint216(Uint216 x, Uint216 y) pure returns (Uint216) { return Uint216.wrap(Uint216.unwrap(x) | Uint216.unwrap(y)); } +function bitorUint224(Uint224 x, Uint224 y) pure returns (Uint224) { return Uint224.wrap(Uint224.unwrap(x) | Uint224.unwrap(y)); } +function bitorUint232(Uint232 x, Uint232 y) pure returns (Uint232) { return Uint232.wrap(Uint232.unwrap(x) | Uint232.unwrap(y)); } +function bitorUint240(Uint240 x, Uint240 y) pure returns (Uint240) { return Uint240.wrap(Uint240.unwrap(x) | Uint240.unwrap(y)); } +function bitorUint248(Uint248 x, Uint248 y) pure returns (Uint248) { return Uint248.wrap(Uint248.unwrap(x) | Uint248.unwrap(y)); } +function bitorUint256(Uint256 x, Uint256 y) pure returns (Uint256) { return Uint256.wrap(Uint256.unwrap(x) | Uint256.unwrap(y)); } +function bitorUint(Uint x, Uint y) pure returns (Uint) { return Uint.wrap(Uint.unwrap(x) | Uint.unwrap(y)); } + +function bitnotUint8(Uint8 x) pure returns (Uint8) { return Uint8.wrap(~Uint8.unwrap(x)); } +function bitnotUint16(Uint16 x) pure returns (Uint16) { return Uint16.wrap(~Uint16.unwrap(x)); } +function bitnotUint24(Uint24 x) pure returns (Uint24) { return Uint24.wrap(~Uint24.unwrap(x)); } +function bitnotUint32(Uint32 x) pure returns (Uint32) { return Uint32.wrap(~Uint32.unwrap(x)); } +function bitnotUint40(Uint40 x) pure returns (Uint40) { return Uint40.wrap(~Uint40.unwrap(x)); } +function bitnotUint48(Uint48 x) pure returns (Uint48) { return Uint48.wrap(~Uint48.unwrap(x)); } +function bitnotUint56(Uint56 x) pure returns (Uint56) { return Uint56.wrap(~Uint56.unwrap(x)); } +function bitnotUint64(Uint64 x) pure returns (Uint64) { return Uint64.wrap(~Uint64.unwrap(x)); } +function bitnotUint72(Uint72 x) pure returns (Uint72) { return Uint72.wrap(~Uint72.unwrap(x)); } +function bitnotUint80(Uint80 x) pure returns (Uint80) { return Uint80.wrap(~Uint80.unwrap(x)); } +function bitnotUint88(Uint88 x) pure returns (Uint88) { return Uint88.wrap(~Uint88.unwrap(x)); } +function bitnotUint96(Uint96 x) pure returns (Uint96) { return Uint96.wrap(~Uint96.unwrap(x)); } +function bitnotUint104(Uint104 x) pure returns (Uint104) { return Uint104.wrap(~Uint104.unwrap(x)); } +function bitnotUint112(Uint112 x) pure returns (Uint112) { return Uint112.wrap(~Uint112.unwrap(x)); } +function bitnotUint120(Uint120 x) pure returns (Uint120) { return Uint120.wrap(~Uint120.unwrap(x)); } +function bitnotUint128(Uint128 x) pure returns (Uint128) { return Uint128.wrap(~Uint128.unwrap(x)); } +function bitnotUint136(Uint136 x) pure returns (Uint136) { return Uint136.wrap(~Uint136.unwrap(x)); } +function bitnotUint144(Uint144 x) pure returns (Uint144) { return Uint144.wrap(~Uint144.unwrap(x)); } +function bitnotUint152(Uint152 x) pure returns (Uint152) { return Uint152.wrap(~Uint152.unwrap(x)); } +function bitnotUint160(Uint160 x) pure returns (Uint160) { return Uint160.wrap(~Uint160.unwrap(x)); } +function bitnotUint168(Uint168 x) pure returns (Uint168) { return Uint168.wrap(~Uint168.unwrap(x)); } +function bitnotUint176(Uint176 x) pure returns (Uint176) { return Uint176.wrap(~Uint176.unwrap(x)); } +function bitnotUint184(Uint184 x) pure returns (Uint184) { return Uint184.wrap(~Uint184.unwrap(x)); } +function bitnotUint192(Uint192 x) pure returns (Uint192) { return Uint192.wrap(~Uint192.unwrap(x)); } +function bitnotUint200(Uint200 x) pure returns (Uint200) { return Uint200.wrap(~Uint200.unwrap(x)); } +function bitnotUint208(Uint208 x) pure returns (Uint208) { return Uint208.wrap(~Uint208.unwrap(x)); } +function bitnotUint216(Uint216 x) pure returns (Uint216) { return Uint216.wrap(~Uint216.unwrap(x)); } +function bitnotUint224(Uint224 x) pure returns (Uint224) { return Uint224.wrap(~Uint224.unwrap(x)); } +function bitnotUint232(Uint232 x) pure returns (Uint232) { return Uint232.wrap(~Uint232.unwrap(x)); } +function bitnotUint240(Uint240 x) pure returns (Uint240) { return Uint240.wrap(~Uint240.unwrap(x)); } +function bitnotUint248(Uint248 x) pure returns (Uint248) { return Uint248.wrap(~Uint248.unwrap(x)); } +function bitnotUint256(Uint256 x) pure returns (Uint256) { return Uint256.wrap(~Uint256.unwrap(x)); } +function bitnotUint(Uint x) pure returns (Uint) { return Uint.wrap(~Uint.unwrap(x)); } + +function bitorBytes1(Bytes1 x, Bytes1 y) pure returns (Bytes1) { return Bytes1.wrap(Bytes1.unwrap(x) | Bytes1.unwrap(y)); } +function bitorBytes2(Bytes2 x, Bytes2 y) pure returns (Bytes2) { return Bytes2.wrap(Bytes2.unwrap(x) | Bytes2.unwrap(y)); } +function bitorBytes3(Bytes3 x, Bytes3 y) pure returns (Bytes3) { return Bytes3.wrap(Bytes3.unwrap(x) | Bytes3.unwrap(y)); } +function bitorBytes4(Bytes4 x, Bytes4 y) pure returns (Bytes4) { return Bytes4.wrap(Bytes4.unwrap(x) | Bytes4.unwrap(y)); } +function bitorBytes5(Bytes5 x, Bytes5 y) pure returns (Bytes5) { return Bytes5.wrap(Bytes5.unwrap(x) | Bytes5.unwrap(y)); } +function bitorBytes6(Bytes6 x, Bytes6 y) pure returns (Bytes6) { return Bytes6.wrap(Bytes6.unwrap(x) | Bytes6.unwrap(y)); } +function bitorBytes7(Bytes7 x, Bytes7 y) pure returns (Bytes7) { return Bytes7.wrap(Bytes7.unwrap(x) | Bytes7.unwrap(y)); } +function bitorBytes8(Bytes8 x, Bytes8 y) pure returns (Bytes8) { return Bytes8.wrap(Bytes8.unwrap(x) | Bytes8.unwrap(y)); } +function bitorBytes9(Bytes9 x, Bytes9 y) pure returns (Bytes9) { return Bytes9.wrap(Bytes9.unwrap(x) | Bytes9.unwrap(y)); } +function bitorBytes10(Bytes10 x, Bytes10 y) pure returns (Bytes10) { return Bytes10.wrap(Bytes10.unwrap(x) | Bytes10.unwrap(y)); } +function bitorBytes11(Bytes11 x, Bytes11 y) pure returns (Bytes11) { return Bytes11.wrap(Bytes11.unwrap(x) | Bytes11.unwrap(y)); } +function bitorBytes12(Bytes12 x, Bytes12 y) pure returns (Bytes12) { return Bytes12.wrap(Bytes12.unwrap(x) | Bytes12.unwrap(y)); } +function bitorBytes13(Bytes13 x, Bytes13 y) pure returns (Bytes13) { return Bytes13.wrap(Bytes13.unwrap(x) | Bytes13.unwrap(y)); } +function bitorBytes14(Bytes14 x, Bytes14 y) pure returns (Bytes14) { return Bytes14.wrap(Bytes14.unwrap(x) | Bytes14.unwrap(y)); } +function bitorBytes15(Bytes15 x, Bytes15 y) pure returns (Bytes15) { return Bytes15.wrap(Bytes15.unwrap(x) | Bytes15.unwrap(y)); } +function bitorBytes16(Bytes16 x, Bytes16 y) pure returns (Bytes16) { return Bytes16.wrap(Bytes16.unwrap(x) | Bytes16.unwrap(y)); } +function bitorBytes17(Bytes17 x, Bytes17 y) pure returns (Bytes17) { return Bytes17.wrap(Bytes17.unwrap(x) | Bytes17.unwrap(y)); } +function bitorBytes18(Bytes18 x, Bytes18 y) pure returns (Bytes18) { return Bytes18.wrap(Bytes18.unwrap(x) | Bytes18.unwrap(y)); } +function bitorBytes19(Bytes19 x, Bytes19 y) pure returns (Bytes19) { return Bytes19.wrap(Bytes19.unwrap(x) | Bytes19.unwrap(y)); } +function bitorBytes20(Bytes20 x, Bytes20 y) pure returns (Bytes20) { return Bytes20.wrap(Bytes20.unwrap(x) | Bytes20.unwrap(y)); } +function bitorBytes21(Bytes21 x, Bytes21 y) pure returns (Bytes21) { return Bytes21.wrap(Bytes21.unwrap(x) | Bytes21.unwrap(y)); } +function bitorBytes22(Bytes22 x, Bytes22 y) pure returns (Bytes22) { return Bytes22.wrap(Bytes22.unwrap(x) | Bytes22.unwrap(y)); } +function bitorBytes23(Bytes23 x, Bytes23 y) pure returns (Bytes23) { return Bytes23.wrap(Bytes23.unwrap(x) | Bytes23.unwrap(y)); } +function bitorBytes24(Bytes24 x, Bytes24 y) pure returns (Bytes24) { return Bytes24.wrap(Bytes24.unwrap(x) | Bytes24.unwrap(y)); } +function bitorBytes25(Bytes25 x, Bytes25 y) pure returns (Bytes25) { return Bytes25.wrap(Bytes25.unwrap(x) | Bytes25.unwrap(y)); } +function bitorBytes26(Bytes26 x, Bytes26 y) pure returns (Bytes26) { return Bytes26.wrap(Bytes26.unwrap(x) | Bytes26.unwrap(y)); } +function bitorBytes27(Bytes27 x, Bytes27 y) pure returns (Bytes27) { return Bytes27.wrap(Bytes27.unwrap(x) | Bytes27.unwrap(y)); } +function bitorBytes28(Bytes28 x, Bytes28 y) pure returns (Bytes28) { return Bytes28.wrap(Bytes28.unwrap(x) | Bytes28.unwrap(y)); } +function bitorBytes29(Bytes29 x, Bytes29 y) pure returns (Bytes29) { return Bytes29.wrap(Bytes29.unwrap(x) | Bytes29.unwrap(y)); } +function bitorBytes30(Bytes30 x, Bytes30 y) pure returns (Bytes30) { return Bytes30.wrap(Bytes30.unwrap(x) | Bytes30.unwrap(y)); } +function bitorBytes31(Bytes31 x, Bytes31 y) pure returns (Bytes31) { return Bytes31.wrap(Bytes31.unwrap(x) | Bytes31.unwrap(y)); } +function bitorBytes32(Bytes32 x, Bytes32 y) pure returns (Bytes32) { return Bytes32.wrap(Bytes32.unwrap(x) | Bytes32.unwrap(y)); } + +function bitnotBytes1(Bytes1 x) pure returns (Bytes1) { return Bytes1.wrap(~Bytes1.unwrap(x)); } +function bitnotBytes2(Bytes2 x) pure returns (Bytes2) { return Bytes2.wrap(~Bytes2.unwrap(x)); } +function bitnotBytes3(Bytes3 x) pure returns (Bytes3) { return Bytes3.wrap(~Bytes3.unwrap(x)); } +function bitnotBytes4(Bytes4 x) pure returns (Bytes4) { return Bytes4.wrap(~Bytes4.unwrap(x)); } +function bitnotBytes5(Bytes5 x) pure returns (Bytes5) { return Bytes5.wrap(~Bytes5.unwrap(x)); } +function bitnotBytes6(Bytes6 x) pure returns (Bytes6) { return Bytes6.wrap(~Bytes6.unwrap(x)); } +function bitnotBytes7(Bytes7 x) pure returns (Bytes7) { return Bytes7.wrap(~Bytes7.unwrap(x)); } +function bitnotBytes8(Bytes8 x) pure returns (Bytes8) { return Bytes8.wrap(~Bytes8.unwrap(x)); } +function bitnotBytes9(Bytes9 x) pure returns (Bytes9) { return Bytes9.wrap(~Bytes9.unwrap(x)); } +function bitnotBytes10(Bytes10 x) pure returns (Bytes10) { return Bytes10.wrap(~Bytes10.unwrap(x)); } +function bitnotBytes11(Bytes11 x) pure returns (Bytes11) { return Bytes11.wrap(~Bytes11.unwrap(x)); } +function bitnotBytes12(Bytes12 x) pure returns (Bytes12) { return Bytes12.wrap(~Bytes12.unwrap(x)); } +function bitnotBytes13(Bytes13 x) pure returns (Bytes13) { return Bytes13.wrap(~Bytes13.unwrap(x)); } +function bitnotBytes14(Bytes14 x) pure returns (Bytes14) { return Bytes14.wrap(~Bytes14.unwrap(x)); } +function bitnotBytes15(Bytes15 x) pure returns (Bytes15) { return Bytes15.wrap(~Bytes15.unwrap(x)); } +function bitnotBytes16(Bytes16 x) pure returns (Bytes16) { return Bytes16.wrap(~Bytes16.unwrap(x)); } +function bitnotBytes17(Bytes17 x) pure returns (Bytes17) { return Bytes17.wrap(~Bytes17.unwrap(x)); } +function bitnotBytes18(Bytes18 x) pure returns (Bytes18) { return Bytes18.wrap(~Bytes18.unwrap(x)); } +function bitnotBytes19(Bytes19 x) pure returns (Bytes19) { return Bytes19.wrap(~Bytes19.unwrap(x)); } +function bitnotBytes20(Bytes20 x) pure returns (Bytes20) { return Bytes20.wrap(~Bytes20.unwrap(x)); } +function bitnotBytes21(Bytes21 x) pure returns (Bytes21) { return Bytes21.wrap(~Bytes21.unwrap(x)); } +function bitnotBytes22(Bytes22 x) pure returns (Bytes22) { return Bytes22.wrap(~Bytes22.unwrap(x)); } +function bitnotBytes23(Bytes23 x) pure returns (Bytes23) { return Bytes23.wrap(~Bytes23.unwrap(x)); } +function bitnotBytes24(Bytes24 x) pure returns (Bytes24) { return Bytes24.wrap(~Bytes24.unwrap(x)); } +function bitnotBytes25(Bytes25 x) pure returns (Bytes25) { return Bytes25.wrap(~Bytes25.unwrap(x)); } +function bitnotBytes26(Bytes26 x) pure returns (Bytes26) { return Bytes26.wrap(~Bytes26.unwrap(x)); } +function bitnotBytes27(Bytes27 x) pure returns (Bytes27) { return Bytes27.wrap(~Bytes27.unwrap(x)); } +function bitnotBytes28(Bytes28 x) pure returns (Bytes28) { return Bytes28.wrap(~Bytes28.unwrap(x)); } +function bitnotBytes29(Bytes29 x) pure returns (Bytes29) { return Bytes29.wrap(~Bytes29.unwrap(x)); } +function bitnotBytes30(Bytes30 x) pure returns (Bytes30) { return Bytes30.wrap(~Bytes30.unwrap(x)); } +function bitnotBytes31(Bytes31 x) pure returns (Bytes31) { return Bytes31.wrap(~Bytes31.unwrap(x)); } +function bitnotBytes32(Bytes32 x) pure returns (Bytes32) { return Bytes32.wrap(~Bytes32.unwrap(x)); } + +using {bitorAddress as |, bitnotAddress as ~} for Address global; +using {bitorAddressPayable as |, bitnotAddressPayable as ~} for AddressPayable global; +using {bitorBool as |, bitnotBool as ~} for Bool global; + +function bitorAddress(Address x, Address y) pure returns (Address) { + return Address.wrap(address(bytes20(Address.unwrap(x)) | bytes20(Address.unwrap(y)))); +} +function bitnotAddress(Address x) pure returns (Address) { + return Address.wrap(address(~bytes20(Address.unwrap(x)))); +} + +function bitorAddressPayable(AddressPayable x, AddressPayable y) pure returns (AddressPayable) { + return AddressPayable.wrap(payable(address(bytes20(address(AddressPayable.unwrap(x))) | bytes20(address(AddressPayable.unwrap(y)))))); +} +function bitnotAddressPayable(AddressPayable x) pure returns (AddressPayable) { + return AddressPayable.wrap(payable(address(~bytes20(address(AddressPayable.unwrap(x)))))); +} + +function bitorBool(Bool x, Bool y) pure returns (Bool) { + return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y)); +} +function bitnotBool(Bool x) pure returns (Bool) { + return Bool.wrap(!Bool.unwrap(x)); +} + +contract C { + function testIntBinary() public pure { + assert(Int8.unwrap(Int8.wrap(1) | Int8.wrap(2)) == 3); + assert(Int16.unwrap(Int16.wrap(1) | Int16.wrap(2)) == 3); + assert(Int24.unwrap(Int24.wrap(1) | Int24.wrap(2)) == 3); + assert(Int32.unwrap(Int32.wrap(1) | Int32.wrap(2)) == 3); + assert(Int40.unwrap(Int40.wrap(1) | Int40.wrap(2)) == 3); + assert(Int48.unwrap(Int48.wrap(1) | Int48.wrap(2)) == 3); + assert(Int56.unwrap(Int56.wrap(1) | Int56.wrap(2)) == 3); + assert(Int64.unwrap(Int64.wrap(1) | Int64.wrap(2)) == 3); + assert(Int72.unwrap(Int72.wrap(1) | Int72.wrap(2)) == 3); + assert(Int80.unwrap(Int80.wrap(1) | Int80.wrap(2)) == 3); + assert(Int88.unwrap(Int88.wrap(1) | Int88.wrap(2)) == 3); + assert(Int96.unwrap(Int96.wrap(1) | Int96.wrap(2)) == 3); + assert(Int104.unwrap(Int104.wrap(1) | Int104.wrap(2)) == 3); + assert(Int112.unwrap(Int112.wrap(1) | Int112.wrap(2)) == 3); + assert(Int120.unwrap(Int120.wrap(1) | Int120.wrap(2)) == 3); + assert(Int128.unwrap(Int128.wrap(1) | Int128.wrap(2)) == 3); + assert(Int136.unwrap(Int136.wrap(1) | Int136.wrap(2)) == 3); + assert(Int144.unwrap(Int144.wrap(1) | Int144.wrap(2)) == 3); + assert(Int152.unwrap(Int152.wrap(1) | Int152.wrap(2)) == 3); + assert(Int160.unwrap(Int160.wrap(1) | Int160.wrap(2)) == 3); + assert(Int168.unwrap(Int168.wrap(1) | Int168.wrap(2)) == 3); + assert(Int176.unwrap(Int176.wrap(1) | Int176.wrap(2)) == 3); + assert(Int184.unwrap(Int184.wrap(1) | Int184.wrap(2)) == 3); + assert(Int192.unwrap(Int192.wrap(1) | Int192.wrap(2)) == 3); + assert(Int200.unwrap(Int200.wrap(1) | Int200.wrap(2)) == 3); + assert(Int208.unwrap(Int208.wrap(1) | Int208.wrap(2)) == 3); + assert(Int216.unwrap(Int216.wrap(1) | Int216.wrap(2)) == 3); + assert(Int224.unwrap(Int224.wrap(1) | Int224.wrap(2)) == 3); + assert(Int232.unwrap(Int232.wrap(1) | Int232.wrap(2)) == 3); + assert(Int240.unwrap(Int240.wrap(1) | Int240.wrap(2)) == 3); + assert(Int248.unwrap(Int248.wrap(1) | Int248.wrap(2)) == 3); + assert(Int256.unwrap(Int256.wrap(1) | Int256.wrap(2)) == 3); + assert(Int.unwrap(Int.wrap(1) | Int.wrap(2)) == 3); + } + + function testIntUnary() public pure { + assert(Int8.unwrap(-Int8.wrap(1)) == -1); + assert(Int16.unwrap(-Int16.wrap(1)) == -1); + assert(Int24.unwrap(-Int24.wrap(1)) == -1); + assert(Int32.unwrap(-Int32.wrap(1)) == -1); + assert(Int40.unwrap(-Int40.wrap(1)) == -1); + assert(Int48.unwrap(-Int48.wrap(1)) == -1); + assert(Int56.unwrap(-Int56.wrap(1)) == -1); + assert(Int64.unwrap(-Int64.wrap(1)) == -1); + assert(Int72.unwrap(-Int72.wrap(1)) == -1); + assert(Int80.unwrap(-Int80.wrap(1)) == -1); + assert(Int88.unwrap(-Int88.wrap(1)) == -1); + assert(Int96.unwrap(-Int96.wrap(1)) == -1); + assert(Int104.unwrap(-Int104.wrap(1)) == -1); + assert(Int112.unwrap(-Int112.wrap(1)) == -1); + assert(Int120.unwrap(-Int120.wrap(1)) == -1); + assert(Int128.unwrap(-Int128.wrap(1)) == -1); + assert(Int136.unwrap(-Int136.wrap(1)) == -1); + assert(Int144.unwrap(-Int144.wrap(1)) == -1); + assert(Int152.unwrap(-Int152.wrap(1)) == -1); + assert(Int160.unwrap(-Int160.wrap(1)) == -1); + assert(Int168.unwrap(-Int168.wrap(1)) == -1); + assert(Int176.unwrap(-Int176.wrap(1)) == -1); + assert(Int184.unwrap(-Int184.wrap(1)) == -1); + assert(Int192.unwrap(-Int192.wrap(1)) == -1); + assert(Int200.unwrap(-Int200.wrap(1)) == -1); + assert(Int208.unwrap(-Int208.wrap(1)) == -1); + assert(Int216.unwrap(-Int216.wrap(1)) == -1); + assert(Int224.unwrap(-Int224.wrap(1)) == -1); + assert(Int232.unwrap(-Int232.wrap(1)) == -1); + assert(Int240.unwrap(-Int240.wrap(1)) == -1); + assert(Int248.unwrap(-Int248.wrap(1)) == -1); + assert(Int256.unwrap(-Int256.wrap(1)) == -1); + assert(Int.unwrap(-Int.wrap(1)) == -1); + } + + function testUintBinary() public pure { + assert(Uint8.unwrap(Uint8.wrap(1) | Uint8.wrap(2)) == 3); + assert(Uint16.unwrap(Uint16.wrap(1) | Uint16.wrap(2)) == 3); + assert(Uint24.unwrap(Uint24.wrap(1) | Uint24.wrap(2)) == 3); + assert(Uint32.unwrap(Uint32.wrap(1) | Uint32.wrap(2)) == 3); + assert(Uint40.unwrap(Uint40.wrap(1) | Uint40.wrap(2)) == 3); + assert(Uint48.unwrap(Uint48.wrap(1) | Uint48.wrap(2)) == 3); + assert(Uint56.unwrap(Uint56.wrap(1) | Uint56.wrap(2)) == 3); + assert(Uint64.unwrap(Uint64.wrap(1) | Uint64.wrap(2)) == 3); + assert(Uint72.unwrap(Uint72.wrap(1) | Uint72.wrap(2)) == 3); + assert(Uint80.unwrap(Uint80.wrap(1) | Uint80.wrap(2)) == 3); + assert(Uint88.unwrap(Uint88.wrap(1) | Uint88.wrap(2)) == 3); + assert(Uint96.unwrap(Uint96.wrap(1) | Uint96.wrap(2)) == 3); + assert(Uint104.unwrap(Uint104.wrap(1) | Uint104.wrap(2)) == 3); + assert(Uint112.unwrap(Uint112.wrap(1) | Uint112.wrap(2)) == 3); + assert(Uint120.unwrap(Uint120.wrap(1) | Uint120.wrap(2)) == 3); + assert(Uint128.unwrap(Uint128.wrap(1) | Uint128.wrap(2)) == 3); + assert(Uint136.unwrap(Uint136.wrap(1) | Uint136.wrap(2)) == 3); + assert(Uint144.unwrap(Uint144.wrap(1) | Uint144.wrap(2)) == 3); + assert(Uint152.unwrap(Uint152.wrap(1) | Uint152.wrap(2)) == 3); + assert(Uint160.unwrap(Uint160.wrap(1) | Uint160.wrap(2)) == 3); + assert(Uint168.unwrap(Uint168.wrap(1) | Uint168.wrap(2)) == 3); + assert(Uint176.unwrap(Uint176.wrap(1) | Uint176.wrap(2)) == 3); + assert(Uint184.unwrap(Uint184.wrap(1) | Uint184.wrap(2)) == 3); + assert(Uint192.unwrap(Uint192.wrap(1) | Uint192.wrap(2)) == 3); + assert(Uint200.unwrap(Uint200.wrap(1) | Uint200.wrap(2)) == 3); + assert(Uint208.unwrap(Uint208.wrap(1) | Uint208.wrap(2)) == 3); + assert(Uint216.unwrap(Uint216.wrap(1) | Uint216.wrap(2)) == 3); + assert(Uint224.unwrap(Uint224.wrap(1) | Uint224.wrap(2)) == 3); + assert(Uint232.unwrap(Uint232.wrap(1) | Uint232.wrap(2)) == 3); + assert(Uint240.unwrap(Uint240.wrap(1) | Uint240.wrap(2)) == 3); + assert(Uint248.unwrap(Uint248.wrap(1) | Uint248.wrap(2)) == 3); + assert(Uint256.unwrap(Uint256.wrap(1) | Uint256.wrap(2)) == 3); + assert(Uint.unwrap(Uint.wrap(1) | Uint.wrap(2)) == 3); + } + + function testUintUnary() public pure { + assert(Uint8.unwrap(~Uint8.wrap(1)) == ~uint8(1)); + assert(Uint16.unwrap(~Uint16.wrap(1)) == ~uint16(1)); + assert(Uint24.unwrap(~Uint24.wrap(1)) == ~uint24(1)); + assert(Uint32.unwrap(~Uint32.wrap(1)) == ~uint32(1)); + assert(Uint40.unwrap(~Uint40.wrap(1)) == ~uint40(1)); + assert(Uint48.unwrap(~Uint48.wrap(1)) == ~uint48(1)); + assert(Uint56.unwrap(~Uint56.wrap(1)) == ~uint56(1)); + assert(Uint64.unwrap(~Uint64.wrap(1)) == ~uint64(1)); + assert(Uint72.unwrap(~Uint72.wrap(1)) == ~uint72(1)); + assert(Uint80.unwrap(~Uint80.wrap(1)) == ~uint80(1)); + assert(Uint88.unwrap(~Uint88.wrap(1)) == ~uint88(1)); + assert(Uint96.unwrap(~Uint96.wrap(1)) == ~uint96(1)); + assert(Uint104.unwrap(~Uint104.wrap(1)) == ~uint104(1)); + assert(Uint112.unwrap(~Uint112.wrap(1)) == ~uint112(1)); + assert(Uint120.unwrap(~Uint120.wrap(1)) == ~uint120(1)); + assert(Uint128.unwrap(~Uint128.wrap(1)) == ~uint128(1)); + assert(Uint136.unwrap(~Uint136.wrap(1)) == ~uint136(1)); + assert(Uint144.unwrap(~Uint144.wrap(1)) == ~uint144(1)); + assert(Uint152.unwrap(~Uint152.wrap(1)) == ~uint152(1)); + assert(Uint160.unwrap(~Uint160.wrap(1)) == ~uint160(1)); + assert(Uint168.unwrap(~Uint168.wrap(1)) == ~uint168(1)); + assert(Uint176.unwrap(~Uint176.wrap(1)) == ~uint176(1)); + assert(Uint184.unwrap(~Uint184.wrap(1)) == ~uint184(1)); + assert(Uint192.unwrap(~Uint192.wrap(1)) == ~uint192(1)); + assert(Uint200.unwrap(~Uint200.wrap(1)) == ~uint200(1)); + assert(Uint208.unwrap(~Uint208.wrap(1)) == ~uint208(1)); + assert(Uint216.unwrap(~Uint216.wrap(1)) == ~uint216(1)); + assert(Uint224.unwrap(~Uint224.wrap(1)) == ~uint224(1)); + assert(Uint232.unwrap(~Uint232.wrap(1)) == ~uint232(1)); + assert(Uint240.unwrap(~Uint240.wrap(1)) == ~uint240(1)); + assert(Uint248.unwrap(~Uint248.wrap(1)) == ~uint248(1)); + assert(Uint256.unwrap(~Uint256.wrap(1)) == ~uint256(1)); + assert(Uint.unwrap(~Uint.wrap(1)) == ~uint(1)); + } + + function testBytesBinary() public pure { + assert(Bytes1.unwrap(Bytes1.wrap(0x01) | Bytes1.wrap(0x02)) == bytes1(0x03)); + assert(Bytes2.unwrap(Bytes2.wrap(bytes2(bytes1(0x01))) | Bytes2.wrap(bytes2(bytes1(0x02)))) == bytes2(bytes1(0x03))); + assert(Bytes3.unwrap(Bytes3.wrap(bytes3(bytes1(0x01))) | Bytes3.wrap(bytes3(bytes1(0x02)))) == bytes3(bytes1(0x03))); + assert(Bytes4.unwrap(Bytes4.wrap(bytes4(bytes1(0x01))) | Bytes4.wrap(bytes4(bytes1(0x02)))) == bytes4(bytes1(0x03))); + assert(Bytes5.unwrap(Bytes5.wrap(bytes5(bytes1(0x01))) | Bytes5.wrap(bytes5(bytes1(0x02)))) == bytes5(bytes1(0x03))); + assert(Bytes6.unwrap(Bytes6.wrap(bytes6(bytes1(0x01))) | Bytes6.wrap(bytes6(bytes1(0x02)))) == bytes6(bytes1(0x03))); + assert(Bytes7.unwrap(Bytes7.wrap(bytes7(bytes1(0x01))) | Bytes7.wrap(bytes7(bytes1(0x02)))) == bytes7(bytes1(0x03))); + assert(Bytes8.unwrap(Bytes8.wrap(bytes8(bytes1(0x01))) | Bytes8.wrap(bytes8(bytes1(0x02)))) == bytes8(bytes1(0x03))); + assert(Bytes9.unwrap(Bytes9.wrap(bytes9(bytes1(0x01))) | Bytes9.wrap(bytes9(bytes1(0x02)))) == bytes9(bytes1(0x03))); + assert(Bytes10.unwrap(Bytes10.wrap(bytes10(bytes1(0x01))) | Bytes10.wrap(bytes10(bytes1(0x02)))) == bytes10(bytes1(0x03))); + assert(Bytes11.unwrap(Bytes11.wrap(bytes11(bytes1(0x01))) | Bytes11.wrap(bytes11(bytes1(0x02)))) == bytes11(bytes1(0x03))); + assert(Bytes12.unwrap(Bytes12.wrap(bytes12(bytes1(0x01))) | Bytes12.wrap(bytes12(bytes1(0x02)))) == bytes12(bytes1(0x03))); + assert(Bytes13.unwrap(Bytes13.wrap(bytes13(bytes1(0x01))) | Bytes13.wrap(bytes13(bytes1(0x02)))) == bytes13(bytes1(0x03))); + assert(Bytes14.unwrap(Bytes14.wrap(bytes14(bytes1(0x01))) | Bytes14.wrap(bytes14(bytes1(0x02)))) == bytes14(bytes1(0x03))); + assert(Bytes15.unwrap(Bytes15.wrap(bytes15(bytes1(0x01))) | Bytes15.wrap(bytes15(bytes1(0x02)))) == bytes15(bytes1(0x03))); + assert(Bytes16.unwrap(Bytes16.wrap(bytes16(bytes1(0x01))) | Bytes16.wrap(bytes16(bytes1(0x02)))) == bytes16(bytes1(0x03))); + assert(Bytes17.unwrap(Bytes17.wrap(bytes17(bytes1(0x01))) | Bytes17.wrap(bytes17(bytes1(0x02)))) == bytes17(bytes1(0x03))); + assert(Bytes18.unwrap(Bytes18.wrap(bytes18(bytes1(0x01))) | Bytes18.wrap(bytes18(bytes1(0x02)))) == bytes18(bytes1(0x03))); + assert(Bytes19.unwrap(Bytes19.wrap(bytes19(bytes1(0x01))) | Bytes19.wrap(bytes19(bytes1(0x02)))) == bytes19(bytes1(0x03))); + assert(Bytes20.unwrap(Bytes20.wrap(bytes20(bytes1(0x01))) | Bytes20.wrap(bytes20(bytes1(0x02)))) == bytes20(bytes1(0x03))); + assert(Bytes21.unwrap(Bytes21.wrap(bytes21(bytes1(0x01))) | Bytes21.wrap(bytes21(bytes1(0x02)))) == bytes21(bytes1(0x03))); + assert(Bytes22.unwrap(Bytes22.wrap(bytes22(bytes1(0x01))) | Bytes22.wrap(bytes22(bytes1(0x02)))) == bytes22(bytes1(0x03))); + assert(Bytes23.unwrap(Bytes23.wrap(bytes23(bytes1(0x01))) | Bytes23.wrap(bytes23(bytes1(0x02)))) == bytes23(bytes1(0x03))); + assert(Bytes24.unwrap(Bytes24.wrap(bytes24(bytes1(0x01))) | Bytes24.wrap(bytes24(bytes1(0x02)))) == bytes24(bytes1(0x03))); + assert(Bytes25.unwrap(Bytes25.wrap(bytes25(bytes1(0x01))) | Bytes25.wrap(bytes25(bytes1(0x02)))) == bytes25(bytes1(0x03))); + assert(Bytes26.unwrap(Bytes26.wrap(bytes26(bytes1(0x01))) | Bytes26.wrap(bytes26(bytes1(0x02)))) == bytes26(bytes1(0x03))); + assert(Bytes27.unwrap(Bytes27.wrap(bytes27(bytes1(0x01))) | Bytes27.wrap(bytes27(bytes1(0x02)))) == bytes27(bytes1(0x03))); + assert(Bytes28.unwrap(Bytes28.wrap(bytes28(bytes1(0x01))) | Bytes28.wrap(bytes28(bytes1(0x02)))) == bytes28(bytes1(0x03))); + assert(Bytes29.unwrap(Bytes29.wrap(bytes29(bytes1(0x01))) | Bytes29.wrap(bytes29(bytes1(0x02)))) == bytes29(bytes1(0x03))); + assert(Bytes30.unwrap(Bytes30.wrap(bytes30(bytes1(0x01))) | Bytes30.wrap(bytes30(bytes1(0x02)))) == bytes30(bytes1(0x03))); + assert(Bytes31.unwrap(Bytes31.wrap(bytes31(bytes1(0x01))) | Bytes31.wrap(bytes31(bytes1(0x02)))) == bytes31(bytes1(0x03))); + assert(Bytes32.unwrap(Bytes32.wrap(bytes32(bytes1(0x01))) | Bytes32.wrap(bytes32(bytes1(0x02)))) == bytes32(bytes1(0x03))); + } + + function testBytesUnary() public pure { + assert(Bytes1.unwrap(~Bytes1.wrap(bytes1(0x01))) == ~bytes1(0x01)); + assert(Bytes2.unwrap(~Bytes2.wrap(bytes2(bytes1(0x01)))) == ~bytes2(bytes1(0x01))); + assert(Bytes3.unwrap(~Bytes3.wrap(bytes3(bytes1(0x01)))) == ~bytes3(bytes1(0x01))); + assert(Bytes4.unwrap(~Bytes4.wrap(bytes4(bytes1(0x01)))) == ~bytes4(bytes1(0x01))); + assert(Bytes5.unwrap(~Bytes5.wrap(bytes5(bytes1(0x01)))) == ~bytes5(bytes1(0x01))); + assert(Bytes6.unwrap(~Bytes6.wrap(bytes6(bytes1(0x01)))) == ~bytes6(bytes1(0x01))); + assert(Bytes7.unwrap(~Bytes7.wrap(bytes7(bytes1(0x01)))) == ~bytes7(bytes1(0x01))); + assert(Bytes8.unwrap(~Bytes8.wrap(bytes8(bytes1(0x01)))) == ~bytes8(bytes1(0x01))); + assert(Bytes9.unwrap(~Bytes9.wrap(bytes9(bytes1(0x01)))) == ~bytes9(bytes1(0x01))); + assert(Bytes10.unwrap(~Bytes10.wrap(bytes10(bytes1(0x01)))) == ~bytes10(bytes1(0x01))); + assert(Bytes11.unwrap(~Bytes11.wrap(bytes11(bytes1(0x01)))) == ~bytes11(bytes1(0x01))); + assert(Bytes12.unwrap(~Bytes12.wrap(bytes12(bytes1(0x01)))) == ~bytes12(bytes1(0x01))); + assert(Bytes13.unwrap(~Bytes13.wrap(bytes13(bytes1(0x01)))) == ~bytes13(bytes1(0x01))); + assert(Bytes14.unwrap(~Bytes14.wrap(bytes14(bytes1(0x01)))) == ~bytes14(bytes1(0x01))); + assert(Bytes15.unwrap(~Bytes15.wrap(bytes15(bytes1(0x01)))) == ~bytes15(bytes1(0x01))); + assert(Bytes16.unwrap(~Bytes16.wrap(bytes16(bytes1(0x01)))) == ~bytes16(bytes1(0x01))); + assert(Bytes17.unwrap(~Bytes17.wrap(bytes17(bytes1(0x01)))) == ~bytes17(bytes1(0x01))); + assert(Bytes18.unwrap(~Bytes18.wrap(bytes18(bytes1(0x01)))) == ~bytes18(bytes1(0x01))); + assert(Bytes19.unwrap(~Bytes19.wrap(bytes19(bytes1(0x01)))) == ~bytes19(bytes1(0x01))); + assert(Bytes20.unwrap(~Bytes20.wrap(bytes20(bytes1(0x01)))) == ~bytes20(bytes1(0x01))); + assert(Bytes21.unwrap(~Bytes21.wrap(bytes21(bytes1(0x01)))) == ~bytes21(bytes1(0x01))); + assert(Bytes22.unwrap(~Bytes22.wrap(bytes22(bytes1(0x01)))) == ~bytes22(bytes1(0x01))); + assert(Bytes23.unwrap(~Bytes23.wrap(bytes23(bytes1(0x01)))) == ~bytes23(bytes1(0x01))); + assert(Bytes24.unwrap(~Bytes24.wrap(bytes24(bytes1(0x01)))) == ~bytes24(bytes1(0x01))); + assert(Bytes25.unwrap(~Bytes25.wrap(bytes25(bytes1(0x01)))) == ~bytes25(bytes1(0x01))); + assert(Bytes26.unwrap(~Bytes26.wrap(bytes26(bytes1(0x01)))) == ~bytes26(bytes1(0x01))); + assert(Bytes27.unwrap(~Bytes27.wrap(bytes27(bytes1(0x01)))) == ~bytes27(bytes1(0x01))); + assert(Bytes28.unwrap(~Bytes28.wrap(bytes28(bytes1(0x01)))) == ~bytes28(bytes1(0x01))); + assert(Bytes29.unwrap(~Bytes29.wrap(bytes29(bytes1(0x01)))) == ~bytes29(bytes1(0x01))); + assert(Bytes30.unwrap(~Bytes30.wrap(bytes30(bytes1(0x01)))) == ~bytes30(bytes1(0x01))); + assert(Bytes31.unwrap(~Bytes31.wrap(bytes31(bytes1(0x01)))) == ~bytes31(bytes1(0x01))); + assert(Bytes32.unwrap(~Bytes32.wrap(bytes32(bytes1(0x01)))) == ~bytes32(bytes1(0x01))); + } + + function testOtherBinary() public pure { + assert(Address.unwrap(Address.wrap(address(0x01)) | Address.wrap(address(0x02))) == address(0x03)); + assert(AddressPayable.unwrap(AddressPayable.wrap(payable(address(0x01))) | AddressPayable.wrap(payable(address(0x02)))) == payable(address(0x03))); + assert(Bool.unwrap(~Bool.wrap(true)) == false); + } + + function testOtherUnary() public pure { + assert(Address.unwrap(~Address.wrap(address(0))) == address(~bytes20(0))); + assert(AddressPayable.unwrap(~AddressPayable.wrap(payable(address(0)))) == payable(address(~bytes20(0)))); + assert(Bool.unwrap(~Bool.wrap(true)) == false); + } +} +// ---- +// testIntBinary() -> +// testIntUnary() -> +// testUintBinary() -> +// testUintUnary() -> +// testBytesBinary() -> +// testBytesUnary() -> +// testOtherBinary() -> +// testOtherUnary() -> diff --git a/test/libsolidity/semanticTests/operators/userDefined/attaching_and_defining_operator_with_same_function.sol b/test/libsolidity/semanticTests/operators/userDefined/attaching_and_defining_operator_with_same_function.sol new file mode 100644 index 000000000..6f0323869 --- /dev/null +++ b/test/libsolidity/semanticTests/operators/userDefined/attaching_and_defining_operator_with_same_function.sol @@ -0,0 +1,20 @@ +type Int is int16; + +using {add as +, add} for Int global; + +function add(Int _a, Int _b) pure returns (Int) { + return Int.wrap(Int.unwrap(_a) + Int.unwrap(_b)); +} + +contract C { + function f() pure public returns (Int) { + return Int.wrap(5) + Int.wrap(5); + } + + function g() pure public returns (Int) { + return Int.wrap(7).add(Int.wrap(6)); + } +} +// ---- +// f() -> 10 +// g() -> 13 diff --git a/test/libsolidity/semanticTests/operators/userDefined/checked_operators.sol b/test/libsolidity/semanticTests/operators/userDefined/checked_operators.sol new file mode 100644 index 000000000..599e894b2 --- /dev/null +++ b/test/libsolidity/semanticTests/operators/userDefined/checked_operators.sol @@ -0,0 +1,22 @@ +type U8 is uint8; + +function checkedAdd(U8 x, U8 y) pure returns (U8) { + return U8.wrap(U8.unwrap(x) + U8.unwrap(y)); +} + +using {checkedAdd as +} for U8 global; + +contract C { + function testCheckedOperator() public pure returns (U8) { + return U8.wrap(250) + U8.wrap(10); + } + + function testCheckedOperatorInUncheckedBlock() public pure returns (U8) { + unchecked { + return U8.wrap(250) + U8.wrap(10); + } + } +} +// ---- +// testCheckedOperator() -> FAILURE, hex"4e487b71", 0x11 +// testCheckedOperatorInUncheckedBlock() -> FAILURE, hex"4e487b71", 0x11 diff --git a/test/libsolidity/semanticTests/operators/userDefined/consecutive_operator_invocations.sol b/test/libsolidity/semanticTests/operators/userDefined/consecutive_operator_invocations.sol new file mode 100644 index 000000000..ef36294a6 --- /dev/null +++ b/test/libsolidity/semanticTests/operators/userDefined/consecutive_operator_invocations.sol @@ -0,0 +1,18 @@ +type A is address; + +using {add as +} for A global; + +function add(A a, A b) pure returns (A) { + return A.wrap(address(uint160(A.unwrap(a)) + uint160(A.unwrap(b)))); +} + +contract C { + function g() public pure returns (A) { + A a = A.wrap(0x3333333333333333333333333333333333333333); + A b = A.wrap(0x1111111111111111111111111111111111111111); + A c = A.wrap(0x5555555555555555555555555555555555555555); + return a + b + c; + } +} +// ---- +// g() -> 0x9999999999999999999999999999999999999999 diff --git a/test/libsolidity/semanticTests/operators/userDefined/fixed_point_udvt_with_operators.sol b/test/libsolidity/semanticTests/operators/userDefined/fixed_point_udvt_with_operators.sol new file mode 100644 index 000000000..6f17b16eb --- /dev/null +++ b/test/libsolidity/semanticTests/operators/userDefined/fixed_point_udvt_with_operators.sol @@ -0,0 +1,22 @@ +type Fixed is int128; +using {add as +, mul as *} for Fixed global; + +int constant MULTIPLIER = 10**18; + +function add(Fixed a, Fixed b) pure returns (Fixed) { + return Fixed.wrap(Fixed.unwrap(a) + Fixed.unwrap(b)); +} + +function mul(Fixed a, Fixed b) pure returns (Fixed) { + int intermediate = (int(Fixed.unwrap(a)) * int(Fixed.unwrap(b))) / MULTIPLIER; + if (int128(intermediate) != intermediate) { revert("Overflow"); } + return Fixed.wrap(int128(intermediate)); +} + +contract C { + function applyInterest(Fixed value, Fixed percentage) public pure returns (Fixed result) { + return value + value * percentage; + } +} +// ---- +// applyInterest(int128,int128): 500000000000000000000, 100000000000000000 -> 550000000000000000000 diff --git a/test/libsolidity/semanticTests/operators/userDefined/multiple_operator_definitions_different_types_different_functions_separate_directives.sol b/test/libsolidity/semanticTests/operators/userDefined/multiple_operator_definitions_different_types_different_functions_separate_directives.sol new file mode 100644 index 000000000..0b2d740a6 --- /dev/null +++ b/test/libsolidity/semanticTests/operators/userDefined/multiple_operator_definitions_different_types_different_functions_separate_directives.sol @@ -0,0 +1,26 @@ +type SmallInt is int; +type BigInt is int; + +using {addSmall as +} for SmallInt global; +using {addBig as +} for BigInt global; + +function addSmall(SmallInt a, SmallInt b) pure returns (SmallInt) { + return SmallInt.wrap(SmallInt.unwrap(a) + SmallInt.unwrap(b)); +} + +function addBig(BigInt a, BigInt b) pure returns (BigInt) { + return BigInt.wrap(10 * (BigInt.unwrap(a) + BigInt.unwrap(b))); +} + +contract C { + function small() public pure returns (SmallInt) { + return SmallInt.wrap(1) + SmallInt.wrap(2); + } + + function big() public pure returns (BigInt) { + return BigInt.wrap(3) + BigInt.wrap(4); + } +} +// ---- +// small() -> 3 +// big() -> 70 diff --git a/test/libsolidity/semanticTests/operators/userDefined/multiple_operator_definitions_same_type_same_function_same_directive.sol b/test/libsolidity/semanticTests/operators/userDefined/multiple_operator_definitions_same_type_same_function_same_directive.sol new file mode 100644 index 000000000..3085d8e89 --- /dev/null +++ b/test/libsolidity/semanticTests/operators/userDefined/multiple_operator_definitions_same_type_same_function_same_directive.sol @@ -0,0 +1,20 @@ +type Int is int32; + +using {foo as +, foo as -} for Int global; + +function foo(Int a, Int b) pure returns(Int) { + return Int.wrap(Int.unwrap(a) + Int.unwrap(b)); +} + +contract C { + function f() pure public returns (Int) { + return Int.wrap(2) + Int.wrap(3); + } + + function g() pure public returns (Int) { + return Int.wrap(6) - Int.wrap(1); + } +} +// ---- +// f() -> 5 +// g() -> 7 diff --git a/test/libsolidity/semanticTests/operators/userDefined/operator_definition_shadowing_builtin_keccak256.sol b/test/libsolidity/semanticTests/operators/userDefined/operator_definition_shadowing_builtin_keccak256.sol new file mode 100644 index 000000000..a26a750cd --- /dev/null +++ b/test/libsolidity/semanticTests/operators/userDefined/operator_definition_shadowing_builtin_keccak256.sol @@ -0,0 +1,15 @@ +type Int is int16; + +using {keccak256 as +} for Int global; + +function keccak256(Int a, Int b) pure returns (Int) { + return Int.wrap(Int.unwrap(a) + Int.unwrap(b)); +} + +contract C { + function test() public returns (Int) { + return Int.wrap(3) + Int.wrap(4); + } +} +// ---- +// test() -> 7 diff --git a/test/libsolidity/semanticTests/operators/userDefined/operator_evaluation_order.sol b/test/libsolidity/semanticTests/operators/userDefined/operator_evaluation_order.sol new file mode 100644 index 000000000..781f21d16 --- /dev/null +++ b/test/libsolidity/semanticTests/operators/userDefined/operator_evaluation_order.sol @@ -0,0 +1,83 @@ +type Bool is bool; +using {add as +, mul as *, unsub as -} for Bool global; + +function add(Bool x, Bool y) pure returns (Bool) { + return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y)); +} + +function mul(Bool x, Bool y) pure returns (Bool) { + return Bool.wrap(Bool.unwrap(x) && Bool.unwrap(y)); +} + +function unsub(Bool x) pure returns (Bool) { + return Bool.wrap(!Bool.unwrap(x)); +} + +contract C { + event Wrapped(uint); + event Probe(Bool); + + function toBool(uint x) public returns (Bool) { + emit Wrapped(x); + return Bool.wrap(x > 0); + } + + function probe(Bool x) public returns (Bool) { + emit Probe(x); + return x; + } + + function testSingleOperator() public { + toBool(0) + + (toBool(1) + toBool(2)) + + toBool(3); + } + + function testTwoBinaryOperators() public { + toBool(0) * toBool(1) + + (toBool(2) * toBool(3)) + + toBool(4) * toBool(5); + } + + function testBinaryAndUnaryOperators() public { + -toBool(0) * -toBool(1) + + (-toBool(2) * -toBool(3)) + + -toBool(4) * -toBool(5); + } + + function testOperatorsNestedInCalls() public { + -probe(toBool(0) * -toBool(1)) + + (-probe(toBool(2) * -toBool(3))) + + -probe(toBool(4) * -toBool(5)); + } +} +// ---- +// testSingleOperator() -> +// ~ emit Wrapped(uint256): 0x00 +// ~ emit Wrapped(uint256): 0x01 +// ~ emit Wrapped(uint256): 0x02 +// ~ emit Wrapped(uint256): 0x03 +// testTwoBinaryOperators() -> +// ~ emit Wrapped(uint256): 0x00 +// ~ emit Wrapped(uint256): 0x01 +// ~ emit Wrapped(uint256): 0x02 +// ~ emit Wrapped(uint256): 0x03 +// ~ emit Wrapped(uint256): 0x04 +// ~ emit Wrapped(uint256): 0x05 +// testBinaryAndUnaryOperators() -> +// ~ emit Wrapped(uint256): 0x00 +// ~ emit Wrapped(uint256): 0x01 +// ~ emit Wrapped(uint256): 0x02 +// ~ emit Wrapped(uint256): 0x03 +// ~ emit Wrapped(uint256): 0x04 +// ~ emit Wrapped(uint256): 0x05 +// testOperatorsNestedInCalls() -> +// ~ emit Wrapped(uint256): 0x00 +// ~ emit Wrapped(uint256): 0x01 +// ~ emit Probe(bool): 0x00 +// ~ emit Wrapped(uint256): 0x02 +// ~ emit Wrapped(uint256): 0x03 +// ~ emit Probe(bool): 0x00 +// ~ emit Wrapped(uint256): 0x04 +// ~ emit Wrapped(uint256): 0x05 +// ~ emit Probe(bool): 0x00 diff --git a/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol b/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol new file mode 100644 index 000000000..0f95d2cda --- /dev/null +++ b/test/libsolidity/semanticTests/operators/userDefined/operator_making_pure_external_call.sol @@ -0,0 +1,61 @@ +type Int32 is int32; +using {add as +, unsub as -} for Int32 global; + +function add(Int32 x, Int32 y) pure returns (Int32) { + return loadAdder().mul(x, y); +} + +function unsub(Int32 x) pure returns (Int32) { + return loadAdder().inc(x); +} + +interface IAdder { + function mul(Int32, Int32) external pure returns (Int32); + function inc(Int32) external pure returns (Int32); +} + +contract Adder is IAdder { + function mul(Int32 x, Int32 y) external pure override returns (Int32) { + return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y)); + } + + function inc(Int32 x) external pure override returns (Int32) { + return Int32.wrap(Int32.unwrap(x) + 1); + } +} + +function storeAdder(IAdder adder) pure { + assembly { + // This test would also work without assembly if we could hard-code an address here. + mstore(0, adder) + } +} + +function loadAdder() pure returns (IAdder adder) { + assembly { + adder := mload(0) + } +} + +contract C { + function testMul(Int32 x, Int32 y) public returns (Int32) { + storeAdder(new Adder()); + + return x + y; + } + + function testInc(Int32 x) public returns (Int32) { + storeAdder(new Adder()); + + return -x; + } +} +// ---- +// testMul(int32,int32): 42, 10 -> 420 +// gas irOptimized: 103347 +// gas legacy: 188203 +// gas legacyOptimized: 126164 +// testInc(int32): 42 -> 43 +// gas irOptimized: 103173 +// gas legacy: 187452 +// gas legacyOptimized: 125851 diff --git a/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol b/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol new file mode 100644 index 000000000..1d51576e8 --- /dev/null +++ b/test/libsolidity/semanticTests/operators/userDefined/operator_making_view_external_call.sol @@ -0,0 +1,67 @@ +type Int32 is int32; +using {add as +, unsub as -} for Int32 global; + +function add(Int32 x, Int32 y) pure returns (Int32) { + return loadAdder().mul(x, y); +} + +function unsub(Int32 x) pure returns (Int32) { + return loadAdder().inc(x); +} + +interface IAdderPure { + function mul(Int32, Int32) external pure returns (Int32); + function inc(Int32) external pure returns (Int32); +} + +interface IAdderView { + function mul(Int32, Int32) external view returns (Int32); + function inc(Int32) external view returns (Int32); +} + +contract Adder is IAdderView { + function mul(Int32 x, Int32 y) external view override returns (Int32) { + return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y)); + } + + function inc(Int32 x) external view override returns (Int32) { + return Int32.wrap(Int32.unwrap(x) + 1); + } +} + +function storeAdder(IAdderView adder) pure { + assembly { + // This test would also work without assembly if we could hard-code an address here. + mstore(0, adder) + } +} + +function loadAdder() pure returns (IAdderPure adder) { + assembly { + // The adder we stored is view but we cheat by using a modified version with pure functions + adder := mload(0) + } +} + +contract C { + function testMul(Int32 x, Int32 y) public returns (Int32) { + storeAdder(new Adder()); + + return x + y; + } + + function testInc(Int32 x) public returns (Int32) { + storeAdder(new Adder()); + + return -x; + } +} +// ---- +// testMul(int32,int32): 42, 10 -> 420 +// gas irOptimized: 103347 +// gas legacy: 188203 +// gas legacyOptimized: 126164 +// testInc(int32): 42 -> 43 +// gas irOptimized: 103173 +// gas legacy: 187452 +// gas legacyOptimized: 125851 diff --git a/test/libsolidity/semanticTests/operators/userDefined/operator_parameter_cleanup.sol b/test/libsolidity/semanticTests/operators/userDefined/operator_parameter_cleanup.sol new file mode 100644 index 000000000..fe37a0e12 --- /dev/null +++ b/test/libsolidity/semanticTests/operators/userDefined/operator_parameter_cleanup.sol @@ -0,0 +1,40 @@ +type U8 is uint8; +using {f as ~, add as +} for U8 global; + +function f(U8 x) pure returns (U8 z) { + assembly { + // NOTE: Not using shr so that the test works pre-constantinople too + z := div(x, 256) + } +} + +function add(U8 x, U8 y) pure returns (U8 z) { + assembly { + z := add(div(x, 256), div(x, 256)) + } +} + +contract C { + function testUnary() external pure returns (U8, U8) { + U8 a; + assembly { + a := 0x4200 + } + // If the result is not 0, no cleanup was performed. + return (~a, f(a)); + } + + function testBinary() external pure returns (U8, U8) { + U8 a; + U8 b; + assembly { + a := 0x4200 + b := 0x4200 + } + // If the result is not 0, no cleanup was performed. + return (a + b, add(a, b)); + } +} +// ---- +// testUnary() -> 0x42, 0x42 +// testBinary() -> 0x84, 0x84 diff --git a/test/libsolidity/semanticTests/operators/userDefined/operator_precendence.sol b/test/libsolidity/semanticTests/operators/userDefined/operator_precendence.sol new file mode 100644 index 000000000..961e03169 --- /dev/null +++ b/test/libsolidity/semanticTests/operators/userDefined/operator_precendence.sol @@ -0,0 +1,71 @@ +type Int is int64; +using { + bitor as |, bitand as &, bitxor as ^, bitnot as ~, + add as +, sub as -, unsub as -, mul as *, div as /, mod as % +} for Int global; + +function bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); } +function bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); } +function bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); } +function bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); } + +function add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); } +function sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); } +function unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); } +function mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); } +function div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); } +function mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); } + +contract C { + Int constant I0 = Int.wrap(0); + Int constant I1 = Int.wrap(1); + Int constant I2 = Int.wrap(2); + Int constant I3 = Int.wrap(3); + Int constant I4 = Int.wrap(4); + Int constant I5 = Int.wrap(5); + Int constant I6 = Int.wrap(6); + Int constant I7 = Int.wrap(7); + Int constant I8 = Int.wrap(8); + Int constant I10 = Int.wrap(10); + Int constant I13 = Int.wrap(13); + Int constant I15 = Int.wrap(15); + Int constant I20 = Int.wrap(20); + Int constant I128 = Int.wrap(128); + + function testBitwise() public pure { + assert(Int.unwrap(I0 & I0 | I1) == (0 & 0 | 1)); + assert(Int.unwrap(I0 & I0 | I1) == ((0 & 0) | 1)); + } + + function testBitwise_arithmetic() public pure { + assert(Int.unwrap(I2 + I2 & ~I1 | I6 * I6 - I4 & ~I3) == (2 + 2 & ~1 | 6 * 6 - 4 & ~3)); + assert(Int.unwrap(I2 + I2 & ~I1 | I6 * I6 - I4 & ~I3) == (((2 + 2) & (~1)) | (((6 * 6) - 4) & (~3)))); + } + + function testArithmetic() public pure { + assert(Int.unwrap(I1 + I8 / I4 - I5 % I6 * I7) == (1 + 8 / 4 - 5 % 6 * 7)); + assert(Int.unwrap(I1 + I8 / I4 - I5 % I6 * I7) == ((1 + (8 / 4)) - ((5 % 6) * 7))); + } + + function testAll() public pure { + assert( + Int.unwrap(I128 + I1 - I10 + I4 & ~I1 ^ ~I1 * I2 | -I15 % -I10 * I20 / I2 + I13 & ~I3) == + (128 + 1 - 10 + 4 & ~1 ^ ~1 * 2 | -15 % -10 * 20 / 2 + 13 & ~3) + ); + assert( + Int.unwrap(I128 + I1 - I10 + I4 & ~I1 ^ ~I1 * I2 | -I15 % -I10 * I20 / I2 + I13 & ~I3) == + ( + ( + ((((128 + 1) - 10) + 4) & (~1)) ^ + ((~1) * 2) + ) | + ((((((-15) % (-10)) * 20) / 2) + 13) & (~3)) + ) + ); + } +} +// ---- +// testBitwise() -> +// testBitwise_arithmetic() -> +// testArithmetic() -> +// testAll() -> diff --git a/test/libsolidity/semanticTests/operators/userDefined/operator_return_parameter_cleanup.sol b/test/libsolidity/semanticTests/operators/userDefined/operator_return_parameter_cleanup.sol new file mode 100644 index 000000000..3798a0036 --- /dev/null +++ b/test/libsolidity/semanticTests/operators/userDefined/operator_return_parameter_cleanup.sol @@ -0,0 +1,58 @@ +type U8 is uint8; +using {f as ~, g as +} for U8 global; + +function f(U8) pure returns (U8 z) { + assembly { + // Return a value with dirty bytes outside of uint8 + z := 0xffff + } +} + +function g(U8, U8) pure returns (U8 z) { + assembly { + // Return a value with dirty bytes outside of uint8 + z := 0xffff + } +} + +contract C { + function testUnary() external pure returns (uint, uint) { + U8 a; // Value does not matter + + U8 opResult = ~a; + U8 fResult = f(a); + + // Get the slot, including bytes outside of uint8 + uint opResultFull; + uint fResultFull; + assembly { + opResultFull := opResult + fResultFull := fResult + } + + // If the result is not 0xff, no cleanup was performed. + return (opResultFull, fResultFull); + } + + function testBinary() external pure returns (uint, uint) { + U8 a; // Value does not matter + U8 b; // Value does not matter + + U8 opResult = a + b; + U8 fResult = g(a, b); + + // Get the slot, including bytes outside of uint8 + uint opResultFull; + uint fResultFull; + assembly { + opResultFull := opResult + fResultFull := fResult + } + + // If the result is not 0xff, no cleanup was performed. + return (opResultFull, fResultFull); + } +} +// ---- +// testUnary() -> 0xffff, 0xffff +// testBinary() -> 0xffff, 0xffff diff --git a/test/libsolidity/semanticTests/operators/userDefined/recursive_operator.sol b/test/libsolidity/semanticTests/operators/userDefined/recursive_operator.sol new file mode 100644 index 000000000..3ce080c34 --- /dev/null +++ b/test/libsolidity/semanticTests/operators/userDefined/recursive_operator.sol @@ -0,0 +1,41 @@ +type Uint is uint; +using {unaryCountdown as ~, binaryCountdown as ^, eq as ==} for Uint global; + +function unaryCountdown(Uint x) pure returns (Uint) { + if (x == Uint.wrap(0)) + return Uint.wrap(0); + + return ~Uint.wrap(Uint.unwrap(x) - 1); +} + +function binaryCountdown(Uint x, Uint y) pure returns (Uint) { + if (x == Uint.wrap(0) && y == Uint.wrap(0)) + return Uint.wrap(0); + if (x == Uint.wrap(0)) + return y ^ x; + + return Uint.wrap(Uint.unwrap(x) - 1) ^ y; +} + +function eq(Uint x, Uint y) pure returns (bool) { + return Uint.unwrap(x) == Uint.unwrap(y); +} + +contract C { + function testUnary(Uint x) public pure returns (Uint) { + return ~x; + } + + function testBinary(Uint x, Uint y) public pure returns (Uint) { + return x ^ y; + } +} +// ---- +// testUnary(uint256): 0 -> 0 +// testUnary(uint256): 1 -> 0 +// testUnary(uint256): 99999999999 -> FAILURE +// testBinary(uint256,uint256): 0, 0 -> 0 +// testBinary(uint256,uint256): 1, 0 -> 0 +// testBinary(uint256,uint256): 0, 1 -> 0 +// testBinary(uint256,uint256): 1, 1 -> 0 +// testBinary(uint256,uint256): 99999999999, 99999999999 -> FAILURE diff --git a/test/libsolidity/semanticTests/operators/userDefined/unchecked_operators.sol b/test/libsolidity/semanticTests/operators/userDefined/unchecked_operators.sol new file mode 100644 index 000000000..684ea1b43 --- /dev/null +++ b/test/libsolidity/semanticTests/operators/userDefined/unchecked_operators.sol @@ -0,0 +1,25 @@ +type U8 is uint8; + +function uncheckedAdd(U8 x, U8 y) pure returns (U8) { + unchecked { + return U8.wrap(U8.unwrap(x) + U8.unwrap(y)); + } +} + +using {uncheckedAdd as +} for U8 global; + +contract D { + function testUncheckedOperator() public pure returns (U8) { + return U8.wrap(250) + U8.wrap(10); + } + + function testUncheckedOperatorInUncheckedBlock() public pure returns (U8) { + unchecked { + return U8.wrap(250) + U8.wrap(10); + } + } +} + +// ---- +// testUncheckedOperator() -> 4 +// testUncheckedOperatorInUncheckedBlock() -> 4 diff --git a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_division_same_as_builtin.sol b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_division_same_as_builtin.sol new file mode 100644 index 000000000..20889af05 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_division_same_as_builtin.sol @@ -0,0 +1,16 @@ +type U is uint; +using {div as /} for U global; + +function div(U x, U y) pure returns (U) { + return U.wrap(U.unwrap(x) / U.unwrap(y)); +} + +contract C { + function f(U x, U y) public pure returns (U) { + return x / y; // FIXME: should detect div by zero + } +} +// ==== +// SMTEngine: all +// ---- +// Warning 6756: (218-223): User-defined operators are not yet supported by SMTChecker. This invocation of operator / has been ignored, which may lead to incorrect results. diff --git a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_division_with_safe_division_by_zero.sol b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_division_with_safe_division_by_zero.sol new file mode 100644 index 000000000..edc4d2a97 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_division_with_safe_division_by_zero.sol @@ -0,0 +1,19 @@ +type U is uint; +using {div as /} for U global; + +function div(U x, U y) pure returns (U) { + if (U.unwrap(y) == 0) + return U.wrap(0); + + return U.wrap(U.unwrap(x) / U.unwrap(y)); +} + +contract C { + function f(U x, U y) public pure returns (U) { + return x / y; // no div by zero possible here + } +} +// ==== +// SMTEngine: all +// ---- +// Warning 6756: (271-276): User-defined operators are not yet supported by SMTChecker. This invocation of operator / has been ignored, which may lead to incorrect results. diff --git a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants.sol b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants.sol new file mode 100644 index 000000000..10ec6a199 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants.sol @@ -0,0 +1,104 @@ +type I16 is int16; +using { + bitor as |, bitand as &, bitxor as ^, bitnot as ~, + add as +, sub as -, unsub as -, mul as *, div as /, mod as %, + eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >= +} for I16 global; + +function bitor(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) | I16.unwrap(y)); } +function bitand(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) & I16.unwrap(y)); } +function bitxor(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) ^ I16.unwrap(y)); } +function bitnot(I16 x) pure returns (I16) { return I16.wrap(~I16.unwrap(x)); } + +function add(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) + I16.unwrap(y)); } +function sub(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) - I16.unwrap(y)); } +function unsub(I16 x) pure returns (I16) { return I16.wrap(-I16.unwrap(x)); } +function mul(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) * I16.unwrap(y)); } +function div(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) / I16.unwrap(y)); } +function mod(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) % I16.unwrap(y)); } + +function eq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) == I16.unwrap(y); } +function noteq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) != I16.unwrap(y); } +function lt(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) < I16.unwrap(y); } +function gt(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) > I16.unwrap(y); } +function leq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) <= I16.unwrap(y); } +function geq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) >= I16.unwrap(y); } + +contract C { + I16 constant MINUS_TWO = I16.wrap(-2); + I16 constant ZERO = I16.wrap(0); + I16 constant ONE = I16.wrap(1); + I16 constant TWO = I16.wrap(2); + I16 constant THREE = I16.wrap(3); + I16 constant FOUR = I16.wrap(4); + + function testBitwise() public pure { + assert(ONE | TWO == THREE); // FIXME: should hold + assert(ONE & THREE == ZERO); // FIXME: should hold + assert(TWO ^ TWO == ZERO); // FIXME: should hold + assert(~ONE == MINUS_TWO); // FIXME: should hold + } + + function testArithmetic() public pure { + assert(TWO + TWO == FOUR); // FIXME: should hold + assert(TWO - TWO == ZERO); // FIXME: should hold + assert(-TWO == MINUS_TWO); // FIXME: should hold + assert(TWO * TWO == FOUR); // FIXME: should hold + assert(TWO / TWO == ONE); // FIXME: should hold + assert(TWO % TWO == ZERO); // FIXME: should hold + } + + function testComparison() public pure { + assert(TWO == TWO); // FIXME: should hold + assert(!(TWO != TWO)); // FIXME: should hold + assert(!(TWO < TWO)); // FIXME: should hold + assert(!(TWO > TWO)); // FIXME: should hold + assert(TWO <= TWO); // FIXME: should hold + assert(TWO >= TWO); // FIXME: should hold + } +} +// ==== +// SMTEngine: all +// ---- +// Warning 6756: (2019-2028): User-defined operators are not yet supported by SMTChecker. This invocation of operator | has been ignored, which may lead to incorrect results. +// Warning 6756: (2019-2037): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2077-2088): User-defined operators are not yet supported by SMTChecker. This invocation of operator & has been ignored, which may lead to incorrect results. +// Warning 6756: (2077-2096): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2136-2145): User-defined operators are not yet supported by SMTChecker. This invocation of operator ^ has been ignored, which may lead to incorrect results. +// Warning 6756: (2136-2153): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6156: (2193-2197): User-defined operators are not yet supported by SMTChecker. This invocation of operator ~ has been ignored, which may lead to incorrect results. +// Warning 6756: (2193-2210): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2301-2310): User-defined operators are not yet supported by SMTChecker. This invocation of operator + has been ignored, which may lead to incorrect results. +// Warning 6756: (2301-2318): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2358-2367): User-defined operators are not yet supported by SMTChecker. This invocation of operator - has been ignored, which may lead to incorrect results. +// Warning 6756: (2358-2375): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6156: (2415-2419): User-defined operators are not yet supported by SMTChecker. This invocation of operator - has been ignored, which may lead to incorrect results. +// Warning 6756: (2415-2432): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2472-2481): User-defined operators are not yet supported by SMTChecker. This invocation of operator * has been ignored, which may lead to incorrect results. +// Warning 6756: (2472-2489): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2529-2538): User-defined operators are not yet supported by SMTChecker. This invocation of operator / has been ignored, which may lead to incorrect results. +// Warning 6756: (2529-2545): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2585-2594): User-defined operators are not yet supported by SMTChecker. This invocation of operator % has been ignored, which may lead to incorrect results. +// Warning 6756: (2585-2602): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2693-2703): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2745-2755): User-defined operators are not yet supported by SMTChecker. This invocation of operator != has been ignored, which may lead to incorrect results. +// Warning 6756: (2798-2807): User-defined operators are not yet supported by SMTChecker. This invocation of operator < has been ignored, which may lead to incorrect results. +// Warning 6756: (2850-2859): User-defined operators are not yet supported by SMTChecker. This invocation of operator > has been ignored, which may lead to incorrect results. +// Warning 6756: (2900-2910): User-defined operators are not yet supported by SMTChecker. This invocation of operator <= has been ignored, which may lead to incorrect results. +// Warning 6756: (2950-2960): User-defined operators are not yet supported by SMTChecker. This invocation of operator >= has been ignored, which may lead to incorrect results. +// Warning 6328: (2012-2038): CHC: Assertion violation happens here. +// Warning 6328: (2070-2097): CHC: Assertion violation happens here. +// Warning 6328: (2129-2154): CHC: Assertion violation happens here. +// Warning 6328: (2186-2211): CHC: Assertion violation happens here. +// Warning 6328: (2294-2319): CHC: Assertion violation happens here. +// Warning 6328: (2351-2376): CHC: Assertion violation happens here. +// Warning 6328: (2408-2433): CHC: Assertion violation happens here. +// Warning 6328: (2465-2490): CHC: Assertion violation happens here. +// Warning 6328: (2522-2546): CHC: Assertion violation happens here. +// Warning 6328: (2578-2603): CHC: Assertion violation happens here. +// Warning 6328: (2686-2704): CHC: Assertion violation happens here. +// Warning 6328: (2736-2757): CHC: Assertion violation happens here. +// Warning 6328: (2789-2809): CHC: Assertion violation happens here. +// Warning 6328: (2841-2861): CHC: Assertion violation happens here. +// Warning 6328: (2893-2911): CHC: Assertion violation happens here. +// Warning 6328: (2943-2961): CHC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants_fail.sol b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants_fail.sol new file mode 100644 index 000000000..c30bb21c1 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operations_on_constants_fail.sol @@ -0,0 +1,104 @@ +type I16 is int16; +using { + bitor as |, bitand as &, bitxor as ^, bitnot as ~, + add as +, sub as -, unsub as -, mul as *, div as /, mod as %, + eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >= +} for I16 global; + +function bitor(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) | I16.unwrap(y)); } +function bitand(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) & I16.unwrap(y)); } +function bitxor(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) ^ I16.unwrap(y)); } +function bitnot(I16 x) pure returns (I16) { return I16.wrap(~I16.unwrap(x)); } + +function add(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) + I16.unwrap(y)); } +function sub(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) - I16.unwrap(y)); } +function unsub(I16 x) pure returns (I16) { return I16.wrap(-I16.unwrap(x)); } +function mul(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) * I16.unwrap(y)); } +function div(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) / I16.unwrap(y)); } +function mod(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) % I16.unwrap(y)); } + +function eq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) == I16.unwrap(y); } +function noteq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) != I16.unwrap(y); } +function lt(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) < I16.unwrap(y); } +function gt(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) > I16.unwrap(y); } +function leq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) <= I16.unwrap(y); } +function geq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) >= I16.unwrap(y); } + +contract C { + I16 constant MINUS_TWO = I16.wrap(-2); + I16 constant ZERO = I16.wrap(0); + I16 constant ONE = I16.wrap(1); + I16 constant TWO = I16.wrap(2); + I16 constant THREE = I16.wrap(3); + I16 constant FOUR = I16.wrap(4); + + function testBitwise() public pure { + assert(ONE | TWO == FOUR); // should fail + assert(ONE & THREE == FOUR); // should fail + assert(TWO ^ TWO == FOUR); // should fail + assert(~ONE == FOUR); // should fail + } + + function testArithmetic() public pure { + assert(TWO + THREE == FOUR); // should fail + assert(TWO - TWO == FOUR); // should fail + assert(-TWO == FOUR); // should fail + assert(TWO * THREE == FOUR); // should fail + assert(TWO / TWO == FOUR); // should fail + assert(TWO % TWO == FOUR); // should fail + } + + function testComparison() public pure { + assert(!(TWO == TWO)); // should fail + assert(TWO != TWO); // should fail + assert(TWO < TWO); // should fail + assert(TWO > TWO); // should fail + assert(!(TWO <= TWO)); // should fail + assert(!(TWO >= TWO)); // should fail + } +} +// ==== +// SMTEngine: all +// ---- +// Warning 6756: (2019-2028): User-defined operators are not yet supported by SMTChecker. This invocation of operator | has been ignored, which may lead to incorrect results. +// Warning 6756: (2019-2036): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2069-2080): User-defined operators are not yet supported by SMTChecker. This invocation of operator & has been ignored, which may lead to incorrect results. +// Warning 6756: (2069-2088): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2121-2130): User-defined operators are not yet supported by SMTChecker. This invocation of operator ^ has been ignored, which may lead to incorrect results. +// Warning 6756: (2121-2138): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6156: (2171-2175): User-defined operators are not yet supported by SMTChecker. This invocation of operator ~ has been ignored, which may lead to incorrect results. +// Warning 6756: (2171-2183): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2267-2278): User-defined operators are not yet supported by SMTChecker. This invocation of operator + has been ignored, which may lead to incorrect results. +// Warning 6756: (2267-2286): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2319-2328): User-defined operators are not yet supported by SMTChecker. This invocation of operator - has been ignored, which may lead to incorrect results. +// Warning 6756: (2319-2336): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6156: (2369-2373): User-defined operators are not yet supported by SMTChecker. This invocation of operator - has been ignored, which may lead to incorrect results. +// Warning 6756: (2369-2381): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2414-2425): User-defined operators are not yet supported by SMTChecker. This invocation of operator * has been ignored, which may lead to incorrect results. +// Warning 6756: (2414-2433): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2466-2475): User-defined operators are not yet supported by SMTChecker. This invocation of operator / has been ignored, which may lead to incorrect results. +// Warning 6756: (2466-2483): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2516-2525): User-defined operators are not yet supported by SMTChecker. This invocation of operator % has been ignored, which may lead to incorrect results. +// Warning 6756: (2516-2533): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2619-2629): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2663-2673): User-defined operators are not yet supported by SMTChecker. This invocation of operator != has been ignored, which may lead to incorrect results. +// Warning 6756: (2706-2715): User-defined operators are not yet supported by SMTChecker. This invocation of operator < has been ignored, which may lead to incorrect results. +// Warning 6756: (2748-2757): User-defined operators are not yet supported by SMTChecker. This invocation of operator > has been ignored, which may lead to incorrect results. +// Warning 6756: (2792-2802): User-defined operators are not yet supported by SMTChecker. This invocation of operator <= has been ignored, which may lead to incorrect results. +// Warning 6756: (2838-2848): User-defined operators are not yet supported by SMTChecker. This invocation of operator >= has been ignored, which may lead to incorrect results. +// Warning 6328: (2012-2037): CHC: Assertion violation happens here. +// Warning 6328: (2062-2089): CHC: Assertion violation happens here. +// Warning 6328: (2114-2139): CHC: Assertion violation happens here. +// Warning 6328: (2164-2184): CHC: Assertion violation happens here. +// Warning 6328: (2260-2287): CHC: Assertion violation happens here. +// Warning 6328: (2312-2337): CHC: Assertion violation happens here. +// Warning 6328: (2362-2382): CHC: Assertion violation happens here. +// Warning 6328: (2407-2434): CHC: Assertion violation happens here. +// Warning 6328: (2459-2484): CHC: Assertion violation happens here. +// Warning 6328: (2509-2534): CHC: Assertion violation happens here. +// Warning 6328: (2610-2631): CHC: Assertion violation happens here. +// Warning 6328: (2656-2674): CHC: Assertion violation happens here. +// Warning 6328: (2699-2716): CHC: Assertion violation happens here. +// Warning 6328: (2741-2758): CHC: Assertion violation happens here. +// Warning 6328: (2783-2804): CHC: Assertion violation happens here. +// Warning 6328: (2829-2850): CHC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol new file mode 100644 index 000000000..f97b82f81 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_operator_matches_equivalent_function_call.sol @@ -0,0 +1,105 @@ +type I16 is int16; +using { + bitor as |, bitand as &, bitxor as ^, bitnot as ~, + add as +, sub as -, unsub as -, mul as *, div as /, mod as %, + eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >= +} for I16 global; + +function bitor(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) | I16.unwrap(y)); } +function bitand(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) & I16.unwrap(y)); } +function bitxor(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) ^ I16.unwrap(y)); } +function bitnot(I16 x) pure returns (I16) { return I16.wrap(~I16.unwrap(x)); } + +function add(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) + I16.unwrap(y)); } +function sub(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) - I16.unwrap(y)); } +function unsub(I16 x) pure returns (I16) { return I16.wrap(-I16.unwrap(x)); } +function mul(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) * I16.unwrap(y)); } +function div(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) / I16.unwrap(y)); } +function mod(I16 x, I16 y) pure returns (I16) { return I16.wrap(I16.unwrap(x) % I16.unwrap(y)); } + +function eq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) == I16.unwrap(y); } +function noteq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) != I16.unwrap(y); } +function lt(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) < I16.unwrap(y); } +function gt(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) > I16.unwrap(y); } +function leq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) <= I16.unwrap(y); } +function geq(I16 x, I16 y) pure returns (bool) { return I16.unwrap(x) >= I16.unwrap(y); } + +contract C { + function testBitwise(I16 x, I16 y) public pure { + assert(x | y == bitor(x, y)); // FIXME: should hold + assert(x & y == bitand(x, y)); // FIXME: should hold + assert(x ^ y == bitxor(x, y)); // FIXME: should hold + assert(~x == bitnot(x)); // FIXME: should hold + } + + function testArithmetic(I16 x, I16 y) public pure { + assert(x + y == add(x, y)); // FIXME: should hold + assert(x - y == sub(x, y)); // FIXME: should hold + assert(-x == unsub(x)); // FIXME: should hold + assert(x * y == mul(x, y)); // FIXME: should hold + assert(x / y == div(x, y)); // FIXME: should hold + assert(x % y == mod(x, y)); // FIXME: should hold + } + + function testComparison(I16 x, I16 y) public pure { + assert((x == y) == eq(x, y)); // FIXME: should hold + assert((x != y) == noteq(x, y)); // FIXME: should hold + assert((x < y) == lt(x, y)); // FIXME: should hold + assert((x > y) == gt(x, y)); // FIXME: should hold + assert((x <= y) == leq(x, y)); // FIXME: should hold + assert((x >= y) == geq(x, y)); // FIXME: should hold + } +} +// ==== +// SMTEngine: all +// ---- +// Warning 6756: (1803-1808): User-defined operators are not yet supported by SMTChecker. This invocation of operator | has been ignored, which may lead to incorrect results. +// Warning 6756: (1803-1823): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (1863-1868): User-defined operators are not yet supported by SMTChecker. This invocation of operator & has been ignored, which may lead to incorrect results. +// Warning 6756: (1863-1884): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (1924-1929): User-defined operators are not yet supported by SMTChecker. This invocation of operator ^ has been ignored, which may lead to incorrect results. +// Warning 6756: (1924-1945): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6156: (1985-1987): User-defined operators are not yet supported by SMTChecker. This invocation of operator ~ has been ignored, which may lead to incorrect results. +// Warning 6756: (1985-2000): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2103-2108): User-defined operators are not yet supported by SMTChecker. This invocation of operator + has been ignored, which may lead to incorrect results. +// Warning 6756: (2103-2121): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2161-2166): User-defined operators are not yet supported by SMTChecker. This invocation of operator - has been ignored, which may lead to incorrect results. +// Warning 6756: (2161-2179): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6156: (2219-2221): User-defined operators are not yet supported by SMTChecker. This invocation of operator - has been ignored, which may lead to incorrect results. +// Warning 6756: (2219-2233): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2273-2278): User-defined operators are not yet supported by SMTChecker. This invocation of operator * has been ignored, which may lead to incorrect results. +// Warning 6756: (2273-2291): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2331-2336): User-defined operators are not yet supported by SMTChecker. This invocation of operator / has been ignored, which may lead to incorrect results. +// Warning 6756: (2331-2349): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2389-2394): User-defined operators are not yet supported by SMTChecker. This invocation of operator % has been ignored, which may lead to incorrect results. +// Warning 6756: (2389-2407): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2511-2517): User-defined operators are not yet supported by SMTChecker. This invocation of operator == has been ignored, which may lead to incorrect results. +// Warning 6756: (2571-2577): User-defined operators are not yet supported by SMTChecker. This invocation of operator != has been ignored, which may lead to incorrect results. +// Warning 6756: (2634-2639): User-defined operators are not yet supported by SMTChecker. This invocation of operator < has been ignored, which may lead to incorrect results. +// Warning 6756: (2693-2698): User-defined operators are not yet supported by SMTChecker. This invocation of operator > has been ignored, which may lead to incorrect results. +// Warning 6756: (2752-2758): User-defined operators are not yet supported by SMTChecker. This invocation of operator <= has been ignored, which may lead to incorrect results. +// Warning 6756: (2813-2819): User-defined operators are not yet supported by SMTChecker. This invocation of operator >= has been ignored, which may lead to incorrect results. +// Warning 3944: (679-708): CHC: Underflow (resulting value less than -32768) happens here. +// Warning 4984: (679-708): CHC: Overflow (resulting value larger than 32767) happens here. +// Warning 3944: (777-806): CHC: Underflow (resulting value less than -32768) happens here. +// Warning 4984: (777-806): CHC: Overflow (resulting value larger than 32767) happens here. +// Warning 3944: (953-982): CHC: Underflow (resulting value less than -32768) happens here. +// Warning 4984: (953-982): CHC: Overflow (resulting value larger than 32767) happens here. +// Warning 4281: (1051-1080): CHC: Division by zero happens here. +// Warning 4281: (1149-1178): CHC: Division by zero happens here. +// Warning 6328: (1796-1824): CHC: Assertion violation happens here. +// Warning 6328: (1856-1885): CHC: Assertion violation happens here. +// Warning 6328: (1917-1946): CHC: Assertion violation happens here. +// Warning 6328: (1978-2001): CHC: Assertion violation happens here. +// Warning 6328: (2096-2122): CHC: Assertion violation happens here. +// Warning 6328: (2154-2180): CHC: Assertion violation happens here. +// Warning 6328: (2212-2234): CHC: Assertion violation happens here. +// Warning 6328: (2266-2292): CHC: Assertion violation happens here. +// Warning 6328: (2324-2350): CHC: Assertion violation happens here. +// Warning 6328: (2382-2408): CHC: Assertion violation happens here. +// Warning 6328: (2503-2531): CHC: Assertion violation happens here. +// Warning 6328: (2563-2594): CHC: Assertion violation happens here. +// Warning 6328: (2626-2653): CHC: Assertion violation happens here. +// Warning 6328: (2685-2712): CHC: Assertion violation happens here. +// Warning 6328: (2744-2773): CHC: Assertion violation happens here. +// Warning 6328: (2805-2834): CHC: Assertion violation happens here. diff --git a/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_overflow.sol b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_overflow.sol new file mode 100644 index 000000000..e785be5e5 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/operators/userDefined/user_defined_overflow.sol @@ -0,0 +1,23 @@ +type U8 is uint8; +using {add as +} for U8 global; + +function add(U8 x, U8 y) pure returns (U8) { + return U8.wrap(U8.unwrap(x) + U8.unwrap(y)); // FIXME: should detect possible overflow here +} + +contract C { + U8 x = U8.wrap(254); + + function inc() public { + x = x + U8.wrap(1); // FIXME: should detect possible overflow here + } + + function check() view public { + U8 y = x; + assert(U8.unwrap(y) < 256); + } +} +// ==== +// SMTEngine: all +// ---- +// Warning 6756: (274-288): User-defined operators are not yet supported by SMTChecker. This invocation of operator + has been ignored, which may lead to incorrect results. diff --git a/test/libsolidity/syntaxTests/constants/constant_cyclic_via_user_operators.sol b/test/libsolidity/syntaxTests/constants/constant_cyclic_via_user_operators.sol new file mode 100644 index 000000000..e0af337c7 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/constant_cyclic_via_user_operators.sol @@ -0,0 +1,10 @@ +type Type is uint; +using {f as +} for Type global; +function f(Type, Type) pure returns (Type) {} + +Type constant t = Type.wrap(1); +Type constant u = v + t; +Type constant v = u + t; +// ---- +// TypeError 8349: (148-153): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (173-178): Initial value for constant variable has to be compile-time constant. diff --git a/test/libsolidity/syntaxTests/controlFlow/userDefinedOperators/binary_operator_udvt.sol b/test/libsolidity/syntaxTests/controlFlow/userDefinedOperators/binary_operator_udvt.sol new file mode 100644 index 000000000..d0a0b6ea6 --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/userDefinedOperators/binary_operator_udvt.sol @@ -0,0 +1,17 @@ +type X is uint24; +type Y is uint16; + +using {addX as +} for X global; +using {addY as +} for Y global; + +function addX(X, X) pure returns (X) {} +function addY(Y, Y) pure returns (Y) { revert(); } + +contract C { + function f() public pure { + X.wrap(1) + X.wrap(Y.unwrap(Y.wrap(2) + Y.wrap(3))); + X.wrap(4) + X.wrap(5); // Unreachable + } +} +// ---- +// Warning 5740: (307-328): Unreachable code. diff --git a/test/libsolidity/syntaxTests/controlFlow/userDefinedOperators/unary_operator_udvt.sol b/test/libsolidity/syntaxTests/controlFlow/userDefinedOperators/unary_operator_udvt.sol new file mode 100644 index 000000000..12b0f03b9 --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/userDefinedOperators/unary_operator_udvt.sol @@ -0,0 +1,17 @@ +type X is uint24; +type Y is uint16; + +using {unsubX as -} for X global; +using {unsubY as -} for Y global; + +function unsubX(X) pure returns (X) {} +function unsubY(Y) pure returns (Y) { revert(); } + +contract C { + function f() public pure { + -X.wrap(Y.unwrap(-Y.wrap(1))); + -X.wrap(Y.unwrap(Y.wrap(2))); // Unreachable + } +} +// ---- +// Warning 5740: (287-315): Unreachable code. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/203_struct_reference_compare_operators.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/203_struct_reference_compare_operators.sol index 930e79a3b..1cf46ac83 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/203_struct_reference_compare_operators.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/203_struct_reference_compare_operators.sol @@ -7,4 +7,4 @@ contract test { } } // ---- -// TypeError 2271: (79-85): Built-in binary operator == cannot be applied to types struct test.s storage ref and struct test.s storage ref. +// TypeError 2271: (79-85): Built-in binary operator == cannot be applied to types struct test.s storage ref and struct test.s storage ref. No matching user-defined operator found. diff --git a/test/libsolidity/syntaxTests/operators/calling_operator_binary_user_defined_not_available.sol b/test/libsolidity/syntaxTests/operators/calling_operator_binary_user_defined_not_available.sol new file mode 100644 index 000000000..ea0c8f9d8 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/calling_operator_binary_user_defined_not_available.sol @@ -0,0 +1,11 @@ +type Int is int256; + +function f() pure { + Int a = Int.wrap(0); + a + a; + a >>> a; +} + +// ---- +// TypeError 2271: (70-75): Built-in binary operator + cannot be applied to types Int and Int. No matching user-defined operator found. +// TypeError 2271: (81-88): Built-in binary operator >>> cannot be applied to types Int and Int. diff --git a/test/libsolidity/syntaxTests/operators/calling_operator_unary_user_defined_not_available.sol b/test/libsolidity/syntaxTests/operators/calling_operator_unary_user_defined_not_available.sol new file mode 100644 index 000000000..29273852e --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/calling_operator_unary_user_defined_not_available.sol @@ -0,0 +1,11 @@ +type Int is int256; + +function f() pure { + Int a = Int.wrap(0); + -a; + a++; +} + +// ---- +// TypeError 4907: (70-72): Built-in unary operator - cannot be applied to type Int. No matching user-defined operator found. +// TypeError 9767: (78-81): Built-in unary operator ++ cannot be applied to type Int. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/calling_operator.sol b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator.sol new file mode 100644 index 000000000..a00eb2ce5 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator.sol @@ -0,0 +1,11 @@ +type Int is int; +using {add as +} for Int global; +using {unsub as -} for Int global; + +function add(Int, Int) pure returns (Int) {} +function unsub(Int) pure returns (Int) {} + +function f() pure { + Int.wrap(0) + Int.wrap(0); + -Int.wrap(0); +} diff --git a/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_as_attached_function_via_function_name.sol b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_as_attached_function_via_function_name.sol new file mode 100644 index 000000000..6c1baa4b1 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_as_attached_function_via_function_name.sol @@ -0,0 +1,12 @@ +type Int is int16; + +using {add as +} for Int global; + +function add(Int, Int) pure returns (Int) {} + +function f() { + Int a; + a.add(a); +} +// ---- +// TypeError 9582: (130-135): Member "add" not found or not visible after argument-dependent lookup in Int. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_as_attached_function_via_operator_name.sol b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_as_attached_function_via_operator_name.sol new file mode 100644 index 000000000..62c53cb8e --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_as_attached_function_via_operator_name.sol @@ -0,0 +1,12 @@ +type Int is int16; + +using {add as +} for Int global; + +function add(Int, Int) pure returns (Int) {} + +function f() { + Int a; + a.+(a); +} +// ---- +// ParserError 2314: (132-133): Expected identifier but got '+' diff --git a/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_defined_separately_from_type.sol b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_defined_separately_from_type.sol new file mode 100644 index 000000000..827853938 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_defined_separately_from_type.sol @@ -0,0 +1,23 @@ +==== Source: definition.sol ==== +import "type-and-binding.sol"; + +function add(Int, Int) pure returns (Int) {} +function unsub(Int) pure returns (Int) {} + +==== Source: type-and-binding.sol ==== +import "definition.sol"; + +type Int is int; + +using {add as +} for Int global; +using {unsub as -} for Int global; + +==== Source: use.sol ==== +import "type-and-binding.sol"; + +contract C { + function f() pure public { + Int.wrap(0) + Int.wrap(0); + -Int.wrap(0); + } +} diff --git a/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_defined_separately_from_type_and_binding.sol b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_defined_separately_from_type_and_binding.sol new file mode 100644 index 000000000..d7a9ed057 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_defined_separately_from_type_and_binding.sol @@ -0,0 +1,30 @@ +==== Source: binding.sol ==== +import "definition.sol"; +import "type.sol"; + +using {add as +} for Int global; +using {unsub as -} for Int global; + +==== Source: definition.sol ==== +import "type.sol"; + +function add(Int, Int) pure returns (Int) {} +function unsub(Int) pure returns (Int) {} + +==== Source: type.sol ==== +type Int is int; + +==== Source: use.sol ==== +import "type.sol"; + +contract C { + function f() pure public { + Int.wrap(0) + Int.wrap(0); + -Int.wrap(0); + } +} +// ---- +// TypeError 4117: (binding.sol:45-77): Can only use "global" with types defined in the same source unit at file level. +// TypeError 4117: (binding.sol:78-112): Can only use "global" with types defined in the same source unit at file level. +// TypeError 2271: (use.sol:72-97): Built-in binary operator + cannot be applied to types Int and Int. No matching user-defined operator found. +// TypeError 4907: (use.sol:107-119): Built-in unary operator - cannot be applied to type Int. No matching user-defined operator found. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_imported.sol b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_imported.sol new file mode 100644 index 000000000..7c56bd6d6 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_imported.sol @@ -0,0 +1,17 @@ +==== Source: s1.sol ==== +type Int is int; +using {add as +} for Int global; +using {unsub as -} for Int global; + +function add(Int, Int) pure returns (Int) {} +function unsub(Int) pure returns (Int) {} + +==== Source: s2.sol ==== +import "s1.sol"; + +contract C { + function f() pure public { + Int.wrap(0) + Int.wrap(0); + -Int.wrap(0); + } +} diff --git a/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_imported_non_global.sol b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_imported_non_global.sol new file mode 100644 index 000000000..ab2a83797 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_imported_non_global.sol @@ -0,0 +1,22 @@ +==== Source: s1.sol ==== +type Int is int; +using {add as +} for Int; +using {unsub as -} for Int; + +function add(Int, Int) pure returns (Int) {} +function unsub(Int) pure returns (Int) {} + +==== Source: s2.sol ==== +import "s1.sol"; + +contract C { + function f() pure public { + Int.wrap(0) + Int.wrap(0); + -Int.wrap(0); + } +} +// ---- +// TypeError 3320: (s1.sol:24-27): Operators can only be defined in a global 'using for' directive. +// TypeError 3320: (s1.sol:50-55): Operators can only be defined in a global 'using for' directive. +// TypeError 2271: (s2.sol:70-95): Built-in binary operator + cannot be applied to types Int and Int. No matching user-defined operator found. +// TypeError 4907: (s2.sol:105-117): Built-in unary operator - cannot be applied to type Int. No matching user-defined operator found. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_imported_transitively.sol b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_imported_transitively.sol new file mode 100644 index 000000000..86e4c2f43 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_imported_transitively.sol @@ -0,0 +1,35 @@ +==== Source: s0.sol ==== +type Int is int; + +==== Source: s1.sol ==== +import "s0.sol"; +using {add1 as +} for Int global; +using {unsub1 as -} for Int global; + +function add1(Int, Int) pure returns (Int) {} +function unsub1(Int) pure returns (Int) {} + +==== Source: s2.sol ==== +import "s0.sol"; +using {add2 as +} for Int global; +using {unsub2 as -} for Int global; + +function add2(Int, Int) pure returns (Int) {} +function unsub2(Int) pure returns (Int) {} + +==== Source: s3.sol ==== +import "s1.sol"; +import "s2.sol"; +contract C { + function f() public { + Int.wrap(0) + Int.wrap(0); + -Int.wrap(0); + } +} +// ---- +// TypeError 4117: (s1.sol:17-50): Can only use "global" with types defined in the same source unit at file level. +// TypeError 4117: (s1.sol:51-86): Can only use "global" with types defined in the same source unit at file level. +// TypeError 4117: (s2.sol:17-50): Can only use "global" with types defined in the same source unit at file level. +// TypeError 4117: (s2.sol:51-86): Can only use "global" with types defined in the same source unit at file level. +// TypeError 2271: (s3.sol:81-106): Built-in binary operator + cannot be applied to types Int and Int. No matching user-defined operator found. +// TypeError 4907: (s3.sol:116-128): Built-in unary operator - cannot be applied to type Int. No matching user-defined operator found. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_imported_transitively_non_global.sol b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_imported_transitively_non_global.sol new file mode 100644 index 000000000..7bd3fa146 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_imported_transitively_non_global.sol @@ -0,0 +1,35 @@ +==== Source: s0.sol ==== +type Int is int; + +==== Source: s1.sol ==== +import "s0.sol"; +using {add1 as +} for Int; +using {unsub1 as -} for Int; + +function add1(Int, Int) pure returns (Int) {} +function unsub1(Int) pure returns (Int) {} + +==== Source: s2.sol ==== +import "s0.sol"; +using {add2 as +} for Int; +using {unsub2 as -} for Int; + +function add2(Int, Int) pure returns (Int) {} +function unsub2(Int) pure returns (Int) {} + +==== Source: s3.sol ==== +import "s1.sol"; +import "s2.sol"; +contract C { + function f() public { + Int.wrap(0) + Int.wrap(0); + -Int.wrap(0); + } +} +// ---- +// TypeError 3320: (s1.sol:24-28): Operators can only be defined in a global 'using for' directive. +// TypeError 3320: (s1.sol:51-57): Operators can only be defined in a global 'using for' directive. +// TypeError 3320: (s2.sol:24-28): Operators can only be defined in a global 'using for' directive. +// TypeError 3320: (s2.sol:51-57): Operators can only be defined in a global 'using for' directive. +// TypeError 2271: (s3.sol:81-106): Built-in binary operator + cannot be applied to types Int and Int. No matching user-defined operator found. +// TypeError 4907: (s3.sol:116-128): Built-in unary operator - cannot be applied to type Int. No matching user-defined operator found. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_in_constant_initialization.sol b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_in_constant_initialization.sol new file mode 100644 index 000000000..f05655b65 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_in_constant_initialization.sol @@ -0,0 +1,24 @@ +type B4 is bytes4; +using {bitor as |, bitnot as ~} for B4 global; + +function bitor(B4, B4) pure returns (B4) {} +function bitnot(B4) pure returns (B4) {} + +B4 constant X = B4.wrap(0x12345678) | B4.wrap(0xaabbccdd); + +contract C { + B4 constant Y = B4.wrap(0x12345678) | B4.wrap(0xaabbccdd); +} + +library L { + B4 constant Z = ~B4.wrap(0x12345678); +} + +interface I { + B4 constant W = ~B4.wrap(0x12345678); +} +// ---- +// TypeError 8349: (169-210): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (246-287): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (324-344): Initial value for constant variable has to be compile-time constant. +// TypeError 8349: (383-403): Initial value for constant variable has to be compile-time constant. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_non_global.sol b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_non_global.sol new file mode 100644 index 000000000..5af79ad47 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_non_global.sol @@ -0,0 +1,14 @@ +type Int is int; +using {add as +} for Int; +using {unsub as -} for Int; + +function add(Int, Int) pure returns (Int) {} +function unsub(Int) pure returns (Int) {} + +function f() pure { + Int.wrap(0) + Int.wrap(0); + -Int.wrap(0); +} +// ---- +// TypeError 3320: (24-27): Operators can only be defined in a global 'using for' directive. +// TypeError 3320: (50-55): Operators can only be defined in a global 'using for' directive. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_that_deploys_contract.sol b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_that_deploys_contract.sol new file mode 100644 index 000000000..08e9e68d9 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_that_deploys_contract.sol @@ -0,0 +1,24 @@ +type Int is int16; + +using {add as +} for Int global; + +function add(Int, Int) returns (Int) { + B b = new B(); + return b.f(); +} + +contract B { + Int s; + function f() external returns (Int) { + s = Int.wrap(3); + return s; + } +} + +contract C { + function test() public returns (Int) { + return Int.wrap(0) + Int.wrap(0); + } +} +// ---- +// TypeError 7775: (27-30): Only pure free functions can be used to define operators. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_that_makes_external_call.sol b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_that_makes_external_call.sol new file mode 100644 index 000000000..02c5d655f --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_that_makes_external_call.sol @@ -0,0 +1,20 @@ +type Int is int16; +using {add as +, unsub as -} for Int global; + +IAdder constant ADDER = IAdder(address(0)); + +function add(Int x, Int y) pure returns (Int) { + return ADDER.mul(x, y); +} + +function unsub(Int x) pure returns (Int) { + return ADDER.inc(x); +} + +interface IAdder { + function mul(Int, Int) external returns (Int); + function inc(Int) external returns (Int); +} +// ---- +// TypeError 8961: (169-184): Function cannot be declared as pure because this expression (potentially) modifies the state. +// TypeError 8961: (243-255): Function cannot be declared as pure because this expression (potentially) modifies the state. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_that_makes_pure_external_call.sol b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_that_makes_pure_external_call.sol new file mode 100644 index 000000000..37a8add56 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_that_makes_pure_external_call.sol @@ -0,0 +1,17 @@ +type Int is int16; +using {add as +, unsub as -} for Int global; + +IAdder constant ADDER = IAdder(address(0)); + +function add(Int x, Int y) pure returns (Int) { + return ADDER.mul(x, y); +} + +function unsub(Int x) pure returns (Int) { + return ADDER.inc(x); +} + +interface IAdder { + function mul(Int, Int) external pure returns (Int); + function inc(Int) external pure returns (Int); +} diff --git a/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_that_makes_view_external_call.sol b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_that_makes_view_external_call.sol new file mode 100644 index 000000000..f45f7a30f --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_that_makes_view_external_call.sol @@ -0,0 +1,20 @@ +type Int is int16; +using {add as +, unsub as -} for Int global; + +IAdder constant ADDER = IAdder(address(0)); + +function add(Int x, Int y) pure returns (Int) { + return ADDER.mul(x, y); +} + +function unsub(Int x) pure returns (Int) { + return ADDER.inc(x); +} + +interface IAdder { + function mul(Int, Int) external view returns (Int); + function inc(Int) external view returns (Int); +} +// ---- +// TypeError 2527: (169-184): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". +// TypeError 2527: (243-255): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". diff --git a/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_with_implicit_conversion.sol b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_with_implicit_conversion.sol new file mode 100644 index 000000000..afe4e46e8 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/calling_operator_with_implicit_conversion.sol @@ -0,0 +1,32 @@ +using {add as +, unsub as -} for U global; + +type U is uint; + +function add(U, U) pure returns (U) {} +function unsub(U) pure returns (U) {} + +contract C { + function fromBool() public { + U u; + + u + true; + true + u; + -true; + } + + function fromUint() public { + U u; + uint32 u32; + + u + u32; + u32 + u; + -u32; + } +} +// ---- +// TypeError 5653: (207-215): The type of the second operand of this user-defined binary operator + does not match the type of the first operand, which is U. +// TypeError 2271: (225-233): Built-in binary operator + cannot be applied to types bool and U. +// TypeError 4907: (243-248): Built-in unary operator - cannot be applied to type bool. +// TypeError 5653: (332-339): The type of the second operand of this user-defined binary operator + does not match the type of the first operand, which is U. +// TypeError 2271: (349-356): Built-in binary operator + cannot be applied to types uint32 and U. +// TypeError 4907: (366-370): Built-in unary operator - cannot be applied to type uint32. Unary negation is only allowed for signed integers. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_builtin_types.sol b/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_builtin_types.sol new file mode 100644 index 000000000..8bdcd510a --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_builtin_types.sol @@ -0,0 +1,18 @@ +using {f as +} for uint global; +using {f as +} for uint[2] global; +using {f as +} for mapping(uint => uint) global; +using {f as +} for function (uint) pure returns (uint) global; +using {f as +} for string global; + +function f(uint, uint) pure returns (uint) {} +// ---- +// TypeError 8841: (0-31): Can only use "global" with user-defined types. +// TypeError 5332: (7-8): Operators can only be implemented for user-defined value types. +// TypeError 8841: (32-66): Can only use "global" with user-defined types. +// TypeError 5332: (39-40): Operators can only be implemented for user-defined value types. +// TypeError 8841: (67-115): Can only use "global" with user-defined types. +// TypeError 5332: (74-75): Operators can only be implemented for user-defined value types. +// TypeError 8841: (116-178): Can only use "global" with user-defined types. +// TypeError 5332: (123-124): Operators can only be implemented for user-defined value types. +// TypeError 8841: (179-212): Can only use "global" with user-defined types. +// TypeError 5332: (186-187): Operators can only be implemented for user-defined value types. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_contract.sol b/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_contract.sol new file mode 100644 index 000000000..55418f579 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_contract.sol @@ -0,0 +1,13 @@ +using {fc as +} for C global; +using {fa as +} for A global; + +function fc(C, C) pure returns (C) {} +function fa(A, A) pure returns (A) {} + +contract C {} +abstract contract A {} +// ---- +// TypeError 8841: (0-29): Can only use "global" with user-defined types. +// TypeError 5332: (7-9): Operators can only be implemented for user-defined value types. +// TypeError 8841: (30-59): Can only use "global" with user-defined types. +// TypeError 5332: (37-39): Operators can only be implemented for user-defined value types. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_enum.sol b/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_enum.sol new file mode 100644 index 000000000..dce100994 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_enum.sol @@ -0,0 +1,10 @@ +using {add as +} for E global; + +enum E { + E1, + E2 +} + +function add(E, E) pure returns (E) {} +// ---- +// TypeError 5332: (7-10): Operators can only be implemented for user-defined value types. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_error.sol b/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_error.sol new file mode 100644 index 000000000..0dcab966d --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_error.sol @@ -0,0 +1,10 @@ +using {add as +} for E global; + +error E(); + +function add(E, E) pure returns (E) { + return E.E1; +} + +// ---- +// TypeError 5172: (21-22): Name has to refer to a user-defined type. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_event.sol b/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_event.sol new file mode 100644 index 000000000..5dd5fbce9 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_event.sol @@ -0,0 +1,10 @@ +using {add as +} for C.Event global; + +contract C { + event Event(); +} + +function add(C.Event, C.Event) pure returns (C.Event) {} + +// ---- +// TypeError 5172: (21-28): Name has to refer to a user-defined type. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_interface.sol b/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_interface.sol new file mode 100644 index 000000000..9db33819c --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_interface.sol @@ -0,0 +1,8 @@ +using {f as +} for I global; + +function f(I, I) pure returns (I) {} + +interface I {} +// ---- +// TypeError 8841: (0-28): Can only use "global" with user-defined types. +// TypeError 5332: (7-8): Operators can only be implemented for user-defined value types. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_library.sol b/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_library.sol new file mode 100644 index 000000000..210cb3009 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_library.sol @@ -0,0 +1,6 @@ +using {f as +} for L global; + +function f() pure {} +library L {} +// ---- +// TypeError 1130: (19-20): Invalid use of a library name. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_struct.sol b/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_struct.sol new file mode 100644 index 000000000..0244f731c --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_struct.sol @@ -0,0 +1,9 @@ +using {add as +} for S global; + +struct S { + uint x; +} + +function add(S memory, S memory) pure returns (S memory) {} +// ---- +// TypeError 5332: (7-10): Operators can only be implemented for user-defined value types. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_wildcard_type_at_contract_level.sol b/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_wildcard_type_at_contract_level.sol new file mode 100644 index 000000000..1e3c9e775 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_wildcard_type_at_contract_level.sol @@ -0,0 +1,16 @@ +type Int is int; + +function add(Int, Int) pure returns (Int) {} + +contract C { + using {add as +} for *; +} + +contract D { + using {add as +} for * global; +} +// ---- +// SyntaxError 3349: (81-104): The type has to be specified explicitly when attaching specific functions. +// SyntaxError 3349: (125-155): The type has to be specified explicitly when attaching specific functions. +// SyntaxError 2854: (125-155): Can only globally attach functions to specific types. +// SyntaxError 3367: (125-155): "global" can only be used at file level. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_wildcard_type_at_file_level.sol b/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_wildcard_type_at_file_level.sol new file mode 100644 index 000000000..25325f756 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/defining_operator_for_wildcard_type_at_file_level.sol @@ -0,0 +1,6 @@ +using {add as +} for * global; + +function add(int, int) returns (int) {} +// ---- +// SyntaxError 8118: (0-30): The type has to be specified explicitly at file level (cannot use '*'). +// SyntaxError 2854: (0-30): Can only globally attach functions to specific types. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_attached_free_function.sol b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_attached_free_function.sol new file mode 100644 index 000000000..a04e81c31 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_attached_free_function.sol @@ -0,0 +1,9 @@ +type Int is uint; +using {f} for Int; + +Int constant v; +using {v.f as +} for Int global; + +function f(Int) pure returns (Int) {} +// ---- +// DeclarationError 9589: (61-64): Identifier is not a function name or not unique. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_builtin_abi_encode.sol b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_builtin_abi_encode.sol new file mode 100644 index 000000000..00889bc09 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_builtin_abi_encode.sol @@ -0,0 +1,8 @@ +type Int is int16; + +using {abi.encode as +} for Int global; + +function f(Int, Int) pure returns (Int) {} + +// ---- +// DeclarationError 9589: (27-37): Identifier is not a function name or not unique. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_builtin_keccak256.sol b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_builtin_keccak256.sol new file mode 100644 index 000000000..ee088624c --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_builtin_keccak256.sol @@ -0,0 +1,5 @@ +type Int is int16; + +using {keccak256 as +} for Int global; +// ---- +// TypeError 8187: (27-36): Expected function name. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_builtin_revert.sol b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_builtin_revert.sol new file mode 100644 index 000000000..daf4cab6b --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_builtin_revert.sol @@ -0,0 +1,5 @@ +type Int is int16; + +using {revert as +} for Int global; +// ---- +// DeclarationError 9589: (27-33): Identifier is not a function name or not unique. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_contract_function_at_contract_level.sol b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_contract_function_at_contract_level.sol new file mode 100644 index 000000000..309ea9558 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_contract_function_at_contract_level.sol @@ -0,0 +1,9 @@ +type Int is int; + +contract C { + using {add as +} for Int; + + function add(Int, Int) public pure returns (Int) {} +} +// ---- +// TypeError 4167: (42-45): Only file-level functions and library functions can be attached to a type in a "using" statement diff --git a/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_contract_function_at_file_level.sol b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_contract_function_at_file_level.sol new file mode 100644 index 000000000..969dd8094 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_contract_function_at_file_level.sol @@ -0,0 +1,11 @@ +type Int is int; + +using {C.add as +} for Int global; + +contract C { + function add(Int, Int) public pure returns (Int) { + return 0; + } +} +// ---- +// TypeError 4167: (25-30): Only file-level functions and library functions can be attached to a type in a "using" statement diff --git a/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_error.sol b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_error.sol new file mode 100644 index 000000000..1bec8b44d --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_error.sol @@ -0,0 +1,7 @@ +type Int is int16; + +using {IntError as +} for Int global; + +error IntError(Int a, Int b); +// ---- +// TypeError 8187: (27-35): Expected function name. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_event.sol b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_event.sol new file mode 100644 index 000000000..3a7b6423a --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_event.sol @@ -0,0 +1,9 @@ +type Int is int16; + +using {C.IntEvent as +} for Int global; + +contract C { + event IntEvent(Int a, Int b); +} +// ---- +// TypeError 8187: (27-37): Expected function name. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_function_pointer.sol b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_function_pointer.sol new file mode 100644 index 000000000..834fe2d7d --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_function_pointer.sol @@ -0,0 +1,8 @@ +type Int is int8; + +contract C { + function(Int, Int) external pure returns (Int) ptr; + using {ptr as +} for Int; +} +// ---- +// TypeError 8187: (99-102): Expected function name. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_function_shadowing_builtin_keccak256.sol b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_function_shadowing_builtin_keccak256.sol new file mode 100644 index 000000000..52f4e362d --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_function_shadowing_builtin_keccak256.sol @@ -0,0 +1,9 @@ +type Int is int16; + +using {keccak256 as +} for Int global; + +function keccak256(Int, Int) pure returns (Int) { + return Int.wrap(0); +} +// ---- +// Warning 2319: (60-135): This declaration shadows a builtin symbol. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_library.sol b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_library.sol new file mode 100644 index 000000000..a6460da13 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_library.sol @@ -0,0 +1,7 @@ +type Int is int16; + +using {L as +} for Int global; + +library L {} +// ---- +// TypeError 8187: (27-28): Expected function name. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_library_function_at_contract_level.sol b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_library_function_at_contract_level.sol new file mode 100644 index 000000000..889fc0eb2 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_library_function_at_contract_level.sol @@ -0,0 +1,113 @@ +==== Source: external.sol ==== +type Int is int128; + +library L { + function binaryOperator(Int, Int) external pure returns (Int) {} + function unaryOperator(Int) external pure returns (Int) {} + + using {L.binaryOperator as *} for Int; + using {L.unaryOperator as ~} for Int; +} + +contract C { + using {L.binaryOperator as *} for Int; + using {L.unaryOperator as ~} for Int; +} + +library X { + using {L.binaryOperator as *} for Int; + using {L.unaryOperator as ~} for Int; +} + +==== Source: internal.sol ==== +type Int is int128; + +library L { + function binaryOperator(Int, Int) internal pure returns (Int) {} + function unaryOperator(Int) internal pure returns (Int) {} + + using {L.binaryOperator as *} for Int; + using {L.unaryOperator as ~} for Int; +} + +contract C { + using {L.binaryOperator as *} for Int; + using {L.unaryOperator as ~} for Int; +} + +library X { + using {L.binaryOperator as *} for Int; + using {L.unaryOperator as ~} for Int; +} + +==== Source: private.sol ==== +type Int is int128; + +library L { + function binaryOperator(Int, Int) private pure returns (Int) {} + function unaryOperator(Int) private pure returns (Int) {} + + using {L.binaryOperator as *} for Int; + using {L.unaryOperator as ~} for Int; +} +==== Source: public.sol ==== +type Int is int128; + +library L { + function binaryOperator(Int, Int) public pure returns (Int) {} + function unaryOperator(Int) public pure returns (Int) {} + + using {L.binaryOperator as *} for Int; + using {L.unaryOperator as ~} for Int; +} + +contract C { + using {L.binaryOperator as *} for Int; + using {L.unaryOperator as ~} for Int; +} + +library X { + using {L.binaryOperator as *} for Int; + using {L.unaryOperator as ~} for Int; +} +// ---- +// TypeError 3320: (external.sol:177-193): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (external.sol:177-193): Only pure free functions can be used to define operators. +// TypeError 3320: (external.sol:220-235): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (external.sol:220-235): Only pure free functions can be used to define operators. +// TypeError 3320: (external.sol:278-294): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (external.sol:278-294): Only pure free functions can be used to define operators. +// TypeError 3320: (external.sol:321-336): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (external.sol:321-336): Only pure free functions can be used to define operators. +// TypeError 3320: (external.sol:378-394): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (external.sol:378-394): Only pure free functions can be used to define operators. +// TypeError 3320: (external.sol:421-436): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (external.sol:421-436): Only pure free functions can be used to define operators. +// TypeError 3320: (internal.sol:177-193): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (internal.sol:177-193): Only pure free functions can be used to define operators. +// TypeError 3320: (internal.sol:220-235): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (internal.sol:220-235): Only pure free functions can be used to define operators. +// TypeError 3320: (internal.sol:278-294): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (internal.sol:278-294): Only pure free functions can be used to define operators. +// TypeError 3320: (internal.sol:321-336): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (internal.sol:321-336): Only pure free functions can be used to define operators. +// TypeError 3320: (internal.sol:378-394): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (internal.sol:378-394): Only pure free functions can be used to define operators. +// TypeError 3320: (internal.sol:421-436): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (internal.sol:421-436): Only pure free functions can be used to define operators. +// TypeError 3320: (private.sol:175-191): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (private.sol:175-191): Only pure free functions can be used to define operators. +// TypeError 3320: (private.sol:218-233): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (private.sol:218-233): Only pure free functions can be used to define operators. +// TypeError 3320: (public.sol:173-189): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (public.sol:173-189): Only pure free functions can be used to define operators. +// TypeError 3320: (public.sol:216-231): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (public.sol:216-231): Only pure free functions can be used to define operators. +// TypeError 3320: (public.sol:274-290): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (public.sol:274-290): Only pure free functions can be used to define operators. +// TypeError 3320: (public.sol:317-332): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (public.sol:317-332): Only pure free functions can be used to define operators. +// TypeError 3320: (public.sol:374-390): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (public.sol:374-390): Only pure free functions can be used to define operators. +// TypeError 3320: (public.sol:417-432): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (public.sol:417-432): Only pure free functions can be used to define operators. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_library_function_at_file_level.sol b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_library_function_at_file_level.sol new file mode 100644 index 000000000..1e3c13aec --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_library_function_at_file_level.sol @@ -0,0 +1,39 @@ +==== Source: external.sol ==== +type Int is int128; + +library L { + function binaryOperator(Int, Int) external pure returns (Int) {} + function unaryOperator(Int) external pure returns (Int) {} +} + +using {L.binaryOperator as +} for Int global; +using {L.unaryOperator as -} for Int global; + +==== Source: internal.sol ==== +type Int is int128; + +library L { + function binaryOperator(Int, Int) internal pure returns (Int) {} + function unaryOperator(Int) internal pure returns (Int) {} +} + +using {L.binaryOperator as +} for Int global; +using {L.unaryOperator as -} for Int global; + +==== Source: public.sol ==== +type Int is int128; + +library L { + function binaryOperator(Int, Int) public pure returns (Int) {} + function unaryOperator(Int) public pure returns (Int) {} +} + +using {L.binaryOperator as +} for Int global; +using {L.unaryOperator as -} for Int global; +// ---- +// TypeError 7775: (external.sol:175-191): Only pure free functions can be used to define operators. +// TypeError 7775: (external.sol:221-236): Only pure free functions can be used to define operators. +// TypeError 7775: (internal.sol:175-191): Only pure free functions can be used to define operators. +// TypeError 7775: (internal.sol:221-236): Only pure free functions can be used to define operators. +// TypeError 7775: (public.sol:171-187): Only pure free functions can be used to define operators. +// TypeError 7775: (public.sol:217-232): Only pure free functions can be used to define operators. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_library_function_private_outside_of_library.sol b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_library_function_private_outside_of_library.sol new file mode 100644 index 000000000..077330baf --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_library_function_private_outside_of_library.sol @@ -0,0 +1,36 @@ +type Int is int128; + +library L { + function binaryOperator(Int, Int) private pure returns (Int) {} + function unaryOperator(Int) private pure returns (Int) {} +} + +using {L.binaryOperator as +} for Int global; +using {L.unaryOperator as -} for Int global; + +contract C { + using {L.binaryOperator as *} for Int; + using {L.unaryOperator as ~} for Int; +} + +library X { + using {L.binaryOperator as *} for Int; + using {L.unaryOperator as ~} for Int; +} +// ---- +// TypeError 6772: (173-189): Function "L.binaryOperator" is private and therefore cannot be attached to a type outside of the library where it is defined. +// TypeError 7775: (173-189): Only pure free functions can be used to define operators. +// TypeError 6772: (219-234): Function "L.unaryOperator" is private and therefore cannot be attached to a type outside of the library where it is defined. +// TypeError 7775: (219-234): Only pure free functions can be used to define operators. +// TypeError 6772: (282-298): Function "L.binaryOperator" is private and therefore cannot be attached to a type outside of the library where it is defined. +// TypeError 3320: (282-298): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (282-298): Only pure free functions can be used to define operators. +// TypeError 6772: (325-340): Function "L.unaryOperator" is private and therefore cannot be attached to a type outside of the library where it is defined. +// TypeError 3320: (325-340): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (325-340): Only pure free functions can be used to define operators. +// TypeError 6772: (382-398): Function "L.binaryOperator" is private and therefore cannot be attached to a type outside of the library where it is defined. +// TypeError 3320: (382-398): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (382-398): Only pure free functions can be used to define operators. +// TypeError 6772: (425-440): Function "L.unaryOperator" is private and therefore cannot be attached to a type outside of the library where it is defined. +// TypeError 3320: (425-440): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (425-440): Only pure free functions can be used to define operators. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_non_pure_function.sol b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_non_pure_function.sol new file mode 100644 index 000000000..e009fa03d --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_non_pure_function.sol @@ -0,0 +1,12 @@ +using {add as +, sub as -, mul as *} for A global; + +function add(A, A) view returns (A) {} +function sub(A, A) returns (A) {} +function mul(A, A) payable returns (A) {} + +type A is address payable; +// ---- +// TypeError 7775: (7-10): Only pure free functions can be used to define operators. +// TypeError 7775: (17-20): Only pure free functions can be used to define operators. +// TypeError 7775: (27-30): Only pure free functions can be used to define operators. +// TypeError 9559: (125-166): Free functions cannot be payable. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_non_pure_function_on_built_in_type_non_global.sol b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_non_pure_function_on_built_in_type_non_global.sol new file mode 100644 index 000000000..15581a1c1 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_non_pure_function_on_built_in_type_non_global.sol @@ -0,0 +1,8 @@ +// This should point out all 3 errors, rather than give up after the first one. +using {add as +} for address; + +function add(address, address) view returns (address) {} +// ---- +// TypeError 3320: (87-90): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (87-90): Only pure free functions can be used to define operators. +// TypeError 5332: (87-90): Operators can only be implemented for user-defined value types. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_overloaded_function.sol b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_overloaded_function.sol new file mode 100644 index 000000000..ccddd3fa7 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_overloaded_function.sol @@ -0,0 +1,10 @@ +using {add as +} for A global; +using {add as +} for AP global; + +function add(A, A) pure returns (A) {} +function add(AP, AP) pure returns (AP) {} + +type A is address; +type AP is address payable; +// ---- +// DeclarationError 9589: (7-10): Identifier is not a function name or not unique. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_privately_overloaded_function.sol b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_privately_overloaded_function.sol new file mode 100644 index 000000000..d41db77db --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_privately_overloaded_function.sol @@ -0,0 +1,12 @@ +using {L.add as +} for A global; +using {L.add as +} for AP global; + +library L { + function add(A, A) private pure returns (A) {} + function add(AP, AP) internal pure returns (AP) {} +} + +type A is address; +type AP is address payable; +// ---- +// DeclarationError 9589: (7-12): Identifier is not a function name or not unique. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_unqualified_library_function_at_file_level.sol b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_unqualified_library_function_at_file_level.sol new file mode 100644 index 000000000..80793f68d --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_unqualified_library_function_at_file_level.sol @@ -0,0 +1,9 @@ +type B32 is bytes32; + +library L { + function publicOperator(B32, B32) public pure returns (B32) {} +} + +using {publicOperator as +} for B32 global; +// ---- +// DeclarationError 9589: (111-125): Identifier is not a function name or not unique. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_unqualified_library_function_in_library.sol b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_unqualified_library_function_in_library.sol new file mode 100644 index 000000000..565aa6dc9 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/implementing_operator_with_unqualified_library_function_in_library.sol @@ -0,0 +1,22 @@ +type B32 is bytes32; + +library L { + using {externalOperator as +} for B32; + using {publicOperator as -} for B32; + using {internalOperator as *} for B32; + using {privateOperator as /} for B32; + + function externalOperator(B32, B32) external pure returns (B32) {} + function publicOperator(B32, B32) public pure returns (B32) {} + function internalOperator(B32, B32) internal pure returns (B32) {} + function privateOperator(B32, B32) private pure returns (B32) {} +} +// ---- +// TypeError 3320: (45-61): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (45-61): Only pure free functions can be used to define operators. +// TypeError 3320: (88-102): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (88-102): Only pure free functions can be used to define operators. +// TypeError 3320: (129-145): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (129-145): Only pure free functions can be used to define operators. +// TypeError 3320: (172-187): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (172-187): Only pure free functions can be used to define operators. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_global_and_non_global_different_files.sol b/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_global_and_non_global_different_files.sol new file mode 100644 index 000000000..94769ee17 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_global_and_non_global_different_files.sol @@ -0,0 +1,20 @@ +==== Source: Int.sol ==== +type Int is int; + +using {add as +} for Int global; + +function add(Int, Int) pure returns (Int) {} + +==== Source: test.sol ==== +import "Int.sol"; + +using {anotherAdd as +} for Int; + +function anotherAdd(Int, Int) pure returns (Int) {} + +function test() pure returns (Int) { + return Int.wrap(0) + Int.wrap(0); +} +// ---- +// TypeError 3320: (test.sol:26-36): Operators can only be defined in a global 'using for' directive. +// TypeError 4705: (test.sol:26-36): User-defined binary operator + has more than one definition matching the operand type visible in the current scope. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_global_non_global.sol b/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_global_non_global.sol new file mode 100644 index 000000000..0b30e06ba --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_global_non_global.sol @@ -0,0 +1,26 @@ +type Int is int; + +using {add as +} for Int global; +using {add2 as +} for Int; +using {unsub as -} for Int global; +using {unsub2 as -} for Int; + +function add(Int, Int) pure returns (Int) {} +function add2(Int, Int) pure returns (Int) {} +function unsub(Int) pure returns (Int) {} +function unsub2(Int) pure returns (Int) {} + +function testBinary() pure returns (Int) { + return Int.wrap(1) + Int.wrap(2); +} + +function testUnary() pure returns (Int) { + return -Int.wrap(2); +} +// ---- +// TypeError 4705: (25-28): User-defined binary operator + has more than one definition matching the operand type visible in the current scope. +// TypeError 3320: (58-62): Operators can only be defined in a global 'using for' directive. +// TypeError 4705: (58-62): User-defined binary operator + has more than one definition matching the operand type visible in the current scope. +// TypeError 4705: (85-90): User-defined unary operator - has more than one definition matching the operand type visible in the current scope. +// TypeError 3320: (120-126): Operators can only be defined in a global 'using for' directive. +// TypeError 4705: (120-126): User-defined unary operator - has more than one definition matching the operand type visible in the current scope. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_non_global_and_global_different_files.sol b/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_non_global_and_global_different_files.sol new file mode 100644 index 000000000..2d6e47a8f --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_non_global_and_global_different_files.sol @@ -0,0 +1,20 @@ +==== Source: Int.sol ==== +type Int is int; + +using {add as +} for Int; + +function add(Int, Int) pure returns (Int) {} + +==== Source: test.sol ==== +import "Int.sol"; + +using {anotherAdd as +} for Int global; + +function anotherAdd(Int, Int) pure returns (Int) {} + +function test() pure returns (Int) { + return Int.wrap(0) + Int.wrap(0); +} +// ---- +// TypeError 3320: (Int.sol:25-28): Operators can only be defined in a global 'using for' directive. +// TypeError 4117: (test.sol:19-58): Can only use "global" with types defined in the same source unit at file level. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_same_directive.sol b/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_same_directive.sol new file mode 100644 index 000000000..4972deef1 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_same_directive.sol @@ -0,0 +1,13 @@ +type Int is uint128; + +using {add as +, sub as +} for Int global; + +function add(Int, Int) pure returns (Int) {} +function sub(Int, Int) pure returns (Int) {} + +function test() { + Int.wrap(0) + Int.wrap(1); +} +// ---- +// TypeError 4705: (29-32): User-defined binary operator + has more than one definition matching the operand type visible in the current scope. +// TypeError 4705: (39-42): User-defined binary operator + has more than one definition matching the operand type visible in the current scope. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_same_directive_operator_not_used.sol b/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_same_directive_operator_not_used.sol new file mode 100644 index 000000000..ec4274c7b --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_different_functions_same_directive_operator_not_used.sol @@ -0,0 +1,15 @@ +type Int is uint128; + +// Still an error, even if the operator is not actually used +using {add1 as +, add2 as +} for Int global; +using {unsub1 as -, unsub2 as -} for Int global; + +function add1(Int, Int) pure returns (Int) {} +function add2(Int, Int) pure returns (Int) {} +function unsub1(Int) pure returns (Int) {} +function unsub2(Int) pure returns (Int) {} +// ---- +// TypeError 4705: (90-94): User-defined binary operator + has more than one definition matching the operand type visible in the current scope. +// TypeError 4705: (101-105): User-defined binary operator + has more than one definition matching the operand type visible in the current scope. +// TypeError 4705: (135-141): User-defined unary operator - has more than one definition matching the operand type visible in the current scope. +// TypeError 4705: (148-154): User-defined unary operator - has more than one definition matching the operand type visible in the current scope. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_on_file_and_contract_level.sol b/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_on_file_and_contract_level.sol new file mode 100644 index 000000000..bb517ca7b --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_on_file_and_contract_level.sol @@ -0,0 +1,23 @@ +type Int is int; + +using {add as +} for Int global; + +function add(Int, Int) pure returns (Int) {} +function another_add(Int, Int) pure returns (Int) {} + +contract B { + using {another_add as +} for Int; + + function f() public { + Int.wrap(0) + Int.wrap(0); + } +} + +contract C is B { + function g() public { + Int.wrap(0) + Int.wrap(0); + } +} +// ---- +// TypeError 3320: (175-186): Operators can only be defined in a global 'using for' directive. +// TypeError 4705: (175-186): User-defined binary operator + has more than one definition matching the operand type visible in the current scope. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_same_function_different_levels_free_function.sol b/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_same_function_different_levels_free_function.sol new file mode 100644 index 000000000..4cd956ba3 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_same_function_different_levels_free_function.sol @@ -0,0 +1,19 @@ +type Int is int; + +function add(Int, Int) pure returns (Int) {} +function unsub(Int) pure returns (Int) {} + +using {add as +, unsub as -} for Int global; + +contract C { + using {add as +, unsub as -} for Int; +} + +library X { + using {add as +, unsub as -} for Int; +} +// ---- +// TypeError 3320: (176-179): Operators can only be defined in a global 'using for' directive. +// TypeError 3320: (186-191): Operators can only be defined in a global 'using for' directive. +// TypeError 3320: (233-236): Operators can only be defined in a global 'using for' directive. +// TypeError 3320: (243-248): Operators can only be defined in a global 'using for' directive. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_same_function_different_levels_library_function.sol b/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_same_function_different_levels_library_function.sol new file mode 100644 index 000000000..9fd4c7331 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_same_function_different_levels_library_function.sol @@ -0,0 +1,38 @@ +type Int is int; + +library L { + using {add as +, unsub as -} for Int; + using {L.add as +, L.unsub as -} for Int; + + function add(Int, Int) internal pure returns (Int) {} + function unsub(Int) internal pure returns (Int) {} +} + +using {L.add as +, L.unsub as -} for Int global; + +contract C { + using {L.add as +, L.unsub as -} for Int; +} + +library X { + using {L.add as +, L.unsub as -} for Int; +} +// ---- +// TypeError 3320: (41-44): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (41-44): Only pure free functions can be used to define operators. +// TypeError 3320: (51-56): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (51-56): Only pure free functions can be used to define operators. +// TypeError 3320: (83-88): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (83-88): Only pure free functions can be used to define operators. +// TypeError 3320: (95-102): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (95-102): Only pure free functions can be used to define operators. +// TypeError 7775: (242-247): Only pure free functions can be used to define operators. +// TypeError 7775: (254-261): Only pure free functions can be used to define operators. +// TypeError 3320: (309-314): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (309-314): Only pure free functions can be used to define operators. +// TypeError 3320: (321-328): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (321-328): Only pure free functions can be used to define operators. +// TypeError 3320: (370-375): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (370-375): Only pure free functions can be used to define operators. +// TypeError 3320: (382-389): Operators can only be defined in a global 'using for' directive. +// TypeError 7775: (382-389): Only pure free functions can be used to define operators. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_same_function_same_directive.sol b/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_same_function_same_directive.sol new file mode 100644 index 000000000..9bb4d6236 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_same_function_same_directive.sol @@ -0,0 +1,9 @@ +type Int is int32; + +using {add as +, add as +} for Int global; + +function add(Int, Int) pure returns(Int) {} + +function f(int32 a, int32 b) pure { + Int.wrap(a) + Int.wrap(b); +} diff --git a/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_same_function_separate_directives.sol b/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_same_function_separate_directives.sol new file mode 100644 index 000000000..d2a648e78 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/multiple_operator_definitions_same_function_separate_directives.sol @@ -0,0 +1,10 @@ +type Int is int32; + +using {add as +} for Int global; +using {add as +} for Int global; + +function add(Int, Int) pure returns(Int) {} + +function f(int32 a, int32 b) pure { + Int.wrap(a) + Int.wrap(b); +} diff --git a/test/libsolidity/syntaxTests/operators/userDefined/operator_overloading.sol b/test/libsolidity/syntaxTests/operators/userDefined/operator_overloading.sol new file mode 100644 index 000000000..e7b0a7642 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/operator_overloading.sol @@ -0,0 +1,14 @@ +type Int is uint128; + +using {add as +, add128 as +} for Int global; + +function add(Int, Int) pure returns (Int) {} +function add128(Int, int128) pure returns (Int) {} + +function test() { + Int.wrap(0) + Int.wrap(1); +} +// ---- +// TypeError 4705: (29-32): User-defined binary operator + has more than one definition matching the operand type visible in the current scope. +// TypeError 1884: (129-142): Wrong parameters in operator definition. The function "add128" needs to have two parameters of type Int and the same data location to be used for the operator +. +// TypeError 4705: (39-45): User-defined binary operator + has more than one definition matching the operand type visible in the current scope. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_function_name_missing.sol b/test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_function_name_missing.sol new file mode 100644 index 000000000..5911fc653 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_function_name_missing.sol @@ -0,0 +1,3 @@ +using {as -} for uint global; +// ---- +// ParserError 2314: (7-9): Expected identifier but got 'as' diff --git a/test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_no_brace.sol b/test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_no_brace.sol new file mode 100644 index 000000000..1a1be262a --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_no_brace.sol @@ -0,0 +1,3 @@ +using f as - for uint global; +// ---- +// ParserError 2314: (8-10): Expected 'for' but got 'as' diff --git a/test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_non_user_definable.sol b/test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_non_user_definable.sol new file mode 100644 index 000000000..ed4fb13a4 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_non_user_definable.sol @@ -0,0 +1,45 @@ +using { + f as new, + f as delete, + f as **, + f as <<, + f as >>, + f as &&, + f as ||, + f as !, + f as =, + f as |=, + f as ^=, + f as &=, + f as <<=, + f as >>=, + f as +=, + f as -=, + f as *=, + f as /=, + f as %=, + f as ++, + f as -- +} for int256 global; +// ---- +// ParserError 4403: (17-20): Not a user-definable operator: new. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (31-37): Not a user-definable operator: delete. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (48-50): Not a user-definable operator: **. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (61-63): Not a user-definable operator: <<. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (74-76): Not a user-definable operator: >>. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (87-89): Not a user-definable operator: &&. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (100-102): Not a user-definable operator: ||. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (113-114): Not a user-definable operator: !. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (125-126): Not a user-definable operator: =. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (137-139): Not a user-definable operator: |=. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (150-152): Not a user-definable operator: ^=. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (163-165): Not a user-definable operator: &=. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (176-179): Not a user-definable operator: <<=. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (190-193): Not a user-definable operator: >>=. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (204-206): Not a user-definable operator: +=. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (217-219): Not a user-definable operator: -=. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (230-232): Not a user-definable operator: *=. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (243-245): Not a user-definable operator: /=. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (256-258): Not a user-definable operator: %=. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (269-271): Not a user-definable operator: ++. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (282-284): Not a user-definable operator: --. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= diff --git a/test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_not_an_operator.sol b/test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_not_an_operator.sol new file mode 100644 index 000000000..7fa8c5eeb --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_not_an_operator.sol @@ -0,0 +1,14 @@ +using { + f as x, + f as operator, + f as as, + f as 123, + f as () +} for int256 global; +// ---- +// ParserError 4403: (17-18): Not a user-definable operator: x. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (29-37): Not a user-definable operator: operator. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (48-50): Not a user-definable operator: as. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (61-64): Not a user-definable operator: 123. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 4403: (75-76): Not a user-definable operator: (. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 2314: (76-77): Expected '}' but got ')' diff --git a/test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_operator_name_missing.sol b/test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_operator_name_missing.sol new file mode 100644 index 000000000..a6970a9b8 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_operator_name_missing.sol @@ -0,0 +1,4 @@ +using {f as} for uint global; +// ---- +// ParserError 4403: (11-12): Not a user-definable operator: }. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= +// ParserError 2314: (13-16): Expected '}' but got 'for' diff --git a/test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_operator_named_as.sol b/test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_operator_named_as.sol new file mode 100644 index 000000000..526693189 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/operator_parsing_operator_named_as.sol @@ -0,0 +1,3 @@ +using {f as as} for uint global; +// ---- +// ParserError 4403: (12-14): Not a user-definable operator: as. Only the following operators can be user-defined: |, &, ^, ~, +, -, *, /, %, ==, !=, <, >, <=, >= diff --git a/test/libsolidity/syntaxTests/operators/userDefined/operator_returning_wrong_types.sol b/test/libsolidity/syntaxTests/operators/userDefined/operator_returning_wrong_types.sol new file mode 100644 index 000000000..676f2c475 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/operator_returning_wrong_types.sol @@ -0,0 +1,33 @@ +type Int is int256; + +using { + add as +, + div as /, + unsub as -, + bitnot as ~, + gt as >, + lt as < +} for Int global; + +function add(Int x, Int y) pure returns (int256) {} +function div(Int x, Int y) pure {} +function unsub(Int) pure returns (Int, Int) {} +function bitnot(Int) pure returns (int256) {} +function gt(Int, Int) pure returns (Int) {} +function lt(Int, Int) pure returns (bool, Int) {} + +function f() pure { + Int.wrap(0) + Int.wrap(1); + Int.wrap(0) / Int.wrap(0); + -Int.wrap(0); + ~Int.wrap(0); + Int.wrap(0) < Int.wrap(0); + Int.wrap(0) > Int.wrap(0); +} +// ---- +// TypeError 7743: (174-182): Wrong return parameters in operator definition. The function "add" needs to return exactly one value of type Int to be used for the operator +. +// TypeError 7743: (218-218): Wrong return parameters in operator definition. The function "div" needs to return exactly one value of type Int to be used for the operator /. +// TypeError 7743: (254-264): Wrong return parameters in operator definition. The function "unsub" needs to return exactly one value of type Int to be used for the operator -. +// TypeError 7743: (302-310): Wrong return parameters in operator definition. The function "bitnot" needs to return exactly one value of type Int to be used for the operator ~. +// TypeError 7743: (349-354): Wrong return parameters in operator definition. The function "gt" needs to return exactly one value of type bool to be used for the operator >. +// TypeError 7743: (393-404): Wrong return parameters in operator definition. The function "lt" needs to return exactly one value of type bool to be used for the operator <. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/operator_taking_and_returning_types_not_matching_using_for.sol b/test/libsolidity/syntaxTests/operators/userDefined/operator_taking_and_returning_types_not_matching_using_for.sol new file mode 100644 index 000000000..1d034c8ec --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/operator_taking_and_returning_types_not_matching_using_for.sol @@ -0,0 +1,26 @@ +type Int is int256; + +using { + add as +, + sub as -, + div as / +} for Int global; + +function add(Int) pure returns (Int) {} +function sub(Int, Int, Int) pure returns (Int) {} +function div(int256, int256) pure returns (Int) {} + +function f() pure { + Int.wrap(0) + Int.wrap(1); + Int.wrap(0) - Int.wrap(0); + Int.wrap(0) / Int.wrap(0); +} + +// ---- +// TypeError 1884: (101-106): Wrong parameters in operator definition. The function "add" needs to have two parameters of type Int and the same data location to be used for the operator +. +// TypeError 1884: (141-156): Wrong parameters in operator definition. The function "sub" needs to have one or two parameters of type Int and the same data location to be used for the operator -. +// TypeError 1884: (191-207): Wrong parameters in operator definition. The function "div" needs to have one or two parameters of type Int and the same data location to be used for the operator /. +// TypeError 7743: (221-226): Wrong return parameters in operator definition. The function "div" needs to return a value of the same type and data location as its parameters to be used for the operator /. +// TypeError 2271: (255-280): Built-in binary operator + cannot be applied to types Int and Int. No matching user-defined operator found. +// TypeError 2271: (286-311): Built-in binary operator - cannot be applied to types Int and Int. No matching user-defined operator found. +// TypeError 2271: (317-342): Built-in binary operator / cannot be applied to types Int and Int. No matching user-defined operator found. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/operator_taking_no_parameters_binary.sol b/test/libsolidity/syntaxTests/operators/userDefined/operator_taking_no_parameters_binary.sol new file mode 100644 index 000000000..ffd35cc1d --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/operator_taking_no_parameters_binary.sol @@ -0,0 +1,11 @@ +type Int is int; + +using { + f as + +} for Int global; + +function f() returns (Int) { + return Int.wrap(0); +} +// ---- +// TypeError 4731: (30-31): The function "f" does not have any parameters, and therefore cannot be attached to the type "Int". diff --git a/test/libsolidity/syntaxTests/operators/userDefined/operator_taking_no_parameters_unary.sol b/test/libsolidity/syntaxTests/operators/userDefined/operator_taking_no_parameters_unary.sol new file mode 100644 index 000000000..323b56449 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/operator_taking_no_parameters_unary.sol @@ -0,0 +1,11 @@ +type Int is int; + +using { + f as ~ +} for Int global; + +function f() returns (Int) { + return Int.wrap(0); +} +// ---- +// TypeError 4731: (30-31): The function "f" does not have any parameters, and therefore cannot be attached to the type "Int". diff --git a/test/libsolidity/syntaxTests/operators/userDefined/operator_taking_or_returning_different_types.sol b/test/libsolidity/syntaxTests/operators/userDefined/operator_taking_or_returning_different_types.sol new file mode 100644 index 000000000..c254ad04a --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/operator_taking_or_returning_different_types.sol @@ -0,0 +1,20 @@ +type Int is int128; + +using { + add as +, + sub as -, + mul as *, + div as / +} for Int global; + +function add(Int, int128) pure returns (Int) {} +function sub(int128, Int) pure returns (int128) {} +function mul(int128, int256) pure returns (Int) {} +function div(Int, Int) pure returns (int256) {} +// ---- +// TypeError 1884: (115-128): Wrong parameters in operator definition. The function "add" needs to have two parameters of type Int and the same data location to be used for the operator +. +// TypeError 1884: (163-176): Wrong parameters in operator definition. The function "sub" needs to have one or two parameters of type Int and the same data location to be used for the operator -. +// TypeError 7743: (190-198): Wrong return parameters in operator definition. The function "sub" needs to return exactly one value of type Int to be used for the operator -. +// TypeError 1884: (214-230): Wrong parameters in operator definition. The function "mul" needs to have two parameters of type Int and the same data location to be used for the operator *. +// TypeError 7743: (244-249): Wrong return parameters in operator definition. The function "mul" needs to return a value of the same type and data location as its parameters to be used for the operator *. +// TypeError 7743: (289-297): Wrong return parameters in operator definition. The function "div" needs to return exactly one value of type Int to be used for the operator /. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/operator_taking_two_parameters_unary.sol b/test/libsolidity/syntaxTests/operators/userDefined/operator_taking_two_parameters_unary.sol new file mode 100644 index 000000000..81d454623 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/operator_taking_two_parameters_unary.sol @@ -0,0 +1,14 @@ +type Int is int128; + +using {bitnot as ~} for Int global; + +function bitnot(Int, Int) pure returns (Int) {} + +contract C { + function test() public pure { + ~Int.wrap(1); + } +} +// ---- +// TypeError 1884: (73-83): Wrong parameters in operator definition. The function "bitnot" needs to have exactly one parameter of type Int to be used for the operator ~. +// TypeError 4907: (162-174): Built-in unary operator ~ cannot be applied to type Int. No matching user-defined operator found. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/using_for_attaching_functions_and_defining_operators_same_directive.sol b/test/libsolidity/syntaxTests/operators/userDefined/using_for_attaching_functions_and_defining_operators_same_directive.sol new file mode 100644 index 000000000..612c377e9 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/using_for_attaching_functions_and_defining_operators_same_directive.sol @@ -0,0 +1,10 @@ +type AP is address payable; + +function sub(AP, AP) pure returns (AP) {} +function unsub(AP) pure returns (AP) {} + +function attachedPure(AP, uint, address) pure {} +function attachedView(AP) view {} +function attached(AP, function(AP)) {} + +using {sub as -, attachedPure, attachedView, unsub as -, attached} for AP global; diff --git a/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_for_contract_level_type.sol b/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_for_contract_level_type.sol new file mode 100644 index 000000000..9b7f80054 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_for_contract_level_type.sol @@ -0,0 +1,19 @@ +library L { + type FixedBytes is bytes10; +} + +function add(L.FixedBytes, L.FixedBytes) pure returns (L.FixedBytes) {} +function unsub(L.FixedBytes, L.FixedBytes) pure returns (L.FixedBytes) {} + +library LX { + using {add as +, unsub as -} for L.FixedBytes; +} + +contract CX { + using {add as +, unsub as -} for L.FixedBytes; +} +// ---- +// TypeError 3320: (218-221): Operators can only be defined in a global 'using for' directive. +// TypeError 3320: (228-233): Operators can only be defined in a global 'using for' directive. +// TypeError 3320: (286-289): Operators can only be defined in a global 'using for' directive. +// TypeError 3320: (296-301): Operators can only be defined in a global 'using for' directive. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_global.sol b/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_global.sol new file mode 100644 index 000000000..c99fd0e68 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_global.sol @@ -0,0 +1,13 @@ +type Int is int16; + +function add(Int, Int) pure returns (Int) {} + +contract C { + using {add as +} for Int global; + + function test() pure public { + Int.wrap(0) + Int.wrap(0); + } +} +// ---- +// SyntaxError 3367: (83-115): "global" can only be used at file level. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_global_different_file.sol b/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_global_different_file.sol new file mode 100644 index 000000000..d4f9d9ac1 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_global_different_file.sol @@ -0,0 +1,13 @@ +==== Source: s1.sol ==== +type Int is int; + +==== Source: s2.sol ==== +import "s1.sol"; + +function bitnot(Int) pure returns (Int) {} + +contract C { + using {bitnot as ~} for Int global; +} +// ---- +// SyntaxError 3367: (s2.sol:79-114): "global" can only be used at file level. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_in_base_contract.sol b/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_in_base_contract.sol new file mode 100644 index 000000000..17351599f --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_in_base_contract.sol @@ -0,0 +1,30 @@ +type Int is int128; + +function add(Int, Int) pure returns (Int) {} +function another_add(Int, Int) pure returns (Int) {} + +contract B { + using {add as +} for Int; + + function f() pure public returns (Int) { + return Int.wrap(0) + Int.wrap(0); + } +} + +contract C is B { + using {another_add as +} for Int; + + function g() pure public returns (Int) { + return Int.wrap(0) + Int.wrap(0); + } +} + +contract D is B { + function h() pure public returns (Int) { + return Int.wrap(0) + Int.wrap(0); + } +} +// ---- +// TypeError 3320: (144-147): Operators can only be defined in a global 'using for' directive. +// TypeError 3320: (289-300): Operators can only be defined in a global 'using for' directive. +// TypeError 2271: (491-516): Built-in binary operator + cannot be applied to types Int and Int. No matching user-defined operator found. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_in_interface.sol b/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_in_interface.sol new file mode 100644 index 000000000..46dbee970 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_contract_level_in_interface.sol @@ -0,0 +1,10 @@ +type Int is int; + +function add(Int, Int) pure returns (Int) {} + +interface I { + using {add as +} for Int; +} +// ---- +// SyntaxError 9088: (82-107): The "using for" directive is not allowed inside interfaces. +// TypeError 3320: (89-92): Operators can only be defined in a global 'using for' directive. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_for_contract_level_type.sol b/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_for_contract_level_type.sol new file mode 100644 index 000000000..6efae72fe --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_for_contract_level_type.sol @@ -0,0 +1,27 @@ +library L { + type FixedBytes is bytes1; +} + +contract C { + type FixedBytes is bytes2; +} + +interface I { + type FixedBytes is bytes3; +} + +function addL(L.FixedBytes, L.FixedBytes) pure returns (L.FixedBytes) {} +function addC(C.FixedBytes, C.FixedBytes) pure returns (C.FixedBytes) {} +function addI(I.FixedBytes, I.FixedBytes) pure returns (I.FixedBytes) {} + +function unsubL(L.FixedBytes) pure returns (L.FixedBytes) {} +function unsubC(C.FixedBytes) pure returns (C.FixedBytes) {} +function unsubI(I.FixedBytes) pure returns (I.FixedBytes) {} + +using {addL as +, unsubL as -} for L.FixedBytes global; +using {addC as +, unsubC as -} for C.FixedBytes global; +using {addI as +, unsubI as -} for I.FixedBytes global; +// ---- +// TypeError 4117: (545-600): Can only use "global" with types defined in the same source unit at file level. +// TypeError 4117: (601-656): Can only use "global" with types defined in the same source unit at file level. +// TypeError 4117: (657-712): Can only use "global" with types defined in the same source unit at file level. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_for_contract_level_type_non_global.sol b/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_for_contract_level_type_non_global.sol new file mode 100644 index 000000000..fa0e467eb --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_for_contract_level_type_non_global.sol @@ -0,0 +1,30 @@ +library L { + type FixedBytes is bytes1; +} + +contract C { + type FixedBytes is bytes2; +} + +interface I { + type FixedBytes is bytes3; +} + +function addL(L.FixedBytes, L.FixedBytes) pure returns (L.FixedBytes) {} +function addC(C.FixedBytes, C.FixedBytes) pure returns (C.FixedBytes) {} +function addI(I.FixedBytes, I.FixedBytes) pure returns (I.FixedBytes) {} + +function unsubL(L.FixedBytes) pure returns (L.FixedBytes) {} +function unsubC(C.FixedBytes) pure returns (C.FixedBytes) {} +function unsubI(I.FixedBytes) pure returns (I.FixedBytes) {} + +using {addL as +, unsubL as -} for L.FixedBytes; +using {addC as +, unsubC as -} for C.FixedBytes; +using {addI as +, unsubI as -} for I.FixedBytes; +// ---- +// TypeError 3320: (552-556): Operators can only be defined in a global 'using for' directive. +// TypeError 3320: (563-569): Operators can only be defined in a global 'using for' directive. +// TypeError 3320: (601-605): Operators can only be defined in a global 'using for' directive. +// TypeError 3320: (612-618): Operators can only be defined in a global 'using for' directive. +// TypeError 3320: (650-654): Operators can only be defined in a global 'using for' directive. +// TypeError 3320: (661-667): Operators can only be defined in a global 'using for' directive. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_global_and_non_global.sol b/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_global_and_non_global.sol new file mode 100644 index 000000000..b04934d96 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_global_and_non_global.sol @@ -0,0 +1,23 @@ +==== Source: s1.sol ==== +type Int is int; + +using {add as +} for Int global; +using {add as +} for Int; + +function add(Int a, Int b) pure returns (Int) {} +function test_add() pure returns (Int) {} + +==== Source: s2.sol ==== +import "s1.sol"; + +contract C2 { + function test1() pure public returns (Int) { + return test_add(); + } + + function test2() pure public returns (Int) { + return Int.wrap(3) + Int.wrap(4); + } +} +// ---- +// TypeError 3320: (s1.sol:58-61): Operators can only be defined in a global 'using for' directive. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_global_different_file.sol b/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_global_different_file.sol new file mode 100644 index 000000000..7eda376e3 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_global_different_file.sol @@ -0,0 +1,11 @@ +==== Source: s1.sol ==== +type Int is int; + +==== Source: s2.sol ==== +import "s1.sol"; + +function bitnot(Int) pure returns (Int) {} + +using {bitnot as ~} for Int global; +// ---- +// TypeError 4117: (s2.sol:62-97): Can only use "global" with types defined in the same source unit at file level. diff --git a/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_global_unary_and_non_global_binary_same_file.sol b/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_global_unary_and_non_global_binary_same_file.sol new file mode 100644 index 000000000..68f619886 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/userDefined/using_for_with_operator_at_file_level_global_unary_and_non_global_binary_same_file.sol @@ -0,0 +1,20 @@ +type Int is int16; + +using {unsub as -} for Int global; +using {sub as -} for Int; + +function sub(Int a, Int b) pure returns (Int) {} + +function unsub(Int a) pure returns (Int) {} + +contract C { + function test_sub() public pure returns (Int) { + return Int.wrap(7) - Int.wrap(2); + } + + function test_unsub() public pure returns (Int) { + return -Int.wrap(4); + } +} +// ---- +// TypeError 3320: (62-65): Operators can only be defined in a global 'using for' directive. diff --git a/test/libsolidity/syntaxTests/using/using_for_enum.sol b/test/libsolidity/syntaxTests/using/using_for_enum.sol new file mode 100644 index 000000000..e7c6b5c82 --- /dev/null +++ b/test/libsolidity/syntaxTests/using/using_for_enum.sol @@ -0,0 +1,5 @@ +enum E {A, B, C} + +function f(E) {} + +using {f} for E; diff --git a/test/libsolidity/syntaxTests/viewPureChecker/user_operator_with_pure_modifier_can_be_restricted.sol b/test/libsolidity/syntaxTests/viewPureChecker/user_operator_with_pure_modifier_can_be_restricted.sol new file mode 100644 index 000000000..eb7ce354d --- /dev/null +++ b/test/libsolidity/syntaxTests/viewPureChecker/user_operator_with_pure_modifier_can_be_restricted.sol @@ -0,0 +1,20 @@ +type Int is uint8; + +using {add as +} for Int global; + +function add(Int, Int) pure returns (Int) {} + +function f() pure { + Int.wrap(0) + Int.wrap(1); +} + +function g() view { + Int.wrap(0) + Int.wrap(1); +} + +function h() { + Int.wrap(0) + Int.wrap(1); +} +// ---- +// Warning 2018: (154-206): Function state mutability can be restricted to pure +// Warning 2018: (208-255): Function state mutability can be restricted to pure