@@ -10,6 +10,10 @@ use rustc_target::spec::PanicStrategy;
10
10
11
11
use crate :: errors;
12
12
13
+ /// Some of the functions declard 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 cincluding
16
+ /// that a function call can unwind.
13
17
fn abi_can_unwind ( abi : Abi ) -> bool {
14
18
use Abi :: * ;
15
19
match abi {
@@ -33,10 +37,9 @@ fn abi_can_unwind(abi: Abi) -> bool {
33
37
| RiscvInterruptS
34
38
| CCmseNonSecureCall
35
39
| Wasm
36
- | RustIntrinsic
37
40
| PlatformIntrinsic
38
41
| Unadjusted => false ,
39
- Rust | RustCall | RustCold => true ,
42
+ RustIntrinsic | Rust | RustCall | RustCold => unreachable ! ( ) , // these ABIs are already skipped earlier
40
43
}
41
44
}
42
45
@@ -82,14 +85,16 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool {
82
85
let sig = ty. fn_sig ( tcx) ;
83
86
84
87
// Rust calls cannot themselves create foreign unwinds.
85
- if let Abi :: Rust | Abi :: RustCall | Abi :: RustCold = sig. abi ( ) {
88
+ // We assume this is true for intrinsics as well.
89
+ if let Abi :: RustIntrinsic | Abi :: Rust | Abi :: RustCall | Abi :: RustCold = sig. abi ( ) {
86
90
continue ;
87
91
} ;
88
92
89
93
let fn_def_id = match ty. kind ( ) {
90
94
ty:: FnPtr ( _) => None ,
91
95
& ty:: FnDef ( def_id, _) => {
92
- // Rust calls cannot themselves create foreign unwinds.
96
+ // Rust calls cannot themselves create foreign unwinds (even if they use a non-Rust ABI).
97
+ // So the leak of the foreign unwind into Rust can only be elsewhere, not here.
93
98
if !tcx. is_foreign_item ( def_id) {
94
99
continue ;
95
100
}
0 commit comments