Save a created event for zero-size reborrows
This commit is contained in:
parent
5c3e4b6556
commit
9a1475dbe2
2 changed files with 25 additions and 2 deletions
|
|
@ -706,7 +706,26 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
if size == Size::ZERO {
|
||||
// Nothing to do for zero-sized accesses.
|
||||
// Don't update any stacks for a zero-sized access; borrow stacks are per-byte and this
|
||||
// touches no bytes so there is no stack to put this tag in.
|
||||
// However, if the pointer for this operation points at a real allocation we still
|
||||
// record where it was created so that we can issue a helpful diagnostic if there is an
|
||||
// attempt to use it for a non-zero-sized access.
|
||||
// Dangling slices are a common case here; it's valid to get their length but with raw
|
||||
// pointer tagging for example all calls to get_unchecked on them are invalid.
|
||||
if let Ok((alloc_id, base_offset, orig_tag)) = this.ptr_try_get_alloc_id(place.ptr) {
|
||||
let extra = this.get_alloc_extra(alloc_id)?;
|
||||
let stacked_borrows =
|
||||
extra.stacked_borrows.as_ref().expect("we should have Stacked Borrows data");
|
||||
let mut alloc_history = stacked_borrows.history.borrow_mut();
|
||||
alloc_history.log_creation(
|
||||
Some(orig_tag),
|
||||
new_tag,
|
||||
alloc_range(base_offset, Size::ZERO),
|
||||
&mut this.machine.current_span(),
|
||||
);
|
||||
}
|
||||
|
||||
trace!(
|
||||
"reborrow of size 0: {} reference {:?} derived from {:?} (pointee {})",
|
||||
kind,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,11 @@ error: Undefined Behavior: trying to reborrow <TAG> for SharedReadOnly permissio
|
|||
|
|
||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental
|
||||
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
|
||||
|
||||
help: <TAG> was created by a retag at offsets [0x0..0x0]
|
||||
--> $DIR/zst_slice.rs:LL:CC
|
||||
|
|
||||
LL | assert_eq!(*s.get_unchecked(1), 2);
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
= note: inside `core::slice::<impl [i32]>::get_unchecked::<usize>` at rustc_src/src/slice/mod.rs:LL:CC
|
||||
note: inside `main` at $DIR/zst_slice.rs:LL:CC
|
||||
--> $DIR/zst_slice.rs:LL:CC
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue