rustc_target: add "unwind" payloads to Abi
### Overview
This commit begins the implementation work for RFC 2945. For more
information, see the rendered RFC [1] and tracking issue [2].
A boolean `unwind` payload is added to the `C`, `System`, `Stdcall`,
and `Thiscall` variants, marking whether unwinding across FFI
boundaries is acceptable. The cases where each of these variants'
`unwind` member is true correspond with the `C-unwind`,
`system-unwind`, `stdcall-unwind`, and `thiscall-unwind` ABI strings
introduced in RFC 2945 [3].
### Feature Gate and Unstable Book
This commit adds a `c_unwind` feature gate for the new ABI strings.
Tests for this feature gate are included in `src/test/ui/c-unwind/`,
which ensure that this feature gate works correctly for each of the
new ABIs.
A new language features entry in the unstable book is added as well.
### Further Work To Be Done
This commit does not proceed to implement the new unwinding ABIs,
and is intentionally scoped specifically to *defining* the ABIs and
their feature flag.
### One Note on Test Churn
This will lead to some test churn, in re-blessing hash tests, as the
deleted comment in `src/librustc_target/spec/abi.rs` mentioned,
because we can no longer guarantee the ordering of the `Abi`
variants.
While this is a downside, this decision was made bearing in mind
that RFC 2945 states the following, in the "Other `unwind` Strings"
section [3]:
> More unwind variants of existing ABI strings may be introduced,
> with the same semantics, without an additional RFC.
Adding a new variant for each of these cases, rather than specifying
a payload for a given ABI, would quickly become untenable, and make
working with the `Abi` enum prone to mistakes.
This approach encodes the unwinding information *into* a given ABI,
to account for the future possibility of other `-unwind` ABI
strings.
### Ignore Directives
`ignore-*` directives are used 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 would otherwise fail on some targets, see:
fcf697f902
### Footnotes
[1]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md
[2]: https://github.com/rust-lang/rust/issues/74990
[3]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md#other-unwind-abi-strings
This commit is contained in:
parent
3a5d45f68c
commit
df45c579de
29 changed files with 277 additions and 52 deletions
|
@ -2666,7 +2666,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
|
|||
} else if tcx.sess.check_name(attr, sym::used) {
|
||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED;
|
||||
} else if tcx.sess.check_name(attr, sym::cmse_nonsecure_entry) {
|
||||
if tcx.fn_sig(id).abi() != abi::Abi::C {
|
||||
if !matches!(tcx.fn_sig(id).abi(), abi::Abi::C { .. }) {
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
attr.span,
|
||||
|
|
|
@ -118,14 +118,19 @@ use astconv::AstConv;
|
|||
use bounds::Bounds;
|
||||
|
||||
fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi, span: Span) {
|
||||
if decl.c_variadic && !(abi == Abi::C || abi == Abi::Cdecl) {
|
||||
let mut err = struct_span_err!(
|
||||
tcx.sess,
|
||||
span,
|
||||
E0045,
|
||||
"C-variadic function must have C or cdecl calling convention"
|
||||
);
|
||||
err.span_label(span, "C-variadics require C or cdecl calling convention").emit();
|
||||
match (decl.c_variadic, abi) {
|
||||
// The function has the correct calling convention, or isn't a "C-variadic" function.
|
||||
(false, _) | (true, Abi::C { .. }) | (true, Abi::Cdecl) => {}
|
||||
// The function is a "C-variadic" function with an incorrect calling convention.
|
||||
(true, _) => {
|
||||
let mut err = struct_span_err!(
|
||||
tcx.sess,
|
||||
span,
|
||||
E0045,
|
||||
"C-variadic function must have C or cdecl calling convention"
|
||||
);
|
||||
err.span_label(span, "C-variadics require C or cdecl calling convention").emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue