add panic_fmt_nounwind for panicing without unwinding, and use it for panic_no_unwind
This commit is contained in:
parent
2b50cd1877
commit
66282cb47d
2 changed files with 19 additions and 10 deletions
|
@ -1582,13 +1582,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
|
||||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER;
|
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 supported_target_features = tcx.supported_target_features(LOCAL_CRATE);
|
||||||
|
|
||||||
let mut inline_span = None;
|
let mut inline_span = None;
|
||||||
|
|
|
@ -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}")
|
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
|
/// Panic because we cannot unwind out of a function.
|
||||||
// any extra arguments (including those synthesized by track_caller).
|
///
|
||||||
|
/// This function is called directly by the codegen backend, and must not have
|
||||||
|
/// any extra arguments (including those synthesized by track_caller).
|
||||||
#[cold]
|
#[cold]
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
#[lang = "panic_no_unwind"] // needed by codegen for panic in nounwind function
|
#[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() -> ! {
|
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") {
|
if cfg!(feature = "panic_immediate_abort") {
|
||||||
super::intrinsics::abort()
|
super::intrinsics::abort()
|
||||||
}
|
}
|
||||||
|
@ -102,7 +117,8 @@ fn panic_no_unwind() -> ! {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PanicInfo with the `can_unwind` flag set to false forces an abort.
|
// 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);
|
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.
|
// SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
|
||||||
|
|
Loading…
Reference in a new issue