|
| 1 | +//@compile-flags: -Zmiri-tree-borrows |
| 2 | +// This test tests that TB's protector end semantics correctly ensure |
| 3 | +// that protected activated writes can be reordered. |
| 4 | +fn the_other_function(ref_to_fst_elem: &mut i32, ptr_to_vec: *mut i32) -> *mut i32 { |
| 5 | + // Activate the reference. Afterwards, we should be able to reorder arbitrary writes. |
| 6 | + *ref_to_fst_elem = 0; |
| 7 | + // Here is such an arbitrary write. |
| 8 | + // It could be moved down after the retag, in which case the `funky_ref` would be invalidated. |
| 9 | + // We need to ensure that the `funky_ptr` is unusable even if the write to `ref_to_fst_elem` |
| 10 | + // happens before the retag. |
| 11 | + *ref_to_fst_elem = 42; |
| 12 | + // this creates a reference that is Reserved Lazy on the first element (offset 0). |
| 13 | + // It does so by doing a proper retag on the second element (offset 1), which is fine |
| 14 | + // since nothing else happens at that offset, but the lazy init mechanism means it's |
| 15 | + // also reserved at offset 0, but not initialized. |
| 16 | + let funky_ptr_lazy_on_fst_elem = |
| 17 | + unsafe { (&mut *(ptr_to_vec.wrapping_add(1))) as *mut i32 }.wrapping_sub(1); |
| 18 | + // If we write to `ref_to_fst_elem` here, then any further access to `funky_ptr_lazy_on_fst_elem` would |
| 19 | + // definitely be UB. Since the compiler ought to be able to reorder the write of `42` above down to |
| 20 | + // here, that means we want this program to also be UB. |
| 21 | + return funky_ptr_lazy_on_fst_elem; |
| 22 | +} |
| 23 | + |
| 24 | +fn main() { |
| 25 | + let mut v = vec![0, 1]; |
| 26 | + // get a pointer to the root of the allocation |
| 27 | + // note that it's not important it's the actual root, what matters is that it's a parent |
| 28 | + // of both references that will be created |
| 29 | + let ptr_to_vec = v.as_mut_ptr(); |
| 30 | + let ref_to_fst_elem = unsafe { &mut *ptr_to_vec }; |
| 31 | + let funky_ptr_lazy_on_fst_elem = the_other_function(ref_to_fst_elem, ptr_to_vec); |
| 32 | + // now we try to use the funky lazy pointer. |
| 33 | + // It should be UB, since the write-on-protector-end should disable it. |
| 34 | + unsafe { println!("Value of funky: {}", *funky_ptr_lazy_on_fst_elem) } //~ ERROR: /reborrow through .* is forbidden/ |
| 35 | +} |
0 commit comments