Skip to content

Commit c0507a6

Browse files
committed
Invoke panic handler instead of trap for assert_* intrinsics
1 parent bcb0862 commit c0507a6

File tree

3 files changed

+75
-44
lines changed

3 files changed

+75
-44
lines changed

src/base.rs

Lines changed: 55 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -274,47 +274,26 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Backend>) {
274274
fx.bcx.switch_to_block(failure);
275275
fx.bcx.ins().nop();
276276

277-
let location = fx
278-
.get_caller_location(bb_data.terminator().source_info.span)
279-
.load_scalar(fx);
280-
281-
let args;
282-
let lang_item = match msg {
277+
match msg {
283278
AssertKind::BoundsCheck { ref len, ref index } => {
284279
let len = trans_operand(fx, len).load_scalar(fx);
285280
let index = trans_operand(fx, index).load_scalar(fx);
286-
args = [index, len, location];
287-
rustc_hir::LangItem::PanicBoundsCheck
281+
let location = fx
282+
.get_caller_location(bb_data.terminator().source_info.span)
283+
.load_scalar(fx);
284+
285+
codegen_panic_inner(
286+
fx,
287+
rustc_hir::LangItem::PanicBoundsCheck,
288+
&[index, len, location],
289+
bb_data.terminator().source_info.span,
290+
);
288291
}
289292
_ => {
290293
let msg_str = msg.description();
291-
let msg_ptr = fx.anonymous_str("assert", msg_str);
292-
let msg_len = fx
293-
.bcx
294-
.ins()
295-
.iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap());
296-
args = [msg_ptr, msg_len, location];
297-
rustc_hir::LangItem::Panic
294+
codegen_panic(fx, msg_str, bb_data.terminator().source_info.span);
298295
}
299-
};
300-
301-
let def_id = fx.tcx.lang_items().require(lang_item).unwrap_or_else(|s| {
302-
fx.tcx
303-
.sess
304-
.span_fatal(bb_data.terminator().source_info.span, &s)
305-
});
306-
307-
let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx);
308-
let symbol_name = fx.tcx.symbol_name(instance).name;
309-
310-
fx.lib_call(
311-
&*symbol_name,
312-
vec![fx.pointer_type, fx.pointer_type, fx.pointer_type],
313-
vec![],
314-
&args,
315-
);
316-
317-
crate::trap::trap_unreachable(fx, "panic lang item returned");
296+
}
318297
}
319298

320299
TerminatorKind::SwitchInt {
@@ -997,3 +976,45 @@ pub(crate) fn trans_operand<'tcx>(
997976
Operand::Constant(const_) => crate::constant::trans_constant(fx, const_),
998977
}
999978
}
979+
980+
pub(crate) fn codegen_panic<'tcx>(
981+
fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
982+
msg_str: &str,
983+
span: Span,
984+
) {
985+
let location = fx.get_caller_location(span).load_scalar(fx);
986+
987+
let msg_ptr = fx.anonymous_str("assert", msg_str);
988+
let msg_len = fx
989+
.bcx
990+
.ins()
991+
.iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap());
992+
let args = [msg_ptr, msg_len, location];
993+
994+
codegen_panic_inner(fx, rustc_hir::LangItem::Panic, &args, span);
995+
}
996+
997+
pub(crate) fn codegen_panic_inner<'tcx>(
998+
fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
999+
lang_item: rustc_hir::LangItem,
1000+
args: &[Value],
1001+
span: Span,
1002+
) {
1003+
let def_id = fx
1004+
.tcx
1005+
.lang_items()
1006+
.require(lang_item)
1007+
.unwrap_or_else(|s| fx.tcx.sess.span_fatal(span, &s));
1008+
1009+
let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx);
1010+
let symbol_name = fx.tcx.symbol_name(instance).name;
1011+
1012+
fx.lib_call(
1013+
&*symbol_name,
1014+
vec![fx.pointer_type, fx.pointer_type, fx.pointer_type],
1015+
vec![],
1016+
args,
1017+
);
1018+
1019+
crate::trap::trap_unreachable(fx, "panic lang item returned");
1020+
}

src/intrinsics/mod.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -413,13 +413,13 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
413413
// Insert non returning intrinsics here
414414
match intrinsic {
415415
"abort" => {
416-
trap_panic(fx, "Called intrinsic::abort.");
416+
trap_abort(fx, "Called intrinsic::abort.");
417417
}
418418
"unreachable" => {
419419
trap_unreachable(fx, "[corruption] Called intrinsic::unreachable.");
420420
}
421421
"transmute" => {
422-
trap_unreachable(fx, "[corruption] Transmuting to uninhabited type.");
422+
crate::base::codegen_panic(fx, "Transmuting to uninhabited type.", span);
423423
}
424424
_ => unimplemented!("unsupported instrinsic {}", intrinsic),
425425
}
@@ -819,17 +819,29 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
819819
assert_inhabited | assert_zero_valid | assert_uninit_valid, <T> () {
820820
let layout = fx.layout_of(T);
821821
if layout.abi.is_uninhabited() {
822-
crate::trap::trap_panic(fx, &format!("attempted to instantiate uninhabited type `{}`", T));
822+
crate::base::codegen_panic(
823+
fx,
824+
&format!("attempted to instantiate uninhabited type `{}`", T),
825+
span,
826+
);
823827
return;
824828
}
825829

826830
if intrinsic == "assert_zero_valid" && !layout.might_permit_raw_init(fx, /*zero:*/ true).unwrap() {
827-
crate::trap::trap_panic(fx, &format!("attempted to zero-initialize type `{}`, which is invalid", T));
831+
crate::base::codegen_panic(
832+
fx,
833+
&format!("attempted to zero-initialize type `{}`, which is invalid", T),
834+
span,
835+
);
828836
return;
829837
}
830838

831839
if intrinsic == "assert_uninit_valid" && !layout.might_permit_raw_init(fx, /*zero:*/ false).unwrap() {
832-
crate::trap::trap_panic(fx, &format!("attempted to leave type `{}` uninitialized, which is invalid", T));
840+
crate::base::codegen_panic(
841+
fx,
842+
&format!("attempted to leave type `{}` uninitialized, which is invalid", T),
843+
span,
844+
);
833845
return;
834846
}
835847
};

src/trap.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,13 @@ fn codegen_print(fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>, ms
2828
fx.bcx.ins().call(puts, &[msg_ptr]);
2929
}
3030

31-
/// Use this when `rustc_codegen_llvm` would insert a call to the panic handler.
32-
///
33-
/// Trap code: user0
34-
pub(crate) fn trap_panic(
31+
/// Trap code: user1
32+
pub(crate) fn trap_abort(
3533
fx: &mut FunctionCx<'_, '_, impl cranelift_module::Backend>,
3634
msg: impl AsRef<str>,
3735
) {
3836
codegen_print(fx, msg.as_ref());
39-
fx.bcx.ins().trap(TrapCode::User(0));
37+
fx.bcx.ins().trap(TrapCode::User(1));
4038
}
4139

4240
/// Use this for example when a function call should never return. This will fill the current block,

0 commit comments

Comments
 (0)