Skip to content

Commit a87a0f7

Browse files
committed
Fix constantness of event and error selectors. Reported by #13137
1 parent fd3a226 commit a87a0f7

File tree

2 files changed

+40
-7
lines changed

2 files changed

+40
-7
lines changed

libsolidity/analysis/TypeChecker.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3280,18 +3280,31 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
32803280
auto const* functionType = dynamic_cast<FunctionType const*>(exprType);
32813281
functionType &&
32823282
functionType->hasDeclaration() &&
3283-
dynamic_cast<FunctionDefinition const*>(&functionType->declaration()) &&
32843283
memberName == "selector"
32853284
)
3286-
if (auto const* parentAccess = dynamic_cast<MemberAccess const*>(&_memberAccess.expression()))
3285+
{
3286+
if (dynamic_cast<FunctionDefinition const*>(&functionType->declaration()))
32873287
{
3288-
bool isPure = *parentAccess->expression().annotation().isPure;
3289-
if (auto const* exprInt = dynamic_cast<Identifier const*>(&parentAccess->expression()))
3290-
if (exprInt->name() == "this" || exprInt->name() == "super")
3291-
isPure = true;
3288+
if (auto const* parentAccess = dynamic_cast<MemberAccess const*>(&_memberAccess.expression()))
3289+
{
3290+
bool isPure = *parentAccess->expression().annotation().isPure;
3291+
// TODO: Add explanation.
3292+
if (auto const* exprInt = dynamic_cast<Identifier const*>(&parentAccess->expression()))
3293+
if (exprInt->name() == "this" || exprInt->name() == "super")
3294+
isPure = true;
32923295

3293-
annotation.isPure = isPure;
3296+
annotation.isPure = isPure;
3297+
}
32943298
}
3299+
// In case of event or error definition the selector is always compile-time constant, as it can be
3300+
// a keccak256 hash of the event signature or a function selector in case of an error.
3301+
else if (
3302+
dynamic_cast<EventDefinition const*>(&functionType->declaration()) ||
3303+
dynamic_cast<ErrorDefinition const*>(&functionType->declaration())
3304+
)
3305+
annotation.isPure = true;
3306+
}
3307+
32953308
if (
32963309
auto const* varDecl = dynamic_cast<VariableDeclaration const*>(annotation.referencedDeclaration);
32973310
!annotation.isPure.set() &&
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
event EvExt();
2+
error ErExt();
3+
4+
contract C {
5+
event Ev();
6+
error Er();
7+
function f() external {}
8+
9+
bytes4 constant errorExtSelector = ErExt.selector;
10+
bytes32 constant eventExtSelector = EvExt.selector;
11+
12+
bytes4 constant functionSelector = this.f.selector;
13+
bytes4 constant errorSelector = Er.selector;
14+
bytes32 constant eventSelector = Ev.selector;
15+
16+
bytes4 constant functionSelectorC = C.f.selector;
17+
bytes4 constant errorSelectorC = C.Er.selector;
18+
bytes32 constant eventSelectorC = C.Ev.selector;
19+
}
20+
// ----

0 commit comments

Comments
 (0)