diff options
| author | Ralf Jung <post@ralfj.de> | 2022-10-06 12:40:43 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2022-10-11 22:47:31 +0200 |
| commit | 66282cb47d0f4c651fc58a6f458f1e93a2dc33b7 (patch) | |
| tree | 0bd9458704b90b6dde97d95e650776c14ece4526 | |
| parent | 2b50cd18772d3db523070d418dc0411b885a3ff4 (diff) | |
| download | rust-66282cb47d0f4c651fc58a6f458f1e93a2dc33b7.tar.gz rust-66282cb47d0f4c651fc58a6f458f1e93a2dc33b7.zip | |
add panic_fmt_nounwind for panicing without unwinding, and use it for panic_no_unwind
| -rw-r--r-- | compiler/rustc_hir_analysis/src/collect.rs | 7 | ||||
| -rw-r--r-- | library/core/src/panicking.rs | 22 |
2 files changed, 19 insertions, 10 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index cf7fde2a090..5c76016c662 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1582,13 +1582,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs { codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER; } - // The panic_no_unwind function called by TerminatorKind::Abort will never - // unwind. If the panic handler that it invokes unwind then it will simply - // call the panic handler again. - if Some(did.to_def_id()) == tcx.lang_items().panic_no_unwind() { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND; - } - let supported_target_features = tcx.supported_target_features(LOCAL_CRATE); let mut inline_span = None; diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index d4afe0f5326..68c8e8555d3 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -84,12 +84,27 @@ fn panic_bounds_check(index: usize, len: usize) -> ! { panic!("index out of bounds: the len is {len} but the index is {index}") } -// This function is called directly by the codegen backend, and must not have -// any extra arguments (including those synthesized by track_caller). +/// Panic because we cannot unwind out of a function. +/// +/// This function is called directly by the codegen backend, and must not have +/// any extra arguments (including those synthesized by track_caller). #[cold] #[inline(never)] #[lang = "panic_no_unwind"] // needed by codegen for panic in nounwind function +#[cfg_attr(not(bootstrap), rustc_nounwind)] +#[cfg_attr(bootstrap, rustc_allocator_nounwind)] fn panic_no_unwind() -> ! { + panic_str_nounwind("panic in a function that cannot unwind") +} + +/// Like panic_fmt, but without unwinding and track_caller to reduce the impact on codesize. +/// Also just works on `str`, as a `fmt::Arguments` needs more space to be passed. +#[cold] +#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] +#[cfg_attr(feature = "panic_immediate_abort", inline)] +#[cfg_attr(not(bootstrap), rustc_nounwind)] +#[cfg_attr(bootstrap, rustc_allocator_nounwind)] +pub fn panic_str_nounwind(msg: &'static str) -> ! { if cfg!(feature = "panic_immediate_abort") { super::intrinsics::abort() } @@ -102,7 +117,8 @@ fn panic_no_unwind() -> ! { } // PanicInfo with the `can_unwind` flag set to false forces an abort. - let fmt = format_args!("panic in a function that cannot unwind"); + let pieces = [msg]; + let fmt = fmt::Arguments::new_v1(&pieces, &[]); let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), false); // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call. |
