Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

don't use #[miri_run] anymore, but execute the main function #23

Merged
merged 5 commits into from
Jun 15, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions benches/fibonacci_helper.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
#![feature(custom_attribute)]
#![allow(unused_attributes)]

#[miri_run]
#[inline(never)]
pub fn main() {
assert_eq!(fib(10), 55);
Expand Down
4 changes: 0 additions & 4 deletions benches/fibonacci_helper_iterative.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
#![feature(custom_attribute)]
#![allow(unused_attributes)]

#[miri_run]
#[inline(never)]
pub fn main() {
assert_eq!(fib(10), 55);
Expand Down
4 changes: 0 additions & 4 deletions benches/smoke_helper.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
#![feature(custom_attribute)]
#![allow(unused_attributes)]

#[miri_run]
#[inline(never)]
pub fn main() {
}
73 changes: 32 additions & 41 deletions src/bin/miri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ use rustc::session::Session;
use rustc_driver::{driver, CompilerCalls};
use rustc::ty::{TyCtxt, subst};
use rustc::mir::mir_map::MirMap;
use rustc::mir::repr::Mir;
use rustc::hir::def_id::DefId;
use rustc::hir::{map, ItemFn, Item};
use syntax::codemap::Span;

struct MiriCompilerCalls;

Expand All @@ -34,58 +37,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());

let tcx = state.tcx.unwrap();
let mir_map = state.mir_map.unwrap();
let (span, mir, def_id) = get_main(tcx, mir_map);
println!("found `main` function at: {:?}", span);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should use a logging macro.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whoops, sorry, wanted to make that its own commit


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));

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
}
}



fn interpret_start_points<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir_map: &MirMap<'tcx>,
) {
let initial_indentation = ::log_settings::settings().indentation;
fn get_main<'a, 'b, 'tcx: 'b>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir_map: &'b MirMap<'tcx>) -> (Span, &'b Mir<'tcx>, DefId) {
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;
}
}
if let map::Node::NodeItem(&Item { name, span, ref node, .. }) = tcx.map.get(id) {
if let ItemFn(..) = *node {
if name.as_str() == "main" {
Copy link
Member

@solson solson Jun 14, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method doesn't account for #[start] which can make the start point something other than main. Ideally we'd just call an existing rustc method to find this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#[main] is actually the thing here. See this function for how to easily do this check.

return (span, mir, tcx.map.local_def_id(id));
}
}
}
}
panic!("no main function found");
}

fn report(tcx: TyCtxt, ecx: &EvalContext, e: EvalError) {
Expand Down
8 changes: 8 additions & 0 deletions tests/compile-fail/dangling_pointer_deref.rs
Original file line number Diff line number Diff line change
@@ -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);
}
13 changes: 4 additions & 9 deletions tests/compile-fail/deref_fn_ptr.rs
Original file line number Diff line number Diff line change
@@ -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::<fn(), *const i32>(f) //~ ERROR: tried to dereference a function pointer
}
};
panic!("this should never print: {}", x);
}

fn main() {}
62 changes: 0 additions & 62 deletions tests/compile-fail/errors.rs

This file was deleted.

8 changes: 2 additions & 6 deletions tests/compile-fail/execute_memory.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
#![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 {
let f = std::mem::transmute::<Box<i32>, fn()>(x);
f()
}
}

fn main() {}
4 changes: 4 additions & 0 deletions tests/compile-fail/invalid_bool.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fn main() {
let b = unsafe { std::mem::transmute::<u8, bool>(2) };
if b { unreachable!() } else { unreachable!() } //~ ERROR: invalid boolean value read
}
4 changes: 4 additions & 0 deletions tests/compile-fail/null_pointer_deref.rs
Original file line number Diff line number Diff line change
@@ -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);
}
5 changes: 5 additions & 0 deletions tests/compile-fail/out_of_bounds_read.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
fn main() {
let v: Vec<u8> = 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);
}
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -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!()
}
}
6 changes: 6 additions & 0 deletions tests/compile-fail/undefined_byte_read.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fn main() {
let v: Vec<u8> = 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);
}
9 changes: 1 addition & 8 deletions tests/compile-fail/unimplemented.rs
Original file line number Diff line number Diff line change
@@ -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() {}
5 changes: 5 additions & 0 deletions tests/compile-fail/wild_pointer_deref.rs
Original file line number Diff line number Diff line change
@@ -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);
}
2 changes: 1 addition & 1 deletion tests/compiletest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ 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 sysroot_flag = format!("--sysroot {} -Dwarnings", sysroot);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so our compile-fail tests don't contain unnecessary warnings anymore... like functions that are never called (those had #[miri_run], but weren't called from main)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, okay. I guess rename sysroot_flag to flags.


// 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"];
Expand Down
13 changes: 1 addition & 12 deletions tests/run-pass/arrays.rs
Original file line number Diff line number Diff line change
@@ -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);
Expand All @@ -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]);
}
8 changes: 0 additions & 8 deletions tests/run-pass/bools.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -27,7 +20,6 @@ fn match_bool() -> i16 {
}
}

#[miri_run]
fn main() {
assert!(boolean());
assert_eq!(if_false(), 0);
Expand Down
Loading