diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index aa0db9891a5ad..c12fc0a0f9c2e 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -78,6 +78,8 @@ declare_features! (
     (accepted, braced_empty_structs, "1.8.0", Some(29720)),
     /// Allows `c"foo"` literals.
     (accepted, c_str_literals, "1.76.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 60586f54fd584..e431cede53c57 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -361,8 +361,6 @@ declare_features! (
     (unstable, async_for_loop, "CURRENT_RUSTC_VERSION", 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 8a02914b4359c..b7dc2af15997a 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -1198,37 +1198,6 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, 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 }
@@ -1240,10 +1209,7 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, 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/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 0af3ac38ee534..9105bd8b165ba 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -92,6 +92,7 @@
 #![warn(multiple_supertrait_upcastable)]
 #![allow(internal_features)]
 #![allow(rustdoc::redundant_explicit_links)]
+#![deny(ffi_unwind_calls)]
 //
 // Library features:
 // tidy-alphabetical-start
@@ -167,13 +168,13 @@
 //
 // 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(associated_type_bounds)]
-#![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 07720f235989b..0903eaec6d223 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -106,6 +106,7 @@
 #![allow(incomplete_features)]
 #![warn(multiple_supertrait_upcastable)]
 #![allow(internal_features)]
+#![deny(ffi_unwind_calls)]
 // Do not check link redundancy on bootstraping phase
 #![allow(rustdoc::redundant_explicit_links)]
 //
@@ -198,6 +199,7 @@
 //
 // Language features:
 // tidy-alphabetical-start
+#![cfg_attr(bootstrap, feature(c_unwind))]
 #![feature(abi_unadjusted)]
 #![feature(adt_const_params)]
 #![feature(allow_internal_unsafe)]
@@ -205,7 +207,6 @@
 #![feature(asm_const)]
 #![feature(associated_type_bounds)]
 #![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 8fd64279ac5a7..4bda5f477c84f 100644
--- a/library/panic_abort/src/lib.rs
+++ b/library/panic_abort/src/lib.rs
@@ -13,7 +13,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 7a0bae34642d6..a7a68f98a3aae 100644
--- a/library/panic_unwind/src/lib.rs
+++ b/library/panic_unwind/src/lib.rs
@@ -22,7 +22,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/proc_macro/src/bridge/buffer.rs b/library/proc_macro/src/bridge/buffer.rs
index 48030f8d82dca..5e6e25c78bbd6 100644
--- a/library/proc_macro/src/bridge/buffer.rs
+++ b/library/proc_macro/src/bridge/buffer.rs
@@ -119,7 +119,9 @@ impl Write for Buffer {
 }
 
 impl Drop for Buffer {
-    #[inline]
+    // HACK(nbdd0121): Hack to prevent LLVM < 17.0.4 will misoptimise,
+    // change to `#[inline]` if fixed.
+    #[inline(never)]
     fn drop(&mut self) {
         let b = self.take();
         (b.drop)(b);
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 6e664a162df92..59111b67f755c 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -35,6 +35,7 @@
 #![feature(strict_provenance)]
 #![recursion_limit = "256"]
 #![allow(internal_features)]
+#![deny(ffi_unwind_calls)]
 
 #[unstable(feature = "proc_macro_internals", issue = "27812")]
 #[doc(hidden)]
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 6365366297c43..88854e10ab5d4 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -265,11 +265,11 @@
 //
 // 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(c_unwind)]
 #![feature(cfg_target_thread_local)]
 #![feature(cfi_encoding)]
 #![feature(concat_idents)]
diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs
index eeee98f754e09..d9af16b13a11f 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(cfg_target_abi)]
 #![feature(strict_provenance)]
 #![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 fb32918d5e439..0000000000000
--- 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
diff --git a/src/tools/miri/tests/fail-dep/concurrency/unwind_top_of_stack.rs b/src/tools/miri/tests/fail-dep/concurrency/unwind_top_of_stack.rs
index 4704cfed03938..9a5234717d1ff 100644
--- a/src/tools/miri/tests/fail-dep/concurrency/unwind_top_of_stack.rs
+++ b/src/tools/miri/tests/fail-dep/concurrency/unwind_top_of_stack.rs
@@ -4,8 +4,6 @@
 
 //! Unwinding past the top frame of a stack is Undefined Behavior.
 
-#![feature(c_unwind)]
-
 use std::{mem, ptr};
 
 extern "C-unwind" fn thread_start(_null: *mut libc::c_void) -> *mut libc::c_void {
diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.rs b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.rs
index 5f4df7c6a1ef3..1ebfecc44e8bc 100644
--- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.rs
+++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.rs
@@ -1,5 +1,4 @@
 //@compile-flags: -Zmiri-disable-abi-check
-#![feature(c_unwind)]
 
 #[no_mangle]
 extern "C-unwind" fn unwind() {
diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.rs b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.rs
index e6aff19b02d49..1382e9571f316 100644
--- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.rs
+++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.rs
@@ -4,7 +4,7 @@
 //@normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> ""
 //@normalize-stderr-test: "\n +at [^\n]+" -> ""
 //@[definition,both]error-in-other-file: aborted execution
-#![feature(rustc_attrs, c_unwind)]
+#![feature(rustc_attrs)]
 
 #[cfg_attr(any(definition, both), rustc_nounwind)]
 #[no_mangle]
diff --git a/src/tools/miri/tests/fail/panic/bad_miri_start_panic.rs b/src/tools/miri/tests/fail/panic/bad_miri_start_panic.rs
index 4b0ae60b10101..be2ac7195968e 100644
--- a/src/tools/miri/tests/fail/panic/bad_miri_start_panic.rs
+++ b/src/tools/miri/tests/fail/panic/bad_miri_start_panic.rs
@@ -1,6 +1,5 @@
 //@compile-flags: -Zmiri-disable-abi-check
 // This feature is required to trigger the error using the "C" ABI.
-#![feature(c_unwind)]
 
 extern "C" {
     fn miri_start_panic(payload: *mut u8) -> !;
diff --git a/src/tools/miri/tests/fail/panic/bad_unwind.rs b/src/tools/miri/tests/fail/panic/bad_unwind.rs
index 370b372a7d373..9c9571a460357 100644
--- a/src/tools/miri/tests/fail/panic/bad_unwind.rs
+++ b/src/tools/miri/tests/fail/panic/bad_unwind.rs
@@ -1,5 +1,3 @@
-#![feature(c_unwind)]
-
 //! Unwinding when the caller ABI is "C" (without "-unwind") is UB.
 
 extern "C-unwind" fn unwind() {
diff --git a/src/tools/miri/tests/fail/terminate-terminator.rs b/src/tools/miri/tests/fail/terminate-terminator.rs
index 7c6728280305d..465625c757251 100644
--- a/src/tools/miri/tests/fail/terminate-terminator.rs
+++ b/src/tools/miri/tests/fail/terminate-terminator.rs
@@ -7,8 +7,6 @@
 // Enable MIR inlining to ensure that `TerminatorKind::UnwindTerminate` is generated
 // instead of just `UnwindAction::Terminate`.
 
-#![feature(c_unwind)]
-
 struct Foo;
 
 impl Drop for Foo {
diff --git a/src/tools/miri/tests/fail/unwind-action-terminate.rs b/src/tools/miri/tests/fail/unwind-action-terminate.rs
index 86406872c5991..465e07c8db4b8 100644
--- a/src/tools/miri/tests/fail/unwind-action-terminate.rs
+++ b/src/tools/miri/tests/fail/unwind-action-terminate.rs
@@ -3,8 +3,6 @@
 //@normalize-stderr-test: "\| +\^+" -> "| ^"
 //@normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> ""
 //@normalize-stderr-test: "\n +at [^\n]+" -> ""
-#![feature(c_unwind)]
-
 extern "C" fn panic_abort() {
     panic!()
 }
diff --git a/src/tools/miri/tests/panic/function_calls/exported_symbol_good_unwind.rs b/src/tools/miri/tests/panic/function_calls/exported_symbol_good_unwind.rs
index 71b799a1f12ba..0e8d45af27fdf 100644
--- a/src/tools/miri/tests/panic/function_calls/exported_symbol_good_unwind.rs
+++ b/src/tools/miri/tests/panic/function_calls/exported_symbol_good_unwind.rs
@@ -2,7 +2,7 @@
 // found in this form" errors works without `-C prefer-dynamic` (`panic!` calls foreign function
 // `__rust_start_panic`).
 // no-prefer-dynamic
-#![feature(c_unwind, unboxed_closures)]
+#![feature(unboxed_closures)]
 
 use std::panic;
 
diff --git a/tests/assembly/asm/aarch64-modifiers.rs b/tests/assembly/asm/aarch64-modifiers.rs
index 5196aa9fa1759..2f707e2cdc395 100644
--- a/tests/assembly/asm/aarch64-modifiers.rs
+++ b/tests/assembly/asm/aarch64-modifiers.rs
@@ -1,5 +1,5 @@
 // assembly-output: emit-asm
-// compile-flags: -O
+// compile-flags: -O -C panic=abort
 // compile-flags: --target aarch64-unknown-linux-gnu
 // needs-llvm-components: aarch64
 
diff --git a/tests/assembly/asm/arm-modifiers.rs b/tests/assembly/asm/arm-modifiers.rs
index 88ffeaecfecb6..6c390be8696ea 100644
--- a/tests/assembly/asm/arm-modifiers.rs
+++ b/tests/assembly/asm/arm-modifiers.rs
@@ -1,5 +1,5 @@
 // assembly-output: emit-asm
-// compile-flags: -O
+// compile-flags: -O -C panic=abort
 // compile-flags: --target armv7-unknown-linux-gnueabihf
 // compile-flags: -C target-feature=+neon
 // needs-llvm-components: arm
diff --git a/tests/assembly/asm/x86-modifiers.rs b/tests/assembly/asm/x86-modifiers.rs
index 574fdf12cd040..4a58ec52f7540 100644
--- a/tests/assembly/asm/x86-modifiers.rs
+++ b/tests/assembly/asm/x86-modifiers.rs
@@ -1,6 +1,6 @@
 // revisions: x86_64 i686
 // assembly-output: emit-asm
-// compile-flags: -O
+// compile-flags: -O -C panic=abort
 //[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
 //[x86_64] needs-llvm-components: x86
 //[i686] compile-flags: --target i686-unknown-linux-gnu
diff --git a/tests/codegen/avr/avr-func-addrspace.rs b/tests/codegen/avr/avr-func-addrspace.rs
index dc36a9fac8c23..f16d43881a429 100644
--- a/tests/codegen/avr/avr-func-addrspace.rs
+++ b/tests/codegen/avr/avr-func-addrspace.rs
@@ -1,4 +1,4 @@
-// compile-flags: -O --target=avr-unknown-gnu-atmega328 --crate-type=rlib
+// compile-flags: -O --target=avr-unknown-gnu-atmega328 --crate-type=rlib -C panic=abort
 // needs-llvm-components: avr
 
 // This test validates that function pointers can be stored in global variables
diff --git a/tests/codegen/catch-unwind.rs b/tests/codegen/catch-unwind.rs
index 6b63b83ef4594..22620226508e6 100644
--- a/tests/codegen/catch-unwind.rs
+++ b/tests/codegen/catch-unwind.rs
@@ -14,7 +14,6 @@
 // ignore-loongarch64 FIXME
 
 #![crate_type = "lib"]
-#![feature(c_unwind)]
 
 extern "C" {
     fn bar();
diff --git a/tests/codegen/cffi/c-variadic.rs b/tests/codegen/cffi/c-variadic.rs
index cab32652210d0..fc6440dcd383e 100644
--- a/tests/codegen/cffi/c-variadic.rs
+++ b/tests/codegen/cffi/c-variadic.rs
@@ -4,7 +4,6 @@
 
 #![crate_type = "lib"]
 #![feature(c_variadic)]
-#![feature(c_unwind)]
 #![no_std]
 use core::ffi::VaList;
 
diff --git a/tests/codegen/debuginfo-inline-callsite-location.rs b/tests/codegen/debuginfo-inline-callsite-location.rs
index b1475ee793160..b042d181921c9 100644
--- a/tests/codegen/debuginfo-inline-callsite-location.rs
+++ b/tests/codegen/debuginfo-inline-callsite-location.rs
@@ -20,7 +20,7 @@
 #![crate_type = "lib"]
 
 #[no_mangle]
-extern "C" fn add_numbers(x: &Option<i32>, y: &Option<i32>) -> i32 {
+extern "C-unwind" fn add_numbers(x: &Option<i32>, y: &Option<i32>) -> i32 {
     let x1 = x.unwrap();
     let y1 = y.unwrap();
 
diff --git a/tests/codegen/unwind-abis/aapcs-unwind-abi.rs b/tests/codegen/unwind-abis/aapcs-unwind-abi.rs
index c092e28a05ac8..d5b1a00a4f116 100644
--- a/tests/codegen/unwind-abis/aapcs-unwind-abi.rs
+++ b/tests/codegen/unwind-abis/aapcs-unwind-abi.rs
@@ -1,7 +1,7 @@
 // needs-llvm-components: arm
 // compile-flags: --target=armv7-unknown-linux-gnueabihf --crate-type=rlib -Cno-prepopulate-passes
 #![no_core]
-#![feature(no_core, lang_items, c_unwind)]
+#![feature(no_core, lang_items)]
 #[lang="sized"]
 trait Sized { }
 
diff --git a/tests/codegen/unwind-abis/c-unwind-abi-panic-abort.rs b/tests/codegen/unwind-abis/c-unwind-abi-panic-abort.rs
index ea5bae18e2337..50cc3e4b45b20 100644
--- a/tests/codegen/unwind-abis/c-unwind-abi-panic-abort.rs
+++ b/tests/codegen/unwind-abis/c-unwind-abi-panic-abort.rs
@@ -4,7 +4,6 @@
 // when the code is compiled with `panic=abort`.
 
 #![crate_type = "lib"]
-#![feature(c_unwind)]
 
 // CHECK: @rust_item_that_can_unwind() unnamed_addr [[ATTR0:#[0-9]+]]
 #[no_mangle]
diff --git a/tests/codegen/unwind-abis/c-unwind-abi.rs b/tests/codegen/unwind-abis/c-unwind-abi.rs
index fa5b6bad75cb3..4001d5a6ca373 100644
--- a/tests/codegen/unwind-abis/c-unwind-abi.rs
+++ b/tests/codegen/unwind-abis/c-unwind-abi.rs
@@ -6,7 +6,6 @@
 // to prevent LLVM from inferring the attribute.
 
 #![crate_type = "lib"]
-#![feature(c_unwind)]
 
 // CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 {
 #[no_mangle]
diff --git a/tests/codegen/unwind-abis/cdecl-unwind-abi.rs b/tests/codegen/unwind-abis/cdecl-unwind-abi.rs
index 64746d32175be..f4906adf50e2e 100644
--- a/tests/codegen/unwind-abis/cdecl-unwind-abi.rs
+++ b/tests/codegen/unwind-abis/cdecl-unwind-abi.rs
@@ -6,7 +6,6 @@
 // disable optimizations above to prevent LLVM from inferring the attribute.
 
 #![crate_type = "lib"]
-#![feature(c_unwind)]
 
 // CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 {
 #[no_mangle]
diff --git a/tests/codegen/unwind-abis/fastcall-unwind-abi.rs b/tests/codegen/unwind-abis/fastcall-unwind-abi.rs
index b74099a5d965b..68df2a903e2d0 100644
--- a/tests/codegen/unwind-abis/fastcall-unwind-abi.rs
+++ b/tests/codegen/unwind-abis/fastcall-unwind-abi.rs
@@ -1,7 +1,7 @@
 // needs-llvm-components: x86
 // compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes
 #![no_core]
-#![feature(no_core, lang_items, c_unwind)]
+#![feature(no_core, lang_items)]
 #[lang="sized"]
 trait Sized { }
 
diff --git a/tests/codegen/unwind-abis/nounwind-on-stable-panic-unwind.rs b/tests/codegen/unwind-abis/nounwind-on-stable-panic-unwind.rs
deleted file mode 100644
index dc3911cd4ebac..0000000000000
--- a/tests/codegen/unwind-abis/nounwind-on-stable-panic-unwind.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-// compile-flags: -C opt-level=0
-// ignore-wasm32-bare compiled with panic=abort by default
-// needs-unwind
-
-#![crate_type = "lib"]
-
-// We disable optimizations to prevent LLVM from inferring the attribute.
-
-extern "C" {
-    fn bar();
-}
-
-// CHECK-NOT: Function Attrs:{{.*}}nounwind
-pub unsafe extern "C" fn foo() {
-    bar();
-}
-
-// Note that this test will get removed when `C-unwind` is fully stabilized
diff --git a/tests/codegen/unwind-abis/nounwind.rs b/tests/codegen/unwind-abis/nounwind.rs
index c46d717331b46..106d593b21de2 100644
--- a/tests/codegen/unwind-abis/nounwind.rs
+++ b/tests/codegen/unwind-abis/nounwind.rs
@@ -2,7 +2,6 @@
 // ignore-wasm32-bare compiled with panic=abort by default
 
 #![crate_type = "lib"]
-#![feature(c_unwind)]
 
 // We disable optimizations to prevent LLVM from inferring the attribute.
 
diff --git a/tests/codegen/unwind-abis/stdcall-unwind-abi.rs b/tests/codegen/unwind-abis/stdcall-unwind-abi.rs
index 8eff0719f8fa7..4f2edb5a9b511 100644
--- a/tests/codegen/unwind-abis/stdcall-unwind-abi.rs
+++ b/tests/codegen/unwind-abis/stdcall-unwind-abi.rs
@@ -1,7 +1,7 @@
 // needs-llvm-components: x86
 // compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes
 #![no_core]
-#![feature(no_core, lang_items, c_unwind)]
+#![feature(no_core, lang_items)]
 #[lang="sized"]
 trait Sized { }
 
diff --git a/tests/codegen/unwind-abis/system-unwind-abi.rs b/tests/codegen/unwind-abis/system-unwind-abi.rs
index f274a33b09948..6336f91c3388a 100644
--- a/tests/codegen/unwind-abis/system-unwind-abi.rs
+++ b/tests/codegen/unwind-abis/system-unwind-abi.rs
@@ -6,7 +6,6 @@
 // optimizations above to prevent LLVM from inferring the attribute.
 
 #![crate_type = "lib"]
-#![feature(c_unwind)]
 
 // CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 {
 #[no_mangle]
diff --git a/tests/codegen/unwind-abis/sysv64-unwind-abi.rs b/tests/codegen/unwind-abis/sysv64-unwind-abi.rs
index 694fde17c3cbe..3bdd6b5161002 100644
--- a/tests/codegen/unwind-abis/sysv64-unwind-abi.rs
+++ b/tests/codegen/unwind-abis/sysv64-unwind-abi.rs
@@ -1,7 +1,7 @@
 // needs-llvm-components: x86
 // compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib -Cno-prepopulate-passes
 #![no_core]
-#![feature(no_core, lang_items, c_unwind)]
+#![feature(no_core, lang_items)]
 #[lang="sized"]
 trait Sized { }
 
diff --git a/tests/codegen/unwind-abis/thiscall-unwind-abi.rs b/tests/codegen/unwind-abis/thiscall-unwind-abi.rs
index 0a02755a2cd85..05e8034c894ae 100644
--- a/tests/codegen/unwind-abis/thiscall-unwind-abi.rs
+++ b/tests/codegen/unwind-abis/thiscall-unwind-abi.rs
@@ -1,7 +1,7 @@
 // needs-llvm-components: x86
 // compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes
 #![no_core]
-#![feature(no_core, lang_items, c_unwind)]
+#![feature(no_core, lang_items)]
 #[lang="sized"]
 trait Sized { }
 
diff --git a/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs b/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs
index d7eca2a970002..cb59977ae56f4 100644
--- a/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs
+++ b/tests/codegen/unwind-abis/vectorcall-unwind-abi.rs
@@ -1,7 +1,7 @@
 // needs-llvm-components: x86
 // compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes
 #![no_core]
-#![feature(no_core, lang_items, c_unwind, abi_vectorcall)]
+#![feature(no_core, lang_items, abi_vectorcall)]
 #[lang="sized"]
 trait Sized { }
 
diff --git a/tests/codegen/unwind-abis/win64-unwind-abi.rs b/tests/codegen/unwind-abis/win64-unwind-abi.rs
index 6591348c35d3d..e32946cddede0 100644
--- a/tests/codegen/unwind-abis/win64-unwind-abi.rs
+++ b/tests/codegen/unwind-abis/win64-unwind-abi.rs
@@ -1,7 +1,7 @@
 // needs-llvm-components: x86
 // compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib -Cno-prepopulate-passes
 #![no_core]
-#![feature(no_core, lang_items, c_unwind)]
+#![feature(no_core, lang_items)]
 #[lang="sized"]
 trait Sized { }
 
diff --git a/tests/codegen/unwind-and-panic-abort.rs b/tests/codegen/unwind-and-panic-abort.rs
index e43e73b96b996..f319fb422d66b 100644
--- a/tests/codegen/unwind-and-panic-abort.rs
+++ b/tests/codegen/unwind-and-panic-abort.rs
@@ -1,7 +1,6 @@
 // compile-flags: -C panic=abort
 
 #![crate_type = "lib"]
-#![feature(c_unwind)]
 
 extern "C-unwind" {
     fn bar();
diff --git a/tests/codegen/unwind-extern-exports.rs b/tests/codegen/unwind-extern-exports.rs
index 4e1e719d5cd18..a20b4926f52c0 100644
--- a/tests/codegen/unwind-extern-exports.rs
+++ b/tests/codegen/unwind-extern-exports.rs
@@ -3,7 +3,6 @@
 // needs-unwind
 
 #![crate_type = "lib"]
-#![feature(c_unwind)]
 
 // Make sure these all do *not* get the attribute.
 // We disable optimizations to prevent LLVM from inferring the attribute.
diff --git a/tests/codegen/unwind-extern-imports.rs b/tests/codegen/unwind-extern-imports.rs
index 260dcc628cc0e..386d2e65f08b5 100644
--- a/tests/codegen/unwind-extern-imports.rs
+++ b/tests/codegen/unwind-extern-imports.rs
@@ -3,7 +3,6 @@
 // needs-unwind
 
 #![crate_type = "lib"]
-#![feature(c_unwind)]
 
 extern "C" {
     // CHECK: Function Attrs:{{.*}}nounwind
diff --git a/tests/coverage/abort.cov-map b/tests/coverage/abort.cov-map
index 45d3795eff8f3..c939ca21e38af 100644
--- a/tests/coverage/abort.cov-map
+++ b/tests/coverage/abort.cov-map
@@ -1,5 +1,5 @@
 Function name: abort::main
-Raw bytes (105): 0x[01, 01, 12, 01, 47, 05, 09, 03, 0d, 42, 11, 03, 0d, 11, 3e, 42, 11, 03, 0d, 3b, 15, 11, 3e, 42, 11, 03, 0d, 15, 36, 3b, 15, 11, 3e, 42, 11, 03, 0d, 05, 09, 0d, 01, 0d, 01, 01, 1b, 03, 02, 0b, 00, 18, 42, 01, 0c, 00, 19, 11, 00, 1a, 02, 0a, 3e, 02, 0a, 00, 0b, 3b, 02, 0c, 00, 19, 15, 00, 1a, 00, 31, 36, 00, 31, 00, 32, 33, 04, 0c, 00, 19, 05, 00, 1a, 00, 31, 09, 00, 31, 00, 32, 47, 01, 09, 00, 17, 0d, 02, 05, 01, 02]
+Raw bytes (105): 0x[01, 01, 12, 01, 47, 05, 09, 03, 0d, 42, 11, 03, 0d, 11, 3e, 42, 11, 03, 0d, 3b, 15, 11, 3e, 42, 11, 03, 0d, 15, 36, 3b, 15, 11, 3e, 42, 11, 03, 0d, 05, 09, 0d, 01, 0c, 01, 01, 1b, 03, 02, 0b, 00, 18, 42, 01, 0c, 00, 19, 11, 00, 1a, 02, 0a, 3e, 02, 0a, 00, 0b, 3b, 02, 0c, 00, 19, 15, 00, 1a, 00, 31, 36, 00, 31, 00, 32, 33, 04, 0c, 00, 19, 05, 00, 1a, 00, 31, 09, 00, 31, 00, 32, 47, 01, 09, 00, 17, 0d, 02, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 18
@@ -22,7 +22,7 @@ Number of expressions: 18
 - expression 16 operands: lhs = Expression(0, Add), rhs = Counter(3)
 - expression 17 operands: lhs = Counter(1), rhs = Counter(2)
 Number of file 0 mappings: 13
-- Code(Counter(0)) at (prev + 13, 1) to (start + 1, 27)
+- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 27)
 - Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 24)
     = (c0 + (c1 + c2))
 - Code(Expression(16, Sub)) at (prev + 1, 12) to (start + 0, 25)
@@ -44,13 +44,13 @@ Number of file 0 mappings: 13
 - Code(Counter(3)) at (prev + 2, 5) to (start + 1, 2)
 
 Function name: abort::might_abort
-Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 04, 01, 01, 14, 05, 02, 09, 01, 24, 02, 02, 0c, 03, 02]
+Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 03, 01, 01, 14, 05, 02, 09, 01, 24, 02, 02, 0c, 03, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 3
-- Code(Counter(0)) at (prev + 4, 1) to (start + 1, 20)
+- Code(Counter(0)) at (prev + 3, 1) to (start + 1, 20)
 - Code(Counter(1)) at (prev + 2, 9) to (start + 1, 36)
 - Code(Expression(0, Sub)) at (prev + 2, 12) to (start + 3, 2)
     = (c0 - c1)
diff --git a/tests/coverage/abort.rs b/tests/coverage/abort.rs
index 98264bdc1afe5..11ad4286f5865 100644
--- a/tests/coverage/abort.rs
+++ b/tests/coverage/abort.rs
@@ -1,4 +1,3 @@
-#![feature(c_unwind)]
 #![allow(unused_assignments)]
 
 extern "C" fn might_abort(should_abort: bool) {
diff --git a/tests/run-make/forced-unwind-terminate-pof/foo.rs b/tests/run-make/forced-unwind-terminate-pof/foo.rs
index 0a51287313f6e..3a84784621708 100644
--- a/tests/run-make/forced-unwind-terminate-pof/foo.rs
+++ b/tests/run-make/forced-unwind-terminate-pof/foo.rs
@@ -1,6 +1,5 @@
 // Tests that forced unwind through POF Rust frames wouldn't trigger our terminating guards.
 
-#![feature(c_unwind)]
 #![no_main]
 
 extern "C-unwind" {
diff --git a/tests/run-make/no-builtins-lto/Makefile b/tests/run-make/no-builtins-lto/Makefile
index c7be4836466db..33362e03c7a7b 100644
--- a/tests/run-make/no-builtins-lto/Makefile
+++ b/tests/run-make/no-builtins-lto/Makefile
@@ -8,8 +8,8 @@ include ../tools.mk
 # Others will use the built-in memcpy.
 
 all:
-	$(RUSTC) -C linker-plugin-lto -C opt-level=2 -C debuginfo=0 foo.rs
-	$(RUSTC) -C linker-plugin-lto -C opt-level=2 -C debuginfo=0 no_builtins.rs
-	$(RUSTC) main.rs -C lto -C opt-level=2 -C debuginfo=0 -C save-temps -C metadata=1 -C codegen-units=1
+	$(RUSTC) -C linker-plugin-lto -C panic=abort -C opt-level=2 -C debuginfo=0 foo.rs
+	$(RUSTC) -C linker-plugin-lto -C panic=abort -C opt-level=2 -C debuginfo=0 no_builtins.rs
+	$(RUSTC) main.rs -C lto -C panic=abort -C opt-level=2 -C debuginfo=0 -C save-temps -C metadata=1 -C codegen-units=1
 	"$(LLVM_BIN_DIR)"/llvm-dis $(TMPDIR)/main.main.*-cgu.0.rcgu.lto.input.bc -o $(TMPDIR)/lto.ll
 	cat "$(TMPDIR)"/lto.ll | "$(LLVM_FILECHECK)" filecheck.lto.txt
diff --git a/tests/ui/asm/x86_64/may_unwind.rs b/tests/ui/asm/x86_64/may_unwind.rs
index c11f0938d0b6c..171cae8c514f4 100644
--- a/tests/ui/asm/x86_64/may_unwind.rs
+++ b/tests/ui/asm/x86_64/may_unwind.rs
@@ -16,7 +16,7 @@ impl Drop for Foo<'_> {
     }
 }
 
-extern "C" fn panicky() {
+extern "C-unwind" fn panicky() {
     resume_unwind(Box::new(()));
 }
 
diff --git a/tests/ui/consts/const-eval/unwind-abort.rs b/tests/ui/consts/const-eval/unwind-abort.rs
index 57959e7db6ad9..26113e238883d 100644
--- a/tests/ui/consts/const-eval/unwind-abort.rs
+++ b/tests/ui/consts/const-eval/unwind-abort.rs
@@ -1,4 +1,4 @@
-#![feature(c_unwind, const_extern_fn)]
+#![feature(const_extern_fn)]
 
 const extern "C" fn foo() {
     panic!() //~ ERROR evaluation of constant value failed
diff --git a/tests/ui/consts/unwind-abort.rs b/tests/ui/consts/unwind-abort.rs
index 6c94fc7b98b75..7b38d6653d1af 100644
--- a/tests/ui/consts/unwind-abort.rs
+++ b/tests/ui/consts/unwind-abort.rs
@@ -1,6 +1,6 @@
 // check-pass
 
-#![feature(c_unwind, const_extern_fn)]
+#![feature(const_extern_fn)]
 
 // We don't unwind in const-eval anyways.
 const extern "C" fn foo() {
diff --git a/tests/ui/panics/abort-on-panic.rs b/tests/ui/panics/abort-on-panic.rs
index ff31fc2431740..660e483830b80 100644
--- a/tests/ui/panics/abort-on-panic.rs
+++ b/tests/ui/panics/abort-on-panic.rs
@@ -3,7 +3,6 @@
 //[next] compile-flags: -Znext-solver
 
 #![allow(unused_must_use)]
-#![feature(c_unwind)]
 #![feature(panic_always_abort)]
 // Since we mark some ABIs as "nounwind" to LLVM, we must make sure that
 // we never unwind through them.
diff --git a/tests/ui/panics/panic-in-ffi.rs b/tests/ui/panics/panic-in-ffi.rs
index d9f1fcee85546..ea067eb3a8b8f 100644
--- a/tests/ui/panics/panic-in-ffi.rs
+++ b/tests/ui/panics/panic-in-ffi.rs
@@ -7,7 +7,6 @@
 // normalize-stderr-test: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL"
 // needs-unwind
 // ignore-emscripten "RuntimeError" junk in output
-#![feature(c_unwind)]
 
 extern "C" fn panic_in_ffi() {
     panic!("Test");
diff --git a/tests/ui/panics/panic-in-ffi.run.stderr b/tests/ui/panics/panic-in-ffi.run.stderr
index a92a66c57fd7d..596355399c801 100644
--- a/tests/ui/panics/panic-in-ffi.run.stderr
+++ b/tests/ui/panics/panic-in-ffi.run.stderr
@@ -1,4 +1,4 @@
-thread 'main' panicked at $DIR/panic-in-ffi.rs:13:5:
+thread 'main' panicked at $DIR/panic-in-ffi.rs:12:5:
 Test
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 thread 'main' panicked at library/core/src/panicking.rs:$LINE:$COL:
diff --git a/tests/ui/unwind-abis/feature-gate-c_unwind.rs b/tests/ui/unwind-abis/feature-gate-c_unwind.rs
deleted file mode 100644
index d73fe3e0bdada..0000000000000
--- a/tests/ui/unwind-abis/feature-gate-c_unwind.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-// ignore-test
-
-// After partial stabilisation, `c_unwind` only contains codegen behaviour changes
-// and are tested in `src/test/codegen/unwind-abis`