-
Notifications
You must be signed in to change notification settings - Fork 410
Support retagging of wildcard references in tree borrows #4707
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: master
Are you sure you want to change the base?
Support retagging of wildcard references in tree borrows #4707
Conversation
|
Thank you for contributing to Miri! A reviewer will take a look at your PR, typically within a week or two. |
| // then check if we can skip the entire subtree because the access might not | ||
| // change any permissions here anyway. |
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'm confused by the "might not" here. (Isn't that something you already had before and we removed it in the previous PR?)
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, your right. This got lost in a rebase.
This comment has been minimized.
This comment has been minimized.
99dacc6 to
52f2087
Compare
This comment has been minimized.
This comment has been minimized.
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.
Overall approach looks good. Here's a bunch of comments. :)
Please also add the 3 SB tests in this area: illegal_read/write_despite_exposed*.
|
|
||
| let state = perm.or_insert(node.default_location_state()); | ||
| #[cfg(feature = "expensive-consistency-checks")] | ||
| self.verify_wildcard_consistency(global); |
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 should only need this if a wildcard is involved in the access, right? I.e. if the tag is wildcard, or if there are multiple roots.
| pub(super) root: UniIndex, | ||
| /// Contains both the root of the main tree as well as the roots of the wildcard subtrees. | ||
| /// Sorted according to `BorTag` from low to high. This also means the main root is `root[0]`. | ||
| pub(super) roots: SmallVec<[UniIndex; 2]>, |
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 seems like a good place to describe what these multiple trees even mean.
| parent_node.children.push(idx); | ||
| } else { | ||
| // If the parent had wildcard provenance, then register the idx | ||
| // as a new wildcard root. |
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.
Please explain why this preserves sortedness.
| } | ||
|
|
||
| // We need to ensure the consistency of the wildcard access tracking data structure. | ||
| // For this, we insert the correct entry for this tag based on its parent, if it exists. |
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 comment does not cover the else branch.
| // Foreign accesses are always possible on wildcard subtrees, as they have | ||
| // `max_foreign_access==Write` on their root. However on the main tree this can fail | ||
| // resulting in an access error. | ||
| let accessed_root_tag = accessed_root.map(|idx| nodes.get(idx).unwrap().tag); |
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 doesn't seem to directly relate to the comment. You can just move it up.
|
|
||
| /// Print extra text if the tag is exposed. | ||
| fn print_exposed(&self, exposed: bool) -> S { | ||
| if exposed { " Exposed" } else { "" } |
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 exposed { " Exposed" } else { "" } | |
| if exposed { " (exposed)" } else { "" } |
| // We can still access both ref1, ref2. | ||
| assert_eq!(*ref2, 13); |
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.
Comment and code don't quite match... we can access both, after all.
You can just explain that this is technically UB we don't catch.
| // We should be able to access any of the references. | ||
| assert_eq!(*ref2, 13); |
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.
Again this doesn't quite test what the comment says.
| // │ │ | ||
| // └────────────┘ | ||
|
|
||
| // This is the only valid ordering these accesses can happen in. |
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 refer back to the comment for the test: accessing reb2 doesn't invalidate reb1 because ref1 exists. (Also, please pick more distinguishable names.)
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.
Please explain in the comment that this tests the max_local_tag logic.
|
Reminder, once the PR becomes ready for a review, use |
| }; | ||
| // Afterwards we check all tags in arbitrary order, so that we also catch | ||
| // protectors on different subtrees. | ||
| // (This unnecessarily checks the tags of `start_idx`s subtree again) |
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 comment seems outdated now.
| TreeVisitor { nodes: &mut self.nodes, loc }.traverse_this_parents_children_other( | ||
| *root, | ||
| // Visit all children, skipping none. | ||
| |_| ContinueTraversal::Recurse, | ||
| check_strong_protector, | ||
| )?; |
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 part is still duplicated between the two branches... maybe it makes more sense to share the entire visitor invocation, not just the check_strong_protector closure?
This comment has been minimized.
This comment has been minimized.
8c7ac81 to
4097b0a
Compare
|
This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
Adds proper suport for reborrowing wildcard pointers to tree borrows.