blob: f1ca1b51aa8573c061237bffaf7a067dafb1151a [file] [log] [blame] [edit]
//@revisions: default uniq
// We disable the GC for this test because it would change what is printed.
//@compile-flags: -Zmiri-tree-borrows -Zmiri-provenance-gc=0
//@[uniq]compile-flags: -Zmiri-unique-is-unique
#![feature(ptr_internals)]
#[path = "../../utils/mod.rs"]
#[macro_use]
mod utils;
use core::ptr::Unique;
// Check general handling of Unique
fn main() {
unsafe {
let base = &mut 5u8;
let alloc_id = alloc_id!(base);
name!(base);
let raw = &mut *base as *mut u8;
name!(raw);
// We create a `Unique` and expect it to have a fresh tag
// and uninitialized permissions.
let uniq = Unique::new_unchecked(raw);
// With `-Zmiri-unique-is-unique`, `Unique::as_ptr` (which is called by
// `Vec::as_ptr`) generates pointers with a fresh tag, so to name the actual
// `base` pointer we care about we have to walk up the tree a bit.
//
// We care about naming this specific parent tag because it is the one
// that stays `Active` during the entire execution, unlike the leaves
// that will be invalidated the next time `as_ptr` is called.
//
// (We name it twice so that we have an indicator in the output of
// whether we got the distance correct:
// If the output shows
//
// |- <XYZ: uniq>
// '- <XYZ: uniq>
//
// then `nth_parent` is not big enough.
// The correct value for `nth_parent` should be the minimum
// integer for which the output shows
//
// '- <XYZ: uniq, uniq>
// )
//
// Ultimately we want pointers obtained through independent
// calls of `as_ptr` to be able to alias, which will probably involve
// a new permission that allows aliasing when there is no protector.
let nth_parent = if cfg!(uniq) { 2 } else { 0 };
name!(uniq.as_ptr()=>nth_parent, "uniq");
name!(uniq.as_ptr()=>nth_parent, "uniq");
print_state!(alloc_id);
// We can activate the Unique and use it mutably.
*uniq.as_ptr() = 42;
print_state!(alloc_id);
// Write through the raw parent disables the Unique
*raw = 42;
print_state!(alloc_id);
}
}