-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Fix crash when declaring function selector of parent class as public constant #16053
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,11 @@ | ||||||
contract B { | ||||||
function g() public {} | ||||||
} | ||||||
|
||||||
contract C is B { | ||||||
bytes4 public constant s2 = B.g.selector; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is enough as a repro for the issue, but for completeness you should do something with the constant, because we only run the E.g. use negation on it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The test also does not really check if the value of the constant is correct (I'd have to calculate it and compare to be sure). Would be better to have the test verify it: assert(s2 == B.g.selector); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should add some coverage for related cases:
|
||||||
} | ||||||
|
||||||
|
||||||
// ---- | ||||||
// s2() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not declaring the variable is not necessarily the right solution in a general case. It helps in the repro because we're only accessing the selector, so the variable would go unused, but if we were instead trying to get a pointer to the function, we'd end up trying to access a variable that does not exist.
Theoretically, you should be able to reproduce that by making a constant of an internal function type:
But we don't allow this:
It actually looks to me like an unrelated bug - I can't see a good reason not to treat references to functions as compile-time constants. It's not like functions can change at runtime.
The weird thing is that the crash happens only when you try to access the selector inside a constant initializer, and not e.g. in the body of a function. You should check why. I'd expect
assignInternalFunctionIDIfNotCalledDirectly()
to be called in this case too so apparently it does find the ID then. I suspect that the actual cause might be in how (or when)internalFunctionIDs
is populated.