Skip to content

Commit 2155f7a

Browse files
committed
Fix tests
1 parent 47b189e commit 2155f7a

File tree

9 files changed

+96
-62
lines changed

9 files changed

+96
-62
lines changed

src/fn_call.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
205205
// Construct an ImmTy, using the precomputed layout of '*mut &mut dyn BoxMeUp'
206206
let imm_ty = ImmTy::from_scalar(
207207
payload_raw,
208-
this.machine.cached_data.as_ref().unwrap().box_me_up_layout
208+
this.machine.cached_data.box_me_up_layout
209209
);
210210

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

225225
//this.machine.unwinding = true;

src/helpers.rs

+36-35
Original file line numberDiff line numberDiff line change
@@ -7,46 +7,47 @@ use crate::*;
77

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

10-
pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'a, 'mir, 'tcx> {
11-
/// Gets an instance for a path.
12-
fn resolve_did(&self, path: &[&str]) -> EvalResult<'tcx, DefId> {
13-
let this = self.eval_context_ref();
14-
this.tcx
15-
.crates()
16-
.iter()
17-
.find(|&&krate| this.tcx.original_crate_name(krate).as_str() == path[0])
18-
.and_then(|krate| {
19-
let krate = DefId {
20-
krate: *krate,
21-
index: CRATE_DEF_INDEX,
22-
};
23-
let mut items = this.tcx.item_children(krate);
24-
let mut path_it = path.iter().skip(1).peekable();
25-
26-
while let Some(segment) = path_it.next() {
27-
for item in mem::replace(&mut items, Default::default()).iter() {
28-
if item.ident.name.as_str() == *segment {
29-
if path_it.peek().is_none() {
30-
return Some(item.res.def_id())
31-
//eprintln!("Generics: {:?}", this.tcx.generics_of(item.res.def_id()));
32-
//return Some(ty::Instance::mono(this.tcx.tcx, item.res.def_id()).def_id());
33-
}
34-
35-
items = this.tcx.item_children(item.res.def_id());
36-
break;
10+
/// Gets an instance for a path.
11+
pub fn resolve_did<'a,'mir, 'tcx>(tcx: TyCtxt<'a, 'mir, 'tcx>, path: &[&str]) -> EvalResult<'tcx, DefId> {
12+
tcx
13+
.crates()
14+
.iter()
15+
.find(|&&krate| tcx.original_crate_name(krate).as_str() == path[0])
16+
.and_then(|krate| {
17+
let krate = DefId {
18+
krate: *krate,
19+
index: CRATE_DEF_INDEX,
20+
};
21+
let mut items = tcx.item_children(krate);
22+
let mut path_it = path.iter().skip(1).peekable();
23+
24+
while let Some(segment) = path_it.next() {
25+
for item in mem::replace(&mut items, Default::default()).iter() {
26+
if item.ident.name.as_str() == *segment {
27+
if path_it.peek().is_none() {
28+
return Some(item.res.def_id())
29+
//eprintln!("Generics: {:?}", this.tcx.generics_of(item.res.def_id()));
30+
//return Some(ty::Instance::mono(this.tcx.tcx, item.res.def_id()).def_id());
3731
}
32+
33+
items = tcx.item_children(item.res.def_id());
34+
break;
3835
}
3936
}
40-
None
41-
})
42-
.ok_or_else(|| {
43-
let path = path.iter().map(|&s| s.to_owned()).collect();
44-
InterpError::PathNotFound(path).into()
45-
})
46-
}
37+
}
38+
None
39+
})
40+
.ok_or_else(|| {
41+
let path = path.iter().map(|&s| s.to_owned()).collect();
42+
InterpError::PathNotFound(path).into()
43+
})
44+
}
45+
46+
47+
pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'a, 'mir, 'tcx> {
4748

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

5253
/// Visits the memory covered by `place`, sensitive to freezing: the 3rd parameter

src/lib.rs

+32-25
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use rand::rngs::StdRng;
2929
use rand::SeedableRng;
3030

3131
use rustc_target::spec::PanicStrategy;
32-
use rustc::ty::{ExistentialPredicate, ExistentialTraitRef, RegionKind, List};
32+
use rustc::ty::{ExistentialPredicate, ExistentialTraitRef, RegionKind, List, ParamEnv};
3333
use rustc::ty::{self, TyCtxt, query::TyCtxtAt};
3434
use rustc::ty::layout::{LayoutOf, Size, Align, TyLayout};
3535
use rustc::hir::{self, def_id::DefId};
@@ -72,16 +72,40 @@ pub struct MiriConfig {
7272
pub seed: Option<u64>,
7373
}
7474

