Rollup merge of #93489 - Amanieu:panic_no_unwind, r=nagisa

Mark the panic_no_unwind lang item as nounwind

This has 2 effects:
- It helps LLVM when inlining since it doesn't need to generate landing pads for `panic_no_unwind`.
- It makes it sound for a panic handler to unwind even if `PanicInfo::can_unwind` returns true. This will simply cause another panic once the unwind tries to go past the `panic_no_unwind` lang item. Eventually this will cause a stack overflow, which is safe.
This commit is contained in:
Matthias Krüger 2022-02-06 10:43:51 +01:00 committed by GitHub
commit 4695c2157c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 11 additions and 0 deletions

View File

@ -2778,6 +2778,13 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
}
}
// 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(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;

View File

@ -136,6 +136,10 @@ impl<'a> PanicInfo<'a> {
/// This is true for most kinds of panics with the exception of panics
/// caused by trying to unwind out of a `Drop` implementation or a function
/// whose ABI does not support unwinding.
///
/// It is safe for a panic handler to unwind even when this function returns
/// true, however this will simply cause the panic handler to be called
/// again.
#[must_use]
#[unstable(feature = "panic_can_unwind", issue = "92988")]
pub fn can_unwind(&self) -> bool {