From c23a457e72abe608715ac76f076f47dc42af07a5 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 30 May 2024 20:31:44 +0200 Subject: Merging upstream version 1.74.1+dfsg1. Signed-off-by: Daniel Baumann --- library/core/src/panicking.rs | 57 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 8 deletions(-) (limited to 'library/core/src/panicking.rs') diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 7b6249207..e6cdffd96 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -61,7 +61,12 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { fn panic_impl(pi: &PanicInfo<'_>) -> !; } - let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), true); + let pi = PanicInfo::internal_constructor( + Some(&fmt), + Location::caller(), + /* can_unwind */ true, + /* force_no_backtrace */ false, + ); // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call. unsafe { panic_impl(&pi) } @@ -77,7 +82,7 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { // and unwinds anyway, we will hit the "unwinding out of nounwind function" guard, // which causes a "panic in a function that cannot unwind". #[rustc_nounwind] -pub fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>) -> ! { +pub fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: bool) -> ! { if cfg!(feature = "panic_immediate_abort") { super::intrinsics::abort() } @@ -90,7 +95,12 @@ pub fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>) -> ! { } // PanicInfo with the `can_unwind` flag set to false forces an abort. - let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), false); + let pi = PanicInfo::internal_constructor( + Some(&fmt), + Location::caller(), + /* can_unwind */ false, + force_no_backtrace, + ); // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call. unsafe { panic_impl(&pi) } @@ -123,7 +133,15 @@ pub const fn panic(expr: &'static str) -> ! { #[lang = "panic_nounwind"] // needed by codegen for non-unwinding panics #[rustc_nounwind] pub fn panic_nounwind(expr: &'static str) -> ! { - panic_nounwind_fmt(fmt::Arguments::new_const(&[expr])); + panic_nounwind_fmt(fmt::Arguments::new_const(&[expr]), /* force_no_backtrace */ false); +} + +/// Like `panic_nounwind`, but also inhibits showing a backtrace. +#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] +#[cfg_attr(feature = "panic_immediate_abort", inline)] +#[rustc_nounwind] +pub fn panic_nounwind_nobacktrace(expr: &'static str) -> ! { + panic_nounwind_fmt(fmt::Arguments::new_const(&[expr]), /* force_no_backtrace */ true); } #[inline] @@ -172,13 +190,18 @@ fn panic_misaligned_pointer_dereference(required: usize, found: usize) -> ! { super::intrinsics::abort() } - panic_nounwind_fmt(format_args!( - "misaligned pointer dereference: address must be a multiple of {required:#x} but is {found:#x}" - )) + panic_nounwind_fmt( + format_args!( + "misaligned pointer dereference: address must be a multiple of {required:#x} but is {found:#x}" + ), + /* force_no_backtrace */ false, + ) } /// Panic because we cannot unwind out of a function. /// +/// This is a separate function to avoid the codesize impact of each crate containing the string to +/// pass to `panic_nounwind`. /// This function is called directly by the codegen backend, and must not have /// any extra arguments (including those synthesized by track_caller). #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] @@ -186,15 +209,33 @@ fn panic_misaligned_pointer_dereference(required: usize, found: usize) -> ! { #[lang = "panic_cannot_unwind"] // needed by codegen for panic in nounwind function #[rustc_nounwind] fn panic_cannot_unwind() -> ! { + // Keep the text in sync with `UnwindTerminateReason::as_str` in `rustc_middle`. panic_nounwind("panic in a function that cannot unwind") } +/// Panic because we are unwinding out of a destructor during cleanup. +/// +/// This is a separate function to avoid the codesize impact of each crate containing the string to +/// pass to `panic_nounwind`. +/// This function is called directly by the codegen backend, and must not have +/// any extra arguments (including those synthesized by track_caller). +#[cfg(not(bootstrap))] +#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] +#[cfg_attr(feature = "panic_immediate_abort", inline)] +#[lang = "panic_in_cleanup"] // needed by codegen for panic in nounwind function +#[rustc_nounwind] +fn panic_in_cleanup() -> ! { + // Keep the text in sync with `UnwindTerminateReason::as_str` in `rustc_middle`. + panic_nounwind_nobacktrace("panic in a destructor during cleanup") +} + /// This function is used instead of panic_fmt in const eval. #[lang = "const_panic_fmt"] #[rustc_const_unstable(feature = "core_panic", issue = "none")] pub const fn const_panic_fmt(fmt: fmt::Arguments<'_>) -> ! { if let Some(msg) = fmt.as_str() { - panic_str(msg); + // The panic_display function is hooked by const eval. + panic_display(&msg); } else { // SAFETY: This is only evaluated at compile time, which reliably // handles this UB (in case this branch turns out to be reachable -- cgit v1.2.3