From 5e94fce7dfcd86ac392168d9cb185a2dd868b13f Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 25 Feb 2021 11:54:09 +0100 Subject: [PATCH] Provide selector for some internal functions. --- .../codegen/ir/IRGeneratorForStatements.cpp | 8 +++++- .../constants/function_unreferenced.sol | 11 ++++++++ .../functionTypes/selector_1.sol | 14 ++++++++++ .../functionTypes/selector_2.sol | 14 ++++++++++ .../syntaxTests/functionTypes/selectors.sol | 26 +++++++++++++++++++ 5 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/semanticTests/constants/function_unreferenced.sol create mode 100644 test/libsolidity/semanticTests/functionTypes/selector_1.sol create mode 100644 test/libsolidity/semanticTests/functionTypes/selector_2.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/selectors.sol diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index c2a54a838..98a874ee5 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -1689,9 +1689,15 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) functionType.kind() == FunctionType::Kind::DelegateCall ) define(IRVariable{_memberAccess}, IRVariable(_memberAccess.expression()).part("functionSelector")); - else if (functionType.kind() == FunctionType::Kind::Declaration) + else if ( + functionType.kind() == FunctionType::Kind::Declaration || + // In some situations, internal function types also provide the "selector" member. + // See Types.cpp for details. + functionType.kind() == FunctionType::Kind::Internal + ) { solAssert(functionType.hasDeclaration(), ""); + solAssert(functionType.declaration().isPartOfExternalInterface(), ""); define(IRVariable{_memberAccess}) << formatNumber(functionType.externalIdentifier() << 224) << "\n"; } else diff --git a/test/libsolidity/semanticTests/constants/function_unreferenced.sol b/test/libsolidity/semanticTests/constants/function_unreferenced.sol new file mode 100644 index 000000000..e65949f30 --- /dev/null +++ b/test/libsolidity/semanticTests/constants/function_unreferenced.sol @@ -0,0 +1,11 @@ +contract B { + function g() public {} +} +contract C is B { + bytes4 constant s2 = B.g.selector; + function f() external pure returns (bytes4) { return s2; } +} +// ==== +// compileViaYul: also +// ---- +// f() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/functionTypes/selector_1.sol b/test/libsolidity/semanticTests/functionTypes/selector_1.sol new file mode 100644 index 000000000..397655dae --- /dev/null +++ b/test/libsolidity/semanticTests/functionTypes/selector_1.sol @@ -0,0 +1,14 @@ +contract B { + function ext() external {} + function pub() public {} +} + +contract C is B { + function test() public returns (bytes4, bytes4, bytes4, bytes4) { + return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector); + } +} +// ==== +// compileViaYul: true +// ---- +// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/functionTypes/selector_2.sol b/test/libsolidity/semanticTests/functionTypes/selector_2.sol new file mode 100644 index 000000000..248e44673 --- /dev/null +++ b/test/libsolidity/semanticTests/functionTypes/selector_2.sol @@ -0,0 +1,14 @@ +contract B { + function ext() external {} + function pub() public {} +} + +contract D { + function test() public returns (bytes4, bytes4) { + return (B.ext.selector, B.pub.selector); + } +} +// ==== +// compileViaYul: true +// ---- +// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/syntaxTests/functionTypes/selectors.sol b/test/libsolidity/syntaxTests/functionTypes/selectors.sol new file mode 100644 index 000000000..21a88fe8e --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/selectors.sol @@ -0,0 +1,26 @@ +contract B { + function ext() external {} + function pub() public {} +} + +contract C is B { + function test() public pure { + B.ext.selector; + B.pub.selector; + this.ext.selector; + pub.selector; + } +} + +contract D { + function test() public pure { + B.ext.selector; + B.pub.selector; + } +} +// ---- +// Warning 6133: (136-150): Statement has no effect. +// Warning 6133: (160-174): Statement has no effect. +// Warning 6133: (184-201): Statement has no effect. +// Warning 6133: (289-303): Statement has no effect. +// Warning 6133: (313-327): Statement has no effect.