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
|
@ -2562,6 +2562,7 @@ fn fn_can_unwind(
|
|||
panic_strategy: PanicStrategy,
|
||||
codegen_fn_attr_flags: CodegenFnAttrFlags,
|
||||
call_conv: Conv,
|
||||
abi: SpecAbi,
|
||||
) -> bool {
|
||||
if panic_strategy != PanicStrategy::Unwind {
|
||||
// In panic=abort mode we assume nothing can unwind anywhere, so
|
||||
|
@ -2586,17 +2587,16 @@ fn fn_can_unwind(
|
|||
//
|
||||
// 2. A Rust item using a non-Rust ABI (like `extern "C" fn foo() { ... }`).
|
||||
//
|
||||
// Foreign items (case 1) are assumed to not unwind; it is
|
||||
// UB otherwise. (At least for now; see also
|
||||
// rust-lang/rust#63909 and Rust RFC 2753.)
|
||||
//
|
||||
// Items defined in Rust with non-Rust ABIs (case 2) are also
|
||||
// not supposed to unwind. Whether this should be enforced
|
||||
// (versus stating it is UB) and *how* it would be enforced
|
||||
// is currently under discussion; see rust-lang/rust#58794.
|
||||
//
|
||||
// In either case, we mark item as explicitly nounwind.
|
||||
false
|
||||
// In both of these cases, we should refer to the ABI to determine whether or not we
|
||||
// should unwind. See Rust RFC 2945 for more information on this behavior, here:
|
||||
// https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md
|
||||
use SpecAbi::*;
|
||||
match abi {
|
||||
C { unwind } | Stdcall { unwind } | System { unwind } | Thiscall { unwind } => {
|
||||
unwind
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2823,7 +2823,12 @@ where
|
|||
c_variadic: sig.c_variadic,
|
||||
fixed_count: inputs.len(),
|
||||
conv,
|
||||
can_unwind: fn_can_unwind(cx.tcx().sess.panic_strategy(), codegen_fn_attr_flags, conv),
|
||||
can_unwind: fn_can_unwind(
|
||||
cx.tcx().sess.panic_strategy(),
|
||||
codegen_fn_attr_flags,
|
||||
conv,
|
||||
sig.abi,
|
||||
),
|
||||
};
|
||||
fn_abi.adjust_for_abi(cx, sig.abi);
|
||||
debug!("FnAbi::new_internal = {:?}", fn_abi);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue