Skip to content

Commit

Permalink
Fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Aaron1011 committed May 29, 2019
1 parent fcf1439 commit b4af833
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 62 deletions.
4 changes: 2 additions & 2 deletions src/fn_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
// Construct an ImmTy, using the precomputed layout of '*mut &mut dyn BoxMeUp'
let imm_ty = ImmTy::from_scalar(
payload_raw,
this.machine.cached_data.as_ref().unwrap().box_me_up_layout
this.machine.cached_data.box_me_up_layout
);

// Convert our ImmTy to an MPlace, and read it
Expand All @@ -219,7 +219,7 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
// the caller of this function, even in abort mode
if this.tcx.tcx.sess.panic_strategy() == PanicStrategy::Abort {
// FIXME: Actually print out the payload here
return err!(MachineError("the evaluated program abort-panicked".to_string()));
return err!(MachineError("the evaluated program panicked".to_string()));
}

//this.machine.unwinding = true;
Expand Down
71 changes: 36 additions & 35 deletions src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,46 +7,47 @@ use crate::*;

impl<'a, 'mir, 'tcx> EvalContextExt<'a, 'mir, 'tcx> for crate::MiriEvalContext<'a, 'mir, 'tcx> {}

pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'a, 'mir, 'tcx> {
/// Gets an instance for a path.
fn resolve_did(&self, path: &[&str]) -> EvalResult<'tcx, DefId> {
let this = self.eval_context_ref();
this.tcx
.crates()
.iter()
.find(|&&krate| this.tcx.original_crate_name(krate).as_str() == path[0])
.and_then(|krate| {
let krate = DefId {
krate: *krate,
index: CRATE_DEF_INDEX,
};
let mut items = this.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.as_str() == *segment {
if path_it.peek().is_none() {
return Some(item.res.def_id())
//eprintln!("Generics: {:?}", this.tcx.generics_of(item.res.def_id()));
//return Some(ty::Instance::mono(this.tcx.tcx, item.res.def_id()).def_id());
}

items = this.tcx.item_children(item.res.def_id());
break;
/// Gets an instance for a path.
pub fn resolve_did<'a,'mir, 'tcx>(tcx: TyCtxt<'a, 'mir, 'tcx>, path: &[&str]) -> EvalResult<'tcx, DefId> {
tcx
.crates()
.iter()
.find(|&&krate| tcx.original_crate_name(krate).as_str() == path[0])
.and_then(|krate| {
let krate = DefId {
krate: *krate,
index: CRATE_DEF_INDEX,
};
let mut items = 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.as_str() == *segment {
if path_it.peek().is_none() {
return Some(item.res.def_id())
//eprintln!("Generics: {:?}", this.tcx.generics_of(item.res.def_id()));
//return Some(ty::Instance::mono(this.tcx.tcx, item.res.def_id()).def_id());
}

items = tcx.item_children(item.res.def_id());
break;
}
}
None
})
.ok_or_else(|| {
let path = path.iter().map(|&s| s.to_owned()).collect();
InterpError::PathNotFound(path).into()
})
}
}
None
})
.ok_or_else(|| {
let path = path.iter().map(|&s| s.to_owned()).collect();
InterpError::PathNotFound(path).into()
})
}


pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'a, 'mir, 'tcx> {

fn resolve_path(&self, path: &[&str]) -> EvalResult<'tcx, ty::Instance<'tcx>> {
Ok(ty::Instance::mono(self.eval_context_ref().tcx.tcx, self.resolve_did(path)?))
Ok(ty::Instance::mono(self.eval_context_ref().tcx.tcx, resolve_did(self.eval_context_ref().tcx.tcx, path)?))
}

/// Visits the memory covered by `place`, sensitive to freezing: the 3rd parameter
Expand Down
57 changes: 32 additions & 25 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use rand::rngs::StdRng;
use rand::SeedableRng;

use rustc_target::spec::PanicStrategy;
use rustc::ty::{ExistentialPredicate, ExistentialTraitRef, RegionKind, List};
use rustc::ty::{ExistentialPredicate, ExistentialTraitRef, RegionKind, List, ParamEnv};
use rustc::ty::{self, TyCtxt, query::TyCtxtAt};
use rustc::ty::layout::{LayoutOf, Size, Align, TyLayout};
use rustc::hir::{self, def_id::DefId};
Expand Down Expand Up @@ -72,16 +72,40 @@ pub struct MiriConfig {
pub seed: Option<u64>,
}


// Used by priroda.
pub fn create_ecx<'a, 'mir: 'a, 'tcx: 'mir>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
main_id: DefId,
config: MiriConfig,
) -> EvalResult<'tcx, InterpretCx<'a, 'mir, 'tcx, Evaluator<'tcx>>> {


// We build up the layout of '*mut &mut dyn core::panic::BoxMeUp'
let box_me_up_did = helpers::resolve_did(tcx, &["core", "panic", "BoxMeUp"])?;
let traits = &[ExistentialPredicate::Trait(ExistentialTraitRef {
def_id: box_me_up_did,
substs: List::empty()
})];

let me_mut_dyn = tcx.mk_dynamic(
ty::Binder::dummy(tcx.intern_existential_predicates(traits)),
&RegionKind::ReErased
);

let me_mut_ref = tcx.mk_mut_ref(&RegionKind::ReErased, me_mut_dyn);
let me_mut_raw = tcx.mk_mut_ptr(me_mut_ref);
let box_me_up_layout = tcx.layout_of(ParamEnv::empty().and(me_mut_raw))
.map_err(|layout| InterpError::Layout(layout))?;

let cached_types = CachedTypes {
box_me_up_layout
};

let mut ecx = InterpretCx::new(
tcx.at(syntax::source_map::DUMMY_SP),
ty::ParamEnv::reveal_all(),
Evaluator::new(config.validate, config.seed),
Evaluator::new(config.validate, config.seed, cached_types),
);

let main_instance = ty::Instance::mono(ecx.tcx.tcx, main_id);
Expand Down Expand Up @@ -211,25 +235,6 @@ pub fn create_ecx<'a, 'mir: 'a, 'tcx: 'mir>(
// Cache some data used by unwinding
if ecx.tcx.tcx.sess.panic_strategy() == PanicStrategy::Unwind {

// We build up the layout of '*mut &mut dyn core::panic::BoxMeUp'
let box_me_up_did = ecx.resolve_did(&["core", "panic", "BoxMeUp"])?;
let traits = &[ExistentialPredicate::Trait(ExistentialTraitRef {
def_id: box_me_up_did,
substs: List::empty()
})];

let me_mut_dyn = ecx.tcx.tcx.mk_dynamic(
ty::Binder::dummy(ecx.tcx.tcx.intern_existential_predicates(traits)),
&RegionKind::ReErased
);

let me_mut_ref = ecx.tcx.tcx.mk_mut_ref(&RegionKind::ReErased, me_mut_dyn);
let me_mut_raw = ecx.tcx.tcx.mk_mut_ptr(me_mut_ref);
let box_me_up_layout = ecx.layout_of(me_mut_raw)?;

ecx.machine.cached_data = Some(CachedTypes {
box_me_up_layout
});
}

assert!(args.next().is_none(), "start lang item has more arguments than expected");
Expand Down Expand Up @@ -374,8 +379,10 @@ pub struct Evaluator<'tcx> {
pub(crate) rng: Option<StdRng>,

/// Extra information needed for unwinding
/// This is 'None' when we're running in abort mode
pub(crate) cached_data: Option<CachedTypes<'tcx>>,
/// We create this even in abort mode, so
/// that we can perform some basic validation
/// during panics
pub(crate) cached_data: CachedTypes<'tcx>,

/// Whether or not we are currently unwinding from
/// a panic
Expand All @@ -389,7 +396,7 @@ pub struct CachedTypes<'tcx> {
}

impl<'tcx> Evaluator<'tcx> {
fn new(validate: bool, seed: Option<u64>) -> Self {
fn new(validate: bool, seed: Option<u64>, cached_data: CachedTypes<'tcx>) -> Self {
Evaluator {
env_vars: HashMap::default(),
argc: None,
Expand All @@ -399,7 +406,7 @@ impl<'tcx> Evaluator<'tcx> {
tls: TlsData::default(),
validate,
rng: seed.map(|s| StdRng::seed_from_u64(s)),
cached_data: None,
cached_data,
unwinding: false,
box_me_up_tmp_ptr: None
}
Expand Down
13 changes: 13 additions & 0 deletions tests/compile-fail/double_panic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// TODO - stub out/implement backtraces for miri in libstd,
// and detect a proper error message
// error-pattern: can't call foreign function: _Unwind_Backtrace
struct Foo;
impl Drop for Foo {
fn drop(&mut self) {
panic!("second");
}
}
fn main() {
let _foo = Foo;
panic!("first");
}
1 change: 1 addition & 0 deletions tests/compile-fail/panic1.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//error-pattern: the evaluated program panicked
// compile-flags: -C panic=abort

fn main() {
std::panic!("panicking from libstd");
Expand Down
1 change: 1 addition & 0 deletions tests/compile-fail/panic2.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//error-pattern: the evaluated program panicked
// compile-flags: -C panic=abort

fn main() {
std::panic!("{}-panicking from libstd", 42);
Expand Down
1 change: 1 addition & 0 deletions tests/compile-fail/panic3.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//error-pattern: the evaluated program panicked
// compile-flags: -C panic=abort

fn main() {
core::panic!("panicking from libcore");
Expand Down
1 change: 1 addition & 0 deletions tests/compile-fail/panic4.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//error-pattern: the evaluated program panicked
// compile-flags: -C panic=abort

fn main() {
core::panic!("{}-panicking from libcore", 42);
Expand Down
9 changes: 9 additions & 0 deletions tests/run-pass/catch_panic.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// error-pattern: thread 'main' panicked at 'Hello from panic: 0', tests/compile-fail/catch_panic.rs:35:5
use std::panic::catch_unwind;
use std::cell::Cell;

thread_local! {
static MY_COUNTER: Cell<usize> = Cell::new(0);
static DROPPED: Cell<bool> = Cell::new(false);
static HOOK_CALLED: Cell<bool> = Cell::new(false);
}

struct DropTester;
Expand Down Expand Up @@ -36,6 +38,9 @@ fn do_panic_counter() {
}

fn main() {
std::panic::set_hook(Box::new(|_panic_info| {
HOOK_CALLED.with(|h| h.set(true));
}));
let res = catch_unwind(do_panic_counter);
let expected: Box<String> = Box::new("Hello from panic: 0".to_string());
let actual = res.expect_err("do_panic() did not panic!")
Expand All @@ -46,5 +51,9 @@ fn main() {
// This should have been set to 'true' by DropTester
assert!(c.get());
});

HOOK_CALLED.with(|h| {
assert!(h.get());
});
}

0 comments on commit b4af833

Please sign in to comment.