Skip to content

Commit

Permalink
Auto merge of #116088 - nbdd0121:unwind, r=Amanieu,RalfJung
Browse files Browse the repository at this point in the history
Stabilise `c_unwind`

Fix #74990
Fix #115285 (that's also where FCP is happening)

Marking as draft PR for now due to `compiler_builtins` issues

r? `@Amanieu`
  • Loading branch information
bors committed Jun 20, 2024
2 parents 1d96de2 + bb2716e commit 1aaab8b
Show file tree
Hide file tree
Showing 64 changed files with 52 additions and 186 deletions.
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

0 comments on commit 1aaab8b

Please sign in to comment.