diff --git a/benches/fibonacci_helper.rs b/benches/fibonacci_helper.rs index cddfff9c2c..004000e70e 100644 --- a/benches/fibonacci_helper.rs +++ b/benches/fibonacci_helper.rs @@ -1,7 +1,3 @@ -#![feature(custom_attribute)] -#![allow(unused_attributes)] - -#[miri_run] #[inline(never)] pub fn main() { assert_eq!(fib(10), 55); diff --git a/benches/fibonacci_helper_iterative.rs b/benches/fibonacci_helper_iterative.rs index 486d8c2e8a..59283be482 100644 --- a/benches/fibonacci_helper_iterative.rs +++ b/benches/fibonacci_helper_iterative.rs @@ -1,7 +1,3 @@ -#![feature(custom_attribute)] -#![allow(unused_attributes)] - -#[miri_run] #[inline(never)] pub fn main() { assert_eq!(fib(10), 55); diff --git a/benches/smoke_helper.rs b/benches/smoke_helper.rs index e8691f244c..ef05b044cd 100644 --- a/benches/smoke_helper.rs +++ b/benches/smoke_helper.rs @@ -1,7 +1,3 @@ -#![feature(custom_attribute)] -#![allow(unused_attributes)] - -#[miri_run] #[inline(never)] pub fn main() { } diff --git a/src/bin/miri.rs b/src/bin/miri.rs index f14eb39439..8ec691dbbb 100644 --- a/src/bin/miri.rs +++ b/src/bin/miri.rs @@ -19,7 +19,6 @@ use miri::{ use rustc::session::Session; use rustc_driver::{driver, CompilerCalls}; use rustc::ty::{TyCtxt, subst}; -use rustc::mir::mir_map::MirMap; use rustc::hir::def_id::DefId; struct MiriCompilerCalls; @@ -34,57 +33,46 @@ impl<'a> CompilerCalls<'a> for MiriCompilerCalls { control.after_analysis.callback = Box::new(|state| { state.session.abort_if_errors(); - interpret_start_points(state.tcx.unwrap(), state.mir_map.unwrap()); - }); - - control - } -} - + let tcx = state.tcx.unwrap(); + let mir_map = state.mir_map.unwrap(); + + let (node_id, span) = state.session.entry_fn.borrow().expect("no main or start function found"); + debug!("found `main` function at: {:?}", span); + + let mir = mir_map.map.get(&node_id).expect("no mir for main function"); + let def_id = tcx.map.local_def_id(node_id); + let mut ecx = EvalContext::new(tcx, mir_map); + let substs = tcx.mk_substs(subst::Substs::empty()); + let return_ptr = ecx.alloc_ret_ptr(mir.return_ty, substs).expect("main function should not be diverging"); + + ecx.push_stack_frame(def_id, mir.span, CachedMir::Ref(mir), substs, Some(return_ptr)); + + if mir.arg_decls.len() == 2 { + // start function + let ptr_size = ecx.memory().pointer_size; + let nargs = ecx.memory_mut().allocate(ptr_size); + ecx.memory_mut().write_usize(nargs, 0).unwrap(); + let args = ecx.memory_mut().allocate(ptr_size); + ecx.memory_mut().write_usize(args, 0).unwrap(); + ecx.frame_mut().locals[0] = nargs; + ecx.frame_mut().locals[1] = args; + } -fn interpret_start_points<'a, 'tcx>( - tcx: TyCtxt<'a, 'tcx, 'tcx>, - mir_map: &MirMap<'tcx>, -) { - let initial_indentation = ::log_settings::settings().indentation; - for (&id, mir) in &mir_map.map { - for attr in tcx.map.attrs(id) { - use syntax::attr::AttrMetaMethods; - if attr.check_name("miri_run") { - let item = tcx.map.expect_item(id); - - ::log_settings::settings().indentation = initial_indentation; - - debug!("Interpreting: {}", item.name); - - let mut ecx = EvalContext::new(tcx, mir_map); - let substs = tcx.mk_substs(subst::Substs::empty()); - let return_ptr = ecx.alloc_ret_ptr(mir.return_ty, substs); - - ecx.push_stack_frame(tcx.map.local_def_id(id), mir.span, CachedMir::Ref(mir), substs, return_ptr); - - loop { - match step(&mut ecx) { - Ok(true) => {} - Ok(false) => { - match return_ptr { - Some(ptr) => if log_enabled!(::log::LogLevel::Debug) { - ecx.memory().dump(ptr.alloc_id); - }, - None => warn!("diverging function returned"), - } - break; - } - // FIXME: diverging functions can end up here in some future miri - Err(e) => { - report(tcx, &ecx, e); - break; - } + loop { + match step(&mut ecx) { + Ok(true) => {} + Ok(false) => break, + // FIXME: diverging functions can end up here in some future miri + Err(e) => { + report(tcx, &ecx, e); + break; } } } - } + }); + + control } } diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index 1b0b416e0e..89a3b2f593 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -154,6 +154,10 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { &self.memory } + pub fn memory_mut(&mut self) -> &mut Memory<'tcx> { + &mut self.memory + } + pub fn stack(&self) -> &[Frame] { &self.stack } @@ -1373,7 +1377,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { self.stack.last().expect("no call frames exist") } - fn frame_mut(&mut self) -> &mut Frame<'a, 'tcx> { + pub fn frame_mut(&mut self) -> &mut Frame<'a, 'tcx> { self.stack.last_mut().expect("no call frames exist") } diff --git a/tests/compile-fail/dangling_pointer_deref.rs b/tests/compile-fail/dangling_pointer_deref.rs new file mode 100644 index 0000000000..0ede7c96f0 --- /dev/null +++ b/tests/compile-fail/dangling_pointer_deref.rs @@ -0,0 +1,8 @@ +fn main() { + let p = { + let b = Box::new(42); + &*b as *const i32 + }; + let x = unsafe { *p }; //~ ERROR: dangling pointer was dereferenced + panic!("this should never print: {}", x); +} diff --git a/tests/compile-fail/deref_fn_ptr.rs b/tests/compile-fail/deref_fn_ptr.rs index 52c7c2b8f9..c1eaf7eaa6 100644 --- a/tests/compile-fail/deref_fn_ptr.rs +++ b/tests/compile-fail/deref_fn_ptr.rs @@ -1,13 +1,8 @@ -#![feature(custom_attribute)] -#![allow(dead_code, unused_attributes)] - fn f() {} -#[miri_run] -fn deref_fn_ptr() -> i32 { - unsafe { +fn main() { + let x: i32 = unsafe { *std::mem::transmute::(f) //~ ERROR: tried to dereference a function pointer - } + }; + panic!("this should never print: {}", x); } - -fn main() {} diff --git a/tests/compile-fail/errors.rs b/tests/compile-fail/errors.rs deleted file mode 100644 index 0cadd76ccc..0000000000 --- a/tests/compile-fail/errors.rs +++ /dev/null @@ -1,62 +0,0 @@ -#![feature(custom_attribute)] -#![allow(dead_code, unused_attributes)] - -#[miri_run] -fn overwriting_part_of_relocation_makes_the_rest_undefined() -> i32 { - let mut p = &42; - unsafe { - let ptr: *mut _ = &mut p; - *(ptr as *mut u8) = 123; // if we ever support 8 bit pointers, this is gonna cause - // "attempted to interpret some raw bytes as a pointer address" instead of - // "attempted to read undefined bytes" - } - *p //~ ERROR: attempted to read undefined bytes -} - -#[miri_run] -fn pointers_to_different_allocations_are_unorderable() -> bool { - let x: *const u8 = &1; - let y: *const u8 = &2; - x < y //~ ERROR: attempted to do math or a comparison on pointers into different allocations -} - -#[miri_run] -fn invalid_bool() -> u8 { - let b = unsafe { std::mem::transmute::(2) }; - if b { 1 } else { 2 } //~ ERROR: invalid boolean value read -} - -#[miri_run] -fn undefined_byte_read() -> u8 { - let v: Vec = Vec::with_capacity(10); - let undef = unsafe { *v.get_unchecked(5) }; - undef + 1 //~ ERROR: attempted to read undefined bytes -} - -#[miri_run] -fn out_of_bounds_read() -> u8 { - let v: Vec = vec![1, 2]; - unsafe { *v.get_unchecked(5) } //~ ERROR: memory access of 5..6 outside bounds of allocation 11 which has size 2 -} - -#[miri_run] -fn dangling_pointer_deref() -> i32 { - let p = { - let b = Box::new(42); - &*b as *const i32 - }; - unsafe { *p } //~ ERROR: dangling pointer was dereferenced -} - -#[miri_run] -fn wild_pointer_deref() -> i32 { - let p = 42 as *const i32; - unsafe { *p } //~ ERROR: attempted to interpret some raw bytes as a pointer address -} - -#[miri_run] -fn null_pointer_deref() -> i32 { - unsafe { *std::ptr::null() } //~ ERROR: attempted to interpret some raw bytes as a pointer address -} - -fn main() {} diff --git a/tests/compile-fail/execute_memory.rs b/tests/compile-fail/execute_memory.rs index 4e06fd8db8..413c660211 100644 --- a/tests/compile-fail/execute_memory.rs +++ b/tests/compile-fail/execute_memory.rs @@ -1,8 +1,6 @@ -#![feature(custom_attribute, box_syntax)] -#![allow(dead_code, unused_attributes)] +#![feature(box_syntax)] -#[miri_run] -fn deref_fn_ptr() { +fn main() { //FIXME: this span is wrong let x = box 42; //~ ERROR: tried to treat a memory pointer as a function pointer unsafe { @@ -10,5 +8,3 @@ fn deref_fn_ptr() { f() } } - -fn main() {} diff --git a/tests/compile-fail/invalid_bool.rs b/tests/compile-fail/invalid_bool.rs new file mode 100644 index 0000000000..9de2630797 --- /dev/null +++ b/tests/compile-fail/invalid_bool.rs @@ -0,0 +1,4 @@ +fn main() { + let b = unsafe { std::mem::transmute::(2) }; + if b { unreachable!() } else { unreachable!() } //~ ERROR: invalid boolean value read +} diff --git a/tests/compile-fail/null_pointer_deref.rs b/tests/compile-fail/null_pointer_deref.rs new file mode 100644 index 0000000000..3d1afe9215 --- /dev/null +++ b/tests/compile-fail/null_pointer_deref.rs @@ -0,0 +1,4 @@ +fn main() { + let x: i32 = unsafe { *std::ptr::null() }; //~ ERROR: attempted to interpret some raw bytes as a pointer address + panic!("this should never print: {}", x); +} diff --git a/tests/compile-fail/out_of_bounds_read.rs b/tests/compile-fail/out_of_bounds_read.rs new file mode 100644 index 0000000000..3e9e87cdc6 --- /dev/null +++ b/tests/compile-fail/out_of_bounds_read.rs @@ -0,0 +1,5 @@ +fn main() { + let v: Vec = vec![1, 2]; + let x = unsafe { *v.get_unchecked(5) }; //~ ERROR: memory access of 5..6 outside bounds of allocation 29 which has size 2 + panic!("this should never print: {}", x); +} diff --git a/tests/compile-fail/overwriting_part_of_relocation_makes_the_rest_undefined.rs b/tests/compile-fail/overwriting_part_of_relocation_makes_the_rest_undefined.rs new file mode 100644 index 0000000000..50f51d0ba9 --- /dev/null +++ b/tests/compile-fail/overwriting_part_of_relocation_makes_the_rest_undefined.rs @@ -0,0 +1,11 @@ +fn main() { + let mut p = &42; + unsafe { + let ptr: *mut _ = &mut p; + *(ptr as *mut u8) = 123; // if we ever support 8 bit pointers, this is gonna cause + // "attempted to interpret some raw bytes as a pointer address" instead of + // "attempted to read undefined bytes" + } + let x = *p; //~ ERROR: attempted to read undefined bytes + panic!("this should never print: {}", x); +} diff --git a/tests/compile-fail/pointers_to_different_allocations_are_unorderable.rs b/tests/compile-fail/pointers_to_different_allocations_are_unorderable.rs new file mode 100644 index 0000000000..be478c8213 --- /dev/null +++ b/tests/compile-fail/pointers_to_different_allocations_are_unorderable.rs @@ -0,0 +1,7 @@ +fn main() { + let x: *const u8 = &1; + let y: *const u8 = &2; + if x < y { //~ ERROR: attempted to do math or a comparison on pointers into different allocations + unreachable!() + } +} diff --git a/tests/compile-fail/undefined_byte_read.rs b/tests/compile-fail/undefined_byte_read.rs new file mode 100644 index 0000000000..f8b6f7f4ae --- /dev/null +++ b/tests/compile-fail/undefined_byte_read.rs @@ -0,0 +1,6 @@ +fn main() { + let v: Vec = Vec::with_capacity(10); + let undef = unsafe { *v.get_unchecked(5) }; + let x = undef + 1; //~ ERROR: attempted to read undefined bytes + panic!("this should never print: {}", x); +} diff --git a/tests/compile-fail/unimplemented.rs b/tests/compile-fail/unimplemented.rs index 7752650ade..9611631a47 100644 --- a/tests/compile-fail/unimplemented.rs +++ b/tests/compile-fail/unimplemented.rs @@ -1,12 +1,5 @@ -#![feature(custom_attribute)] -#![allow(dead_code, unused_attributes)] - //error-pattern:begin_panic_fmt - -#[miri_run] -fn failed_assertions() { +fn main() { assert_eq!(5, 6); } - -fn main() {} diff --git a/tests/compile-fail/wild_pointer_deref.rs b/tests/compile-fail/wild_pointer_deref.rs new file mode 100644 index 0000000000..1f472489b4 --- /dev/null +++ b/tests/compile-fail/wild_pointer_deref.rs @@ -0,0 +1,5 @@ +fn main() { + let p = 42 as *const i32; + let x = unsafe { *p }; //~ ERROR: attempted to interpret some raw bytes as a pointer address + panic!("this should never print: {}", x); +} diff --git a/tests/compiletest.rs b/tests/compiletest.rs index 76b5b5f6e9..7ce9636fc0 100644 --- a/tests/compiletest.rs +++ b/tests/compiletest.rs @@ -15,20 +15,23 @@ fn run_mode(mode: &'static str) { .expect("need to specify RUST_SYSROOT env var or use rustup or multirust") .to_owned(), }; - let sysroot_flag = format!("--sysroot {}", sysroot); + let flags = format!("--sysroot {} -Dwarnings", sysroot); // FIXME: read directories in sysroot/lib/rustlib and generate the test targets from that let targets = &["x86_64-unknown-linux-gnu", "i686-unknown-linux-gnu"]; for &target in targets { + use std::io::Write; + let stderr = std::io::stderr(); + write!(stderr.lock(), "running tests for target {}", target).unwrap(); let mut config = compiletest::default_config(); - config.host_rustcflags = Some(sysroot_flag.clone()); + config.host_rustcflags = Some(flags.clone()); config.mode = mode.parse().expect("Invalid mode"); config.run_lib_path = format!("{}/lib/rustlib/{}/lib", sysroot, target); config.rustc_path = "target/debug/miri".into(); config.src_base = PathBuf::from(format!("tests/{}", mode)); config.target = target.to_owned(); - config.target_rustcflags = Some(sysroot_flag.clone()); + config.target_rustcflags = Some(flags.clone()); compiletest::run_tests(&config); } } diff --git a/tests/run-pass/arrays.rs b/tests/run-pass/arrays.rs index db4f999a8b..469dde3091 100644 --- a/tests/run-pass/arrays.rs +++ b/tests/run-pass/arrays.rs @@ -1,50 +1,38 @@ -#![feature(custom_attribute)] -#![allow(dead_code, unused_attributes)] - -#[miri_run] fn empty_array() -> [u16; 0] { [] } -#[miri_run] fn mini_array() -> [u16; 1] { [42] } -#[miri_run] fn big_array() -> [u16; 5] { [5, 4, 3, 2, 1] } -#[miri_run] fn array_array() -> [[u8; 2]; 3] { [[5, 4], [3, 2], [1, 0]] } -#[miri_run] fn index_unsafe() -> i32 { let a = [0, 10, 20, 30]; unsafe { *a.get_unchecked(2) } } -#[miri_run] fn index() -> i32 { let a = [0, 10, 20, 30]; a[2] } -#[miri_run] fn array_repeat() -> [u8; 8] { [42; 8] } -#[miri_run] fn slice_index() -> u8 { let arr: &[_] = &[101, 102, 103, 104, 105, 106]; arr[5] } -#[miri_run] fn main() { assert_eq!(empty_array(), []); assert_eq!(index_unsafe(), 20); @@ -53,4 +41,5 @@ fn main() { assert_eq!(big_array(), [5, 4, 3, 2, 1]); assert_eq!(array_array(), [[5, 4], [3, 2], [1, 0]]); assert_eq!(array_repeat(), [42; 8]); + assert_eq!(mini_array(), [42]); } diff --git a/tests/run-pass/bools.rs b/tests/run-pass/bools.rs index 953670fef9..103d7eac27 100644 --- a/tests/run-pass/bools.rs +++ b/tests/run-pass/bools.rs @@ -1,24 +1,17 @@ -#![feature(custom_attribute)] -#![allow(dead_code, unused_attributes)] - -#[miri_run] fn boolean() -> bool { true } -#[miri_run] fn if_false() -> i64 { let c = false; if c { 1 } else { 0 } } -#[miri_run] fn if_true() -> i64 { let c = true; if c { 1 } else { 0 } } -#[miri_run] fn match_bool() -> i16 { let b = true; match b { @@ -27,7 +20,6 @@ fn match_bool() -> i16 { } } -#[miri_run] fn main() { assert!(boolean()); assert_eq!(if_false(), 0); diff --git a/tests/run-pass/bug.rs b/tests/run-pass/bug.rs index 3006da2c16..a68f727322 100644 --- a/tests/run-pass/bug.rs +++ b/tests/run-pass/bug.rs @@ -1,14 +1,8 @@ -#![feature(custom_attribute)] -#![allow(dead_code, unused_attributes)] - static mut X: usize = 5; -#[miri_run] -fn static_mut() { +fn main() { unsafe { X = 6; assert_eq!(X, 6); } } - -fn main() {} diff --git a/tests/run-pass/c_enums.rs b/tests/run-pass/c_enums.rs index 60790fef43..11897b73eb 100644 --- a/tests/run-pass/c_enums.rs +++ b/tests/run-pass/c_enums.rs @@ -1,6 +1,3 @@ -#![feature(custom_attribute)] -#![allow(dead_code, unused_attributes)] - enum Foo { Bar = 42, Baz, @@ -13,17 +10,14 @@ enum Signed { Quux = 100, } -#[miri_run] fn foo() -> [u8; 3] { [Foo::Bar as u8, Foo::Baz as u8, Foo::Quux as u8] } -#[miri_run] fn signed() -> [i8; 3] { [Signed::Bar as i8, Signed::Baz as i8, Signed::Quux as i8] } -#[miri_run] fn unsafe_match() -> bool { match unsafe { std::mem::transmute::(43) } { Foo::Baz => true, @@ -31,7 +25,6 @@ fn unsafe_match() -> bool { } } -#[miri_run] fn main() { assert_eq!(foo(), [42, 43, 100]); assert_eq!(signed(), [-42, -41, 100]); diff --git a/tests/run-pass/calls.rs b/tests/run-pass/calls.rs index ba68fb44a6..c4ba4a9b70 100644 --- a/tests/run-pass/calls.rs +++ b/tests/run-pass/calls.rs @@ -1,7 +1,5 @@ -#![feature(custom_attribute, const_fn)] -#![allow(dead_code, unused_attributes)] +#![feature(const_fn)] -#[miri_run] fn call() -> i32 { fn increment(x: i32) -> i32 { x + 1 @@ -9,7 +7,6 @@ fn call() -> i32 { increment(1) } -#[miri_run] fn factorial_recursive() -> i64 { fn fact(n: i64) -> i64 { if n == 0 { @@ -21,31 +18,28 @@ fn factorial_recursive() -> i64 { fact(10) } -#[miri_run] fn call_generic() -> (i16, bool) { fn id(t: T) -> T { t } (id(42), id(true)) } // Test calling a very simple function from the standard library. -#[miri_run] fn cross_crate_fn_call() -> i64 { if 1i32.is_positive() { 1 } else { 0 } } const fn foo(i: i64) -> i64 { *&i + 1 } -#[miri_run] fn const_fn_call() -> i64 { let x = 5 + foo(5); assert_eq!(x, 11); x } -#[miri_run] fn main() { assert_eq!(call(), 2); assert_eq!(factorial_recursive(), 3628800); assert_eq!(call_generic(), (42, true)); assert_eq!(cross_crate_fn_call(), 1); + assert_eq!(const_fn_call(), 11); } diff --git a/tests/run-pass/function_pointers.rs b/tests/run-pass/function_pointers.rs index 55a6f9fbea..8361a58ea4 100644 --- a/tests/run-pass/function_pointers.rs +++ b/tests/run-pass/function_pointers.rs @@ -1,6 +1,3 @@ -#![feature(custom_attribute)] -#![allow(dead_code, unused_attributes)] - fn f() -> i32 { 42 } @@ -9,9 +6,10 @@ fn return_fn_ptr() -> fn() -> i32 { f } -#[miri_run] fn call_fn_ptr() -> i32 { return_fn_ptr()() } -fn main() {} +fn main() { + assert_eq!(call_fn_ptr(), 42); +} diff --git a/tests/run-pass/heap.rs b/tests/run-pass/heap.rs index a7175969ef..b533f91646 100644 --- a/tests/run-pass/heap.rs +++ b/tests/run-pass/heap.rs @@ -1,17 +1,13 @@ -#![feature(custom_attribute, box_syntax)] -#![allow(dead_code, unused_attributes)] +#![feature(box_syntax)] -#[miri_run] fn make_box() -> Box<(i16, i16)> { Box::new((1, 2)) } -#[miri_run] fn make_box_syntax() -> Box<(i16, i16)> { box (1, 2) } -#[miri_run] fn allocate_reallocate() { let mut s = String::new(); @@ -31,8 +27,8 @@ fn allocate_reallocate() { assert_eq!(s.capacity(), 9); } -#[miri_run] fn main() { assert_eq!(*make_box(), (1, 2)); assert_eq!(*make_box_syntax(), (1, 2)); + allocate_reallocate(); } diff --git a/tests/run-pass/intrinsics.rs b/tests/run-pass/intrinsics.rs index ef7fa0d986..3152737a60 100755 --- a/tests/run-pass/intrinsics.rs +++ b/tests/run-pass/intrinsics.rs @@ -1,9 +1,5 @@ -#![feature(custom_attribute)] -#![allow(dead_code, unused_attributes)] - use std::mem::{size_of, size_of_val}; -#[miri_run] fn main() { assert_eq!(size_of::>(), 8); assert_eq!(size_of_val(&()), 0); diff --git a/tests/run-pass/loops.rs b/tests/run-pass/loops.rs index 57a2f7c435..222287cbe0 100644 --- a/tests/run-pass/loops.rs +++ b/tests/run-pass/loops.rs @@ -1,7 +1,3 @@ -#![feature(custom_attribute)] -#![allow(dead_code, unused_attributes)] - -#[miri_run] fn factorial_loop() -> i64 { let mut product = 1; let mut i = 1; @@ -14,7 +10,6 @@ fn factorial_loop() -> i64 { product } -#[miri_run] fn index_for_loop() -> usize { let mut sum = 0; let a = [0, 10, 20, 30]; @@ -24,7 +19,6 @@ fn index_for_loop() -> usize { sum } -#[miri_run] fn for_loop() -> usize { let mut sum = 0; let a = [0, 10, 20, 30]; @@ -34,7 +28,6 @@ fn for_loop() -> usize { sum } -#[miri_run] fn main() { assert_eq!(factorial_loop(), 3628800); assert_eq!(index_for_loop(), 60); diff --git a/tests/run-pass/main_fn.rs b/tests/run-pass/main_fn.rs new file mode 100644 index 0000000000..91d183ee6a --- /dev/null +++ b/tests/run-pass/main_fn.rs @@ -0,0 +1,5 @@ +#![feature(main)] + +#[main] +fn foo() { +} diff --git a/tests/run-pass/pointers.rs b/tests/run-pass/pointers.rs index 9f28b982b4..2ef7eb0102 100644 --- a/tests/run-pass/pointers.rs +++ b/tests/run-pass/pointers.rs @@ -1,25 +1,18 @@ -#![feature(custom_attribute)] -#![allow(dead_code, unused_attributes)] - -#[miri_run] fn one_line_ref() -> i16 { *&1 } -#[miri_run] fn basic_ref() -> i16 { let x = &1; *x } -#[miri_run] fn basic_ref_mut() -> i16 { let x = &mut 1; *x += 2; *x } -#[miri_run] fn basic_ref_mut_var() -> i16 { let mut a = 1; { @@ -29,7 +22,6 @@ fn basic_ref_mut_var() -> i16 { a } -#[miri_run] fn tuple_ref_mut() -> (i8, i8) { let mut t = (10, 20); { @@ -39,7 +31,6 @@ fn tuple_ref_mut() -> (i8, i8) { t } -#[miri_run] fn match_ref_mut() -> i8 { let mut t = (20, 22); { @@ -52,13 +43,11 @@ fn match_ref_mut() -> i8 { t.0 } -#[miri_run] fn dangling_pointer() -> *const i32 { let b = Box::new(42); &*b as *const i32 } -#[miri_run] fn main() { assert_eq!(one_line_ref(), 1); assert_eq!(basic_ref(), 1); diff --git a/tests/run-pass/start_fn.rs b/tests/run-pass/start_fn.rs new file mode 100644 index 0000000000..8b884e22fe --- /dev/null +++ b/tests/run-pass/start_fn.rs @@ -0,0 +1,9 @@ +#![feature(start)] + +#[start] +fn foo(nargs: isize, args: *const *const u8) -> isize { + if nargs > 0 { + assert!(unsafe{*args} as usize != 0); + } + 0 +} diff --git a/tests/run-pass/std.rs b/tests/run-pass/std.rs index 1ec3c5e0bb..2e65550b07 100644 --- a/tests/run-pass/std.rs +++ b/tests/run-pass/std.rs @@ -1,11 +1,7 @@ -#![feature(custom_attribute, box_syntax)] -#![allow(dead_code, unused_attributes)] - -use std::cell::{Cell, RefCell}; +use std::cell::Cell; use std::rc::Rc; use std::sync::Arc; -#[miri_run] fn rc_cell() -> Rc> { let r = Rc::new(Cell::new(42)); let x = r.get(); @@ -15,7 +11,6 @@ fn rc_cell() -> Rc> { // TODO(solson): also requires destructors to run for the second borrow to work // TODO(solson): needs StructWrappedNullablePointer support -// #[miri_run] // fn rc_refcell() -> i32 { // let r = Rc::new(RefCell::new(42)); // *r.borrow_mut() += 10; @@ -23,19 +18,17 @@ fn rc_cell() -> Rc> { // x // } -#[miri_run] fn arc() -> Arc { let a = Arc::new(42); a } -#[miri_run] fn true_assert() { assert_eq!(1, 1); } -#[miri_run] fn main() { assert_eq!(*arc(), 42); assert_eq!(rc_cell().get(), 84); + true_assert(); } diff --git a/tests/run-pass/sums.rs b/tests/run-pass/sums.rs index 120c196abe..adf4e8f987 100644 --- a/tests/run-pass/sums.rs +++ b/tests/run-pass/sums.rs @@ -4,7 +4,6 @@ #[derive(Debug, PartialEq)] enum Unit { Unit(()) } // Force non-C-enum representation. -#[miri_run] fn return_unit() -> Unit { Unit::Unit(()) } @@ -12,27 +11,22 @@ fn return_unit() -> Unit { #[derive(Debug, PartialEq)] enum MyBool { False(()), True(()) } // Force non-C-enum representation. -#[miri_run] fn return_true() -> MyBool { MyBool::True(()) } -#[miri_run] fn return_false() -> MyBool { MyBool::False(()) } -#[miri_run] fn return_none() -> Option { None } -#[miri_run] fn return_some() -> Option { Some(42) } -#[miri_run] fn match_opt_none() -> i8 { let x = None; match x { @@ -41,7 +35,6 @@ fn match_opt_none() -> i8 { } } -#[miri_run] fn match_opt_some() -> i8 { let x = Some(13); match x { @@ -50,13 +43,12 @@ fn match_opt_some() -> i8 { } } -#[miri_run] fn two_nones() -> (Option, Option) { (None, None) } // FIXME(solson): Casts inside PartialEq fails on 32-bit. -#[cfg_attr(target_pointer_width = "64", miri_run)] +#[cfg(target_pointer_width = "64")] fn main() { assert_eq!(two_nones(), (None, None)); assert_eq!(match_opt_some(), 13); @@ -67,3 +59,6 @@ fn main() { assert_eq!(return_true(), MyBool::True(())); assert_eq!(return_unit(), Unit::Unit(())); } + +#[cfg(not(target_pointer_width = "64"))] +fn main() {} diff --git a/tests/run-pass/vecs.rs b/tests/run-pass/vecs.rs index 2a4cc61288..b3a88014e6 100644 --- a/tests/run-pass/vecs.rs +++ b/tests/run-pass/vecs.rs @@ -1,7 +1,3 @@ -#![feature(custom_attribute)] -#![allow(dead_code, unused_attributes)] - -#[miri_run] fn make_vec() -> Vec { let mut v = Vec::with_capacity(4); v.push(1); @@ -9,17 +5,14 @@ fn make_vec() -> Vec { v } -#[miri_run] fn make_vec_macro() -> Vec { vec![1, 2] } -#[miri_run] fn make_vec_macro_repeat() -> Vec { vec![42; 5] } -#[miri_run] fn vec_into_iter() -> u8 { vec![1, 2, 3, 4] .into_iter() @@ -27,7 +20,6 @@ fn vec_into_iter() -> u8 { .fold(0, |x, y| x + y) } -#[miri_run] fn vec_reallocate() -> Vec { let mut v = vec![1, 2]; v.push(3); @@ -36,9 +28,10 @@ fn vec_reallocate() -> Vec { v } -#[miri_run] fn main() { assert_eq!(vec_reallocate().len(), 5); assert_eq!(vec_into_iter(), 30); assert_eq!(make_vec().capacity(), 4); + assert_eq!(make_vec_macro(), [1, 2]); + assert_eq!(make_vec_macro_repeat(), [42; 5]); }