Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stabilise c_unwind #116088

Merged
merged 6 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
36 changes: 1 addition & 35 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1182,37 +1182,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 }
Expand All @@ -1224,10 +1193,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
Expand Down
34 changes: 1 addition & 33 deletions compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:?})");
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
2 changes: 1 addition & 1 deletion library/panic_abort/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down
2 changes: 1 addition & 1 deletion library/panic_unwind/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
4 changes: 3 additions & 1 deletion library/proc_macro/src/bridge/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ impl Write for Buffer {
}

impl Drop for Buffer {
#[inline]
// HACK(nbdd0121): Hack to prevent LLVM < 17.0.4 from misoptimising,
// change to `#[inline]` if fixed.
#[inline(never)]
fn drop(&mut self) {
let b = self.take();
(b.drop)(b);
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
2 changes: 1 addition & 1 deletion library/unwind/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))]
Expand Down
26 changes: 0 additions & 26 deletions src/doc/unstable-book/src/language-features/c-unwind.md

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![feature(c_unwind)]

#[no_mangle]
extern "C-unwind" fn unwind() {
panic!();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
2 changes: 0 additions & 2 deletions src/tools/miri/tests/fail/panic/bad_unwind.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![feature(c_unwind)]

//! Unwinding when the caller ABI is "C" (without "-unwind") is UB.
// The opposite version (callee does not allow unwinding) is impossible to
// even write: MIR validation catches functions that have `UnwindContinue` but
Expand Down
2 changes: 0 additions & 2 deletions src/tools/miri/tests/fail/terminate-terminator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 0 additions & 2 deletions src/tools/miri/tests/fail/unwind-action-terminate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion tests/assembly/asm/aarch64-modifiers.rs
Original file line number Diff line number Diff line change
@@ -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

Expand Down
2 changes: 1 addition & 1 deletion tests/assembly/asm/arm-modifiers.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion tests/assembly/asm/x86-modifiers.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion tests/assembly/simd-bitmask.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//@ [aarch64] needs-llvm-components: aarch64
//@ [aarch64] min-llvm-version: 18.0
//@ assembly-output: emit-asm
//@ compile-flags: --crate-type=lib -O
//@ compile-flags: --crate-type=lib -O -C panic=abort

#![feature(no_core, lang_items, repr_simd, intrinsics)]
#![no_core]
Expand Down
2 changes: 1 addition & 1 deletion tests/assembly/simd-intrinsic-gather.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//@ [x86-avx512] needs-llvm-components: x86
//@ [x86-avx512] min-llvm-version: 18.0
//@ assembly-output: emit-asm
//@ compile-flags: --crate-type=lib -O
//@ compile-flags: --crate-type=lib -O -C panic=abort

#![feature(no_core, lang_items, repr_simd, intrinsics)]
#![no_core]
Expand Down
2 changes: 1 addition & 1 deletion tests/assembly/simd-intrinsic-mask-load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//@ [x86-avx512] compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bw,+avx512dq
//@ [x86-avx512] needs-llvm-components: x86
//@ assembly-output: emit-asm
//@ compile-flags: --crate-type=lib -O
//@ compile-flags: --crate-type=lib -O -C panic=abort

#![feature(no_core, lang_items, repr_simd, intrinsics)]
#![no_core]
Expand Down
2 changes: 1 addition & 1 deletion tests/assembly/simd-intrinsic-mask-reduce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
//@ [aarch64] needs-llvm-components: aarch64
//@ [aarch64] min-llvm-version: 18.0
//@ assembly-output: emit-asm
//@ compile-flags: --crate-type=lib -O
//@ compile-flags: --crate-type=lib -O -C panic=abort

#![feature(no_core, lang_items, repr_simd, intrinsics)]
#![no_core]
Expand Down
2 changes: 1 addition & 1 deletion tests/assembly/simd-intrinsic-mask-store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//@ [x86-avx512] compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bw,+avx512dq
//@ [x86-avx512] needs-llvm-components: x86
//@ assembly-output: emit-asm
//@ compile-flags: --crate-type=lib -O
//@ compile-flags: --crate-type=lib -O -C panic=abort

#![feature(no_core, lang_items, repr_simd, intrinsics)]
#![no_core]
Expand Down
2 changes: 1 addition & 1 deletion tests/assembly/simd-intrinsic-scatter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//@ [x86-avx512] needs-llvm-components: x86
//@ [x86-avx512] min-llvm-version: 18.0
//@ assembly-output: emit-asm
//@ compile-flags: --crate-type=lib -O
//@ compile-flags: --crate-type=lib -O -C panic=abort

#![feature(no_core, lang_items, repr_simd, intrinsics)]
#![no_core]
Expand Down
2 changes: 1 addition & 1 deletion tests/assembly/simd-intrinsic-select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//@ [aarch64] needs-llvm-components: aarch64
//@ [aarch64] min-llvm-version: 18.0
//@ assembly-output: emit-asm
//@ compile-flags: --crate-type=lib -O
//@ compile-flags: --crate-type=lib -O -C panic=abort

#![feature(no_core, lang_items, repr_simd, intrinsics)]
#![no_core]
Expand Down
6 changes: 3 additions & 3 deletions tests/assembly/wasm_exceptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@

#![crate_type = "lib"]
#![feature(core_intrinsics)]
#![feature(rustc_attrs)]

extern "C" {
extern "C-unwind" {
fn may_panic();
}

#[rustc_nounwind]
extern "C" {
fn log_number(number: usize);
}

Expand Down
4 changes: 2 additions & 2 deletions tests/codegen/align-byval-alignment-mismatch.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// ignore-tidy-linelength
//@ revisions:i686-linux x86_64-linux

//@[i686-linux] compile-flags: --target i686-unknown-linux-gnu
//@[i686-linux] compile-flags: --target i686-unknown-linux-gnu -C panic=abort
//@[i686-linux] needs-llvm-components: x86
//@[x86_64-linux] compile-flags: --target x86_64-unknown-linux-gnu
//@[x86_64-linux] compile-flags: --target x86_64-unknown-linux-gnu -C panic=abort
//@[x86_64-linux] needs-llvm-components: x86

// Tests that we correctly copy arguments into allocas when the alignment of the byval argument
Expand Down
2 changes: 1 addition & 1 deletion tests/codegen/avr/avr-func-addrspace.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down
1 change: 0 additions & 1 deletion tests/codegen/catch-unwind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
//@ ignore-loongarch64 FIXME

#![crate_type = "lib"]
#![feature(c_unwind)]

extern "C" {
fn bar();
Expand Down
Loading
Loading