From ebdfcd93a3a71bde87be117bdb9e01e0ade34981 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Fri, 25 Aug 2023 13:45:35 +0100 Subject: [PATCH] Stabilise c_unwind --- compiler/rustc_feature/src/accepted.rs | 2 ++ compiler/rustc_feature/src/unstable.rs | 2 -- compiler/rustc_middle/src/ty/layout.rs | 36 +------------------ .../src/ffi_unwind_calls.rs | 34 +----------------- library/alloc/src/lib.rs | 2 +- library/core/src/lib.rs | 2 +- library/panic_abort/src/lib.rs | 2 +- library/panic_unwind/src/lib.rs | 2 +- library/std/src/lib.rs | 2 +- library/unwind/src/lib.rs | 2 +- .../src/language-features/c-unwind.md | 26 -------------- 11 files changed, 10 insertions(+), 102 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/c-unwind.md diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index ef141c7c25e..9beaa6b8d95 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -80,6 +80,8 @@ declare_features! ( (accepted, braced_empty_structs, "1.8.0", Some(29720)), /// Allows `c"foo"` literals. (accepted, c_str_literals, "1.77.0", Some(105723)), + /// Allows `extern "C-unwind" fn` to enable unwinding across ABI boundaries and treat `extern "C" fn` as nounwind. + (accepted, c_unwind, "CURRENT_RUSTC_VERSION", Some(74990)), /// Allows `#[cfg_attr(predicate, multiple, attributes, here)]`. (accepted, cfg_attr_multi, "1.33.0", Some(54881)), /// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests. diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 5cfbcdcbbbe..45527bec2f2 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -363,8 +363,6 @@ declare_features! ( (unstable, async_for_loop, "1.77.0", Some(118898)), /// Allows builtin # foo() syntax (unstable, builtin_syntax, "1.71.0", Some(110680)), - /// Treat `extern "C"` function as nounwind. - (unstable, c_unwind, "1.52.0", Some(74990)), /// Allows using C-variadics. (unstable, c_variadic, "1.34.0", Some(44930)), /// Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour. diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 3d397b6b37e..f608b02f42c 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1182,37 +1182,6 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option, abi: SpecAbi) -> // ABIs have such an option. Otherwise the only other thing here is Rust // itself, and those ABIs are determined by the panic strategy configured // for this compilation. - // - // Unfortunately at this time there's also another caveat. Rust [RFC - // 2945][rfc] has been accepted and is in the process of being implemented - // and stabilized. In this interim state we need to deal with historical - // rustc behavior as well as plan for future rustc behavior. - // - // Historically functions declared with `extern "C"` were marked at the - // codegen layer as `nounwind`. This happened regardless of `panic=unwind` - // or not. This is UB for functions in `panic=unwind` mode that then - // actually panic and unwind. Note that this behavior is true for both - // externally declared functions as well as Rust-defined function. - // - // To fix this UB rustc would like to change in the future to catch unwinds - // from function calls that may unwind within a Rust-defined `extern "C"` - // function and forcibly abort the process, thereby respecting the - // `nounwind` attribute emitted for `extern "C"`. This behavior change isn't - // ready to roll out, so determining whether or not the `C` family of ABIs - // unwinds is conditional not only on their definition but also whether the - // `#![feature(c_unwind)]` feature gate is active. - // - // Note that this means that unlike historical compilers rustc now, by - // default, unconditionally thinks that the `C` ABI may unwind. This will - // prevent some optimization opportunities, however, so we try to scope this - // change and only assume that `C` unwinds with `panic=unwind` (as opposed - // to `panic=abort`). - // - // Eventually the check against `c_unwind` here will ideally get removed and - // this'll be a little cleaner as it'll be a straightforward check of the - // ABI. - // - // [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md use SpecAbi::*; match abi { C { unwind } @@ -1224,10 +1193,7 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option, abi: SpecAbi) -> | Thiscall { unwind } | Aapcs { unwind } | Win64 { unwind } - | SysV64 { unwind } => { - unwind - || (!tcx.features().c_unwind && tcx.sess.panic_strategy() == PanicStrategy::Unwind) - } + | SysV64 { unwind } => unwind, PtxKernel | Msp430Interrupt | X86Interrupt diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs index 5e3cd853675..0cb304da80a 100644 --- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs +++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs @@ -11,38 +11,6 @@ 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 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 { - C { unwind } - | System { unwind } - | Cdecl { unwind } - | Stdcall { unwind } - | Fastcall { unwind } - | Vectorcall { unwind } - | Thiscall { unwind } - | Aapcs { unwind } - | Win64 { unwind } - | SysV64 { unwind } => unwind, - PtxKernel - | Msp430Interrupt - | X86Interrupt - | EfiApi - | AvrInterrupt - | AvrNonBlockingInterrupt - | RiscvInterruptM - | RiscvInterruptS - | CCmseNonSecureCall - | Wasm - | Unadjusted => false, - RustIntrinsic | Rust | RustCall | RustCold => unreachable!(), // these ABIs are already skipped earlier - } -} - // Check if the body of this def_id can possibly leak a foreign unwind into Rust code. fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool { debug!("has_ffi_unwind_calls({local_def_id:?})"); @@ -103,7 +71,7 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool { _ => bug!("invalid callee of type {:?}", ty), }; - if layout::fn_can_unwind(tcx, fn_def_id, sig.abi()) && abi_can_unwind(sig.abi()) { + if layout::fn_can_unwind(tcx, fn_def_id, sig.abi()) { // We have detected a call that can possibly leak foreign unwind. // // Because the function body itself can unwind, we are not aborting this function call diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 895d1b8d59f..022a14b931a 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -165,12 +165,12 @@ // // Language features: // tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(c_unwind))] #![cfg_attr(not(test), feature(coroutine_trait))] #![cfg_attr(test, feature(panic_update_hook))] #![cfg_attr(test, feature(test))] #![feature(allocator_internals)] #![feature(allow_internal_unstable)] -#![feature(c_unwind)] #![feature(cfg_sanitize)] #![feature(const_mut_refs)] #![feature(const_precise_live_drops)] diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index ef28bc99c4f..a533a7938f1 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -199,13 +199,13 @@ // // Language features: // tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(c_unwind))] #![feature(abi_unadjusted)] #![feature(adt_const_params)] #![feature(allow_internal_unsafe)] #![feature(allow_internal_unstable)] #![feature(asm_const)] #![feature(auto_traits)] -#![feature(c_unwind)] #![feature(cfg_sanitize)] #![feature(cfg_target_has_atomic)] #![feature(cfg_target_has_atomic_equal_alignment)] diff --git a/library/panic_abort/src/lib.rs b/library/panic_abort/src/lib.rs index 353de8c5c57..14ba4af2bb5 100644 --- a/library/panic_abort/src/lib.rs +++ b/library/panic_abort/src/lib.rs @@ -14,7 +14,7 @@ #![feature(std_internals)] #![feature(staged_api)] #![feature(rustc_attrs)] -#![feature(c_unwind)] +#![cfg_attr(bootstrap, feature(c_unwind))] #![allow(internal_features)] #[cfg(target_os = "android")] diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs index b0245de501e..4dc36120608 100644 --- a/library/panic_unwind/src/lib.rs +++ b/library/panic_unwind/src/lib.rs @@ -24,7 +24,7 @@ #![feature(rustc_attrs)] #![panic_runtime] #![feature(panic_runtime)] -#![feature(c_unwind)] +#![cfg_attr(bootstrap, feature(c_unwind))] // `real_imp` is unused with Miri, so silence warnings. #![cfg_attr(miri, allow(dead_code))] #![allow(internal_features)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 1c226f9f08f..80f67838ac0 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -273,12 +273,12 @@ // // Language features: // tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(c_unwind))] #![feature(alloc_error_handler)] #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] #![feature(allow_internal_unstable)] #![feature(asm_experimental_arch)] -#![feature(c_unwind)] #![feature(cfg_sanitizer_cfi)] #![feature(cfg_target_thread_local)] #![feature(cfi_encoding)] diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs index 544d9fbf1ae..45a1c334a44 100644 --- a/library/unwind/src/lib.rs +++ b/library/unwind/src/lib.rs @@ -2,7 +2,7 @@ #![unstable(feature = "panic_unwind", issue = "32837")] #![feature(link_cfg)] #![feature(staged_api)] -#![feature(c_unwind)] +#![cfg_attr(bootstrap, feature(c_unwind))] #![feature(strict_provenance)] #![cfg_attr(target_arch = "wasm64", feature(simd_wasm64))] #![cfg_attr(not(target_env = "msvc"), feature(libc))] diff --git a/src/doc/unstable-book/src/language-features/c-unwind.md b/src/doc/unstable-book/src/language-features/c-unwind.md deleted file mode 100644 index fb32918d5e4..00000000000 --- a/src/doc/unstable-book/src/language-features/c-unwind.md +++ /dev/null @@ -1,26 +0,0 @@ -# `c_unwind` - -The tracking issue for this feature is: [#74990] - -[#74990]: https://github.com/rust-lang/rust/issues/74990 - ------------------------- - -Introduces new ABI strings: -- "C-unwind" -- "cdecl-unwind" -- "stdcall-unwind" -- "fastcall-unwind" -- "vectorcall-unwind" -- "thiscall-unwind" -- "aapcs-unwind" -- "win64-unwind" -- "sysv64-unwind" -- "system-unwind" - -These enable unwinding from other languages (such as C++) into Rust frames and -from Rust into other languages. - -See [RFC 2945] for more information. - -[RFC 2945]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md