1use rustc_abi::ExternAbi;
4use rustc_middle::{mir, ty};
5
6use crate::*;
7
8impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
9pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
10 fn start_panic(&mut self, msg: &str, unwind: mir::UnwindAction) -> InterpResult<'tcx> {
12 let this = self.eval_context_mut();
13
14 let msg = this.allocate_str_dedup(msg)?;
16
17 let panic = this.tcx.lang_items().panic_fn().unwrap();
19 let panic = ty::Instance::mono(this.tcx.tcx, panic);
20 this.call_function(
21 panic,
22 ExternAbi::Rust,
23 &[this.mplace_to_ref(&msg)?],
24 None,
25 ReturnContinuation::Goto { ret: None, unwind },
26 )
27 }
28
29 fn start_panic_nounwind(&mut self, msg: &str) -> InterpResult<'tcx> {
31 let this = self.eval_context_mut();
32
33 let msg = this.allocate_str_dedup(msg)?;
35
36 let panic = this.tcx.lang_items().panic_nounwind().unwrap();
38 let panic = ty::Instance::mono(this.tcx.tcx, panic);
39 this.call_function(
40 panic,
41 ExternAbi::Rust,
42 &[this.mplace_to_ref(&msg)?],
43 None,
44 ReturnContinuation::Goto { ret: None, unwind: mir::UnwindAction::Unreachable },
45 )
46 }
47
48 fn assert_panic(
49 &mut self,
50 msg: &mir::AssertMessage<'tcx>,
51 unwind: mir::UnwindAction,
52 ) -> InterpResult<'tcx> {
53 use rustc_middle::mir::AssertKind::*;
54 let this = self.eval_context_mut();
55
56 match msg {
57 BoundsCheck { index, len } => {
58 let index = this.read_immediate(&this.eval_operand(index, None)?)?;
62 let len = this.read_immediate(&this.eval_operand(len, None)?)?;
64
65 let panic_bounds_check = this.tcx.lang_items().panic_bounds_check_fn().unwrap();
67 let panic_bounds_check = ty::Instance::mono(this.tcx.tcx, panic_bounds_check);
68 this.call_function(
69 panic_bounds_check,
70 ExternAbi::Rust,
71 &[index, len],
72 None,
73 ReturnContinuation::Goto { ret: None, unwind },
74 )?;
75 }
76 MisalignedPointerDereference { required, found } => {
77 let required = this.read_immediate(&this.eval_operand(required, None)?)?;
81 let found = this.read_immediate(&this.eval_operand(found, None)?)?;
83
84 let panic_misaligned_pointer_dereference =
86 this.tcx.lang_items().panic_misaligned_pointer_dereference_fn().unwrap();
87 let panic_misaligned_pointer_dereference =
88 ty::Instance::mono(this.tcx.tcx, panic_misaligned_pointer_dereference);
89 this.call_function(
90 panic_misaligned_pointer_dereference,
91 ExternAbi::Rust,
92 &[required, found],
93 None,
94 ReturnContinuation::Goto { ret: None, unwind },
95 )?;
96 }
97
98 _ => {
99 let fn_item = this.tcx.require_lang_item(msg.panic_function(), this.tcx.span);
101 let instance = ty::Instance::mono(this.tcx.tcx, fn_item);
102 this.call_function(
103 instance,
104 ExternAbi::Rust,
105 &[],
106 None,
107 ReturnContinuation::Goto { ret: None, unwind },
108 )?;
109 }
110 }
111 interp_ok(())
112 }
113}