about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-02-27 13:33:35 +0000
committerbors <bors@rust-lang.org>2024-02-27 13:33:35 +0000
commitb6e4299415646106095a7c3ca71aba9d174ee4ea (patch)
treef142fb51fe86130e6fed9256e35880ed5df37c20 /compiler/rustc_mir_transform/src
parent9afdb8d1d55f7ee80259009c39530d163d24dc65 (diff)
parentf5c80dcd5a7f7b7b9ef4d00ac9bfb68d9c789f6f (diff)
downloadrust-b6e4299415646106095a7c3ca71aba9d174ee4ea.tar.gz
rust-b6e4299415646106095a7c3ca71aba9d174ee4ea.zip
Auto merge of #121548 - RalfJung:ffi-unwind-intrinsics, r=davidtwco
ffi_unwind_calls: treat RustIntrinsic like regular Rust calls

Also add some comments to `abi_can_unwind` to explain what happens.

r? `@nbdd0121`  Cc `@BatmanAoD`
Diffstat (limited to 'compiler/rustc_mir_transform/src')
-rw-r--r--compiler/rustc_mir_transform/src/ffi_unwind_calls.rs13
1 files changed, 9 insertions, 4 deletions
diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
index 0dc06524c79..d9387ecd14c 100644
--- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
+++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
@@ -10,6 +10,10 @@ use rustc_target::spec::PanicStrategy;
 
 use crate::errors;
 
+/// Some of the functions declared as "may unwind" by `fn_can_unwind` can't actually unwind. In
+/// particular, `extern "C"` is still considered as can-unwind on stable, but we need to to consider
+/// it cannot-unwind here. So below we check `fn_can_unwind() && abi_can_unwind()` before concluding
+/// that a function call can unwind.
 fn abi_can_unwind(abi: Abi) -> bool {
     use Abi::*;
     match abi {
@@ -33,9 +37,8 @@ fn abi_can_unwind(abi: Abi) -> bool {
         | RiscvInterruptS
         | CCmseNonSecureCall
         | Wasm
-        | RustIntrinsic
         | Unadjusted => false,
-        Rust | RustCall | RustCold => true,
+        RustIntrinsic | Rust | RustCall | RustCold => unreachable!(), // these ABIs are already skipped earlier
     }
 }
 
@@ -81,14 +84,16 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool {
         let sig = ty.fn_sig(tcx);
 
         // Rust calls cannot themselves create foreign unwinds.
-        if let Abi::Rust | Abi::RustCall | Abi::RustCold = sig.abi() {
+        // We assume this is true for intrinsics as well.
+        if let Abi::RustIntrinsic | Abi::Rust | Abi::RustCall | Abi::RustCold = sig.abi() {
             continue;
         };
 
         let fn_def_id = match ty.kind() {
             ty::FnPtr(_) => None,
             &ty::FnDef(def_id, _) => {
-                // Rust calls cannot themselves create foreign unwinds.
+                // Rust calls cannot themselves create foreign unwinds (even if they use a non-Rust ABI).
+                // So the leak of the foreign unwind into Rust can only be elsewhere, not here.
                 if !tcx.is_foreign_item(def_id) {
                     continue;
                 }