diff options
| author | bors <bors@rust-lang.org> | 2022-05-17 15:04:50 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-05-17 15:04:50 +0000 |
| commit | 00755e4ca68f12ed200e921276788ab19975e85f (patch) | |
| tree | 3eb70385eaa911ef3c3cf4f230a6e2fd6bb303bd | |
| parent | 3655175a75f503c9855b6a73a9d3c83997354c1d (diff) | |
| parent | f86e409f0906deefd0871ba823c086dd58b50870 (diff) | |
| download | rust-00755e4ca68f12ed200e921276788ab19975e85f.tar.gz rust-00755e4ca68f12ed200e921276788ab19975e85f.zip | |
Auto merge of #96959 - nbdd0121:unwind, r=Amanieu
Prevent unwinding when `-C panic=abort` is used regardless declared ABI
Ensures that Rust code will abort with `-C panic=abort` regardless ABI used.
```rust
extern "C-unwind" {
fn may_unwind();
}
// Will be nounwind with `-C panic=abort`, despite `C-unwind` ABI.
pub unsafe extern "C-unwind" fn rust_item_that_can_unwind() {
may_unwind();
}
```
Current behaviour is that unwind will propagate through. While the current behaviour won't cause unsoundness it is inconsistent with the text reading of [RFC2945](https://rust-lang.github.io/rfcs/2945-c-unwind-abi.html).
I tweaked `fn_can_unwind` instead of tweaking `AbortUnwindingCalls` because this approach would allow Rust (non-direct) callers to also see that this function is nounwind, so it can prevent excessive landing pads generation.
For more discussions: https://rust-lang.zulipchat.com/#narrow/stream/210922-project-ffi-unwind/topic/soundness.20in.20mixed.20panic.20mode.
cc `@alexcrichton,` `@BatmanAoD`
r? `@Amanieu`
`@rustbot` label: T-compiler T-lang F-c_unwind
| -rw-r--r-- | compiler/rustc_middle/src/ty/layout.rs | 8 | ||||
| -rw-r--r-- | src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs | 21 |
2 files changed, 21 insertions, 8 deletions
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index d187146476a..a7488fd44cd 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -2888,6 +2888,14 @@ pub fn fn_can_unwind<'tcx>(tcx: TyCtxt<'tcx>, fn_def_id: Option<DefId>, abi: Spe return false; } + // With `-C panic=abort`, all non-FFI functions are required to not unwind. + // + // Note that this is true regardless ABI specified on the function -- a `extern "C-unwind"` + // function defined in Rust is also required to abort. + if tcx.sess.panic_strategy() == PanicStrategy::Abort && !tcx.is_foreign_item(did) { + return false; + } + // With -Z panic-in-drop=abort, drop_in_place never unwinds. // // This is not part of `codegen_fn_attrs` as it can differ between crates diff --git a/src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs b/src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs index 398937a04c9..e817d5715a1 100644 --- a/src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs +++ b/src/test/codegen/unwind-abis/c-unwind-abi-panic-abort.rs @@ -1,22 +1,27 @@ // compile-flags: -C panic=abort -// Test that `nounwind` atributes are not applied to `C-unwind` extern functions -// even when the code is compiled with `panic=abort`. +// Test that `nounwind` atributes are also applied to extern `C-unwind` Rust functions +// when the code is compiled with `panic=abort`. #![crate_type = "lib"] #![feature(c_unwind)] -extern "C-unwind" { - fn may_unwind(); -} - -// CHECK: @rust_item_that_can_unwind() unnamed_addr #0 +// CHECK: @rust_item_that_can_unwind() unnamed_addr [[ATTR0:#[0-9]+]] #[no_mangle] pub unsafe extern "C-unwind" fn rust_item_that_can_unwind() { + // CHECK: call void @_ZN4core9panicking15panic_no_unwind may_unwind(); } +extern "C-unwind" { + // CHECK: @may_unwind() unnamed_addr [[ATTR1:#[0-9]+]] + fn may_unwind(); +} + // Now, make sure that the LLVM attributes for this functions are correct. First, make // sure that the first item is correctly marked with the `nounwind` attribute: // -// CHECK-NOT: attributes #0 = { {{.*}}nounwind{{.*}} } +// CHECK: attributes [[ATTR0]] = { {{.*}}nounwind{{.*}} } +// +// Now, check that foreign item is correctly marked without the `nounwind` attribute. +// CHECK-NOT: attributes [[ATTR1]] = { {{.*}}nounwind{{.*}} } |
