implement proper panicking for failed index check
This commit is contained in:
parent
3c0d3439ee
commit
8a36d12d36
@ -38,6 +38,7 @@ pub use crate::shims::dlsym::{Dlsym, EvalContextExt as DlsymEvalContextExt};
|
||||
pub use crate::shims::env::{EnvVars, EvalContextExt as EnvEvalContextExt};
|
||||
pub use crate::shims::fs::{FileHandler, EvalContextExt as FileEvalContextExt};
|
||||
pub use crate::shims::panic::{CatchUnwindData, EvalContextExt as PanicEvalContextExt};
|
||||
|
||||
pub use crate::operator::EvalContextExt as OperatorEvalContextExt;
|
||||
pub use crate::range_map::RangeMap;
|
||||
pub use crate::helpers::{EvalContextExt as HelpersEvalContextExt};
|
||||
@ -45,7 +46,7 @@ pub use crate::mono_hash_map::MonoHashMap;
|
||||
pub use crate::stacked_borrows::{EvalContextExt as StackedBorEvalContextExt, Tag, Permission, Stack, Stacks, Item};
|
||||
pub use crate::machine::{
|
||||
PAGE_SIZE, STACK_ADDR, STACK_SIZE, NUM_CPUS,
|
||||
MemoryExtra, AllocExtra, MiriMemoryKind, Evaluator, MiriEvalContext, MiriEvalContextExt,
|
||||
MemoryExtra, AllocExtra, FrameData, MiriMemoryKind, Evaluator, MiriEvalContext, MiriEvalContextExt,
|
||||
};
|
||||
pub use crate::eval::{eval_main, create_ecx, MiriConfig, TerminationInfo};
|
||||
|
||||
|
@ -215,6 +215,16 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
|
||||
ecx.call_intrinsic(span, instance, args, ret, unwind)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn assert_panic(
|
||||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||
span: Span,
|
||||
msg: &AssertMessage<'tcx>,
|
||||
unwind: Option<mir::BasicBlock>,
|
||||
) -> InterpResult<'tcx> {
|
||||
ecx.assert_panic(span, msg, unwind)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn binary_ptr_op(
|
||||
ecx: &rustc_mir::interpret::InterpCx<'mir, 'tcx, Self>,
|
||||
|
@ -11,11 +11,12 @@
|
||||
//! gets popped *during unwinding*, we take the panic payload and store it according to the extra
|
||||
//! metadata we remembered when pushing said frame.
|
||||
|
||||
use syntax::source_map::Span;
|
||||
use rustc::mir;
|
||||
use crate::*;
|
||||
use super::machine::FrameData;
|
||||
use rustc::ty::{self, layout::LayoutOf};
|
||||
use rustc_target::spec::PanicStrategy;
|
||||
use crate::rustc_target::abi::LayoutOf;
|
||||
|
||||
use crate::*;
|
||||
|
||||
/// Holds all of the relevant data for a call to
|
||||
/// `__rust_maybe_catch_panic`.
|
||||
@ -150,4 +151,37 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
this.memory.extra.stacked_borrows.borrow_mut().end_call(extra.call_id);
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
fn assert_panic(
|
||||
&mut self,
|
||||
span: Span,
|
||||
msg: &AssertMessage<'tcx>,
|
||||
unwind: Option<mir::BasicBlock>,
|
||||
) -> InterpResult<'tcx> {
|
||||
use rustc::mir::interpret::PanicInfo::*;
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
match msg {
|
||||
BoundsCheck { ref index, ref len } => {
|
||||
// First arg: Caller location.
|
||||
let location = this.alloc_caller_location_for_span(span)?;
|
||||
// Second arg: index.
|
||||
let index = this.read_scalar(this.eval_operand(index, None)?)?;
|
||||
// Third arg: len.
|
||||
let len = this.read_scalar(this.eval_operand(len, None)?)?;
|
||||
|
||||
// Call the lang item.
|
||||
let panic_bounds_check = this.tcx.lang_items().panic_bounds_check_fn().unwrap();
|
||||
let panic_bounds_check = ty::Instance::mono(this.tcx.tcx, panic_bounds_check);
|
||||
this.call_function(
|
||||
panic_bounds_check,
|
||||
&[location.ptr, index.not_undef()?, len.not_undef()?],
|
||||
None,
|
||||
StackPopCleanup::Goto { ret: None, unwind },
|
||||
)?;
|
||||
}
|
||||
_ => unimplemented!()
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user