Auto merge of #93561 - Amanieu:more-unwind-abi, r=nagisa
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" cc `@rust-lang/wg-ffi-unwind`
This commit is contained in:
commit
2a8dbdb1e2
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -2776,17 +2776,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
|
||||
@ -2813,14 +2816,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,
|
||||
@ -2831,7 +2834,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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -1559,15 +1559,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,
|
||||
}
|
||||
@ -1584,12 +1584,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",
|
||||
@ -1626,13 +1626,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,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,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!(
|
||||
|
@ -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.
|
||||
|
||||
|
31
src/test/codegen/unwind-abis/aapcs-unwind-abi.rs
Normal file
31
src/test/codegen/unwind-abis/aapcs-unwind-abi.rs
Normal file
@ -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: }
|
29
src/test/codegen/unwind-abis/cdecl-unwind-abi.rs
Normal file
29
src/test/codegen/unwind-abis/cdecl-unwind-abi.rs
Normal file
@ -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: }
|
31
src/test/codegen/unwind-abis/fastcall-unwind-abi.rs
Normal file
31
src/test/codegen/unwind-abis/fastcall-unwind-abi.rs
Normal file
@ -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: }
|
31
src/test/codegen/unwind-abis/sysv64-unwind-abi.rs
Normal file
31
src/test/codegen/unwind-abis/sysv64-unwind-abi.rs
Normal file
@ -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: }
|
31
src/test/codegen/unwind-abis/vectorcall-unwind-abi.rs
Normal file
31
src/test/codegen/unwind-abis/vectorcall-unwind-abi.rs
Normal file
@ -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: }
|
31
src/test/codegen/unwind-abis/win64-unwind-abi.rs
Normal file
31
src/test/codegen/unwind-abis/win64-unwind-abi.rs
Normal file
@ -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: }
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user