pub use rustc_mir::interpret::*;
-pub use rustc_mir::interpret::{self, AllocMap}; // resolve ambiguity
+pub use rustc_mir::interpret::{self, AllocMap, PlaceTy}; // resolve ambiguity
mod fn_call;
mod operator;
Ok(Pointer::new_with_tag(ptr.alloc_id, ptr.offset, tag))
}
}
+
+ #[inline(always)]
+ fn retag(
+ ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
+ fn_entry: bool,
+ place: PlaceTy<'tcx, Borrow>,
+ ) -> EvalResult<'tcx> {
+ if !ecx.tcx.sess.opts.debugging_opts.mir_emit_retag || !ecx.machine.validate {
+ // No tracking, or no retagging. This is possible because a dependency of ours might be
+ // called with different flags than we are,
+ return Ok(())
+ }
+ ecx.retag(fn_entry, place)
+ }
}
use super::{
MemoryAccess, MemoryKind, MiriMemoryKind, RangeMap, EvalResult, AllocId,
- Pointer,
+ Pointer, PlaceTy,
};
pub type Timestamp = u64;
id: AllocId,
kind: MemoryKind<MiriMemoryKind>,
) -> Borrow;
+
+ fn retag(
+ &mut self,
+ fn_entry: bool,
+ place: PlaceTy<'tcx, Borrow>
+ ) -> EvalResult<'tcx>;
}
impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'a, 'mir, 'tcx> {
alloc.extra.first_borrow(mut_borrow, size);
Borrow::Mut(mut_borrow)
}
+
+ fn retag(
+ &mut self,
+ _fn_entry: bool,
+ _place: PlaceTy<'tcx, Borrow>
+ ) -> EvalResult<'tcx> {
+ // TODO do something
+ Ok(())
+ }
}
// Validation changes why we fail
-// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
+// compile-flags: -Zmiri-disable-validation
// error-pattern: tried to deallocate Stack memory but gave Machine(Rust) as the kind
// Validation makes this fail in the wrong place
-// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
+// compile-flags: -Zmiri-disable-validation
fn main() {
let b = Box::new(42);
// Validation makes this fail in the wrong place
-// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
+// compile-flags: -Zmiri-disable-validation
fn main() {
let g = unsafe {
// Validation makes this fail in the wrong place
-// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
+// compile-flags: -Zmiri-disable-validation
#![feature(box_syntax)]
// Validation makes this fail in the wrong place
-// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
+// compile-flags: -Zmiri-disable-validation
use std::mem;
--- /dev/null
+// Validation makes this fail in the wrong place
+// compile-flags: -Zmiri-disable-validation
+
+fn main() {
+ let b = unsafe { std::mem::transmute::<u8, bool>(2) };
+ let _x = b == true; //~ ERROR invalid boolean value read
+}
+++ /dev/null
-// Validation makes this fail in the wrong place
-// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
-
-fn main() {
- let b = unsafe { std::mem::transmute::<u8, bool>(2) };
- let _x = b == true; //~ ERROR invalid boolean value read
-}
--- /dev/null
+// Validation makes this fail in the wrong place
+// compile-flags: -Zmiri-disable-validation
+
+fn main() {
+ assert!(std::char::from_u32(-1_i32 as u32).is_none());
+ let c = unsafe { std::mem::transmute::<i32, char>(-1) };
+ let _x = c == 'x'; //~ ERROR tried to interpret an invalid 32-bit value as a char
+}
+++ /dev/null
-// Validation makes this fail in the wrong place
-// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
-
-fn main() {
- assert!(std::char::from_u32(-1_i32 as u32).is_none());
- let c = unsafe { std::mem::transmute::<i32, char>(-1) };
- let _x = c == 'x'; //~ ERROR tried to interpret an invalid 32-bit value as a char
-}
--- /dev/null
+// Validation makes this fail in the wrong place
+// compile-flags: -Zmiri-disable-validation
+
+// error-pattern: invalid enum discriminant
+
+use std::mem;
+
+#[repr(C)]
+pub enum Foo {
+ A, B, C, D
+}
+
+fn main() {
+ let f = unsafe { std::mem::transmute::<i32, Foo>(42) };
+ let _ = mem::discriminant(&f);
+}
+++ /dev/null
-// Validation makes this fail in the wrong place
-// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
-
-// error-pattern: invalid enum discriminant
-
-use std::mem;
-
-#[repr(C)]
-pub enum Foo {
- A, B, C, D
-}
-
-fn main() {
- let f = unsafe { std::mem::transmute::<i32, Foo>(42) };
- let _ = mem::discriminant(&f);
-}
// This should fail even without validation
-// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
+// compile-flags: -Zmiri-disable-validation
#![feature(never_type)]
#![allow(unreachable_code)]
// This should fail even without validation
-// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
+// compile-flags: -Zmiri-disable-validation
#![feature(never_type)]
#![allow(unreachable_code)]
// This should fail even without validation
-// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
+// compile-flags: -Zmiri-disable-validation
#![feature(never_type)]
#![allow(unreachable_code)]
-// FIXME: Something in panic handling fails validation with full-MIR
-// compile-flags: -Zmir-emit-validate=0
//error-pattern: the evaluated program panicked
fn main() {
// This should fail even without validation
-// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
+// compile-flags: -Zmiri-disable-validation
#![allow(dead_code, unused_variables)]
--- /dev/null
+static X: usize = 5;
+
+#[allow(mutable_transmutes)]
+fn main() {
+ let _x = unsafe {
+ std::mem::transmute::<&usize, &mut usize>(&X) //~ ERROR mutable reference with frozen tag
+ };
+}
// Validation detects that we are casting & to &mut and so it changes why we fail
-// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
+// compile-flags: -Zmiri-disable-validation
static X: usize = 5;
// Validation detects that we are casting & to &mut and so it changes why we fail
-// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
+// compile-flags: -Zmiri-disable-validation
use std::mem::transmute;
// Validation detects that we are casting & to &mut and so it changes why we fail
-// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
+// compile-flags: -Zmiri-disable-validation
use std::mem::transmute;
// This should fail even without validation
-// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
+// compile-flags: -Zmiri-disable-validation
static mut LEAK: usize = 0;
// This should fail even without validation
-// compile-flags: -Zmir-emit-validate=0
+// compile-flags: -Zmiri-disable-validation
fn main() {
#[cfg(target_pointer_width="64")]
// This should fail even without validation
-// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
+// compile-flags: -Zmiri-disable-validation
fn main() {
let x = &2u16;
// This should fail even without validation
-// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
+// compile-flags: -Zmiri-disable-validation
fn main() {
let x = &2u16;
-// This should fail even without validation
-// compile-flags: -Zmir-emit-validate=0
-
fn main() {
let v: Vec<u8> = Vec::with_capacity(10);
let undef = unsafe { *v.get_unchecked(5) };
--- /dev/null
+#![feature(box_syntax)]
+
+fn main() {
+ let x = box 42;
+ unsafe {
+ let _f = std::mem::transmute::<Box<i32>, fn()>(x); //~ ERROR encountered a pointer, but expected a function pointer
+ }
+}
--- /dev/null
+use std::mem;
+
+fn f() {}
+
+fn main() {
+ let x : fn() = f;
+ let y : *mut u8 = unsafe { mem::transmute(x) };
+ let y = y.wrapping_offset(1);
+ let _x : fn() = unsafe { mem::transmute(y) }; //~ ERROR encountered a potentially NULL pointer
+}
let mut flags = Vec::new();
flags.push(format!("--sysroot {}", sysroot.display()));
flags.push("-Dwarnings -Dunused".to_owned()); // overwrite the -Aunused in compiletest-rs
- flags.push("-Zmir-emit-validate=1".to_owned());
if opt {
// Optimizing too aggressivley makes UB detection harder, but test at least
// the default value.
+ // FIXME: Opt level 3 ICEs during stack trace generation.
flags.push("-Zmir-opt-level=1".to_owned());
- } else {
- flags.push("-Zmir-opt-level=0".to_owned());
}
let mut config = compiletest::Config::default().tempdir();
let mut flags = Vec::new();
flags.push(format!("--sysroot {}", sysroot.display()));
flags.push("-Dwarnings -Dunused".to_owned()); // overwrite the -Aunused in compiletest-rs
- flags.push("-Zmir-emit-validate=1".to_owned());
if opt {
flags.push("-Zmir-opt-level=3".to_owned());
- } else {
- flags.push("-Zmir-opt-level=0".to_owned());
}
let mut config = compiletest::Config::default().tempdir();
-// Moving around undef is not allowed by validation
-// compile-flags: -Zmir-emit-validate=0
-
struct Foo {
_inner: i32,
}
-// compile-flags: -Zmir-emit-validate=0
#![allow(dead_code)]
#![feature(unsize, coerce_unsized)]
-// FIXME: Disable validation until we figure out how to handle recursive statics.
-// compile-flags: -Zmir-emit-validate=0
-
struct S(&'static S);
static S1: S = S(&S2);
static S2: S = S(&S1);
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// FIXME: We handle uninitialized storage here, which currently makes validation fail.
-// compile-flags: -Zmir-emit-validate=0
-
//ignore-windows: Uses POSIX APIs
#![feature(libc)]
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// compile-flags: -C debug-assertions
-
use std::slice;
fn foo<T>(v: &[T]) -> Option<&[T]> {