ffi_unwind_calls: treat RustIntrinsic like regular Rust calls

This commit is contained in:
Ralf Jung 2024-02-24 15:00:49 +01:00
parent 91cae1dcdc
commit bd3ea3e096

View File

@ -10,6 +10,10 @@
use crate::errors; 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 { fn abi_can_unwind(abi: Abi) -> bool {
use Abi::*; use Abi::*;
match abi { match abi {
@ -33,9 +37,8 @@ fn abi_can_unwind(abi: Abi) -> bool {
| RiscvInterruptS | RiscvInterruptS
| CCmseNonSecureCall | CCmseNonSecureCall
| Wasm | Wasm
| RustIntrinsic
| Unadjusted => false, | 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); let sig = ty.fn_sig(tcx);
// Rust calls cannot themselves create foreign unwinds. // 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; continue;
}; };
let fn_def_id = match ty.kind() { let fn_def_id = match ty.kind() {
ty::FnPtr(_) => None, ty::FnPtr(_) => None,
&ty::FnDef(def_id, _) => { &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) { if !tcx.is_foreign_item(def_id) {
continue; continue;
} }