-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Constant evaluator support for member constants #16056
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?
Conversation
93d7f5a
to
78e1d3e
Compare
1e7955b
to
985b03f
Compare
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.
I am not sure if there aren't any unwanted side-effects hiding in this. Looks good to me generally, though!
test/libsolidity/syntaxTests/constantEvaluator/member_access.sol
Outdated
Show resolved
Hide resolved
ad3f23a
to
7fa4363
Compare
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.
LGTM aside from the typo
e596763
to
d5beb9e
Compare
d5beb9e
to
9d5f93f
Compare
This pull request is stale because it has been open for 14 days with no activity. |
This pull request is stale because it has been open for 14 days with no activity. |
66a8367
to
a1c8007
Compare
a1c8007
to
1145d25
Compare
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.
Actually, there are some problems here.
if (auto const* parentIdentifier = dynamic_cast<Identifier const*>(&_memberAccess.expression())) | ||
{ | ||
if (auto const* contract = dynamic_cast<ContractDefinition const*>(parentIdentifier->annotation().referencedDeclaration)) |
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 does not cover all relevant cases. I think it will break at least on these:
m.CONST
(expression is a module)(C).CONST
(expression is not an identifier)m.C.CONST
(member access on a member access)
Especially the first and the third one are not far fetched at all.
These are probably not all cases either. I can also think about a few more that are now disallowed due to our previous changes in implicit conversions:
[C][0].CONST
(true ? C : C).CONST
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 should really be possible to implement in a more general way, without handling all those cases one by one. Have you tried getting the constant definition via _memberAccess.annotation().referencedDeclaration
?
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.
The problem is that constant evaluation is done "on demand" whenever it is needed, so in some (most?) cases information like referencedDeclaration
may not be present and will only be calculated later.
For example, in the case of array sizes, the expression will be evaluated during the DeclarationTypeChecker
step and referencedDeclaration
is resolved later when TypeChecker
step runs.
On the other hand, in the case of the custom storage layout of the contract, the evaluation would occur during the same step and information like referencedDeclaration
would be available.
I ended up focusing only in the simplest use of contract constants, and then later was considering handling modules in a different PR to not hold this one back.
I am not sure about expressions like (true ? C : C).CONST
, I think maybe it kinda falls out of scope, because currently the constant evaluator can't handle them, so it would not be able to yield C
as the "result" there...
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.
We need more tests. At least:
- Access to a non-constant member should produce an appropriate error.
- Member access that is not a top-level expression in array size, e.g.
a[1 + C.CONST + 2]
. - Nesting: member access to a constant whose value contains member access as well.
- Cycles: Two member access constants using each other as values (should be an error).
Especially the last one looks worrying. I just found #12928 (comment), which may be the reason we had this limitation to begin with. If that's the case, then properly solving this may require deeper changes to analysis phases.
Fix #16055.