From 0ab0842c2944680c3f92119ee4185822b9a63350 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 26 Jun 2023 17:00:52 +0200 Subject: [PATCH] Disallow conversions between declaration function types. --- Changelog.md | 1 + libsolidity/ast/Types.cpp | 6 ++++++ .../functionTypes/declaration_type_conversion.sol | 11 +++++++++++ .../declaration_type_conversion_internal_base.sol | 11 +++++++++++ 4 files changed, 29 insertions(+) create mode 100644 test/libsolidity/syntaxTests/functionTypes/declaration_type_conversion.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/declaration_type_conversion_internal_base.sol diff --git a/Changelog.md b/Changelog.md index fa2ea9666..723df4583 100644 --- a/Changelog.md +++ b/Changelog.md @@ -29,6 +29,7 @@ Bugfixes: * SMTChecker: Fix false negative when a verification target can be violated only by trusted external call from another public function. * SMTChecker: Fix internal error caused by using external identifier to encode member access to functions that take an internal function as a parameter. * Standard JSON Interface: Fix an incomplete AST being returned when analysis is interrupted by certain kinds of fatal errors. + * Type Checker: Function declaration types referring to different declarations are no longer convertible to each other. * Yul Optimizer: Ensure that the assignment of memory slots for variables moved to memory does not depend on AST IDs that may depend on whether additional files are included during compilation. * Yul Optimizer: Fix ``FullInliner`` step not ignoring code that is not in expression-split form. * Yul Optimizer: Fix optimized IR being unnecessarily passed through the Yul optimizer again before bytecode generation. diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 6308dbe3d..915440caa 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -3127,6 +3127,12 @@ BoolResult FunctionType::isImplicitlyConvertibleTo(Type const& _convertTo) const if (convertTo.kind() != kind()) return BoolResult::err("Special functions cannot be converted to function types."); + if ( + kind() == FunctionType::Kind::Declaration && + m_declaration != convertTo.m_declaration + ) + return BoolResult::err("Function declaration types referring to different functions cannot be converted to each other."); + if (!equalExcludingStateMutability(convertTo)) return false; diff --git a/test/libsolidity/syntaxTests/functionTypes/declaration_type_conversion.sol b/test/libsolidity/syntaxTests/functionTypes/declaration_type_conversion.sol new file mode 100644 index 000000000..a26460dc1 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/declaration_type_conversion.sol @@ -0,0 +1,11 @@ +contract D { + function f() external {} + function g() external {} +} +contract C { + function f(bool c) public pure { + (c ? D.f : D.g); + } +} +// ---- +// TypeError 1080: (117-130): True expression's type function D.f() does not match false expression's type function D.g(). diff --git a/test/libsolidity/syntaxTests/functionTypes/declaration_type_conversion_internal_base.sol b/test/libsolidity/syntaxTests/functionTypes/declaration_type_conversion_internal_base.sol new file mode 100644 index 000000000..210211b28 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/declaration_type_conversion_internal_base.sol @@ -0,0 +1,11 @@ +contract C { + function f() internal {} + function g() internal {} +} + +contract D is C { + function h(bool b) public pure { + (b ? C.f : C.g); + } +} +// ----