forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implement unwinding abi's (RFC 2945)
### Changes This commit implements unwind ABI's, specified in RFC 2945. We adjust the `rustc_middle::ty::layout::fn_can_unwind` function, used to compute whether or not a `FnAbi` object represents a function that should be able to unwind when `panic=unwind` is in use. Changes are also made to `rustc_mir_build::build::should_abort_on_panic` so that the function ABI is used to determind whether it should abort, assuming that the `panic=unwind` strategy is being used, and no explicit unwind attribute was provided. ### Tests Unit tests, checking that the behavior is correct for `C-unwind`, `stdcall-unwind`, `system-unwind`, and `thiscall-unwind`, are included. These alternative `unwind` ABI strings are specified in RFC 2945, in the "_Other `unwind` ABI strings_" section. Additionally, a test case is included to assert that the LLVM IR generated for an external function defined with the `C-unwind` ABI will be appropriately labeled with the `nounwind` LLVM attribute when the `panic=abort` compilation flag is used. ### Ignore Directives This commit uses `ignore-*` directives in two of our `*-unwind` ABI test cases. Specifically, the `stdcall-unwind` and `thiscall-unwind` test cases ignore architectures that do not support `stdcall` and `thiscall`, respectively. These directives are cribbed from `src/test/ui/c-variadic/variadic-ffi-1.rs` for `stdcall`, and `src/test/ui/extern/extern-thiscall.rs` for `thiscall`.
- Loading branch information
katelyn a. martin
committed
Mar 3, 2021
1 parent
5461ee0
commit 9a007cf
Showing
7 changed files
with
176 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// compile-flags: -C panic=abort -C opt-level=0 | ||
|
||
// Test that `nounwind` atributes are applied to `C-unwind` extern functions when the | ||
// code is compiled with `panic=abort`. We disable optimizations above to prevent LLVM from | ||
// inferring the attribute. | ||
|
||
#![crate_type = "lib"] | ||
#![feature(c_unwind)] | ||
|
||
// CHECK: @rust_item_that_can_unwind() unnamed_addr #0 { | ||
#[no_mangle] | ||
pub extern "C-unwind" fn rust_item_that_can_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: attributes #0 = { {{.*}}nounwind{{.*}} } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// compile-flags: -C opt-level=0 | ||
|
||
// Test that `nounwind` atributes are correctly applied to exported `C` and `C-unwind` extern | ||
// functions. `C-unwind` functions MUST NOT have this attribute. We 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] | ||
pub extern "C" fn rust_item_that_cannot_unwind() { | ||
} | ||
|
||
// CHECK: @rust_item_that_can_unwind() unnamed_addr #1 { | ||
#[no_mangle] | ||
pub extern "C-unwind" fn rust_item_that_can_unwind() { | ||
} | ||
|
||
// Now, make some assertions that the LLVM attributes for these functions are correct. First, make | ||
// sure that the first item is correctly marked with the `nounwind` attribute: | ||
// | ||
// CHECK: attributes #0 = { {{.*}}nounwind{{.*}} } | ||
// | ||
// Next, let's assert that the second item, which CAN unwind, does not have this attribute. | ||
// | ||
// CHECK: attributes #1 = { | ||
// CHECK-NOT: nounwind | ||
// CHECK: } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// compile-flags: -C opt-level=0 | ||
// ignore-arm stdcall isn't supported | ||
// ignore-aarch64 stdcall isn't supported | ||
// ignore-riscv64 stdcall isn't supported | ||
|
||
// Test that `nounwind` atributes are correctly applied to exported `stdcall` and `stdcall-unwind` | ||
// extern functions. `stdcall-unwind` functions MUST NOT have this attribute. We 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] | ||
pub extern "stdcall" fn rust_item_that_cannot_unwind() { | ||
} | ||
|
||
// CHECK: @rust_item_that_can_unwind() unnamed_addr #1 { | ||
#[no_mangle] | ||
pub extern "stdcall-unwind" fn rust_item_that_can_unwind() { | ||
} | ||
|
||
// Now, make some assertions that the LLVM attributes for these functions are correct. First, make | ||
// sure that the first item is correctly marked with the `nounwind` attribute: | ||
// | ||
// CHECK: attributes #0 = { {{.*}}nounwind{{.*}} } | ||
// | ||
// Next, let's assert that the second item, which CAN unwind, does not have this attribute. | ||
// | ||
// CHECK: attributes #1 = { | ||
// CHECK-NOT: nounwind | ||
// CHECK: } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// compile-flags: -C opt-level=0 | ||
|
||
// Test that `nounwind` atributes are correctly applied to exported `system` and `system-unwind` | ||
// extern functions. `system-unwind` functions MUST NOT have this attribute. We 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] | ||
pub extern "system" fn rust_item_that_cannot_unwind() { | ||
} | ||
|
||
// CHECK: @rust_item_that_can_unwind() unnamed_addr #1 { | ||
#[no_mangle] | ||
pub extern "system-unwind" fn rust_item_that_can_unwind() { | ||
} | ||
|
||
// Now, make some assertions that the LLVM attributes for these functions are correct. First, make | ||
// sure that the first item is correctly marked with the `nounwind` attribute: | ||
// | ||
// CHECK: attributes #0 = { {{.*}}nounwind{{.*}} } | ||
// | ||
// Next, let's assert that the second item, which CAN unwind, does not have this attribute. | ||
// | ||
// CHECK: attributes #1 = { | ||
// CHECK-NOT: nounwind | ||
// CHECK: } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// compile-flags: -C opt-level=0 | ||
// ignore-arm thiscall isn't supported | ||
// ignore-aarch64 thiscall isn't supported | ||
// ignore-riscv64 thiscall isn't supported | ||
|
||
// Test that `nounwind` atributes are correctly applied to exported `thiscall` and | ||
// `thiscall-unwind` extern functions. `thiscall-unwind` functions MUST NOT have this attribute. We | ||
// disable optimizations above to prevent LLVM from inferring the attribute. | ||
|
||
#![crate_type = "lib"] | ||
#![feature(abi_thiscall)] | ||
#![feature(c_unwind)] | ||
|
||
// CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 { | ||
#[no_mangle] | ||
pub extern "thiscall" fn rust_item_that_cannot_unwind() { | ||
} | ||
|
||
// CHECK: @rust_item_that_can_unwind() unnamed_addr #1 { | ||
#[no_mangle] | ||
pub extern "thiscall-unwind" fn rust_item_that_can_unwind() { | ||
} | ||
|
||
// Now, make some assertions that the LLVM attributes for these functions are correct. First, make | ||
// sure that the first item is correctly marked with the `nounwind` attribute: | ||
// | ||
// CHECK: attributes #0 = { {{.*}}nounwind{{.*}} } | ||
// | ||
// Next, let's assert that the second item, which CAN unwind, does not have this attribute. | ||
// | ||
// CHECK: attributes #1 = { | ||
// CHECK-NOT: nounwind | ||
// CHECK: } |