implement proper panicking for failed index check

This commit is contained in:
Ralf Jung 2019-11-29 10:16:03 +01:00
parent 3c0d3439ee
commit 8a36d12d36
3 changed files with 49 additions and 4 deletions

View File

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

View File

@ -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>,

View File

@ -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(())
}
}