-
Notifications
You must be signed in to change notification settings - Fork 19
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
Solidity binding fixes driven by Sanctuary #1149
Open
ggiraldez
wants to merge
68
commits into
NomicFoundation:main
Choose a base branch
from
manastech:sanctuary-fixes-only
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…e-or-more operator
- `string` and `bytes` are exported as built-in variables resolving to types that provide a `concat` function - `address` can be used as a function to cast a parameter to `address` to eg. retrieve the balance
This makes resolving to attached functions on types even when the reference of those types happen in a different lexical scope.
And also provide alternative paths with and without propagating the dynamic scope. Otherwise, since scope accumulate on the stack it's possible we'll need to resolve an attached function with the wrong dynamic scope at the top of the scope stack.
Both contracts and libraries can optionally push the dynamics scope when traversing to the parent lexical scope (ie. the source unit). But for libraries, they can also optionally push their name to correctly bind internal types which were extended (with `using`) by their qualified name (ie. `Lib.Type`).
Applying a function call with a type will always return a value of that type, so a symbol stack `type,()` is equivalent to `type,@typeof`. Reflect on the binding entry point of the using clause.
These are parsed as modifiers, and they need a similar treatment as parent constructor calls in new constructor definitions.
A public getter will never return a complex data type, and a special getter function is generated for arrays, mappings and structs. Arrays and mappings we were already handling, but this commit makes that more explicit. For structs, we bind the type of the first field. There is a caveat here: if the first field is not a type that can be flattened and returned in a public getter we're still binding it, instead of the first field that can be returned. But I don't see a way to be 100% correct here.
Re-running the tests against Sanctuary I noticed some things broke with the last few changes. Expect a couple more commits added to this PR. |
We are usually binding `this` to the enclosing contract type, but it can also be used in library code. For this special ocasion, bind it to a built-in. This will need to be resolved later to the actual contract instance by the backend.
ggiraldez
added a commit
to manastech/slang
that referenced
this pull request
Nov 25, 2024
This happens when there is special member access in some Yul identifier (like `x.slot` or `x.offset`). I think this issue was introduced when unreserving the `address` keyword since that changed the structure of `YulPath`. There is a proper test case in NomicFoundation#1149 already, but without this fix running Sanctuary with existing rules crashes.
This avoids some oddities, such as `this` used in libraries which we previously had to bind to an artificial built-in.
ggiraldez
force-pushed
the
sanctuary-fixes-only
branch
from
November 26, 2024 23:54
40e6da0
to
4c19da0
Compare
OmarTawfik
approved these changes
Nov 28, 2024
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.
For the unresolved comments, I'm happy to follow up on it later.
github-merge-queue bot
pushed a commit
that referenced
this pull request
Nov 28, 2024
This PR adds a step to Sanctuary testing to exercise bindings. We now also consider a Sanctuary test to fail if any of the references found in it cannot be resolved to one (or possibly more) definitions. This also includes a small binding rules fix to avoid crashing if we find a Solidity source file with an assembly block that has a `YulPath` with more than one identifier (eg. a member access like `x.slot`). This is properly tested in #1149, but without it running Sanctuary tests will crash since there are contracts with the aforementioned contents.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR contains fixes to bindings for issues that were found by trying to resolve all references in Sanctuary, as well as test cases to verify them. It also improves documentation of the rules and improvements (renames and rearrangements) for readability. The built-in types are also standardized with a PascalCase naming convention.
Most notably, it introduces extension scopes to support resolving attached function set via
using
directives. These extension scopes need to be accessible at any point during the resolution of a symbol stack if the originating reference is located in a lexical scope which is affected by ausing
directive. This forced a refactor of the lexical scope node structure, introducing a new.extended_scope
available in nodes where references may need to resolve to attached functions (ie. function bodies, constant initialization expressions, etc.) Also, for Solidity < 0.7.0using
directives are inherited, so we need to propagate the new extension scopes for all sub-contracts relative to where the directive is located.The extension scope mechanism is implemented using the jump to scope and scope stack features of the stack graphs. The extended scope would optionally push the extension scope for the current contract and then continue resolution through the normal lexical scope. This effectively doubles the search space in the graph when performing a resolution, and this happens every time we inject a new extension scope to the scope stack. This has the potential to exponentially increase the running times and memory requirements. This is a known caveat which will be addressed in a future PR.