Merge remote-tracking branch 'origin/master' into rustup
This commit is contained in:
commit
957d18c343
@ -50,9 +50,9 @@ script:
|
||||
# test `cargo miri`
|
||||
cd cargo-miri-test &&
|
||||
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
cargo miri -q -- -Zmiri-start-fn
|
||||
cargo miri -q
|
||||
else
|
||||
cargo miri -q -- -Zmiri-start-fn >stdout.real 2>stderr.real &&
|
||||
cargo miri -q >stdout.real 2>stderr.real &&
|
||||
cat stdout.real stderr.real &&
|
||||
# Test `cargo miri` output. Not on mac because output redirecting doesn't
|
||||
# work. There is no error. It just stops CI.
|
||||
|
@ -99,6 +99,7 @@ fn main() {
|
||||
);
|
||||
match (test, &kind[..]) {
|
||||
(true, "test") => {
|
||||
// For test binaries we call `cargo rustc --test target -- <rustc args>`
|
||||
if let Err(code) = process(
|
||||
vec!["--test".to_string(), target.name].into_iter().chain(
|
||||
args,
|
||||
@ -109,6 +110,11 @@ fn main() {
|
||||
}
|
||||
}
|
||||
(true, "lib") => {
|
||||
// For libraries we call `cargo rustc -- --test <rustc args>`
|
||||
// Notice now that `--test` is a rustc arg rather than a cargo arg. This tells
|
||||
// rustc to build a test harness which calls all #[test] functions. We don't
|
||||
// use the harness since we execute each #[test] function's MIR ourselves before
|
||||
// compilation even completes, but this option is necessary to build the library.
|
||||
if let Err(code) = process(
|
||||
vec!["--".to_string(), "--test".to_string()].into_iter().chain(
|
||||
args,
|
||||
@ -119,6 +125,7 @@ fn main() {
|
||||
}
|
||||
}
|
||||
(false, "bin") => {
|
||||
// For ordinary binaries we call `cargo rustc --bin target -- <rustc args>`
|
||||
if let Err(code) = process(
|
||||
vec!["--bin".to_string(), target.name].into_iter().chain(
|
||||
args,
|
||||
|
@ -95,7 +95,7 @@ fn after_analysis<'a, 'tcx>(state: &mut CompileState<'a, 'tcx>) {
|
||||
if i.attrs.iter().any(|attr| attr.name() == "test") {
|
||||
let did = self.0.hir.body_owner_def_id(body_id);
|
||||
println!("running test: {}", self.0.def_path_debug_str(did));
|
||||
miri::eval_main(self.0, did, None, /*validate*/true);
|
||||
miri::eval_main(self.0, did, /*validate*/true);
|
||||
self.1.session.abort_if_errors();
|
||||
}
|
||||
}
|
||||
@ -106,7 +106,7 @@ fn after_analysis<'a, 'tcx>(state: &mut CompileState<'a, 'tcx>) {
|
||||
state.hir_crate.unwrap().visit_all_item_likes(&mut Visitor(tcx, state));
|
||||
} else if let Some((entry_node_id, _, _)) = *state.session.entry_fn.borrow() {
|
||||
let entry_def_id = tcx.hir.local_def_id(entry_node_id);
|
||||
miri::eval_main(tcx, entry_def_id, None, /*validate*/true);
|
||||
miri::eval_main(tcx, entry_def_id, /*validate*/true);
|
||||
|
||||
state.session.abort_if_errors();
|
||||
} else {
|
||||
|
@ -26,11 +26,6 @@ use std::path::PathBuf;
|
||||
struct MiriCompilerCalls {
|
||||
default: Box<RustcDefaultCalls>,
|
||||
|
||||
/// Whether to begin interpretation at the start_fn lang item or not.
|
||||
///
|
||||
/// If false, the interpretation begins at the `main` function.
|
||||
start_fn: bool,
|
||||
|
||||
/// Whether to enforce the validity invariant.
|
||||
validate: bool,
|
||||
}
|
||||
@ -90,10 +85,9 @@ impl<'a> CompilerCalls<'a> for MiriCompilerCalls {
|
||||
let this = *self;
|
||||
let mut control = this.default.build_controller(sess, matches);
|
||||
control.after_hir_lowering.callback = Box::new(after_hir_lowering);
|
||||
let start_fn = this.start_fn;
|
||||
let validate = this.validate;
|
||||
control.after_analysis.callback =
|
||||
Box::new(move |state| after_analysis(state, start_fn, validate));
|
||||
Box::new(move |state| after_analysis(state, validate));
|
||||
control.after_analysis.stop = Compilation::Stop;
|
||||
control
|
||||
}
|
||||
@ -109,7 +103,6 @@ fn after_hir_lowering(state: &mut CompileState) {
|
||||
|
||||
fn after_analysis<'a, 'tcx>(
|
||||
state: &mut CompileState<'a, 'tcx>,
|
||||
use_start_fn: bool,
|
||||
validate: bool,
|
||||
) {
|
||||
state.session.abort_if_errors();
|
||||
@ -134,7 +127,7 @@ fn after_analysis<'a, 'tcx>(
|
||||
"running test: {}",
|
||||
self.tcx.def_path_debug_str(did),
|
||||
);
|
||||
miri::eval_main(self.tcx, did, None, self.validate);
|
||||
miri::eval_main(self.tcx, did, self.validate);
|
||||
self.state.session.abort_if_errors();
|
||||
}
|
||||
}
|
||||
@ -147,13 +140,7 @@ fn after_analysis<'a, 'tcx>(
|
||||
);
|
||||
} else if let Some((entry_node_id, _, _)) = *state.session.entry_fn.borrow() {
|
||||
let entry_def_id = tcx.hir.local_def_id(entry_node_id);
|
||||
// Use start_fn lang item if we have -Zmiri-start-fn set
|
||||
let start_wrapper = if use_start_fn {
|
||||
Some(tcx.lang_items().start_fn().unwrap())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
miri::eval_main(tcx, entry_def_id, start_wrapper, validate);
|
||||
miri::eval_main(tcx, entry_def_id, validate);
|
||||
|
||||
state.session.abort_if_errors();
|
||||
} else {
|
||||
@ -231,14 +218,9 @@ fn main() {
|
||||
args.push(find_sysroot());
|
||||
}
|
||||
|
||||
let mut start_fn = false;
|
||||
let mut validate = true;
|
||||
args.retain(|arg| {
|
||||
match arg.as_str() {
|
||||
"-Zmiri-start-fn" => {
|
||||
start_fn = true;
|
||||
false
|
||||
},
|
||||
"-Zmiri-disable-validation" => {
|
||||
validate = false;
|
||||
false
|
||||
@ -251,7 +233,6 @@ fn main() {
|
||||
let result = rustc_driver::run(move || {
|
||||
rustc_driver::run_compiler(&args, Box::new(MiriCompilerCalls {
|
||||
default: Box::new(RustcDefaultCalls),
|
||||
start_fn,
|
||||
validate,
|
||||
}), None, None)
|
||||
});
|
||||
|
@ -1,11 +1,9 @@
|
||||
use rustc::ty;
|
||||
use rustc::ty::layout::{Align, LayoutOf, Size};
|
||||
use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::mir;
|
||||
use syntax::attr;
|
||||
|
||||
use std::mem;
|
||||
|
||||
use super::*;
|
||||
|
||||
pub trait EvalContextExt<'tcx, 'mir> {
|
||||
@ -19,8 +17,6 @@ pub trait EvalContextExt<'tcx, 'mir> {
|
||||
ret: mir::BasicBlock,
|
||||
) -> EvalResult<'tcx>;
|
||||
|
||||
fn resolve_path(&self, path: &[&str]) -> EvalResult<'tcx, ty::Instance<'tcx>>;
|
||||
|
||||
/// Emulate a function that should have MIR but does not.
|
||||
/// This is solely to support execution without full MIR.
|
||||
/// Fail if emulating this function is not supported.
|
||||
@ -643,40 +639,6 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for super::MiriEvalCo
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get an instance for a path.
|
||||
fn resolve_path(&self, path: &[&str]) -> EvalResult<'tcx, ty::Instance<'tcx>> {
|
||||
self.tcx
|
||||
.crates()
|
||||
.iter()
|
||||
.find(|&&krate| self.tcx.original_crate_name(krate) == path[0])
|
||||
.and_then(|krate| {
|
||||
let krate = DefId {
|
||||
krate: *krate,
|
||||
index: CRATE_DEF_INDEX,
|
||||
};
|
||||
let mut items = self.tcx.item_children(krate);
|
||||
let mut path_it = path.iter().skip(1).peekable();
|
||||
|
||||
while let Some(segment) = path_it.next() {
|
||||
for item in mem::replace(&mut items, Default::default()).iter() {
|
||||
if item.ident.name == *segment {
|
||||
if path_it.peek().is_none() {
|
||||
return Some(ty::Instance::mono(self.tcx.tcx, item.def.def_id()));
|
||||
}
|
||||
|
||||
items = self.tcx.item_children(item.def.def_id());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
.ok_or_else(|| {
|
||||
let path = path.iter().map(|&s| s.to_owned()).collect();
|
||||
EvalErrorKind::PathNotFound(path).into()
|
||||
})
|
||||
}
|
||||
|
||||
fn emulate_missing_fn(
|
||||
&mut self,
|
||||
path: String,
|
||||
@ -704,7 +666,7 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx, 'mir> for super::MiriEvalCo
|
||||
"std::io::_print" |
|
||||
"std::io::_eprint" => {
|
||||
warn!(
|
||||
"Ignoring output. To run programs that print, make sure you have a libstd with full MIR."
|
||||
"Ignoring output. To run programs that prints, make sure you have a libstd with full MIR."
|
||||
);
|
||||
}
|
||||
"std::thread::Builder::new" => {
|
||||
|
@ -1,13 +1,18 @@
|
||||
use super::{Scalar, ScalarMaybeUndef, EvalResult};
|
||||
use std::mem;
|
||||
|
||||
pub trait FalibleScalarExt {
|
||||
use rustc::ty;
|
||||
use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX};
|
||||
|
||||
use super::*;
|
||||
|
||||
pub trait ScalarExt {
|
||||
/// HACK: this function just extracts all bits if `defined != 0`
|
||||
/// Mainly used for args of C-functions and we should totally correctly fetch the size
|
||||
/// of their arguments
|
||||
fn to_bytes(self) -> EvalResult<'static, u128>;
|
||||
}
|
||||
|
||||
impl<Tag> FalibleScalarExt for Scalar<Tag> {
|
||||
impl<Tag> ScalarExt for Scalar<Tag> {
|
||||
fn to_bytes(self) -> EvalResult<'static, u128> {
|
||||
match self {
|
||||
Scalar::Bits { bits, size } => {
|
||||
@ -19,8 +24,49 @@ impl<Tag> FalibleScalarExt for Scalar<Tag> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Tag> FalibleScalarExt for ScalarMaybeUndef<Tag> {
|
||||
impl<Tag> ScalarExt for ScalarMaybeUndef<Tag> {
|
||||
fn to_bytes(self) -> EvalResult<'static, u128> {
|
||||
self.not_undef()?.to_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait EvalContextExt<'tcx> {
|
||||
fn resolve_path(&self, path: &[&str]) -> EvalResult<'tcx, ty::Instance<'tcx>>;
|
||||
}
|
||||
|
||||
|
||||
impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super::Evaluator<'tcx>> {
|
||||
/// Get an instance for a path.
|
||||
fn resolve_path(&self, path: &[&str]) -> EvalResult<'tcx, ty::Instance<'tcx>> {
|
||||
self.tcx
|
||||
.crates()
|
||||
.iter()
|
||||
.find(|&&krate| self.tcx.original_crate_name(krate) == path[0])
|
||||
.and_then(|krate| {
|
||||
let krate = DefId {
|
||||
krate: *krate,
|
||||
index: CRATE_DEF_INDEX,
|
||||
};
|
||||
let mut items = self.tcx.item_children(krate);
|
||||
let mut path_it = path.iter().skip(1).peekable();
|
||||
|
||||
while let Some(segment) = path_it.next() {
|
||||
for item in mem::replace(&mut items, Default::default()).iter() {
|
||||
if item.ident.name == *segment {
|
||||
if path_it.peek().is_none() {
|
||||
return Some(ty::Instance::mono(self.tcx.tcx, item.def.def_id()));
|
||||
}
|
||||
|
||||
items = self.tcx.item_children(item.def.def_id());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
.ok_or_else(|| {
|
||||
let path = path.iter().map(|&s| s.to_owned()).collect();
|
||||
EvalErrorKind::PathNotFound(path).into()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use rustc::mir::interpret::{EvalResult, PointerArithmetic};
|
||||
|
||||
use super::{
|
||||
PlaceTy, OpTy, Value, Scalar, ScalarMaybeUndef, Borrow,
|
||||
FalibleScalarExt, OperatorEvalContextExt
|
||||
ScalarExt, OperatorEvalContextExt
|
||||
};
|
||||
|
||||
pub trait EvalContextExt<'tcx> {
|
||||
|
17
src/lib.rs
17
src/lib.rs
@ -41,14 +41,14 @@ use operator::EvalContextExt as OperatorEvalContextExt;
|
||||
use intrinsic::EvalContextExt as IntrinsicEvalContextExt;
|
||||
use tls::{EvalContextExt as TlsEvalContextExt, TlsData};
|
||||
use range_map::RangeMap;
|
||||
use helpers::FalibleScalarExt;
|
||||
#[allow(unused_imports)] // FIXME rustc bug https://github.com/rust-lang/rust/issues/53682
|
||||
use helpers::{ScalarExt, EvalContextExt as HelpersEvalContextExt};
|
||||
use mono_hash_map::MonoHashMap;
|
||||
use stacked_borrows::{EvalContextExt as StackedBorEvalContextExt, Borrow};
|
||||
|
||||
pub fn create_ecx<'a, 'mir: 'a, 'tcx: 'mir>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
main_id: DefId,
|
||||
start_wrapper: Option<DefId>,
|
||||
validate: bool,
|
||||
) -> EvalResult<'tcx, EvalContext<'a, 'mir, 'tcx, Evaluator<'tcx>>> {
|
||||
let mut ecx = EvalContext::new(
|
||||
@ -67,8 +67,14 @@ pub fn create_ecx<'a, 'mir: 'a, 'tcx: 'mir>(
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(start_id) = start_wrapper {
|
||||
let main_ret_ty = ecx.tcx.fn_sig(main_id).output();
|
||||
let libstd_has_mir = {
|
||||
let rustc_panic = ecx.resolve_path(&["std", "panicking", "rust_panic"])?;
|
||||
ecx.load_mir(rustc_panic.def).is_ok()
|
||||
};
|
||||
|
||||
if libstd_has_mir {
|
||||
let start_id = tcx.lang_items().start_fn().unwrap();
|
||||
let main_ret_ty = tcx.fn_sig(main_id).output();
|
||||
let main_ret_ty = main_ret_ty.no_late_bound_regions().unwrap();
|
||||
let start_instance = ty::Instance::resolve(
|
||||
ecx.tcx.tcx,
|
||||
@ -143,10 +149,9 @@ pub fn create_ecx<'a, 'mir: 'a, 'tcx: 'mir>(
|
||||
pub fn eval_main<'a, 'tcx: 'a>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
main_id: DefId,
|
||||
start_wrapper: Option<DefId>,
|
||||
validate: bool,
|
||||
) {
|
||||
let mut ecx = create_ecx(tcx, main_id, start_wrapper, validate).expect("Couldn't create ecx");
|
||||
let mut ecx = create_ecx(tcx, main_id, validate).expect("Couldn't create ecx");
|
||||
|
||||
let res: EvalResult = (|| {
|
||||
ecx.run()?;
|
||||
|
@ -9,7 +9,6 @@ fn main() {
|
||||
unsafe {
|
||||
let x = Global.alloc(Layout::from_size_align_unchecked(1, 1)).unwrap();
|
||||
Global.realloc(x, Layout::from_size_align_unchecked(1, 1), 1).unwrap();
|
||||
let _z = *(x.as_ptr() as *mut u8); //~ ERROR constant evaluation error
|
||||
//~^ NOTE dangling pointer was dereferenced
|
||||
let _z = *(x.as_ptr() as *mut u8); //~ ERROR dangling pointer was dereferenced
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,7 @@ fn main() {
|
||||
let x_ptr: *mut u8 = &mut x[0];
|
||||
let y_ptr = x_ptr as *mut u64;
|
||||
unsafe {
|
||||
*y_ptr = 42; //~ ERROR constant evaluation error
|
||||
//~^ NOTE tried to access memory with alignment 1, but alignment
|
||||
*y_ptr = 42; //~ ERROR tried to access memory with alignment 1, but alignment
|
||||
}
|
||||
panic!("unreachable in miri");
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ fn main() {
|
||||
unsafe {
|
||||
std::intrinsics::assume(x < 10);
|
||||
std::intrinsics::assume(x > 1);
|
||||
std::intrinsics::assume(x > 42); //~ ERROR constant evaluation error
|
||||
//~^ NOTE `assume` argument was false
|
||||
std::intrinsics::assume(x > 42); //~ `assume` argument was false
|
||||
}
|
||||
}
|
||||
|
@ -28,11 +28,10 @@ fn mk_rec() -> Rec {
|
||||
fn is_u64_aligned(u: &Tag<u64>) -> bool {
|
||||
let p: usize = unsafe { mem::transmute(u) };
|
||||
let u64_align = std::mem::align_of::<u64>();
|
||||
return (p & (u64_align + 1)) == 0; //~ ERROR constant evaluation error
|
||||
//~^ NOTE a raw memory access tried to access part of a pointer value as raw bytes
|
||||
return (p & (u64_align + 1)) == 0; //~ ERROR a raw memory access tried to access part of a pointer value as raw bytes
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let x = mk_rec();
|
||||
assert!(is_u64_aligned(&x.t)); //~ NOTE inside call to `is_u64_aligned
|
||||
assert!(is_u64_aligned(&x.t));
|
||||
}
|
||||
|
@ -7,6 +7,5 @@ fn main() {
|
||||
std::mem::transmute::<&usize, &fn(i32)>(&b)
|
||||
};
|
||||
|
||||
(*g)(42) //~ ERROR constant evaluation error
|
||||
//~^ NOTE a memory access tried to interpret some bytes as a pointer
|
||||
(*g)(42) //~ ERROR a memory access tried to interpret some bytes as a pointer
|
||||
}
|
||||
|
@ -6,6 +6,5 @@ fn main() {
|
||||
std::mem::transmute::<usize, fn(i32)>(42)
|
||||
};
|
||||
|
||||
g(42) //~ ERROR constant evaluation error
|
||||
//~^ NOTE a memory access tried to interpret some bytes as a pointer
|
||||
g(42) //~ ERROR a memory access tried to interpret some bytes as a pointer
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ fn main() {
|
||||
let b = Box::new(42);
|
||||
&*b as *const i32
|
||||
};
|
||||
let x = unsafe { *p }; //~ ERROR constant evaluation error
|
||||
//~^ NOTE dangling pointer was dereferenced
|
||||
let x = unsafe { *p }; //~ ERROR dangling pointer was dereferenced
|
||||
panic!("this should never print: {}", x);
|
||||
}
|
||||
|
@ -11,6 +11,5 @@
|
||||
#![allow(const_err)]
|
||||
|
||||
fn main() {
|
||||
let _n = 1 / 0; //~ ERROR constant evaluation error
|
||||
//~^ NOTE attempt to divide by zero
|
||||
let _n = 1 / 0; //~ ERROR attempt to divide by zero
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ fn main() {
|
||||
let x = box 42;
|
||||
unsafe {
|
||||
let f = std::mem::transmute::<Box<i32>, fn()>(x);
|
||||
f() //~ ERROR constant evaluation error
|
||||
//~^ NOTE tried to treat a memory pointer as a function pointer
|
||||
f() //~ ERROR tried to treat a memory pointer as a function pointer
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,5 @@ fn main() {
|
||||
let y : *mut u8 = unsafe { mem::transmute(x) };
|
||||
let y = y.wrapping_offset(1);
|
||||
let x : fn() = unsafe { mem::transmute(y) };
|
||||
x(); //~ ERROR constant evaluation error
|
||||
//~^ NOTE tried to use a function pointer after offsetting it
|
||||
x(); //~ ERROR tried to use a function pointer after offsetting it
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
fn main() {
|
||||
let x = &1; // the `&1` is promoted to a constant, but it used to be that only the pointer is marked static, not the pointee
|
||||
let y = unsafe { &mut *(x as *const i32 as *mut i32) };
|
||||
*y = 42; //~ ERROR constant evaluation error
|
||||
//~^ NOTE tried to modify constant memory
|
||||
*y = 42; //~ ERROR tried to modify constant memory
|
||||
assert_eq!(*x, 42);
|
||||
}
|
||||
|
@ -7,8 +7,7 @@
|
||||
fn main() {
|
||||
let y = &5;
|
||||
let x: ! = unsafe {
|
||||
*(y as *const _ as *const !) //~ ERROR constant evaluation error
|
||||
//~^ NOTE entered unreachable code
|
||||
*(y as *const _ as *const !) //~ ERROR entered unreachable code
|
||||
};
|
||||
f(x)
|
||||
}
|
||||
|
@ -8,8 +8,7 @@
|
||||
enum Void {}
|
||||
|
||||
fn f(v: Void) -> ! {
|
||||
match v {} //~ ERROR constant evaluation error
|
||||
//~^ NOTE entered unreachable code
|
||||
match v {} //~ ERROR entered unreachable code
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -1,6 +1,5 @@
|
||||
fn main() {
|
||||
let v: Vec<u8> = vec![1, 2];
|
||||
let x = unsafe { *v.as_ptr().wrapping_offset(5) }; //~ ERROR constant evaluation error
|
||||
//~^ NOTE which has size 2
|
||||
let x = unsafe { *v.as_ptr().wrapping_offset(5) }; //~ ERROR outside bounds of allocation
|
||||
panic!("this should never print: {}", x);
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
fn main() {
|
||||
let v: Vec<u8> = vec![1, 2];
|
||||
let x = unsafe { *v.as_ptr().wrapping_offset(5) }; //~ ERROR constant evaluation error
|
||||
//~^ NOTE outside bounds of allocation
|
||||
let x = unsafe { *v.as_ptr().wrapping_offset(5) }; //~ ERROR outside bounds of allocation
|
||||
panic!("this should never print: {}", x);
|
||||
}
|
||||
|
@ -12,6 +12,5 @@
|
||||
#![allow(const_err)]
|
||||
|
||||
fn main() {
|
||||
let _n = 2i64 << -1; //~ ERROR constant evaluation error
|
||||
//~^ NOTE attempt to shift left with overflow
|
||||
let _n = 2i64 << -1; //~ ERROR attempt to shift left with overflow
|
||||
}
|
||||
|
@ -12,6 +12,5 @@
|
||||
|
||||
fn main() {
|
||||
// Make sure we catch overflows that would be hidden by first casting the RHS to u32
|
||||
let _n = 1i64 >> (u32::max_value() as i64 + 1); //~ ERROR constant evaluation error
|
||||
//~^ NOTE attempt to shift right with overflow
|
||||
let _n = 1i64 >> (u32::max_value() as i64 + 1); //~ ERROR attempt to shift right with overflow
|
||||
}
|
||||
|
@ -11,6 +11,5 @@
|
||||
#![allow(exceeding_bitshifts)]
|
||||
|
||||
fn main() {
|
||||
let _n = 1i64 >> 64; //~ ERROR constant evaluation error
|
||||
//~^ NOTE attempt to shift right with overflow
|
||||
let _n = 1i64 >> 64; //~ ERROR attempt to shift right with overflow
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ fn main() {
|
||||
// "attempted to interpret some raw bytes as a pointer address" instead of
|
||||
// "attempted to read undefined bytes"
|
||||
}
|
||||
let x = *p; //~ ERROR constant evaluation error
|
||||
//~^ NOTE attempted to read undefined bytes
|
||||
let x = *p; //~ ERROR attempted to read undefined bytes
|
||||
panic!("this should never print: {}", x);
|
||||
}
|
||||
|
@ -3,6 +3,5 @@ fn main() {
|
||||
let y = &x;
|
||||
let z = &y as *const &i32 as *const u8;
|
||||
// the deref fails, because we are reading only a part of the pointer
|
||||
let _ = unsafe { *z }; //~ ERROR constant evaluation error
|
||||
//~^ NOTE tried to access part of a pointer value as raw bytes
|
||||
let _ = unsafe { *z }; //~ ERROR tried to access part of a pointer value as raw bytes
|
||||
}
|
||||
|
@ -1,8 +1,7 @@
|
||||
fn main() {
|
||||
let x: *const u8 = &1;
|
||||
let y: *const u8 = &2;
|
||||
if x < y { //~ ERROR constant evaluation error
|
||||
//~^ NOTE attempted to do invalid arithmetic on pointers
|
||||
if x < y { //~ ERROR attempted to do invalid arithmetic on pointers
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,7 @@ fn main() {
|
||||
let x = &1;
|
||||
// Casting down to u8 and back up to a pointer loses too much precision; this must not work.
|
||||
let x = x as *const i32;
|
||||
let x = x as u8; //~ ERROR constant evaluation error
|
||||
//~^ NOTE a raw memory access tried to access part of a pointer value as raw bytes
|
||||
let x = x as u8; //~ ERROR a raw memory access tried to access part of a pointer value as raw bytes
|
||||
let x = x as *const i32;
|
||||
let _ = unsafe { *x };
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ fn main() {
|
||||
// starts 1 byte to the right, so using it would actually be wrong!
|
||||
let d_alias = &mut w.data as *mut _ as *mut *const u8;
|
||||
unsafe {
|
||||
let _x = *d_alias; //~ ERROR constant evaluation error
|
||||
//~^ NOTE tried to access part of a pointer value as raw bytes
|
||||
let _x = *d_alias; //~ ERROR tried to access part of a pointer value as raw bytes
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,5 @@ fn main() {
|
||||
y: 99,
|
||||
};
|
||||
let p = unsafe { &foo.x };
|
||||
let i = *p; //~ ERROR constant evaluation error
|
||||
//~^ NOTE tried to access memory with alignment 1, but alignment 4 is required
|
||||
let i = *p; //~ ERROR tried to access memory with alignment 1, but alignment 4 is required
|
||||
}
|
||||
|
@ -3,8 +3,7 @@ static X: usize = 5;
|
||||
#[allow(mutable_transmutes)]
|
||||
fn main() {
|
||||
unsafe {
|
||||
*std::mem::transmute::<&usize, &mut usize>(&X) = 6; //~ ERROR constant evaluation error
|
||||
//~^ NOTE tried to modify constant memory
|
||||
*std::mem::transmute::<&usize, &mut usize>(&X) = 6; //~ ERROR tried to modify constant memory
|
||||
assert_eq!(X, 6);
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ use std::mem::transmute;
|
||||
fn main() {
|
||||
unsafe {
|
||||
let s = "this is a test";
|
||||
transmute::<&[u8], &mut [u8]>(s.as_bytes())[4] = 42; //~ ERROR constant evaluation error
|
||||
//~^ NOTE tried to modify constant memory
|
||||
transmute::<&[u8], &mut [u8]>(s.as_bytes())[4] = 42; //~ ERROR tried to modify constant memory
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ use std::mem::transmute;
|
||||
fn main() {
|
||||
unsafe {
|
||||
let bs = b"this is a test";
|
||||
transmute::<&[u8], &mut [u8]>(bs)[4] = 42; //~ ERROR constant evaluation error
|
||||
//~^ NOTE tried to modify constant memory
|
||||
transmute::<&[u8], &mut [u8]>(bs)[4] = 42; //~ ERROR tried to modify constant memory
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,5 @@ fn main() {
|
||||
assert_eq!(byte, 0);
|
||||
}
|
||||
let v = unsafe { *z.offset(first_undef) };
|
||||
if v == 0 {} //~ ERROR constant evaluation error
|
||||
//~^ NOTE attempted to read undefined bytes
|
||||
if v == 0 {} //~ ERROR attempted to read undefined bytes
|
||||
}
|
||||
|
@ -10,6 +10,5 @@ fn main() {
|
||||
let bad = unsafe {
|
||||
std::mem::transmute::<&[u8], [u8; 8]>(&[1u8])
|
||||
};
|
||||
let _ = bad[0] + bad[bad.len()-1]; //~ ERROR constant evaluation error
|
||||
//~^ NOTE a raw memory access tried to access part of a pointer value as raw bytes
|
||||
let _ = bad[0] + bad[bad.len()-1]; //~ ERROR a raw memory access tried to access part of a pointer value as raw bytes
|
||||
}
|
||||
|
@ -7,6 +7,5 @@ fn main() {
|
||||
let bad = unsafe {
|
||||
std::mem::transmute::<u64, &[u8]>(42)
|
||||
};
|
||||
bad[0]; //~ ERROR constant evaluation error
|
||||
//~^ NOTE index out of bounds: the len is 0 but the index is 0
|
||||
bad[0]; //~ ERROR index out of bounds: the len is 0 but the index is 0
|
||||
}
|
||||
|
@ -2,6 +2,5 @@ fn main() {
|
||||
let x = &2u16;
|
||||
let x = x as *const _ as *const u32;
|
||||
// This must fail because alignment is violated
|
||||
let _x = unsafe { *x }; //~ ERROR constant evaluation error
|
||||
//~^ NOTE tried to access memory with alignment 2, but alignment 4 is required
|
||||
let _x = unsafe { *x }; //~ ERROR tried to access memory with alignment 2, but alignment 4 is required
|
||||
}
|
||||
|
@ -3,6 +3,5 @@ fn main() {
|
||||
let x = x as *const _ as *const *const u8;
|
||||
// This must fail because alignment is violated. Test specifically for loading pointers, which have special code
|
||||
// in miri's memory.
|
||||
let _x = unsafe { *x }; //~ ERROR constant evaluation error
|
||||
//~^ NOTE tried to access memory with alignment 2, but alignment
|
||||
let _x = unsafe { *x }; //~ ERROR tried to access memory with alignment 2, but alignment
|
||||
}
|
||||
|
@ -2,6 +2,5 @@ fn main() {
|
||||
let x = &2u16;
|
||||
let x = x as *const _ as *const [u32; 0];
|
||||
// This must fail because alignment is violated. Test specifically for loading ZST.
|
||||
let _x = unsafe { *x }; //~ ERROR constant evaluation error
|
||||
//~^ NOTE tried to access memory with alignment 2, but alignment 4 is required
|
||||
let _x = unsafe { *x }; //~ ERROR tried to access memory with alignment 2, but alignment 4 is required
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
fn main() {
|
||||
let v: Vec<u8> = Vec::with_capacity(10);
|
||||
let undef = unsafe { *v.get_unchecked(5) };
|
||||
let x = undef + 1; //~ ERROR: error
|
||||
//~^ NOTE attempted to read undefined bytes
|
||||
let x = undef + 1; //~ ERROR attempted to read undefined bytes
|
||||
panic!("this should never print: {}", x);
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
fn main() {
|
||||
let p = 44 as *const i32;
|
||||
let x = unsafe { *p }; //~ ERROR constant evaluation error
|
||||
//~^ NOTE a memory access tried to interpret some bytes as a pointer
|
||||
let x = unsafe { *p }; //~ ERROR a memory access tried to interpret some bytes as a pointer
|
||||
panic!("this should never print: {}", x);
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
fn main() {
|
||||
let x = &() as *const () as *const i32;
|
||||
let _ = unsafe { *x }; //~ ERROR constant evaluation error
|
||||
//~^ NOTE tried to access memory with alignment 1, but alignment 4 is required
|
||||
let _ = unsafe { *x }; //~ ERROR tried to access memory with alignment 1, but alignment 4 is required
|
||||
}
|
||||
|
@ -101,9 +101,6 @@ fn miri_pass(sysroot: &Path, path: &str, target: &str, host: &str, need_fullmir:
|
||||
let mut flags = Vec::new();
|
||||
flags.push(format!("--sysroot {}", sysroot.display()));
|
||||
flags.push("-Dwarnings -Dunused".to_owned()); // overwrite the -Aunused in compiletest-rs
|
||||
if have_fullmir() {
|
||||
flags.push("-Zmiri-start-fn".to_owned());
|
||||
}
|
||||
if opt {
|
||||
// FIXME: Using level 1 (instead of 3) for now, as the optimizer is pretty broken
|
||||
// and crashes...
|
||||
|
Loading…
x
Reference in New Issue
Block a user