From 48f7c8e2e6a42b441aa21068ae526ec5affd0c40 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 27 Feb 2021 20:03:51 +0100 Subject: [PATCH] fix reborrowing of tagged ZST references --- src/stacked_borrows.rs | 16 ++++++++++++---- tests/compile-fail/stacked_borrows/zst_slice.rs | 11 +++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 tests/compile-fail/stacked_borrows/zst_slice.rs diff --git a/src/stacked_borrows.rs b/src/stacked_borrows.rs index 52f4ddbc38..cfaf8a9005 100644 --- a/src/stacked_borrows.rs +++ b/src/stacked_borrows.rs @@ -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); } diff --git a/tests/compile-fail/stacked_borrows/zst_slice.rs b/tests/compile-fail/stacked_borrows/zst_slice.rs new file mode 100644 index 0000000000..0804f73030 --- /dev/null +++ b/tests/compile-fail/stacked_borrows/zst_slice.rs @@ -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); + } +}