-
Notifications
You must be signed in to change notification settings - Fork 5.8k
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
Add .address
and .selector
in inside assembly for external function pointers
#12016
Conversation
b30a197
to
bc906c9
Compare
@@ -211,7 +211,7 @@ struct InlineAssemblyAnnotation: StatementAnnotation | |||
struct ExternalIdentifierInfo | |||
{ | |||
Declaration const* declaration = nullptr; | |||
/// Suffix used, one of "slot", "offset", "length" or empty. | |||
/// Suffix used, one of "slot", "offset", "length", "address", "selector" or empty. | |||
std::string suffix; |
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.
Why isn't this an enum? Maybe we could refactor it into one (in a separate PR of course).
else if ( | ||
auto const* functionType = dynamic_cast<FunctionType const*>(variable->type()); | ||
functionType && functionType->kind() == FunctionType::Kind::External | ||
) |
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.
This will not run for storage variables of function types.
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.
That is intended. The ticket specification was "If x is a Solidity local variable of function external type [..]"
function testYul() public returns (uint32) { | ||
function() external fp = this.testFunction; | ||
uint selectorValue = 0; | ||
|
||
assembly { | ||
selectorValue := fp.selector | ||
} | ||
|
||
return uint32(bytes4(bytes32(selectorValue))); | ||
} | ||
function testSol() public returns (uint32) { | ||
return uint32(this.testFunction.selector); | ||
} |
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.
If .selector
in Solidity is uint32
(right-aligned in a 32-byte slot) why do we want it left-aligned in Yul? Wouldn't it be more consistent to have it right-aligned in both cases?
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.
it is not, it is a bytes4
.
} | ||
} | ||
function testSol() public { | ||
this.testFunction.selector = bytes4(bytes32(uint256(0x1234568))); |
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.
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.
Yes, intentional - doing bytes4(7)
would perform two steps at a time in my opinion.
If you plan to also allow assigning, I don't think it is worth arguing about the wording of "read only" inside the documentation. Maybe do both things in the same PR? Or at least keep this in draft mode and base the second one on top of it until both are ready. |
Sure. I just had this pretty much ready when you said we should allow assigning too, so I thought go ahead with that arleady. |
e3c7bcc
to
3332601
Compare
ac3ae9d
to
ad81cad
Compare
5ae4e0c
to
81d5208
Compare
81d5208
to
6d83ca9
Compare
6d83ca9
to
a8d0312
Compare
…nction pointers
a8d0312
to
98dd783
Compare
Found with the Sanctuary run on Arbitrum: https://github.com/NomicFoundation/slang/actions/runs/8803528884 This fixes the last bug in Arbitrum data set: https://github.com/Xanewok/slang/actions/runs/8813993801 Implemented in ethereum/solidity#12016 (0.8.10), grammar updated in ethereum/solidity#12545. This matches the upstream grammar, however: - this is more relaxed and parses code that would be rejected by validation, i.e. `<built-in> := ...` - we do get a bit of noise, since most of the paths will never contain the built-in. I've also changed `YulidentifierPath` to `YulPath` to match upstream and since it's not only an identifier anymore. This also includes a patch level bump - while technically it's breaking the CST shape, I'd consider this a (hopefully last?) grammar bug fix that might justify the patch level.
So far read only.
assigning will happen in another PR.
refs #10358