75+
7576
// Used by priroda.
7677
pub fn create_ecx<'a, 'mir: 'a, 'tcx: 'mir>(
7778
tcx: TyCtxt<'a, 'tcx, 'tcx>,
7879
main_id: DefId,
7980
config: MiriConfig,
8081
) -> EvalResult<'tcx, InterpretCx<'a, 'mir, 'tcx, Evaluator<'tcx>>> {
82+
83+
84+
// We build up the layout of '*mut &mut dyn core::panic::BoxMeUp'
85+
let box_me_up_did = helpers::resolve_did(tcx, &["core", "panic", "BoxMeUp"])?;
86+
let traits = &[ExistentialPredicate::Trait(ExistentialTraitRef {
87+
def_id: box_me_up_did,
88+
substs: List::empty()
89+
})];
90+
91+
let me_mut_dyn = tcx.mk_dynamic(
92+
ty::Binder::dummy(tcx.intern_existential_predicates(traits)),
93+
&RegionKind::ReErased
94+
);
95+
96+
let me_mut_ref = tcx.mk_mut_ref(&RegionKind::ReErased, me_mut_dyn);
97+
let me_mut_raw = tcx.mk_mut_ptr(me_mut_ref);
98+
let box_me_up_layout = tcx.layout_of(ParamEnv::empty().and(me_mut_raw))
99+
.map_err(|layout| InterpError::Layout(layout))?;
100+
101+
let cached_types = CachedTypes {
102+
box_me_up_layout
103+
};
104+
81105
let mut ecx = InterpretCx::new(
82106
tcx.at(syntax::source_map::DUMMY_SP),
83107
ty::ParamEnv::reveal_all(),
84-
Evaluator::new(config.validate, config.seed),
108+
Evaluator::new(config.validate, config.seed, cached_types),
85109
);
86110

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

214-
// We build up the layout of '*mut &mut dyn core::panic::BoxMeUp'
215-
let box_me_up_did = ecx.resolve_did(&["core", "panic", "BoxMeUp"])?;
216-
let traits = &[ExistentialPredicate::Trait(ExistentialTraitRef {
217-
def_id: box_me_up_did,
218-
substs: List::empty()
219-
})];
220-
221-
let me_mut_dyn = ecx.tcx.tcx.mk_dynamic(
222-
ty::Binder::dummy(ecx.tcx.tcx.intern_existential_predicates(traits)),
223-
&RegionKind::ReErased
224-
);
225-
226-
let me_mut_ref = ecx.tcx.tcx.mk_mut_ref(&RegionKind::ReErased, me_mut_dyn);
227-
let me_mut_raw = ecx.tcx.tcx.mk_mut_ptr(me_mut_ref);
228-
let box_me_up_layout = ecx.layout_of(me_mut_raw)?;
229-
230-
ecx.machine.cached_data = Some(CachedTypes {
231-
box_me_up_layout
232-
});
233238
}
234239

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

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

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

391398
impl<'tcx> Evaluator<'tcx> {
392-
fn new(validate: bool, seed: Option<u64>) -> Self {
399+
fn new(validate: bool, seed: Option<u64>, cached_data: CachedTypes<'tcx>) -> Self {
393400
Evaluator {
394401
env_vars: HashMap::default(),
395402
argc: None,
@@ -399,7 +406,7 @@ impl<'tcx> Evaluator<'tcx> {
399406
tls: TlsData::default(),
400407
validate,
401408
rng: seed.map(|s| StdRng::seed_from_u64(s)),
402-
cached_data: None,
409+
cached_data,
403410
unwinding: false,
404411
box_me_up_tmp_ptr: None
405412
}

tests/compile-fail/double_panic.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// TODO - stub out/implement backtraces for miri in libstd,
2+
// and detect a proper error message
3+
// error-pattern: can't call foreign function: _Unwind_Backtrace
4+
struct Foo;
5+
impl Drop for Foo {
6+
fn drop(&mut self) {
7+
panic!("second");
8+
}
9+
}
10+
fn main() {
11+
let _foo = Foo;
12+
panic!("first");
13+
}

tests/compile-fail/panic1.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//error-pattern: the evaluated program panicked
2+
// compile-flags: -C panic=abort
23

34
fn main() {
45
std::panic!("panicking from libstd");

tests/compile-fail/panic2.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//error-pattern: the evaluated program panicked
2+
// compile-flags: -C panic=abort
23

34
fn main() {
45
std::panic!("{}-panicking from libstd", 42);

tests/compile-fail/panic3.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//error-pattern: the evaluated program panicked
2+
// compile-flags: -C panic=abort
23

34
fn main() {
45
core::panic!("panicking from libcore");

tests/compile-fail/panic4.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//error-pattern: the evaluated program panicked
2+
// compile-flags: -C panic=abort
23

34
fn main() {
45
core::panic!("{}-panicking from libcore", 42);

tests/run-pass/catch_panic.rs

+9
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
// error-pattern: thread 'main' panicked at 'Hello from panic: 0', tests/compile-fail/catch_panic.rs:35:5
12
use std::panic::catch_unwind;
23
use std::cell::Cell;
34

45
thread_local! {
56
static MY_COUNTER: Cell<usize> = Cell::new(0);
67
static DROPPED: Cell<bool> = Cell::new(false);
8+
static HOOK_CALLED: Cell<bool> = Cell::new(false);
79
}
810

911
struct DropTester;
@@ -36,6 +38,9 @@ fn do_panic_counter() {
3638
}
3739

3840
fn main() {
41+
std::panic::set_hook(Box::new(|_panic_info| {
42+
HOOK_CALLED.with(|h| h.set(true));
43+
}));
3944
let res = catch_unwind(do_panic_counter);
4045
let expected: Box<String> = Box::new("Hello from panic: 0".to_string());
4146
let actual = res.expect_err("do_panic() did not panic!")
@@ -46,5 +51,9 @@ fn main() {
4651
// This should have been set to 'true' by DropTester
4752
assert!(c.get());
4853
});
54+
55+
HOOK_CALLED.with(|h| {
56+
assert!(h.get());
57+
});
4958
}
5059

0 commit comments

Comments
 (0)