Auto merge of #1725 - RalfJung:zst-reborrow, r=RalfJung
fix reborrowing of tagged ZST references `@SkiFire13` [pointed out](https://github.com/rust-lang/rust/pull/82554#issuecomment-787088712) that Miri fails to detect illegal use of empty slices. This PR fixes that. In so doing, it uncovers a flaw of Stacked Borrows: it is incompatible with how the formatting machinery uses `extern type`, so for now we skip reborrowing when we cannot determine the exact size of the pointee.
This commit is contained in:
commit
4ecb5a99e0
@ -586,15 +586,23 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
let place = this.ref_to_mplace(val)?;
|
||||
let size = this
|
||||
.size_and_align_of_mplace(&place)?
|
||||
.map(|(size, _)| size)
|
||||
.unwrap_or_else(|| place.layout.size);
|
||||
.map(|(size, _)| size);
|
||||
// FIXME: If we cannot determine the size (because the unsized tail is an `extern type`),
|
||||
// bail out -- we cannot reasonably figure out which memory range to reborrow.
|
||||
// See https://github.com/rust-lang/unsafe-code-guidelines/issues/276.
|
||||
let size = match size {
|
||||
Some(size) => size,
|
||||
None => return Ok(*val),
|
||||
};
|
||||
// `reborrow` relies on getting a `Pointer` and everything being in-bounds,
|
||||
// so let's ensure that. However, we do not care about alignment.
|
||||
// We can see dangling ptrs in here e.g. after a Box's `Unique` was
|
||||
// updated using "self.0 = ..." (can happen in Box::from_raw) so we cannot ICE; see miri#1050.
|
||||
let place = this.mplace_access_checked(place, Some(Align::from_bytes(1).unwrap()))?;
|
||||
// Nothing to do for ZSTs.
|
||||
if size == Size::ZERO {
|
||||
// Nothing to do for ZSTs. We use `is_bits` here because we *do* need to retag even ZSTs
|
||||
// when there actually is a tag (to avoid inheriting a tag that would let us access more
|
||||
// than 0 bytes).
|
||||
if size == Size::ZERO && place.ptr.is_bits() {
|
||||
return Ok(*val);
|
||||
}
|
||||
|
||||
|
11
tests/compile-fail/stacked_borrows/zst_slice.rs
Normal file
11
tests/compile-fail/stacked_borrows/zst_slice.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// compile-flags: -Zmiri-track-raw-pointers
|
||||
// error-pattern: does not have an appropriate item in the borrow stack
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let a = [1, 2, 3];
|
||||
let s = &a[0..0];
|
||||
assert_eq!(s.len(), 0);
|
||||
assert_eq!(*s.get_unchecked(1), 2);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user