@@ -10,6 +10,10 @@ use rustc_target::spec::PanicStrategy;
1010
1111use crate :: errors;
1212
13+ /// Some of the functions declared as "may unwind" by `fn_can_unwind` can't actually unwind. In
14+ /// particular, `extern "C"` is still considered as can-unwind on stable, but we need to to consider
15+ /// it cannot-unwind here. So below we check `fn_can_unwind() && abi_can_unwind()` before concluding
16+ /// that a function call can unwind.
1317fn abi_can_unwind ( abi : Abi ) -> bool {
1418 use Abi :: * ;
1519 match abi {
@@ -33,9 +37,8 @@ fn abi_can_unwind(abi: Abi) -> bool {
3337 | RiscvInterruptS
3438 | CCmseNonSecureCall
3539 | Wasm
36- | RustIntrinsic
3740 | Unadjusted => false ,
38- Rust | RustCall | RustCold => true ,
41+ RustIntrinsic | Rust | RustCall | RustCold => unreachable ! ( ) , // these ABIs are already skipped earlier
3942 }
4043}
4144
@@ -81,14 +84,16 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool {
8184 let sig = ty. fn_sig ( tcx) ;
8285
8386 // Rust calls cannot themselves create foreign unwinds.
84- if let Abi :: Rust | Abi :: RustCall | Abi :: RustCold = sig. abi ( ) {
87+ // We assume this is true for intrinsics as well.
88+ if let Abi :: RustIntrinsic | Abi :: Rust | Abi :: RustCall | Abi :: RustCold = sig. abi ( ) {
8589 continue ;
8690 } ;
8791
8892 let fn_def_id = match ty. kind ( ) {
8993 ty:: FnPtr ( _) => None ,
9094 & ty:: FnDef ( def_id, _) => {
91- // Rust calls cannot themselves create foreign unwinds.
95+ // Rust calls cannot themselves create foreign unwinds (even if they use a non-Rust ABI).
96+ // So the leak of the foreign unwind into Rust can only be elsewhere, not here.
9297 if !tcx. is_foreign_item ( def_id) {
9398 continue ;
9499 }
0 commit comments