Skip to content

Commit b7562b1

Browse files
committed
add panic_fmt_nounwind for panicing without unwinding, and use it for panic_no_unwind
1 parent f708c82 commit b7562b1

File tree

2 files changed

+19
-11
lines changed

2 files changed

+19
-11
lines changed

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,13 +1580,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
15801580
codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER;
15811581
}
15821582

1583-
// The panic_no_unwind function called by TerminatorKind::Abort will never
1584-
// unwind. If the panic handler that it invokes unwind then it will simply
1585-
// call the panic handler again.
1586-
if Some(did.to_def_id()) == tcx.lang_items().panic_no_unwind() {
1587-
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND;
1588-
}
1589-
15901583
let supported_target_features = tcx.supported_target_features(LOCAL_CRATE);
15911584

15921585
let mut inline_span = None;

library/core/src/panicking.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,26 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
8484
panic!("index out of bounds: the len is {len} but the index is {index}")
8585
}
8686

87-
// This function is called directly by the codegen backend, and must not have
88-
// any extra arguments (including those synthesized by track_caller).
87+
/// Panic because we cannot unwind out of a function.
88+
///
89+
/// This function is called directly by the codegen backend, and must not have
90+
/// any extra arguments (including those synthesized by track_caller).
8991
#[cold]
90-
#[inline(never)]
9192
#[lang = "panic_no_unwind"] // needed by codegen for panic in nounwind function
93+
#[cfg_attr(not(bootstrap), rustc_nounwind)]
94+
#[cfg_attr(bootstrap, rustc_allocator_nounwind)]
9295
fn panic_no_unwind() -> ! {
96+
panic_str_nounwind("panic in a function that cannot unwind")
97+
}
98+
99+
/// Like panic_fmt, but without unwinding and track_caller to reduce the impact on codesize.
100+
/// Also just works on `str`, as a `fmt::Arguments` needs more space to be passed.
101+
#[cold]
102+
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
103+
#[cfg_attr(feature = "panic_immediate_abort", inline)]
104+
#[cfg_attr(not(bootstrap), rustc_nounwind)]
105+
#[cfg_attr(bootstrap, rustc_allocator_nounwind)]
106+
pub fn panic_str_nounwind(msg: &'static str) -> ! {
93107
if cfg!(feature = "panic_immediate_abort") {
94108
super::intrinsics::abort()
95109
}
@@ -102,7 +116,8 @@ fn panic_no_unwind() -> ! {
102116
}
103117

104118
// PanicInfo with the `can_unwind` flag set to false forces an abort.
105-
let fmt = format_args!("panic in a function that cannot unwind");
119+
let pieces = [msg];
120+
let fmt = fmt::Arguments::new_v1(&pieces, &[]);
106121
let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), false);
107122

108123
// SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.

0 commit comments

Comments
 (0)