-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Don't try to force_ptr pointers to zsts #68088
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Why does the old logic not work any more? The old structure was more clear, not having to duplicate the |
return self.walk_aggregate(op, fields.take(1)); | ||
} | ||
// FIXME: generalize this check to also do the optimization for aggregates that have | ||
// no padding and all bits legal. So basically to all PODs |
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.
AFAIK all C structs are PODs, even if they have padding.
} | ||
_ => false, | ||
ty::Array(tys, ..) | ty::Slice(tys) => { | ||
// This optimization applies for types that can hold arbitrary bytes (such as |
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 here is weird now... the optimization comes way later, after the default case, and the first optimization is only for ZST, not what this comment says.
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'd structure this roughly as follows:
- first optimization: ZST elem type
- second optimization: scalar elem type where all types are valid
- general case
Not sure if you can make the code actually follow this structure, but IMO this makes most sense for the comments.
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 would mean that the "scalar elem type where all types are valid" optimization is inside one big if-block with a tiny else block for the general case in the end. I tried to avoid that.
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.
Yeah I know, that's not great either. Maybe make the check_bytes
into a separate function?
// validation logic is skipped for uninhabited types (which may be zero sized). | ||
let elem_layout = self.ecx.layout_of(tys)?; | ||
if elem_layout.is_zst() { | ||
// Always validate the first element according to the regular rules. |
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 find this comment (and the one above) confusing. What's happening here is:
- We check for ZST.
- All ZST values are the same, so we don't need to check every element of the array/slice, just the first.
Because the old structure did a match inside a match arm guard to figure out whether to enter the arm. Also I didn't want to recompute the layout of the elements twice (once for zst, once for |
What I meant is, why does this code need changing at all? The new PR title makes it sound like it has something to do with // Size is not 0, get a pointer.
let ptr = self.ecx.force_ptr(mplace.ptr)?; That comment seems just entirely bogus now, so shouldn't that use |
We need an |
If the optimizations are early-returns in that branch, we could just fall back to the generic implementation in case of a ZST. But the ZST optimization you are adding here is also fine, even though it's more than the smallest possible bugfix. |
did that now |
@@ -608,9 +608,14 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> | |||
return Ok(()); | |||
} | |||
// This is the element type size. | |||
let ty_size = self.ecx.layout_of(tys)?.size; | |||
let layout = self.ecx.layout_of(tys)?; | |||
// Empty tuples and fieldless structs (the only ZSTs that allow reaching this code) |
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 makes it very odd that we have them in the same match arm as integers, given that we handle them entirely separate... we could have a match arm for these ZST that just doesn't do anything, I think. But that is a pre-existing condition, so we can leave that for later and fix Miri now.
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.
well.. with the check_mplace_access
we additionally get a check ensuring that the zst is correctly aligned (due to the early abort we're not checking this anymore), so if we want to keep doing such checks we're going to have to either duplicate all the logic in a struct/tuple arm or we have to intermingle it here as I did earlier with check_mplace_access
.
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.
IIRC validity checking assumes that the place itself is aligned and dereferencable? For references, we check those before adding them to the TODO list.
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 definitely assume it to be dereferencable:
rust/src/librustc_mir/interpret/validity.rs
Line 668 in 19b9b26
/// This function checks the data at `op`. `op` is assumed to cover valid memory if it |
I don't think we check alignment elsewhere... and that's okay, we want to use this to validate packed structs as well!
@bors r+ p=1 |
📌 Commit 19b9b26 has been approved by |
Don't try to force_ptr pointers to zsts r? @RalfJung cc @wesleywiser This is required to fix miri after #67501 broke it. The reason only miri sees this is that it uses validation on values during interpretation and not just on the final value of constants, which never contain such values.
☀️ Test successful - checks-azure |
r? @RalfJung
cc @wesleywiser
This is required to fix miri after #67501 broke it. The reason only miri sees this is that it uses validation on values during interpretation and not just on the final value of constants, which never contain such values.