From 547b4e601e797e7989f6fc9ebe921376c74bd1f0 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Tue, 1 Feb 2022 18:53:45 +0100 Subject: [PATCH] Add more *-unwind ABI variants The following *-unwind ABIs are now supported: - "C-unwind" - "cdecl-unwind" - "stdcall-unwind" - "fastcall-unwind" - "vectorcall-unwind" - "thiscall-unwind" - "aapcs-unwind" - "win64-unwind" - "sysv64-unwind" - "system-unwind" --- compiler/rustc_ast_passes/src/feature_gate.rs | 48 +++++++++++ compiler/rustc_metadata/src/native_libs.rs | 8 +- compiler/rustc_middle/src/ty/layout.rs | 31 ++++--- compiler/rustc_target/src/abi/call/mod.rs | 20 +++-- compiler/rustc_target/src/spec/abi.rs | 86 +++++++++++-------- compiler/rustc_target/src/spec/mod.rs | 22 ++--- compiler/rustc_typeck/src/lib.rs | 2 +- .../src/language-features/c-unwind.md | 17 +++- .../codegen/unwind-abis/aapcs-unwind-abi.rs | 31 +++++++ .../codegen/unwind-abis/cdecl-unwind-abi.rs | 29 +++++++ .../unwind-abis/fastcall-unwind-abi.rs | 31 +++++++ .../codegen/unwind-abis/sysv64-unwind-abi.rs | 31 +++++++ .../unwind-abis/vectorcall-unwind-abi.rs | 31 +++++++ .../codegen/unwind-abis/win64-unwind-abi.rs | 31 +++++++ src/test/ui/codemap_tests/unicode.stderr | 2 +- src/test/ui/parser/issues/issue-8537.stderr | 2 +- 16 files changed, 342 insertions(+), 80 deletions(-) create mode 100644 src/test/codegen/unwind-abis/aapcs-unwind-abi.rs create mode 100644 src/test/codegen/unwind-abis/cdecl-unwind-abi.rs create mode 100644 src/test/codegen/unwind-abis/fastcall-unwind-abi.rs create mode 100644 src/test/codegen/unwind-abis/sysv64-unwind-abi.rs create mode 100644 src/test/codegen/unwind-abis/vectorcall-unwind-abi.rs create mode 100644 src/test/codegen/unwind-abis/win64-unwind-abi.rs diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index a6ecfa4520608..0a96e60d4d3af 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -196,6 +196,54 @@ impl<'a> PostExpansionVisitor<'a> { "thiscall-unwind ABI is experimental and subject to change" ); } + "cdecl-unwind" => { + gate_feature_post!( + &self, + c_unwind, + span, + "cdecl-unwind ABI is experimental and subject to change" + ); + } + "fastcall-unwind" => { + gate_feature_post!( + &self, + c_unwind, + span, + "fastcall-unwind ABI is experimental and subject to change" + ); + } + "vectorcall-unwind" => { + gate_feature_post!( + &self, + c_unwind, + span, + "vectorcall-unwind ABI is experimental and subject to change" + ); + } + "aapcs-unwind" => { + gate_feature_post!( + &self, + c_unwind, + span, + "aapcs-unwind ABI is experimental and subject to change" + ); + } + "win64-unwind" => { + gate_feature_post!( + &self, + c_unwind, + span, + "win64-unwind ABI is experimental and subject to change" + ); + } + "sysv64-unwind" => { + gate_feature_post!( + &self, + c_unwind, + span, + "sysv64-unwind ABI is experimental and subject to change" + ); + } "wasm" => { gate_feature_post!( &self, diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 13cd8e4a046b0..88292a4422419 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -404,11 +404,13 @@ impl Collector<'_> { fn build_dll_import(&self, abi: Abi, item: &hir::ForeignItemRef) -> DllImport { let calling_convention = if self.tcx.sess.target.arch == "x86" { match abi { - Abi::C { .. } | Abi::Cdecl => DllCallingConvention::C, + Abi::C { .. } | Abi::Cdecl { .. } => DllCallingConvention::C, Abi::Stdcall { .. } | Abi::System { .. } => { DllCallingConvention::Stdcall(self.i686_arg_list_size(item)) } - Abi::Fastcall => DllCallingConvention::Fastcall(self.i686_arg_list_size(item)), + Abi::Fastcall { .. } => { + DllCallingConvention::Fastcall(self.i686_arg_list_size(item)) + } // Vectorcall is intentionally not supported at this time. _ => { self.tcx.sess.span_fatal( @@ -419,7 +421,7 @@ impl Collector<'_> { } } else { match abi { - Abi::C { .. } | Abi::Win64 | Abi::System { .. } => DllCallingConvention::C, + Abi::C { .. } | Abi::Win64 { .. } | Abi::System { .. } => DllCallingConvention::C, _ => { self.tcx.sess.span_fatal( item.span, diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index caf33fa5d213b..c2aa83b8a7f9b 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -2773,17 +2773,20 @@ pub fn fn_can_unwind<'tcx>( // [rfc]: 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 } => { + C { unwind } + | System { unwind } + | Cdecl { unwind } + | Stdcall { unwind } + | Fastcall { unwind } + | Vectorcall { unwind } + | Thiscall { unwind } + | Aapcs { unwind } + | Win64 { unwind } + | SysV64 { unwind } => { unwind || (!tcx.features().c_unwind && tcx.sess.panic_strategy() == PanicStrategy::Unwind) } - Cdecl - | Fastcall - | Vectorcall - | Aapcs - | Win64 - | SysV64 - | PtxKernel + PtxKernel | Msp430Interrupt | X86Interrupt | AmdGpuKernel @@ -2810,14 +2813,14 @@ pub fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi) -> Conv { EfiApi => bug!("eficall abi should be selected elsewhere"), Stdcall { .. } => Conv::X86Stdcall, - Fastcall => Conv::X86Fastcall, - Vectorcall => Conv::X86VectorCall, + Fastcall { .. } => Conv::X86Fastcall, + Vectorcall { .. } => Conv::X86VectorCall, Thiscall { .. } => Conv::X86ThisCall, C { .. } => Conv::C, Unadjusted => Conv::C, - Win64 => Conv::X86_64Win64, - SysV64 => Conv::X86_64SysV, - Aapcs => Conv::ArmAapcs, + Win64 { .. } => Conv::X86_64Win64, + SysV64 { .. } => Conv::X86_64SysV, + Aapcs { .. } => Conv::ArmAapcs, CCmseNonSecureCall => Conv::CCmseNonSecureCall, PtxKernel => Conv::PtxKernel, Msp430Interrupt => Conv::Msp430Intr, @@ -2828,7 +2831,7 @@ pub fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi) -> Conv { Wasm => Conv::C, // These API constants ought to be more specific... - Cdecl => Conv::C, + Cdecl { .. } => Conv::C, } } diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 735b7e76e3862..43eb7ab05e0bf 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -658,22 +658,24 @@ impl<'a, Ty> FnAbi<'a, Ty> { match &cx.target_spec().arch[..] { "x86" => { - let flavor = if abi == spec::abi::Abi::Fastcall { + let flavor = if let spec::abi::Abi::Fastcall { .. } = abi { x86::Flavor::Fastcall } else { x86::Flavor::General }; x86::compute_abi_info(cx, self, flavor); } - "x86_64" => { - if abi == spec::abi::Abi::SysV64 { - x86_64::compute_abi_info(cx, self); - } else if abi == spec::abi::Abi::Win64 || cx.target_spec().is_like_windows { - x86_win64::compute_abi_info(self); - } else { - x86_64::compute_abi_info(cx, self); + "x86_64" => match abi { + spec::abi::Abi::SysV64 { .. } => x86_64::compute_abi_info(cx, self), + spec::abi::Abi::Win64 { .. } => x86_win64::compute_abi_info(self), + _ => { + if cx.target_spec().is_like_windows { + x86_win64::compute_abi_info(self) + } else { + x86_64::compute_abi_info(cx, self) + } } - } + }, "aarch64" => aarch64::compute_abi_info(cx, self), "amdgpu" => amdgpu::compute_abi_info(cx, self), "arm" => arm::compute_abi_info(cx, self), diff --git a/compiler/rustc_target/src/spec/abi.rs b/compiler/rustc_target/src/spec/abi.rs index e3a2226eb9d15..d9e571c72e53a 100644 --- a/compiler/rustc_target/src/spec/abi.rs +++ b/compiler/rustc_target/src/spec/abi.rs @@ -13,14 +13,14 @@ pub enum Abi { // churn. The specific values are meaningless. Rust, C { unwind: bool }, - Cdecl, + Cdecl { unwind: bool }, Stdcall { unwind: bool }, - Fastcall, - Vectorcall, + Fastcall { unwind: bool }, + Vectorcall { unwind: bool }, Thiscall { unwind: bool }, - Aapcs, - Win64, - SysV64, + Aapcs { unwind: bool }, + Win64 { unwind: bool }, + SysV64 { unwind: bool }, PtxKernel, Msp430Interrupt, X86Interrupt, @@ -50,16 +50,22 @@ const AbiDatas: &[AbiData] = &[ AbiData { abi: Abi::Rust, name: "Rust" }, AbiData { abi: Abi::C { unwind: false }, name: "C" }, AbiData { abi: Abi::C { unwind: true }, name: "C-unwind" }, - AbiData { abi: Abi::Cdecl, name: "cdecl" }, + AbiData { abi: Abi::Cdecl { unwind: false }, name: "cdecl" }, + AbiData { abi: Abi::Cdecl { unwind: true }, name: "cdecl-unwind" }, AbiData { abi: Abi::Stdcall { unwind: false }, name: "stdcall" }, AbiData { abi: Abi::Stdcall { unwind: true }, name: "stdcall-unwind" }, - AbiData { abi: Abi::Fastcall, name: "fastcall" }, - AbiData { abi: Abi::Vectorcall, name: "vectorcall" }, + AbiData { abi: Abi::Fastcall { unwind: false }, name: "fastcall" }, + AbiData { abi: Abi::Fastcall { unwind: true }, name: "fastcall-unwind" }, + AbiData { abi: Abi::Vectorcall { unwind: false }, name: "vectorcall" }, + AbiData { abi: Abi::Vectorcall { unwind: true }, name: "vectorcall-unwind" }, AbiData { abi: Abi::Thiscall { unwind: false }, name: "thiscall" }, AbiData { abi: Abi::Thiscall { unwind: true }, name: "thiscall-unwind" }, - AbiData { abi: Abi::Aapcs, name: "aapcs" }, - AbiData { abi: Abi::Win64, name: "win64" }, - AbiData { abi: Abi::SysV64, name: "sysv64" }, + AbiData { abi: Abi::Aapcs { unwind: false }, name: "aapcs" }, + AbiData { abi: Abi::Aapcs { unwind: true }, name: "aapcs-unwind" }, + AbiData { abi: Abi::Win64 { unwind: false }, name: "win64" }, + AbiData { abi: Abi::Win64 { unwind: true }, name: "win64-unwind" }, + AbiData { abi: Abi::SysV64 { unwind: false }, name: "sysv64" }, + AbiData { abi: Abi::SysV64 { unwind: true }, name: "sysv64-unwind" }, AbiData { abi: Abi::PtxKernel, name: "ptx-kernel" }, AbiData { abi: Abi::Msp430Interrupt, name: "msp430-interrupt" }, AbiData { abi: Abi::X86Interrupt, name: "x86-interrupt" }, @@ -101,32 +107,38 @@ impl Abi { 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, - Wasm => 21, + Cdecl { unwind: false } => 3, + Cdecl { unwind: true } => 4, + Stdcall { unwind: false } => 5, + Stdcall { unwind: true } => 6, + Fastcall { unwind: false } => 7, + Fastcall { unwind: true } => 8, + Vectorcall { unwind: false } => 9, + Vectorcall { unwind: true } => 10, + Thiscall { unwind: false } => 11, + Thiscall { unwind: true } => 12, + Aapcs { unwind: false } => 13, + Aapcs { unwind: true } => 14, + Win64 { unwind: false } => 15, + Win64 { unwind: true } => 16, + SysV64 { unwind: false } => 17, + SysV64 { unwind: true } => 18, + PtxKernel => 19, + Msp430Interrupt => 20, + X86Interrupt => 21, + AmdGpuKernel => 22, + EfiApi => 23, + AvrInterrupt => 24, + AvrNonBlockingInterrupt => 25, + CCmseNonSecureCall => 26, + Wasm => 27, // Cross-platform ABIs - System { unwind: false } => 22, - System { unwind: true } => 23, - RustIntrinsic => 24, - RustCall => 25, - PlatformIntrinsic => 26, - Unadjusted => 27, + System { unwind: false } => 28, + System { unwind: true } => 29, + RustIntrinsic => 30, + RustCall => 31, + PlatformIntrinsic => 32, + Unadjusted => 33, }; debug_assert!( AbiDatas diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 4effb8bacf6d6..06d38670a63b2 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1556,15 +1556,15 @@ impl Target { Abi::Stdcall { unwind } } Abi::System { unwind } => Abi::C { unwind }, - Abi::EfiApi if self.arch == "x86_64" => Abi::Win64, + Abi::EfiApi if self.arch == "x86_64" => Abi::Win64 { unwind: false }, Abi::EfiApi => Abi::C { unwind: false }, // See commentary in `is_abi_supported`. Abi::Stdcall { .. } | Abi::Thiscall { .. } if self.arch == "x86" => abi, Abi::Stdcall { unwind } | Abi::Thiscall { unwind } => Abi::C { unwind }, - Abi::Fastcall if self.arch == "x86" => abi, - Abi::Vectorcall if ["x86", "x86_64"].contains(&&self.arch[..]) => abi, - Abi::Fastcall | Abi::Vectorcall => Abi::C { unwind: false }, + Abi::Fastcall { .. } if self.arch == "x86" => abi, + Abi::Vectorcall { .. } if ["x86", "x86_64"].contains(&&self.arch[..]) => abi, + Abi::Fastcall { unwind } | Abi::Vectorcall { unwind } => Abi::C { unwind }, abi => abi, } @@ -1581,12 +1581,12 @@ impl Target { | RustCall | PlatformIntrinsic | Unadjusted - | Cdecl + | Cdecl { .. } | EfiApi => true, X86Interrupt => ["x86", "x86_64"].contains(&&self.arch[..]), - Aapcs => "arm" == self.arch, + Aapcs { .. } => "arm" == self.arch, CCmseNonSecureCall => ["arm", "aarch64"].contains(&&self.arch[..]), - Win64 | SysV64 => self.arch == "x86_64", + Win64 { .. } | SysV64 { .. } => self.arch == "x86_64", PtxKernel => self.arch == "nvptx64", Msp430Interrupt => self.arch == "msp430", AmdGpuKernel => self.arch == "amdgcn", @@ -1623,13 +1623,13 @@ impl Target { // > convention is used. // // -- https://docs.microsoft.com/en-us/cpp/cpp/argument-passing-and-naming-conventions - Stdcall { .. } | Fastcall | Vectorcall if self.is_like_windows => true, + Stdcall { .. } | Fastcall { .. } | Vectorcall { .. } if self.is_like_windows => true, // Outside of Windows we want to only support these calling conventions for the // architectures for which these calling conventions are actually well defined. - Stdcall { .. } | Fastcall if self.arch == "x86" => true, - Vectorcall if ["x86", "x86_64"].contains(&&self.arch[..]) => true, + Stdcall { .. } | Fastcall { .. } if self.arch == "x86" => true, + Vectorcall { .. } if ["x86", "x86_64"].contains(&&self.arch[..]) => true, // Return a `None` for other cases so that we know to emit a future compat lint. - Stdcall { .. } | Fastcall | Vectorcall => return None, + Stdcall { .. } | Fastcall { .. } | Vectorcall { .. } => return None, }) } diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index 6a9f154844a57..e4b708dfd147f 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -121,7 +121,7 @@ use bounds::Bounds; fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi, span: Span) { 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) => {} + (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!( diff --git a/src/doc/unstable-book/src/language-features/c-unwind.md b/src/doc/unstable-book/src/language-features/c-unwind.md index 2801d9b5e7778..fb32918d5e439 100644 --- a/src/doc/unstable-book/src/language-features/c-unwind.md +++ b/src/doc/unstable-book/src/language-features/c-unwind.md @@ -6,9 +6,20 @@ The tracking issue for this feature is: [#74990] ------------------------ -Introduces four new ABI strings: "C-unwind", "stdcall-unwind", -"thiscall-unwind", and "system-unwind". These enable unwinding from other -languages (such as C++) into Rust frames and from Rust into other languages. +Introduces new ABI strings: +- "C-unwind" +- "cdecl-unwind" +- "stdcall-unwind" +- "fastcall-unwind" +- "vectorcall-unwind" +- "thiscall-unwind" +- "aapcs-unwind" +- "win64-unwind" +- "sysv64-unwind" +- "system-unwind" + +These enable unwinding from other languages (such as C++) into Rust frames and +from Rust into other languages. See [RFC 2945] for more information. diff --git a/src/test/codegen/unwind-abis/aapcs-unwind-abi.rs b/src/test/codegen/unwind-abis/aapcs-unwind-abi.rs new file mode 100644 index 0000000000000..1fe048068601d --- /dev/null +++ b/src/test/codegen/unwind-abis/aapcs-unwind-abi.rs @@ -0,0 +1,31 @@ +// needs-llvm-components: arm +// compile-flags: --target=armv7-unknown-linux-gnueabihf --crate-type=rlib -Cno-prepopulate-passes +#![no_core] +#![feature(no_core, lang_items, c_unwind)] +#[lang="sized"] +trait Sized { } + +// Test that `nounwind` atributes are correctly applied to exported `aapcs` and +// `aapcs-unwind` extern functions. `aapcs-unwind` functions MUST NOT have this attribute. We +// disable optimizations above to prevent LLVM from inferring the attribute. + +// CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 { +#[no_mangle] +pub extern "aapcs" fn rust_item_that_cannot_unwind() { +} + +// CHECK: @rust_item_that_can_unwind() unnamed_addr #1 { +#[no_mangle] +pub extern "aapcs-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: } diff --git a/src/test/codegen/unwind-abis/cdecl-unwind-abi.rs b/src/test/codegen/unwind-abis/cdecl-unwind-abi.rs new file mode 100644 index 0000000000000..52e0d2d6e0252 --- /dev/null +++ b/src/test/codegen/unwind-abis/cdecl-unwind-abi.rs @@ -0,0 +1,29 @@ +// compile-flags: -C opt-level=0 + +// Test that `nounwind` atributes are correctly applied to exported `cdecl` and +// `cdecl-unwind` extern functions. `cdecl-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 "cdecl" fn rust_item_that_cannot_unwind() { +} + +// CHECK: @rust_item_that_can_unwind() unnamed_addr #1 { +#[no_mangle] +pub extern "cdecl-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: } diff --git a/src/test/codegen/unwind-abis/fastcall-unwind-abi.rs b/src/test/codegen/unwind-abis/fastcall-unwind-abi.rs new file mode 100644 index 0000000000000..ed23235ebfa80 --- /dev/null +++ b/src/test/codegen/unwind-abis/fastcall-unwind-abi.rs @@ -0,0 +1,31 @@ +// needs-llvm-components: x86 +// compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes +#![no_core] +#![feature(no_core, lang_items, c_unwind)] +#[lang="sized"] +trait Sized { } + +// Test that `nounwind` atributes are correctly applied to exported `fastcall` and +// `fastcall-unwind` extern functions. `fastcall-unwind` functions MUST NOT have this attribute. We +// disable optimizations above to prevent LLVM from inferring the attribute. + +// CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 { +#[no_mangle] +pub extern "fastcall" fn rust_item_that_cannot_unwind() { +} + +// CHECK: @rust_item_that_can_unwind() unnamed_addr #1 { +#[no_mangle] +pub extern "fastcall-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: } diff --git a/src/test/codegen/unwind-abis/sysv64-unwind-abi.rs b/src/test/codegen/unwind-abis/sysv64-unwind-abi.rs new file mode 100644 index 0000000000000..a38736f2a1f95 --- /dev/null +++ b/src/test/codegen/unwind-abis/sysv64-unwind-abi.rs @@ -0,0 +1,31 @@ +// needs-llvm-components: x86 +// compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib -Cno-prepopulate-passes +#![no_core] +#![feature(no_core, lang_items, c_unwind)] +#[lang="sized"] +trait Sized { } + +// Test that `nounwind` atributes are correctly applied to exported `sysv64` and +// `sysv64-unwind` extern functions. `sysv64-unwind` functions MUST NOT have this attribute. We +// disable optimizations above to prevent LLVM from inferring the attribute. + +// CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 { +#[no_mangle] +pub extern "sysv64" fn rust_item_that_cannot_unwind() { +} + +// CHECK: @rust_item_that_can_unwind() unnamed_addr #1 { +#[no_mangle] +pub extern "sysv64-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: } diff --git a/src/test/codegen/unwind-abis/vectorcall-unwind-abi.rs b/src/test/codegen/unwind-abis/vectorcall-unwind-abi.rs new file mode 100644 index 0000000000000..0fb9612a5e4e8 --- /dev/null +++ b/src/test/codegen/unwind-abis/vectorcall-unwind-abi.rs @@ -0,0 +1,31 @@ +// needs-llvm-components: x86 +// compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes +#![no_core] +#![feature(no_core, lang_items, c_unwind, abi_vectorcall)] +#[lang="sized"] +trait Sized { } + +// Test that `nounwind` atributes are correctly applied to exported `vectorcall` and +// `vectorcall-unwind` extern functions. `vectorcall-unwind` functions MUST NOT have this attribute. +// We disable optimizations above to prevent LLVM from inferring the attribute. + +// CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 { +#[no_mangle] +pub extern "vectorcall" fn rust_item_that_cannot_unwind() { +} + +// CHECK: @rust_item_that_can_unwind() unnamed_addr #1 { +#[no_mangle] +pub extern "vectorcall-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: } diff --git a/src/test/codegen/unwind-abis/win64-unwind-abi.rs b/src/test/codegen/unwind-abis/win64-unwind-abi.rs new file mode 100644 index 0000000000000..5d8482da63056 --- /dev/null +++ b/src/test/codegen/unwind-abis/win64-unwind-abi.rs @@ -0,0 +1,31 @@ +// needs-llvm-components: x86 +// compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib -Cno-prepopulate-passes +#![no_core] +#![feature(no_core, lang_items, c_unwind)] +#[lang="sized"] +trait Sized { } + +// Test that `nounwind` atributes are correctly applied to exported `win64` and +// `win64-unwind` extern functions. `win64-unwind` functions MUST NOT have this attribute. We +// disable optimizations above to prevent LLVM from inferring the attribute. + +// CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 { +#[no_mangle] +pub extern "win64" fn rust_item_that_cannot_unwind() { +} + +// CHECK: @rust_item_that_can_unwind() unnamed_addr #1 { +#[no_mangle] +pub extern "win64-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: } diff --git a/src/test/ui/codemap_tests/unicode.stderr b/src/test/ui/codemap_tests/unicode.stderr index 357dd25389ecb..e5aef04b6894e 100644 --- a/src/test/ui/codemap_tests/unicode.stderr +++ b/src/test/ui/codemap_tests/unicode.stderr @@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `路濫狼á́́` LL | extern "路濫狼á́́" fn foo() {} | ^^^^^^^^^ invalid ABI | - = 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, wasm, system, system-unwind, rust-intrinsic, rust-call, platform-intrinsic, unadjusted + = help: valid ABIs: Rust, C, C-unwind, cdecl, cdecl-unwind, stdcall, stdcall-unwind, fastcall, fastcall-unwind, vectorcall, vectorcall-unwind, thiscall, thiscall-unwind, aapcs, aapcs-unwind, win64, win64-unwind, sysv64, sysv64-unwind, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, C-cmse-nonsecure-call, wasm, system, system-unwind, rust-intrinsic, rust-call, platform-intrinsic, unadjusted error: aborting due to previous error diff --git a/src/test/ui/parser/issues/issue-8537.stderr b/src/test/ui/parser/issues/issue-8537.stderr index 5a29ce2221fc2..5f8d4315de829 100644 --- a/src/test/ui/parser/issues/issue-8537.stderr +++ b/src/test/ui/parser/issues/issue-8537.stderr @@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `invalid-ab_isize` LL | "invalid-ab_isize" | ^^^^^^^^^^^^^^^^^^ invalid ABI | - = 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, wasm, system, system-unwind, rust-intrinsic, rust-call, platform-intrinsic, unadjusted + = help: valid ABIs: Rust, C, C-unwind, cdecl, cdecl-unwind, stdcall, stdcall-unwind, fastcall, fastcall-unwind, vectorcall, vectorcall-unwind, thiscall, thiscall-unwind, aapcs, aapcs-unwind, win64, win64-unwind, sysv64, sysv64-unwind, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, C-cmse-nonsecure-call, wasm, system, system-unwind, rust-intrinsic, rust-call, platform-intrinsic, unadjusted error: aborting due to previous error