Skip to content

Commit 8a36d12

Browse files
committed
implement proper panicking for failed index check
1 parent 3c0d343 commit 8a36d12

File tree

3 files changed

+49
-4
lines changed

3 files changed

+49
-4
lines changed

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,15 @@ pub use crate::shims::dlsym::{Dlsym, EvalContextExt as DlsymEvalContextExt};
3838
pub use crate::shims::env::{EnvVars, EvalContextExt as EnvEvalContextExt};
3939
pub use crate::shims::fs::{FileHandler, EvalContextExt as FileEvalContextExt};
4040
pub use crate::shims::panic::{CatchUnwindData, EvalContextExt as PanicEvalContextExt};
41+
4142
pub use crate::operator::EvalContextExt as OperatorEvalContextExt;
4243
pub use crate::range_map::RangeMap;
4344
pub use crate::helpers::{EvalContextExt as HelpersEvalContextExt};
4445
pub use crate::mono_hash_map::MonoHashMap;
4546
pub use crate::stacked_borrows::{EvalContextExt as StackedBorEvalContextExt, Tag, Permission, Stack, Stacks, Item};
4647
pub use crate::machine::{
4748
PAGE_SIZE, STACK_ADDR, STACK_SIZE, NUM_CPUS,
48-
MemoryExtra, AllocExtra, MiriMemoryKind, Evaluator, MiriEvalContext, MiriEvalContextExt,
49+
MemoryExtra, AllocExtra, FrameData, MiriMemoryKind, Evaluator, MiriEvalContext, MiriEvalContextExt,
4950
};
5051
pub use crate::eval::{eval_main, create_ecx, MiriConfig, TerminationInfo};
5152

src/machine.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,16 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
215215
ecx.call_intrinsic(span, instance, args, ret, unwind)
216216
}
217217

218+
#[inline(always)]
219+
fn assert_panic(
220+
ecx: &mut InterpCx<'mir, 'tcx, Self>,
221+
span: Span,
222+
msg: &AssertMessage<'tcx>,
223+
unwind: Option<mir::BasicBlock>,
224+
) -> InterpResult<'tcx> {
225+
ecx.assert_panic(span, msg, unwind)
226+
}
227+
218228
#[inline(always)]
219229
fn binary_ptr_op(
220230
ecx: &rustc_mir::interpret::InterpCx<'mir, 'tcx, Self>,

src/shims/panic.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111
//! gets popped *during unwinding*, we take the panic payload and store it according to the extra
1212
//! metadata we remembered when pushing said frame.
1313
14+
use syntax::source_map::Span;
1415
use rustc::mir;
15-
use crate::*;
16-
use super::machine::FrameData;
16+
use rustc::ty::{self, layout::LayoutOf};
1717
use rustc_target::spec::PanicStrategy;
18-
use crate::rustc_target::abi::LayoutOf;
18+
19+
use crate::*;
1920

2021
/// Holds all of the relevant data for a call to
2122
/// `__rust_maybe_catch_panic`.
@@ -150,4 +151,37 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
150151
this.memory.extra.stacked_borrows.borrow_mut().end_call(extra.call_id);
151152
Ok(res)
152153
}
154+
155+
fn assert_panic(
156+
&mut self,
157+
span: Span,
158+
msg: &AssertMessage<'tcx>,
159+
unwind: Option<mir::BasicBlock>,
160+
) -> InterpResult<'tcx> {
161+
use rustc::mir::interpret::PanicInfo::*;
162+
let this = self.eval_context_mut();
163+
164+
match msg {
165+
BoundsCheck { ref index, ref len } => {
166+
// First arg: Caller location.
167+
let location = this.alloc_caller_location_for_span(span)?;
168+
// Second arg: index.
169+
let index = this.read_scalar(this.eval_operand(index, None)?)?;
170+
// Third arg: len.
171+
let len = this.read_scalar(this.eval_operand(len, None)?)?;
172+
173+
// Call the lang item.
174+
let panic_bounds_check = this.tcx.lang_items().panic_bounds_check_fn().unwrap();
175+
let panic_bounds_check = ty::Instance::mono(this.tcx.tcx, panic_bounds_check);
176+
this.call_function(
177+
panic_bounds_check,
178+
&[location.ptr, index.not_undef()?, len.not_undef()?],
179+
None,
180+
StackPopCleanup::Goto { ret: None, unwind },
181+
)?;
182+
}
183+
_ => unimplemented!()
184+
}
185+
Ok(())
186+
}
153187
}

0 commit comments

Comments
 (0)