From 5c7214cbe343a57540754accb8a4bbc4db3027bd Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 26 Jun 2023 17:14:08 +0200 Subject: [PATCH] Always generate code for .selector member access. --- Changelog.md | 3 +++ libsolidity/codegen/ExpressionCompiler.cpp | 4 ++++ .../selector_expression_side_effect.sol | 13 +++++++++++++ 3 files changed, 20 insertions(+) create mode 100644 test/libsolidity/semanticTests/functionTypes/selector_expression_side_effect.sol diff --git a/Changelog.md b/Changelog.md index 06a761e6e..c47d26ba2 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,7 @@ ### 0.8.21 (unreleased) Important Bugfixes: + * Code Generator: Always generate code for the expression in ``expression.selector``. * Yul Optimizer: Fix ``FullInliner`` step (``i``) not preserving the evaluation order of arguments passed into inlined functions in code that is not in expression-split form (i.e. when using a custom optimizer sequence in which the step not preceded by ``ExpressionSplitter`` (``x``)). @@ -8,6 +9,7 @@ Language Features: * Allow qualified access to events from other contracts. * Relax restrictions on initialization of immutable variables. Reads and writes may now happen at any point at construction time outside of functions and modifiers. Explicit initialization is no longer mandatory. + Compiler Features: * Commandline Interface: Add ``--ast-compact-json`` output in assembler mode. * Commandline Interface: Add ``--ir-ast-json`` and ``--ir-optimized-ast-json`` outputs for Solidity input, providing AST in compact JSON format for IR and optimized IR. @@ -36,6 +38,7 @@ Bugfixes: * 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. + AST Changes: * AST: Add the ``experimentalSolidity`` field to the ``SourceUnit`` nodes, which indicate whether the experimental parsing mode has been enabled via ``pragma experimental solidity``. diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 25bd15d5a..fa94d2f58 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -1659,6 +1659,10 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) { if (functionType->hasDeclaration()) { + // Still visit the expression in case it has side effects. + _memberAccess.expression().accept(*this); + utils().popStackElement(*functionType); + if (functionType->kind() == FunctionType::Kind::Event) m_context << u256(h256::Arith(util::keccak256(functionType->externalSignature()))); else diff --git a/test/libsolidity/semanticTests/functionTypes/selector_expression_side_effect.sol b/test/libsolidity/semanticTests/functionTypes/selector_expression_side_effect.sol new file mode 100644 index 000000000..cdb7b98df --- /dev/null +++ b/test/libsolidity/semanticTests/functionTypes/selector_expression_side_effect.sol @@ -0,0 +1,13 @@ +contract C { + uint x; + function f() public returns (uint256) { + h().f.selector; + return x; + } + function h() public returns (C) { + x = 42; + return this; + } +} +// ---- +// f() -> 42