diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs index 33141306d64..a83dae8ae98 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -248,6 +248,13 @@ fn tb_reborrow( .insert(new_tag, protect); } + let alloc_kind = this.get_alloc_info(alloc_id).2; + if !matches!(alloc_kind, AllocKind::LiveData) { + // There's not actually any bytes here where accesses could even be tracked. + // Just produce the new provenance, nothing else to do. + return Ok(Some(Provenance::Concrete { alloc_id, tag: new_tag })); + } + let span = this.machine.current_span(); let alloc_extra = this.get_alloc_extra(alloc_id)?; let range = alloc_range(base_offset, ptr_size); diff --git a/src/tools/miri/tests/pass/strange_references.rs b/src/tools/miri/tests/pass/strange_references.rs new file mode 100644 index 00000000000..fe5ff93a9ca --- /dev/null +++ b/src/tools/miri/tests/pass/strange_references.rs @@ -0,0 +1,25 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows + +// Create zero-sized references to vtables and function data. +// Just make sure nothing explodes. + +use std::{mem, ptr}; + +fn check_ref(x: &()) { + let _ptr = ptr::addr_of!(*x); +} + +fn main() { + check_ref({ + // Create reference to a function. + let fnptr: fn(&()) = check_ref; + unsafe { mem::transmute(fnptr) } + }); + check_ref({ + // Create reference to a vtable. + let wideptr: &dyn Send = &0; + let fields: (&i32, &()) = unsafe { mem::transmute(wideptr) }; + fields.1 + }) +}