Skip to content

Commit 48f7c8e

Browse files
committed
fix reborrowing of tagged ZST references
1 parent 74b7714 commit 48f7c8e

File tree

2 files changed

+23
-4
lines changed

2 files changed

+23
-4
lines changed

src/stacked_borrows.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -586,15 +586,23 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
586586
let place = this.ref_to_mplace(val)?;
587587
let size = this
588588
.size_and_align_of_mplace(&place)?
589-
.map(|(size, _)| size)
590-
.unwrap_or_else(|| place.layout.size);
589+
.map(|(size, _)| size);
590+
// FIXME: If we cannot determine the size (because the unsized tail is an `extern type`),
591+
// bail out -- we cannot reasonably figure out which memory range to reborrow.
592+
// See https://github.com/rust-lang/unsafe-code-guidelines/issues/276.
593+
let size = match size {
594+
Some(size) => size,
595+
None => return Ok(*val),
596+
};
591597
// `reborrow` relies on getting a `Pointer` and everything being in-bounds,
592598
// so let's ensure that. However, we do not care about alignment.
593599
// We can see dangling ptrs in here e.g. after a Box's `Unique` was
594600
// updated using "self.0 = ..." (can happen in Box::from_raw) so we cannot ICE; see miri#1050.
595601
let place = this.mplace_access_checked(place, Some(Align::from_bytes(1).unwrap()))?;
596-
// Nothing to do for ZSTs.
597-
if size == Size::ZERO {
602+
// Nothing to do for ZSTs. We use `is_bits` here because we *do* need to retag even ZSTs
603+
// when there actually is a tag (to avoid inheriting a tag that would let us access more
604+
// than 0 bytes).
605+
if size == Size::ZERO && place.ptr.is_bits() {
598606
return Ok(*val);
599607
}
600608

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// compile-flags: -Zmiri-track-raw-pointers
2+
// error-pattern: does not have an appropriate item in the borrow stack
3+
4+
fn main() {
5+
unsafe {
6+
let a = [1, 2, 3];
7+
let s = &a[0..0];
8+
assert_eq!(s.len(), 0);
9+
assert_eq!(*s.get_unchecked(1), 2);
10+
}
11+
}

0 commit comments

Comments
 (0)