From e7d5a7da1061cd78867815156bc9b40d86567a8e Mon Sep 17 00:00:00 2001 From: Djordje Mijovic Date: Wed, 15 Jul 2020 16:27:38 +0200 Subject: [PATCH 1/2] [TypeChecker] Remove function input and return parameter names from mobileType --- Changelog.md | 1 + libsolidity/analysis/TypeChecker.cpp | 6 ++--- libsolidity/ast/Types.cpp | 22 +++++++++++++++++++ libsolidity/ast/Types.h | 1 + .../conditional_with_arguments.sol | 10 +++++++++ .../invalid_named_arguments_conditional.sol | 14 ++++++++++++ 6 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 test/libsolidity/semanticTests/functionCall/conditional_with_arguments.sol create mode 100644 test/libsolidity/syntaxTests/functionCalls/invalid_named_arguments_conditional.sol diff --git a/Changelog.md b/Changelog.md index 467bca127..76add9578 100644 --- a/Changelog.md +++ b/Changelog.md @@ -32,6 +32,7 @@ Bugfixes: * NatSpec: Constructors and functions have consistent userdoc output. * Inheritance: Disallow public state variables overwriting ``pure`` functions. * State Mutability: Constant public state variables are considered ``pure`` functions. + * Type Checker: Fixing deduction issues on function types when function call has named arguments. ### 0.6.12 (2020-07-22) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 8b8ceadd5..f0b174d19 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1293,9 +1293,9 @@ bool TypeChecker::visit(Conditional const& _conditional) if (_conditional.annotation().willBeWrittenTo) m_errorReporter.typeError( - 2212_error, - _conditional.location(), - "Conditional expression as left value is not supported yet." + 2212_error, + _conditional.location(), + "Conditional expression as left value is not supported yet." ); return false; diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 2c0889dfa..967aa19d4 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -3425,6 +3425,28 @@ TypeResult FunctionType::interfaceType(bool /*_inLibrary*/) const return TypeResult::err("Internal type is not allowed for public or external functions."); } +TypePointer FunctionType::mobileType() const +{ + if (m_valueSet || m_gasSet || m_saltSet || m_bound) + return nullptr; + + // return function without parameter names + return TypeProvider::function( + m_parameterTypes, + m_returnParameterTypes, + strings(m_parameterTypes.size()), + strings(m_returnParameterNames.size()), + m_kind, + m_arbitraryParameters, + m_stateMutability, + m_declaration, + m_gasSet, + m_valueSet, + m_bound, + m_saltSet + ); +} + bool FunctionType::canTakeArguments( FuncCallArguments const& _arguments, Type const* _selfType diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 5983fe941..938b3f886 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -1234,6 +1234,7 @@ public: MemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override; TypePointer encodingType() const override; TypeResult interfaceType(bool _inLibrary) const override; + TypePointer mobileType() const override; /// @returns TypePointer of a new FunctionType object. All input/return parameters are an /// appropriate external types (i.e. the interfaceType()s) of input/return parameters of diff --git a/test/libsolidity/semanticTests/functionCall/conditional_with_arguments.sol b/test/libsolidity/semanticTests/functionCall/conditional_with_arguments.sol new file mode 100644 index 000000000..f5996d32c --- /dev/null +++ b/test/libsolidity/semanticTests/functionCall/conditional_with_arguments.sol @@ -0,0 +1,10 @@ +contract C { + function g(int x, int y) public pure returns (int) { return x - y; } + function h(int y, int x) public pure returns (int) { return y - x; } + + function f() public pure returns (int) { + return (false ? g : h)(2, 1); + } +} +// ---- +// f() -> 1 diff --git a/test/libsolidity/syntaxTests/functionCalls/invalid_named_arguments_conditional.sol b/test/libsolidity/syntaxTests/functionCalls/invalid_named_arguments_conditional.sol new file mode 100644 index 000000000..0893c0ea6 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionCalls/invalid_named_arguments_conditional.sol @@ -0,0 +1,14 @@ +contract C { + function g(int x, int y) public pure returns (int) { return x - y; } + function h(int y, int x) public pure returns (int) { return y - x; } + + function f() public pure { + (true ? g : h)({x : 1, y : 2}); + [g, h][1]({x : 1, y : 2}); + } +} +// ---- +// TypeError 4974: (199-229): Named argument "x" does not match function declaration. +// TypeError 4974: (199-229): Named argument "y" does not match function declaration. +// TypeError 4974: (239-264): Named argument "x" does not match function declaration. +// TypeError 4974: (239-264): Named argument "y" does not match function declaration. From a1da90d14bb92210e32bd806974b6ba72675f8a7 Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 17 Jul 2020 10:22:30 +0200 Subject: [PATCH 2/2] Adding more tests for function types --- .../functionCall/conditional_with_arguments.sol | 2 ++ .../inline_array_with_value_call_option.sol | 10 ++++++++++ .../functionTypes/function_type_named_call.sol | 9 +++++++++ .../inline_array_with_bound_function.sol | 13 +++++++++++++ .../inline_array_with_bound_function_mixed.sol | 13 +++++++++++++ .../inline_array_with_payable_function.sol | 13 +++++++++++++ .../functionTypes/ternary_with_bound_functions.sol | 14 ++++++++++++++ 7 files changed, 74 insertions(+) create mode 100644 test/libsolidity/semanticTests/functionTypes/inline_array_with_value_call_option.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/function_type_named_call.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/inline_array_with_bound_function.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/inline_array_with_bound_function_mixed.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/inline_array_with_payable_function.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/ternary_with_bound_functions.sol diff --git a/test/libsolidity/semanticTests/functionCall/conditional_with_arguments.sol b/test/libsolidity/semanticTests/functionCall/conditional_with_arguments.sol index f5996d32c..f5e2957c9 100644 --- a/test/libsolidity/semanticTests/functionCall/conditional_with_arguments.sol +++ b/test/libsolidity/semanticTests/functionCall/conditional_with_arguments.sol @@ -6,5 +6,7 @@ contract C { return (false ? g : h)(2, 1); } } +// ==== +// compileViaYul: also // ---- // f() -> 1 diff --git a/test/libsolidity/semanticTests/functionTypes/inline_array_with_value_call_option.sol b/test/libsolidity/semanticTests/functionTypes/inline_array_with_value_call_option.sol new file mode 100644 index 000000000..e65da6e1e --- /dev/null +++ b/test/libsolidity/semanticTests/functionTypes/inline_array_with_value_call_option.sol @@ -0,0 +1,10 @@ +contract C { + function f() external payable returns (uint) { assert(msg.value > 0); return 1; } + function g() external payable returns (uint) { assert(msg.value > 0); return 2; } + + function h() public payable returns (uint) { + return [this.f, this.g][0]{value: 1}(); + } +} +// ---- +// h(), 1 ether -> 1 diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_named_call.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_named_call.sol new file mode 100644 index 000000000..ca337904a --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/function_type_named_call.sol @@ -0,0 +1,9 @@ +contract C { + function f() pure public { + function(uint a) returns (uint) x; + x({a:2}); + } +} +// ---- +// Warning 6162: (61-67): Naming function type parameters is deprecated. +// TypeError 4974: (95-103): Named argument "a" does not match function declaration. diff --git a/test/libsolidity/syntaxTests/functionTypes/inline_array_with_bound_function.sol b/test/libsolidity/syntaxTests/functionTypes/inline_array_with_bound_function.sol new file mode 100644 index 000000000..4e5ae7613 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/inline_array_with_bound_function.sol @@ -0,0 +1,13 @@ +library L { + function f(uint a) internal pure {} + function g(uint a) internal pure {} +} +contract C { + using L for *; + function f() pure public { + uint t = 8; + [t.f, t.g][0](); + } +} +// ---- +// TypeError 9563: (186-189): Invalid mobile type. diff --git a/test/libsolidity/syntaxTests/functionTypes/inline_array_with_bound_function_mixed.sol b/test/libsolidity/syntaxTests/functionTypes/inline_array_with_bound_function_mixed.sol new file mode 100644 index 000000000..be98f2be5 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/inline_array_with_bound_function_mixed.sol @@ -0,0 +1,13 @@ +library L { + function f(uint a) internal pure {} +} +contract C { + using L for *; + function f() pure public { + uint t; + function() pure x; + [t.f, x][0]({a: 8}); + } +} +// ---- +// TypeError 9563: (169-172): Invalid mobile type. diff --git a/test/libsolidity/syntaxTests/functionTypes/inline_array_with_payable_function.sol b/test/libsolidity/syntaxTests/functionTypes/inline_array_with_payable_function.sol new file mode 100644 index 000000000..195287d55 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/inline_array_with_payable_function.sol @@ -0,0 +1,13 @@ +contract D { + function f(uint a) external payable {} + function g(uint a) external {} +} + +contract C { + function f() public { + D d; + [d.f{value: 1}, d.g][0](8); + } +} +// ---- +// TypeError 9563: (155-168): Invalid mobile type. diff --git a/test/libsolidity/syntaxTests/functionTypes/ternary_with_bound_functions.sol b/test/libsolidity/syntaxTests/functionTypes/ternary_with_bound_functions.sol new file mode 100644 index 000000000..2e12e4d2a --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/ternary_with_bound_functions.sol @@ -0,0 +1,14 @@ +library L { + function f(uint a) internal pure {} + function g(uint a) internal pure {} +} +contract C { + using L for *; + function f(bool x) pure public { + uint t = 8; + (x ? t.f : t.g)(); + } +} +// ---- +// TypeError 9717: (196-199): Invalid mobile type in true expression. +// TypeError 3703: (202-205): Invalid mobile type in false expression.