Fix non-constant event and error selectors

This commit is contained in:
Emilio Almansi 2023-06-04 12:58:59 +07:00
parent 374a6fd50e
commit 2f1fa9ae77
5 changed files with 53 additions and 0 deletions

View File

@ -21,6 +21,7 @@ Bugfixes:
* SMTChecker: Fix false negative when a verification target can be violated only by trusted external call from another public function.
* 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 optimized IR being unnecessarily passed through the Yul optimizer again before bytecode generation.
* TypeChecker: Fix non-constant event and error selectors.
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``.

View File

@ -3358,6 +3358,29 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
annotation.isPure = isPure;
}
if (
auto const* functionType = dynamic_cast<FunctionType const*>(exprType);
!annotation.isPure.set() &&
functionType &&
functionType->kind() == FunctionType::Kind::Event &&
functionType->hasDeclaration() &&
memberName == "selector"
)
if (
auto const* eventDefinition = dynamic_cast<EventDefinition const*>(&functionType->declaration());
eventDefinition &&
!eventDefinition->isAnonymous()
)
annotation.isPure = true;
if (
auto const* functionType = dynamic_cast<FunctionType const*>(exprType);
!annotation.isPure.set() &&
functionType &&
functionType->kind() == FunctionType::Kind::Error &&
functionType->hasDeclaration() &&
memberName == "selector"
)
annotation.isPure = true;
if (
auto const* varDecl = dynamic_cast<VariableDeclaration const*>(annotation.referencedDeclaration);
!annotation.isPure.set() &&

View File

@ -0,0 +1,10 @@
interface I {
error Er1();
}
contract C {
function f() external {}
error Er2();
bytes4 constant errorSelector1 = I.Er1.selector;
bytes4 constant errorSelector2 = Er2.selector;
}
// ----

View File

@ -0,0 +1,10 @@
interface I {
event Ev1();
}
contract C {
function f() external {}
event Ev2();
bytes32 constant eventSelector1 = I.Ev1.selector;
bytes32 constant eventSelector2 = Ev2.selector;
}
// ----

View File

@ -0,0 +1,9 @@
interface I {
function f() external;
}
contract C {
function f() external {}
bytes4 constant functionSelector1 = I.f.selector;
bytes4 constant functionSelector2 = this.f.selector;
}
// ----