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
@ -322,10 +322,10 @@ fn lower_item_kind(
|
||||
},
|
||||
ItemKind::ForeignMod(ref fm) => {
|
||||
if fm.abi.is_none() {
|
||||
self.maybe_lint_missing_abi(span, id, abi::Abi::C);
|
||||
self.maybe_lint_missing_abi(span, id, abi::Abi::C { unwind: false });
|
||||
}
|
||||
hir::ItemKind::ForeignMod {
|
||||
abi: fm.abi.map_or(abi::Abi::C, |abi| self.lower_abi(abi)),
|
||||
abi: fm.abi.map_or(abi::Abi::C { unwind: false }, |abi| self.lower_abi(abi)),
|
||||
items: self
|
||||
.arena
|
||||
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
|
||||
@ -1322,8 +1322,8 @@ pub(super) fn lower_extern(&mut self, ext: Extern, span: Span, id: NodeId) -> ab
|
||||
match ext {
|
||||
Extern::None => abi::Abi::Rust,
|
||||
Extern::Implicit => {
|
||||
self.maybe_lint_missing_abi(span, id, abi::Abi::C);
|
||||
abi::Abi::C
|
||||
self.maybe_lint_missing_abi(span, id, abi::Abi::C { unwind: false });
|
||||
abi::Abi::C { unwind: false }
|
||||
}
|
||||
Extern::Explicit(abi) => self.lower_abi(abi),
|
||||
}
|
||||
|
@ -164,6 +164,38 @@ fn check_abi(&self, abi: ast::StrLit) {
|
||||
"C-cmse-nonsecure-call ABI is experimental and subject to change"
|
||||
);
|
||||
}
|
||||
"C-unwind" => {
|
||||
gate_feature_post!(
|
||||
&self,
|
||||
c_unwind,
|
||||
span,
|
||||
"C-unwind ABI is experimental and subject to change"
|
||||
);
|
||||
}
|
||||
"stdcall-unwind" => {
|
||||
gate_feature_post!(
|
||||
&self,
|
||||
c_unwind,
|
||||
span,
|
||||
"stdcall-unwind ABI is experimental and subject to change"
|
||||
);
|
||||
}
|
||||
"system-unwind" => {
|
||||
gate_feature_post!(
|
||||
&self,
|
||||
c_unwind,
|
||||
span,
|
||||
"system-unwind ABI is experimental and subject to change"
|
||||
);
|
||||
}
|
||||
"thiscall-unwind" => {
|
||||
gate_feature_post!(
|
||||
&self,
|
||||
c_unwind,
|
||||
span,
|
||||
"thiscall-unwind ABI is experimental and subject to change"
|
||||
);
|
||||
}
|
||||
abi => self
|
||||
.sess
|
||||
.parse_sess
|
||||
|
@ -476,8 +476,11 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
||||
|
||||
// FIXME find a cleaner way to support varargs
|
||||
if fn_sig.c_variadic {
|
||||
if fn_sig.abi != Abi::C {
|
||||
fx.tcx.sess.span_fatal(span, &format!("Variadic call for non-C abi {:?}", fn_sig.abi));
|
||||
if !matches!(fn_sig.abi, Abi::C { .. }) {
|
||||
fx.tcx.sess.span_fatal(
|
||||
span,
|
||||
&format!("Variadic call for non-C abi {:?}", fn_sig.abi),
|
||||
);
|
||||
}
|
||||
let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap();
|
||||
let abi_params = call_args
|
||||
|
@ -644,6 +644,9 @@ pub fn set(&self, features: &mut Features, span: Span) {
|
||||
/// Allows associated types in inherent impls.
|
||||
(active, inherent_associated_types, "1.52.0", Some(8995), None),
|
||||
|
||||
/// Allows `extern "C-unwind" fn` to enable unwinding across ABI boundaries.
|
||||
(active, c_unwind, "1.52.0", Some(74990), None),
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// feature-group-end: actual feature gates
|
||||
// -------------------------------------------------------------------------
|
||||
|
@ -2654,14 +2654,14 @@ fn new_internal(
|
||||
RustIntrinsic | PlatformIntrinsic | Rust | RustCall => Conv::Rust,
|
||||
|
||||
// It's the ABI's job to select this, not ours.
|
||||
System => bug!("system abi should be selected elsewhere"),
|
||||
System { .. } => bug!("system abi should be selected elsewhere"),
|
||||
EfiApi => bug!("eficall abi should be selected elsewhere"),
|
||||
|
||||
Stdcall => Conv::X86Stdcall,
|
||||
Stdcall { .. } => Conv::X86Stdcall,
|
||||
Fastcall => Conv::X86Fastcall,
|
||||
Vectorcall => Conv::X86VectorCall,
|
||||
Thiscall => Conv::X86ThisCall,
|
||||
C => Conv::C,
|
||||
Thiscall { .. } => Conv::X86ThisCall,
|
||||
C { .. } => Conv::C,
|
||||
Unadjusted => Conv::C,
|
||||
Win64 => Conv::X86_64Win64,
|
||||
SysV64 => Conv::X86_64SysV,
|
||||
|
@ -248,9 +248,9 @@ fn eval_fn_call(
|
||||
};
|
||||
if normalize_abi(caller_abi) != normalize_abi(callee_abi) {
|
||||
throw_ub_format!(
|
||||
"calling a function with ABI {:?} using caller ABI {:?}",
|
||||
callee_abi,
|
||||
caller_abi
|
||||
"calling a function with ABI {} using caller ABI {}",
|
||||
callee_abi.name(),
|
||||
caller_abi.name()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -330,6 +330,7 @@
|
||||
bridge,
|
||||
bswap,
|
||||
c_str,
|
||||
c_unwind,
|
||||
c_variadic,
|
||||
call,
|
||||
call_mut,
|
||||
|
@ -440,7 +440,7 @@ fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
|
||||
}
|
||||
match sig.abi {
|
||||
Abi::Rust => {}
|
||||
Abi::C => cx.push("KC"),
|
||||
Abi::C { unwind: false } => cx.push("KC"),
|
||||
abi => {
|
||||
cx.push("K");
|
||||
let name = abi.name();
|
||||
|
@ -8,24 +8,21 @@
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug)]
|
||||
#[derive(HashStable_Generic, Encodable, Decodable)]
|
||||
pub enum Abi {
|
||||
// N.B., this ordering MUST match the AbiDatas array below.
|
||||
// (This is ensured by the test indices_are_correct().)
|
||||
|
||||
// Multiplatform / generic ABIs
|
||||
//
|
||||
// These ABIs come first because every time we add a new ABI, we
|
||||
// have to re-bless all the hashing tests. These are used in many
|
||||
// places, so giving them stable values reduces test churn. The
|
||||
// specific values are meaningless.
|
||||
Rust = 0,
|
||||
C = 1,
|
||||
Rust,
|
||||
C { unwind: bool },
|
||||
|
||||
// Single platform ABIs
|
||||
Cdecl,
|
||||
Stdcall,
|
||||
Stdcall { unwind: bool },
|
||||
Fastcall,
|
||||
Vectorcall,
|
||||
Thiscall,
|
||||
Thiscall { unwind: bool },
|
||||
Aapcs,
|
||||
Win64,
|
||||
SysV64,
|
||||
@ -39,7 +36,7 @@ pub enum Abi {
|
||||
CCmseNonSecureCall,
|
||||
|
||||
// Multiplatform / generic ABIs
|
||||
System,
|
||||
System { unwind: bool },
|
||||
RustIntrinsic,
|
||||
RustCall,
|
||||
PlatformIntrinsic,
|
||||
@ -61,13 +58,16 @@ pub struct AbiData {
|
||||
const AbiDatas: &[AbiData] = &[
|
||||
// Cross-platform ABIs
|
||||
AbiData { abi: Abi::Rust, name: "Rust", generic: true },
|
||||
AbiData { abi: Abi::C, name: "C", generic: true },
|
||||
AbiData { abi: Abi::C { unwind: false }, name: "C", generic: true },
|
||||
AbiData { abi: Abi::C { unwind: true }, name: "C-unwind", generic: true },
|
||||
// Platform-specific ABIs
|
||||
AbiData { abi: Abi::Cdecl, name: "cdecl", generic: false },
|
||||
AbiData { abi: Abi::Stdcall, name: "stdcall", generic: false },
|
||||
AbiData { abi: Abi::Stdcall { unwind: false }, name: "stdcall", generic: false },
|
||||
AbiData { abi: Abi::Stdcall { unwind: true }, name: "stdcall-unwind", generic: false },
|
||||
AbiData { abi: Abi::Fastcall, name: "fastcall", generic: false },
|
||||
AbiData { abi: Abi::Vectorcall, name: "vectorcall", generic: false },
|
||||
AbiData { abi: Abi::Thiscall, name: "thiscall", generic: false },
|
||||
AbiData { abi: Abi::Thiscall { unwind: false }, name: "thiscall", generic: false },
|
||||
AbiData { abi: Abi::Thiscall { unwind: true }, name: "thiscall-unwind", generic: false },
|
||||
AbiData { abi: Abi::Aapcs, name: "aapcs", generic: false },
|
||||
AbiData { abi: Abi::Win64, name: "win64", generic: false },
|
||||
AbiData { abi: Abi::SysV64, name: "sysv64", generic: false },
|
||||
@ -84,7 +84,8 @@ pub struct AbiData {
|
||||
},
|
||||
AbiData { abi: Abi::CCmseNonSecureCall, name: "C-cmse-nonsecure-call", generic: false },
|
||||
// Cross-platform ABIs
|
||||
AbiData { abi: Abi::System, name: "system", generic: true },
|
||||
AbiData { abi: Abi::System { unwind: false }, name: "system", generic: true },
|
||||
AbiData { abi: Abi::System { unwind: true }, name: "system-unwind", generic: true },
|
||||
AbiData { abi: Abi::RustIntrinsic, name: "rust-intrinsic", generic: true },
|
||||
AbiData { abi: Abi::RustCall, name: "rust-call", generic: true },
|
||||
AbiData { abi: Abi::PlatformIntrinsic, name: "platform-intrinsic", generic: true },
|
||||
@ -103,7 +104,41 @@ pub fn all_names() -> Vec<&'static str> {
|
||||
impl Abi {
|
||||
#[inline]
|
||||
pub fn index(self) -> usize {
|
||||
self as usize
|
||||
// N.B., this ordering MUST match the AbiDatas array above.
|
||||
// (This is ensured by the test indices_are_correct().)
|
||||
use Abi::*;
|
||||
match self {
|
||||
// Cross-platform ABIs
|
||||
Rust => 0,
|
||||
C { unwind: false } => 1,
|
||||
C { unwind: true } => 2,
|
||||
// Platform-specific ABIs
|
||||
Cdecl => 3,
|
||||
Stdcall { unwind: false } => 4,
|
||||
Stdcall { unwind: true } => 5,
|
||||
Fastcall => 6,
|
||||
Vectorcall => 7,
|
||||
Thiscall { unwind: false } => 8,
|
||||
Thiscall { unwind: true } => 9,
|
||||
Aapcs => 10,
|
||||
Win64 => 11,
|
||||
SysV64 => 12,
|
||||
PtxKernel => 13,
|
||||
Msp430Interrupt => 14,
|
||||
X86Interrupt => 15,
|
||||
AmdGpuKernel => 16,
|
||||
EfiApi => 17,
|
||||
AvrInterrupt => 18,
|
||||
AvrNonBlockingInterrupt => 19,
|
||||
CCmseNonSecureCall => 20,
|
||||
// Cross-platform ABIs
|
||||
System { unwind: false } => 21,
|
||||
System { unwind: true } => 22,
|
||||
RustIntrinsic => 23,
|
||||
RustCall => 24,
|
||||
PlatformIntrinsic => 25,
|
||||
Unadjusted => 26,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -122,6 +157,8 @@ pub fn generic(self) -> bool {
|
||||
|
||||
impl fmt::Display for Abi {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "\"{}\"", self.name())
|
||||
match self {
|
||||
abi => write!(f, "\"{}\"", abi.name()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,5 +2,14 @@
|
||||
|
||||
// All the calling conventions trigger an assertion(Unsupported calling convention) in llvm on arm
|
||||
pub fn unsupported_abis() -> Vec<Abi> {
|
||||
vec![Abi::Stdcall, Abi::Fastcall, Abi::Vectorcall, Abi::Thiscall, Abi::Win64, Abi::SysV64]
|
||||
vec![
|
||||
Abi::Stdcall { unwind: false },
|
||||
Abi::Stdcall { unwind: true },
|
||||
Abi::Fastcall,
|
||||
Abi::Vectorcall,
|
||||
Abi::Thiscall { unwind: false },
|
||||
Abi::Thiscall { unwind: true },
|
||||
Abi::Win64,
|
||||
Abi::SysV64,
|
||||
]
|
||||
}
|
||||
|
@ -23,10 +23,12 @@ pub fn target() -> Target {
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
relocation_model: RelocModel::Static,
|
||||
unsupported_abis: vec![
|
||||
Abi::Stdcall,
|
||||
Abi::Stdcall { unwind: false },
|
||||
Abi::Stdcall { unwind: true },
|
||||
Abi::Fastcall,
|
||||
Abi::Vectorcall,
|
||||
Abi::Thiscall,
|
||||
Abi::Thiscall { unwind: false },
|
||||
Abi::Thiscall { unwind: true },
|
||||
Abi::Win64,
|
||||
Abi::SysV64,
|
||||
],
|
||||
|
@ -1283,24 +1283,31 @@ impl Target {
|
||||
/// Given a function ABI, turn it into the correct ABI for this target.
|
||||
pub fn adjust_abi(&self, abi: Abi) -> Abi {
|
||||
match abi {
|
||||
Abi::System => {
|
||||
Abi::System { unwind } => {
|
||||
if self.is_like_windows && self.arch == "x86" {
|
||||
Abi::Stdcall
|
||||
Abi::Stdcall { unwind }
|
||||
} else {
|
||||
Abi::C
|
||||
Abi::C { unwind }
|
||||
}
|
||||
}
|
||||
// These ABI kinds are ignored on non-x86 Windows targets.
|
||||
// See https://docs.microsoft.com/en-us/cpp/cpp/argument-passing-and-naming-conventions
|
||||
// and the individual pages for __stdcall et al.
|
||||
Abi::Stdcall | Abi::Fastcall | Abi::Vectorcall | Abi::Thiscall => {
|
||||
if self.is_like_windows && self.arch != "x86" { Abi::C } else { abi }
|
||||
Abi::Stdcall { unwind } | Abi::Thiscall { unwind } => {
|
||||
if self.is_like_windows && self.arch != "x86" { Abi::C { unwind } } else { abi }
|
||||
}
|
||||
Abi::Fastcall | Abi::Vectorcall => {
|
||||
if self.is_like_windows && self.arch != "x86" {
|
||||
Abi::C { unwind: false }
|
||||
} else {
|
||||
abi
|
||||
}
|
||||
}
|
||||
Abi::EfiApi => {
|
||||
if self.arch == "x86_64" {
|
||||
Abi::Win64
|
||||
} else {
|
||||
Abi::C
|
||||
Abi::C { unwind: false }
|
||||
}
|
||||
}
|
||||
abi => abi,
|
||||
|
@ -49,10 +49,12 @@ pub fn target() -> Target {
|
||||
// create the tests for this.
|
||||
unsupported_abis: vec![
|
||||
Abi::Cdecl,
|
||||
Abi::Stdcall,
|
||||
Abi::Stdcall { unwind: false },
|
||||
Abi::Stdcall { unwind: true },
|
||||
Abi::Fastcall,
|
||||
Abi::Vectorcall,
|
||||
Abi::Thiscall,
|
||||
Abi::Thiscall { unwind: false },
|
||||
Abi::Thiscall { unwind: true },
|
||||
Abi::Aapcs,
|
||||
Abi::Win64,
|
||||
Abi::SysV64,
|
||||
|
@ -5,10 +5,12 @@
|
||||
pub fn unsupported_abis() -> Vec<Abi> {
|
||||
vec![
|
||||
Abi::Cdecl,
|
||||
Abi::Stdcall,
|
||||
Abi::Stdcall { unwind: false },
|
||||
Abi::Stdcall { unwind: true },
|
||||
Abi::Fastcall,
|
||||
Abi::Vectorcall,
|
||||
Abi::Thiscall,
|
||||
Abi::Thiscall { unwind: false },
|
||||
Abi::Thiscall { unwind: true },
|
||||
Abi::Aapcs,
|
||||
Abi::Win64,
|
||||
Abi::SysV64,
|
||||
|
@ -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 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
14
src/doc/unstable-book/src/language-features/c-unwind.md
Normal file
14
src/doc/unstable-book/src/language-features/c-unwind.md
Normal file
@ -0,0 +1,14 @@
|
||||
# `c_unwind`
|
||||
|
||||
The tracking issue for this feature is: [#74990]
|
||||
|
||||
[#74990]: https://github.com/rust-lang/rust/issues/74990
|
||||
|
||||
------------------------
|
||||
|
||||
Introduces a new ABI string, "C-unwind", to enable unwinding from other
|
||||
languages (such as C++) into Rust frames and from Rust into other languages.
|
||||
|
||||
See [RFC 2945] for more information.
|
||||
|
||||
[RFC 2945]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md
|
@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `路濫狼á́́`
|
||||
LL | extern "路濫狼á́́" fn foo() {}
|
||||
| ^^^^^^^^^ invalid ABI
|
||||
|
|
||||
= help: valid ABIs: Rust, C, cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, C-cmse-nonsecure-call, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
|
||||
= help: valid ABIs: Rust, C, C-unwind, cdecl, stdcall, stdcall-unwind, fastcall, vectorcall, thiscall, thiscall-unwind, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, C-cmse-nonsecure-call, system, system-unwind, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `invalid-ab_isize`
|
||||
LL | "invalid-ab_isize"
|
||||
| ^^^^^^^^^^^^^^^^^^ invalid ABI
|
||||
|
|
||||
= help: valid ABIs: Rust, C, cdecl, stdcall, fastcall, vectorcall, thiscall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, C-cmse-nonsecure-call, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
|
||||
= help: valid ABIs: Rust, C, C-unwind, cdecl, stdcall, stdcall-unwind, fastcall, vectorcall, thiscall, thiscall-unwind, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, C-cmse-nonsecure-call, system, system-unwind, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -74,3 +74,7 @@ fn method(&self) {}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// FIXME(katie): The 32-bit symbol hash probably needs updating as well, but I'm slightly unsure
|
||||
// about how to do that. This comment is here so that we don't break the test due to error messages
|
||||
// including incorrect line numbers.
|
||||
|
12
src/test/ui/unwind-abis/feature-gate-c-unwind-enabled.rs
Normal file
12
src/test/ui/unwind-abis/feature-gate-c-unwind-enabled.rs
Normal file
@ -0,0 +1,12 @@
|
||||
// Test that the "C-unwind" ABI is feature-gated, and *can* be used when the
|
||||
// `c_unwind` feature gate is enabled.
|
||||
|
||||
// check-pass
|
||||
|
||||
#![feature(c_unwind)]
|
||||
|
||||
extern "C-unwind" fn f() {}
|
||||
|
||||
fn main() {
|
||||
f();
|
||||
}
|
9
src/test/ui/unwind-abis/feature-gate-c-unwind.rs
Normal file
9
src/test/ui/unwind-abis/feature-gate-c-unwind.rs
Normal file
@ -0,0 +1,9 @@
|
||||
// Test that the "C-unwind" ABI is feature-gated, and cannot be used when the
|
||||
// `c_unwind` feature gate is not used.
|
||||
|
||||
extern "C-unwind" fn f() {}
|
||||
//~^ ERROR C-unwind ABI is experimental and subject to change [E0658]
|
||||
|
||||
fn main() {
|
||||
f();
|
||||
}
|
12
src/test/ui/unwind-abis/feature-gate-c-unwind.stderr
Normal file
12
src/test/ui/unwind-abis/feature-gate-c-unwind.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0658]: C-unwind ABI is experimental and subject to change
|
||||
--> $DIR/feature-gate-c-unwind.rs:4:8
|
||||
|
|
||||
LL | extern "C-unwind" fn f() {}
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information
|
||||
= help: add `#![feature(c_unwind)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
13
src/test/ui/unwind-abis/feature-gate-stdcall-unwind.rs
Normal file
13
src/test/ui/unwind-abis/feature-gate-stdcall-unwind.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// ignore-arm stdcall isn't supported
|
||||
// ignore-aarch64 stdcall isn't supported
|
||||
// ignore-riscv64 stdcall isn't supported
|
||||
|
||||
// Test that the "stdcall-unwind" ABI is feature-gated, and cannot be used when
|
||||
// the `c_unwind` feature gate is not used.
|
||||
|
||||
extern "stdcall-unwind" fn f() {}
|
||||
//~^ ERROR stdcall-unwind ABI is experimental and subject to change [E0658]
|
||||
|
||||
fn main() {
|
||||
f();
|
||||
}
|
12
src/test/ui/unwind-abis/feature-gate-stdcall-unwind.stderr
Normal file
12
src/test/ui/unwind-abis/feature-gate-stdcall-unwind.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0658]: stdcall-unwind ABI is experimental and subject to change
|
||||
--> $DIR/feature-gate-stdcall-unwind.rs:8:8
|
||||
|
|
||||
LL | extern "stdcall-unwind" fn f() {}
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information
|
||||
= help: add `#![feature(c_unwind)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
9
src/test/ui/unwind-abis/feature-gate-system-unwind.rs
Normal file
9
src/test/ui/unwind-abis/feature-gate-system-unwind.rs
Normal file
@ -0,0 +1,9 @@
|
||||
// Test that the "system-unwind" ABI is feature-gated, and cannot be used when
|
||||
// the `c_unwind` feature gate is not used.
|
||||
|
||||
extern "system-unwind" fn f() {}
|
||||
//~^ ERROR system-unwind ABI is experimental and subject to change [E0658]
|
||||
|
||||
fn main() {
|
||||
f();
|
||||
}
|
12
src/test/ui/unwind-abis/feature-gate-system-unwind.stderr
Normal file
12
src/test/ui/unwind-abis/feature-gate-system-unwind.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0658]: system-unwind ABI is experimental and subject to change
|
||||
--> $DIR/feature-gate-system-unwind.rs:4:8
|
||||
|
|
||||
LL | extern "system-unwind" fn f() {}
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information
|
||||
= help: add `#![feature(c_unwind)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
13
src/test/ui/unwind-abis/feature-gate-thiscall-unwind.rs
Normal file
13
src/test/ui/unwind-abis/feature-gate-thiscall-unwind.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// ignore-arm thiscall isn't supported
|
||||
// ignore-aarch64 thiscall isn't supported
|
||||
// ignore-riscv64 thiscall isn't supported
|
||||
|
||||
// Test that the "thiscall-unwind" ABI is feature-gated, and cannot be used when
|
||||
// the `c_unwind` feature gate is not used.
|
||||
|
||||
extern "thiscall-unwind" fn f() {}
|
||||
//~^ ERROR thiscall-unwind ABI is experimental and subject to change [E0658]
|
||||
|
||||
fn main() {
|
||||
f();
|
||||
}
|
12
src/test/ui/unwind-abis/feature-gate-thiscall-unwind.stderr
Normal file
12
src/test/ui/unwind-abis/feature-gate-thiscall-unwind.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0658]: thiscall-unwind ABI is experimental and subject to change
|
||||
--> $DIR/feature-gate-thiscall-unwind.rs:8:8
|
||||
|
|
||||
LL | extern "thiscall-unwind" fn f() {}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information
|
||||
= help: add `#![feature(c_unwind)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
Loading…
Reference in New Issue
Block a user