diff --git a/src/base.rs b/src/base.rs index 1bacfb3fe74..d1b97420aa2 100644 --- a/src/base.rs +++ b/src/base.rs @@ -274,47 +274,26 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Backend>) { fx.bcx.switch_to_block(failure); fx.bcx.ins().nop(); - let location = fx - .get_caller_location(bb_data.terminator().source_info.span) - .load_scalar(fx); - - let args; - let lang_item = match msg { + match msg { AssertKind::BoundsCheck { ref len, ref index } => { let len = trans_operand(fx, len).load_scalar(fx); let index = trans_operand(fx, index).load_scalar(fx); - args = [index, len, location]; - rustc_hir::LangItem::PanicBoundsCheck + let location = fx + .get_caller_location(bb_data.terminator().source_info.span) + .load_scalar(fx); + + codegen_panic_inner( + fx, + rustc_hir::LangItem::PanicBoundsCheck, + &[index, len, location], + bb_data.terminator().source_info.span, + ); } _ => { let msg_str = msg.description(); - let msg_ptr = fx.anonymous_str("assert", msg_str); - let msg_len = fx - .bcx - .ins() - .iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap()); - args = [msg_ptr, msg_len, location]; - rustc_hir::LangItem::Panic + codegen_panic(fx, msg_str, bb_data.terminator().source_info.span); } - }; - - let def_id = fx.tcx.lang_items().require(lang_item).unwrap_or_else(|s| { - fx.tcx - .sess - .span_fatal(bb_data.terminator().source_info.span, &s) - }); - - let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx); - let symbol_name = fx.tcx.symbol_name(instance).name; - - fx.lib_call( - &*symbol_name, - vec![fx.pointer_type, fx.pointer_type, fx.pointer_type], - vec![], - &args, - ); - - crate::trap::trap_unreachable(fx, "panic lang item returned"); + } } TerminatorKind::SwitchInt { @@ -997,3 +976,45 @@ pub(crate) fn trans_operand<'tcx>( Operand::Constant(const_) => crate::constant::trans_constant(fx, const_), } } + +pub(crate) fn codegen_panic<'tcx>( + fx: &mut FunctionCx<'_, 'tcx, impl Backend>, + msg_str: &str, + span: Span, +) { + let location = fx.get_caller_location(span).load_scalar(fx); + + let msg_ptr = fx.anonymous_str("assert", msg_str); + let msg_len = fx + .bcx + .ins() + .iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap()); + let args = [msg_ptr, msg_len, location]; + + codegen_panic_inner(fx, rustc_hir::LangItem::Panic, &args, span); +} + +pub(crate) fn codegen_panic_inner<'tcx>( + fx: &mut FunctionCx<'_, 'tcx, impl Backend>, + lang_item: rustc_hir::LangItem, + args: &[Value], + span: Span, +) { + let def_id = fx + .tcx + .lang_items() + .require(lang_item) + .unwrap_or_else(|s| fx.tcx.sess.span_fatal(span, &s)); + + let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx); + let symbol_name = fx.tcx.symbol_name(instance).name; + + fx.lib_call( + &*symbol_name, + vec![fx.pointer_type, fx.pointer_type, fx.pointer_type], + vec![], + args, + ); + + crate::trap::trap_unreachable(fx, "panic lang item returned"); +} diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 0b7cc7bee90..e75e83b56d6 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -413,13 +413,13 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( // Insert non returning intrinsics here match intrinsic { "abort" => { - trap_panic(fx, "Called intrinsic::abort."); + trap_abort(fx, "Called intrinsic::abort."); } "unreachable" => { trap_unreachable(fx, "[corruption] Called intrinsic::unreachable."); } "transmute" => { - trap_unreachable(fx, "[corruption] Transmuting to uninhabited type."); + crate::base::codegen_panic(fx, "Transmuting to uninhabited type.", span); } _ => unimplemented!("unsupported instrinsic {}", intrinsic), } @@ -819,17 +819,29 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( assert_inhabited | assert_zero_valid | assert_uninit_valid, () { let layout = fx.layout_of(T); if layout.abi.is_uninhabited() { - crate::trap::trap_panic(fx, &format!("attempted to instantiate uninhabited type `{}`", T)); + crate::base::codegen_panic( + fx, + &format!("attempted to instantiate uninhabited type `{}`", T), + span, + ); return; } if intrinsic == "assert_zero_valid" && !layout.might_permit_raw_init(fx, /*zero:*/ true).unwrap() { - crate::trap::trap_panic(fx, &format!("attempted to zero-initialize type `{}`, which is invalid", T)); + crate::base::codegen_panic( + fx, + &format!("attempted to zero-initialize type `{}`, which is invalid", T), + span, + ); return; } if intrinsic == "assert_uninit_valid" && !layout.might_permit_raw_init(fx, /*zero:*/ false).unwrap() { - crate::trap::trap_panic(fx, &format!("attempted to leave type `{}` uninitialized, which is invalid", T)); + crate::base::codegen_panic( + fx, + &format!("attempted to leave type `{}` uninitialized, which is invalid", T), + span, + ); return; } }; diff --git a/src/trap.rs b/src/trap.rs index 7ab3a4a88c2..f3ce0ee4beb 100644 --- a/src/trap.rs +++ b/src/trap.rs @@ -28,15 +28,13 @@ fn codegen_print(fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>, ms fx.bcx.ins().call(puts, &[msg_ptr]); } -/// Use this when `rustc_codegen_llvm` would insert a call to the panic handler. -/// -/// Trap code: user0 -pub(crate) fn trap_panic( +/// Trap code: user1 +pub(crate) fn trap_abort( fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>, msg: impl AsRef, ) { codegen_print(fx, msg.as_ref()); - fx.bcx.ins().trap(TrapCode::User(0)); + fx.bcx.ins().trap(TrapCode::User(1)); } /// Use this for example when a function call should never return. This will fill the current block,