some more compile-fail tests

This commit is contained in:
Ralf Jung 2018-10-19 18:38:23 +02:00
parent dd1558f337
commit fda03e9d7d
6 changed files with 65 additions and 0 deletions

View File

@ -1,3 +1,6 @@
// Validation changes why we fail
// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
// error-pattern: tried to deallocate Stack memory but gave Machine(Rust) as the kind
fn main() {

View File

@ -0,0 +1,11 @@
fn evil(x: &u32) {
let x : &mut u32 = unsafe { &mut *(x as *const _ as *mut _) };
*x = 42; // mutating shared ref without `UnsafeCell`
}
fn main() {
let target = 42;
let ref_ = ⌖
evil(ref_); // invalidates shared ref
let _x = *ref_; //~ ERROR Shr reference with non-reactivatable tag Frz
}

View File

@ -0,0 +1,8 @@
fn main() {
let target = 42;
// Make sure raw ptr with raw tag cannot mutate frozen location without breaking the shared ref.
let r#ref = ⌖ // freeze
let ptr = r#ref as *const _ as *mut _; // raw ptr, with raw tag
unsafe { *ptr = 42; }
let _val = *r#ref; //~ ERROR Shr reference with non-reactivatable tag Frz
}

View File

@ -0,0 +1,31 @@
// The compiler inserts some reborrows, enable optimizations to
// get rid of them.
// compile-flags: -Zmir-opt-level=1
use std::mem;
// This is an example of a piece of code that intuitively seems like we might
// want to reject it, but that doesn't turn out to be possible.
fn main() {
let target = 42;
// Make sure a cannot use a raw-tagged `&mut` pointing to a frozen location, not
// even to create a raw.
let r#ref = ⌖ // freeze
let ptr = r#ref as *const _ as *mut i32; // raw ptr, with raw tag
let mut_ref: &mut i32 = unsafe { mem::transmute(ptr) }; // &mut, with raw tag
// Now we have an &mut to a frozen location, but that is completely normal:
// We'd just unfreeze the location if we used it.
let bad_ptr = mut_ref as *mut i32; // even just creating this is like a use of `mut_ref`.
// That violates the location being frozen! However, we do not properly detect this:
// We first see a `&mut` with a `Raw` tag being deref'd for a frozen location,
// which can happen legitimately if the compiler optimized away an `&mut*` that
// turns a raw into a `&mut`. Next, we create a raw ref to a frozen location
// from a `Raw` tag, which can happen legitimately when interior mutability
// is involved.
let _val = *r#ref; // Make sure it is still frozen.
// We only actually unfreeze once we muteate through the bad pointer.
unsafe { *bad_ptr = 42 };
let _val = *r#ref; //~ ERROR Shr reference with non-reactivatable tag Frz
}

View File

@ -0,0 +1,5 @@
use std::mem;
fn main() {
let _x: &i32 = unsafe { mem::transmute(16usize) }; //~ ERROR tried to interpret some bytes as a pointer
}

View File

@ -0,0 +1,7 @@
use std::mem;
fn main() {
let val = 14;
let ptr = (&val as *const i32).wrapping_offset(1);
let _x: &i32 = unsafe { mem::transmute(ptr) }; //~ ERROR outside bounds of allocation
}