diff options
14 files changed, 144 insertions, 2 deletions
diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index d89d023e..90eb74fe 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -1016,8 +1016,22 @@ void CompilerUtils::convertType( } else { - // All other types should not be convertible to non-equal types. - solAssert(_typeOnStack == _targetType, "Invalid type conversion requested."); + if (stackTypeCategory == Type::Category::Function && targetTypeCategory == Type::Category::Function) + { + FunctionType const& typeOnStack = dynamic_cast<FunctionType const&>(_typeOnStack); + FunctionType const& targetType = dynamic_cast<FunctionType const&>(_targetType); + solAssert( + typeOnStack.isImplicitlyConvertibleTo(targetType) && + typeOnStack.sizeOnStack() == targetType.sizeOnStack() && + (typeOnStack.kind() == FunctionType::Kind::Internal || typeOnStack.kind() == FunctionType::Kind::External) && + typeOnStack.kind() == targetType.kind(), + "Invalid function type conversion requested." + ); + } + else + // All other types should not be convertible to non-equal types. + solAssert(_typeOnStack == _targetType, "Invalid type conversion requested."); + if (_cleanupNeeded && _targetType.canBeStored() && _targetType.storageBytes() < 32) m_context << ((u256(1) << (8 * _targetType.storageBytes())) - 1) diff --git a/test/libsolidity/syntaxTests/conversion/function_type_nonpayable_payable.sol b/test/libsolidity/syntaxTests/conversion/function_type_nonpayable_payable.sol new file mode 100644 index 00000000..75f7a953 --- /dev/null +++ b/test/libsolidity/syntaxTests/conversion/function_type_nonpayable_payable.sol @@ -0,0 +1,10 @@ +contract C { + function h() external { + } + function f() view external returns (bytes4) { + function () payable external g = this.h; + return g.selector; + } +} +// ---- +// TypeError: (105-144): Type function () external is not implicitly convertible to expected type function () payable external. diff --git a/test/libsolidity/syntaxTests/conversion/function_type_nonpayable_pure.sol b/test/libsolidity/syntaxTests/conversion/function_type_nonpayable_pure.sol new file mode 100644 index 00000000..8d1b08aa --- /dev/null +++ b/test/libsolidity/syntaxTests/conversion/function_type_nonpayable_pure.sol @@ -0,0 +1,10 @@ +contract C { + function h() external { + } + function f() view external returns (bytes4) { + function () pure external g = this.h; + return g.selector; + } +} +// ---- +// TypeError: (105-141): Type function () external is not implicitly convertible to expected type function () pure external. diff --git a/test/libsolidity/syntaxTests/conversion/function_type_nonpayable_view.sol b/test/libsolidity/syntaxTests/conversion/function_type_nonpayable_view.sol new file mode 100644 index 00000000..535d6c77 --- /dev/null +++ b/test/libsolidity/syntaxTests/conversion/function_type_nonpayable_view.sol @@ -0,0 +1,10 @@ +contract C { + function h() external { + } + function f() view external returns (bytes4) { + function () view external g = this.h; + return g.selector; + } +} +// ---- +// TypeError: (105-141): Type function () external is not implicitly convertible to expected type function () view external. diff --git a/test/libsolidity/syntaxTests/conversion/function_type_payable_nonpayable.sol b/test/libsolidity/syntaxTests/conversion/function_type_payable_nonpayable.sol new file mode 100644 index 00000000..299d7e30 --- /dev/null +++ b/test/libsolidity/syntaxTests/conversion/function_type_payable_nonpayable.sol @@ -0,0 +1,8 @@ +contract C { + function h() payable external { + } + function f() view external returns (bytes4) { + function () external g = this.h; + return g.selector; + } +} diff --git a/test/libsolidity/syntaxTests/conversion/function_type_payable_pure.sol b/test/libsolidity/syntaxTests/conversion/function_type_payable_pure.sol new file mode 100644 index 00000000..78bada51 --- /dev/null +++ b/test/libsolidity/syntaxTests/conversion/function_type_payable_pure.sol @@ -0,0 +1,10 @@ +contract C { + function h() payable external { + } + function f() view external returns (bytes4) { + function () pure external g = this.h; + return g.selector; + } +} +// ---- +// TypeError: (113-149): Type function () payable external is not implicitly convertible to expected type function () pure external. diff --git a/test/libsolidity/syntaxTests/conversion/function_type_payable_view.sol b/test/libsolidity/syntaxTests/conversion/function_type_payable_view.sol new file mode 100644 index 00000000..f12cb301 --- /dev/null +++ b/test/libsolidity/syntaxTests/conversion/function_type_payable_view.sol @@ -0,0 +1,10 @@ +contract C { + function h() payable external { + } + function f() view external returns (bytes4) { + function () view external g = this.h; + return g.selector; + } +} +// ---- +// TypeError: (113-149): Type function () payable external is not implicitly convertible to expected type function () view external. diff --git a/test/libsolidity/syntaxTests/conversion/function_type_pure_nonpayable.sol b/test/libsolidity/syntaxTests/conversion/function_type_pure_nonpayable.sol new file mode 100644 index 00000000..7742e0c1 --- /dev/null +++ b/test/libsolidity/syntaxTests/conversion/function_type_pure_nonpayable.sol @@ -0,0 +1,8 @@ +contract C { + function h() pure external { + } + function f() view external returns (bytes4) { + function () external g = this.h; + return g.selector; + } +} diff --git a/test/libsolidity/syntaxTests/conversion/function_type_pure_payable.sol b/test/libsolidity/syntaxTests/conversion/function_type_pure_payable.sol new file mode 100644 index 00000000..cd4e9b4e --- /dev/null +++ b/test/libsolidity/syntaxTests/conversion/function_type_pure_payable.sol @@ -0,0 +1,10 @@ +contract C { + function h() pure external { + } + function f() view external returns (bytes4) { + function () payable external g = this.h; + return g.selector; + } +} +// ---- +// TypeError: (110-149): Type function () pure external is not implicitly convertible to expected type function () payable external. diff --git a/test/libsolidity/syntaxTests/conversion/function_type_pure_view.sol b/test/libsolidity/syntaxTests/conversion/function_type_pure_view.sol new file mode 100644 index 00000000..578ecdbd --- /dev/null +++ b/test/libsolidity/syntaxTests/conversion/function_type_pure_view.sol @@ -0,0 +1,8 @@ +contract C { + function h() pure external { + } + function f() view external returns (bytes4) { + function () view external g = this.h; + return g.selector; + } +} diff --git a/test/libsolidity/syntaxTests/conversion/function_type_same.sol b/test/libsolidity/syntaxTests/conversion/function_type_same.sol new file mode 100644 index 00000000..c5ebe1ca --- /dev/null +++ b/test/libsolidity/syntaxTests/conversion/function_type_same.sol @@ -0,0 +1,14 @@ +contract C { + int dummy; + function h_nonpayable() external { dummy = 1; } + function h_payable() payable external {} + function h_view() view external { dummy; } + function h_pure() pure external {} + function f() view external { + function () external g_nonpayable = this.h_nonpayable; g_nonpayable; + function () payable external g_payable = this.h_payable; g_payable; + function () view external g_view = this.h_view; g_view; + function () pure external g_pure = this.h_pure; g_pure; + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/conversion/function_type_view_nonpayable.sol b/test/libsolidity/syntaxTests/conversion/function_type_view_nonpayable.sol new file mode 100644 index 00000000..f52aece0 --- /dev/null +++ b/test/libsolidity/syntaxTests/conversion/function_type_view_nonpayable.sol @@ -0,0 +1,10 @@ +contract C { + int dummy; + function h() view external { + dummy; + } + function f() view external returns (bytes4) { + function () external g = this.h; + return g.selector; + } +} diff --git a/test/libsolidity/syntaxTests/conversion/function_type_view_payable.sol b/test/libsolidity/syntaxTests/conversion/function_type_view_payable.sol new file mode 100644 index 00000000..3bf4bac2 --- /dev/null +++ b/test/libsolidity/syntaxTests/conversion/function_type_view_payable.sol @@ -0,0 +1,10 @@ +contract C { + function h() view external { + } + function f() view external returns (bytes4) { + function () payable external g = this.h; + return g.selector; + } +} +// ---- +// TypeError: (110-149): Type function () view external is not implicitly convertible to expected type function () payable external. diff --git a/test/libsolidity/syntaxTests/conversion/function_type_view_pure.sol b/test/libsolidity/syntaxTests/conversion/function_type_view_pure.sol new file mode 100644 index 00000000..c567a2c8 --- /dev/null +++ b/test/libsolidity/syntaxTests/conversion/function_type_view_pure.sol @@ -0,0 +1,10 @@ +contract C { + function h() view external { + } + function f() view external returns (bytes4) { + function () pure external g = this.h; + return g.selector; + } +} +// ---- +// TypeError: (110-146): Type function () view external is not implicitly convertible to expected type function () pure external. |