]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_codegen_cranelift/src/trap.rs
New upstream version 1.56.0~beta.4+dfsg1
[rustc.git] / compiler / rustc_codegen_cranelift / src / trap.rs
CommitLineData
29967ef6
XL
1//! Helpers used to print a message and abort in case of certain panics and some detected UB.
2
3use crate::prelude::*;
4
6a06907d 5fn codegen_print(fx: &mut FunctionCx<'_, '_, '_>, msg: &str) {
29967ef6 6 let puts = fx
29967ef6
XL
7 .module
8 .declare_function(
9 "puts",
10 Linkage::Import,
11 &Signature {
12 call_conv: CallConv::triple_default(fx.triple()),
94222f64 13 params: vec![AbiParam::new(fx.pointer_type)],
29967ef6
XL
14 returns: vec![AbiParam::new(types::I32)],
15 },
16 )
17 .unwrap();
17df50a5 18 let puts = fx.module.declare_func_in_func(puts, &mut fx.bcx.func);
cdc7bbd5 19 if fx.clif_comments.enabled() {
29967ef6
XL
20 fx.add_comment(puts, "puts");
21 }
22
17df50a5
XL
23 let real_msg = format!("trap at {:?} ({}): {}\0", fx.instance, fx.symbol_name, msg);
24 let msg_ptr = fx.anonymous_str(&real_msg);
29967ef6
XL
25 fx.bcx.ins().call(puts, &[msg_ptr]);
26}
27
28/// Trap code: user1
6a06907d 29pub(crate) fn trap_abort(fx: &mut FunctionCx<'_, '_, '_>, msg: impl AsRef<str>) {
29967ef6
XL
30 codegen_print(fx, msg.as_ref());
31 fx.bcx.ins().trap(TrapCode::User(1));
32}
33
34/// Use this for example when a function call should never return. This will fill the current block,
35/// so you can **not** add instructions to it afterwards.
36///
37/// Trap code: user65535
6a06907d 38pub(crate) fn trap_unreachable(fx: &mut FunctionCx<'_, '_, '_>, msg: impl AsRef<str>) {
29967ef6
XL
39 codegen_print(fx, msg.as_ref());
40 fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
41}
42
43/// Like `trap_unreachable` but returns a fake value of the specified type.
44///
45/// Trap code: user65535
46pub(crate) fn trap_unreachable_ret_value<'tcx>(
6a06907d 47 fx: &mut FunctionCx<'_, '_, 'tcx>,
29967ef6
XL
48 dest_layout: TyAndLayout<'tcx>,
49 msg: impl AsRef<str>,
50) -> CValue<'tcx> {
51 codegen_print(fx, msg.as_ref());
52 let true_ = fx.bcx.ins().iconst(types::I32, 1);
53 fx.bcx.ins().trapnz(true_, TrapCode::UnreachableCodeReached);
54 CValue::by_ref(Pointer::const_addr(fx, 0), dest_layout)
55}
56
57/// Use this when something is unimplemented, but `libcore` or `libstd` requires it to codegen.
58/// Unlike `trap_unreachable` this will not fill the current block, so you **must** add instructions
59/// to it afterwards.
60///
61/// Trap code: user65535
6a06907d 62pub(crate) fn trap_unimplemented(fx: &mut FunctionCx<'_, '_, '_>, msg: impl AsRef<str>) {
29967ef6
XL
63 codegen_print(fx, msg.as_ref());
64 let true_ = fx.bcx.ins().iconst(types::I32, 1);
65 fx.bcx.ins().trapnz(true_, TrapCode::User(!0));
66}
fc512014
XL
67
68/// Like `trap_unimplemented` but returns a fake value of the specified type.
69///
70/// Trap code: user65535
71pub(crate) fn trap_unimplemented_ret_value<'tcx>(
6a06907d 72 fx: &mut FunctionCx<'_, '_, 'tcx>,
fc512014
XL
73 dest_layout: TyAndLayout<'tcx>,
74 msg: impl AsRef<str>,
75) -> CValue<'tcx> {
76 trap_unimplemented(fx, msg);
77 CValue::by_ref(Pointer::const_addr(fx, 0), dest_layout)
78}