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`.
This commit is contained in:
parent
df45c579de
commit
0f33e9f281
7 changed files with 176 additions and 16 deletions
|
@ -548,7 +548,7 @@ macro_rules! unpack {
|
|||
}};
|
||||
}
|
||||
|
||||
fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: LocalDefId, _abi: Abi) -> bool {
|
||||
fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: LocalDefId, abi: Abi) -> bool {
|
||||
// Validate `#[unwind]` syntax regardless of platform-specific panic strategy.
|
||||
let attrs = &tcx.get_attrs(fn_def_id.to_def_id());
|
||||
let unwind_attr = attr::find_unwind_attr(&tcx.sess, attrs);
|
||||
|
@ -558,12 +558,26 @@ fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: LocalDefId, _abi: Abi) -> b
|
|||
return false;
|
||||
}
|
||||
|
||||
// This is a special case: some functions have a C abi but are meant to
|
||||
// unwind anyway. Don't stop them.
|
||||
match unwind_attr {
|
||||
None => false, // FIXME(#58794); should be `!(abi == Abi::Rust || abi == Abi::RustCall)`
|
||||
// If an `#[unwind]` attribute was found, we should adhere to it.
|
||||
Some(UnwindAttr::Allowed) => false,
|
||||
Some(UnwindAttr::Aborts) => true,
|
||||
// If no attribute was found and the panic strategy is `unwind`, then we should examine
|
||||
// the function's ABI string to determine whether it should abort upon panic.
|
||||
None => {
|
||||
use Abi::*;
|
||||
match abi {
|
||||
// In the case of ABI's that have an `-unwind` equivalent, check whether the ABI
|
||||
// permits unwinding. If so, we should not abort. Otherwise, we should.
|
||||
C { unwind } | Stdcall { unwind } | System { unwind } | Thiscall { unwind } => {
|
||||
!unwind
|
||||
}
|
||||
// Rust and `rust-call` functions are allowed to unwind, and should not abort.
|
||||
Rust | RustCall => false,
|
||||
// Other ABI's should abort.
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue