Skip to content

Commit feb28e9

Browse files
authored
Rollup merge of rust-lang#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````
2 parents f624427 + 547b4e6 commit feb28e9

File tree

16 files changed

+342
-80
lines changed

16 files changed

+342
-80
lines changed

compiler/rustc_ast_passes/src/feature_gate.rs

+48
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,54 @@ impl<'a> PostExpansionVisitor<'a> {
196196
"thiscall-unwind ABI is experimental and subject to change"
197197
);
198198
}
199+
"cdecl-unwind" => {
200+
gate_feature_post!(
201+
&self,
202+
c_unwind,
203+
span,
204+
"cdecl-unwind ABI is experimental and subject to change"
205+
);
206+
}
207+
"fastcall-unwind" => {
208+
gate_feature_post!(
209+
&self,
210+
c_unwind,
211+
span,
212+
"fastcall-unwind ABI is experimental and subject to change"
213+
);
214+
}
215+
"vectorcall-unwind" => {
216+
gate_feature_post!(
217+
&self,
218+
c_unwind,
219+
span,
220+
"vectorcall-unwind ABI is experimental and subject to change"
221+
);
222+
}
223+
"aapcs-unwind" => {
224+
gate_feature_post!(
225+
&self,
226+
c_unwind,
227+
span,
228+
"aapcs-unwind ABI is experimental and subject to change"
229+
);
230+
}
231+
"win64-unwind" => {
232+
gate_feature_post!(
233+
&self,
234+
c_unwind,
235+
span,
236+
"win64-unwind ABI is experimental and subject to change"
237+
);
238+
}
239+
"sysv64-unwind" => {
240+
gate_feature_post!(
241+
&self,
242+
c_unwind,
243+
span,
244+
"sysv64-unwind ABI is experimental and subject to change"
245+
);
246+
}
199247
"wasm" => {
200248
gate_feature_post!(
201249
&self,

compiler/rustc_metadata/src/native_libs.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -404,11 +404,13 @@ impl Collector<'_> {
404404
fn build_dll_import(&self, abi: Abi, item: &hir::ForeignItemRef) -> DllImport {
405405
let calling_convention = if self.tcx.sess.target.arch == "x86" {
406406
match abi {
407-
Abi::C { .. } | Abi::Cdecl => DllCallingConvention::C,
407+
Abi::C { .. } | Abi::Cdecl { .. } => DllCallingConvention::C,
408408
Abi::Stdcall { .. } | Abi::System { .. } => {
409409
DllCallingConvention::Stdcall(self.i686_arg_list_size(item))
410410
}
411-
Abi::Fastcall => DllCallingConvention::Fastcall(self.i686_arg_list_size(item)),
411+
Abi::Fastcall { .. } => {
412+
DllCallingConvention::Fastcall(self.i686_arg_list_size(item))
413+
}
412414
// Vectorcall is intentionally not supported at this time.
413415
_ => {
414416
self.tcx.sess.span_fatal(
@@ -419,7 +421,7 @@ impl Collector<'_> {
419421
}
420422
} else {
421423
match abi {
422-
Abi::C { .. } | Abi::Win64 | Abi::System { .. } => DllCallingConvention::C,
424+
Abi::C { .. } | Abi::Win64 { .. } | Abi::System { .. } => DllCallingConvention::C,
423425
_ => {
424426
self.tcx.sess.span_fatal(
425427
item.span,

compiler/rustc_middle/src/ty/layout.rs

+17-14
Original file line numberDiff line numberDiff line change
@@ -2776,17 +2776,20 @@ pub fn fn_can_unwind<'tcx>(
27762776
// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md
27772777
use SpecAbi::*;
27782778
match abi {
2779-
C { unwind } | Stdcall { unwind } | System { unwind } | Thiscall { unwind } => {
2779+
C { unwind }
2780+
| System { unwind }
2781+
| Cdecl { unwind }
2782+
| Stdcall { unwind }
2783+
| Fastcall { unwind }
2784+
| Vectorcall { unwind }
2785+
| Thiscall { unwind }
2786+
| Aapcs { unwind }
2787+
| Win64 { unwind }
2788+
| SysV64 { unwind } => {
27802789
unwind
27812790
|| (!tcx.features().c_unwind && tcx.sess.panic_strategy() == PanicStrategy::Unwind)
27822791
}
2783-
Cdecl
2784-
| Fastcall
2785-
| Vectorcall
2786-
| Aapcs
2787-
| Win64
2788-
| SysV64
2789-
| PtxKernel
2792+
PtxKernel
27902793
| Msp430Interrupt
27912794
| X86Interrupt
27922795
| AmdGpuKernel
@@ -2813,14 +2816,14 @@ pub fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi) -> Conv {
28132816
EfiApi => bug!("eficall abi should be selected elsewhere"),
28142817

28152818
Stdcall { .. } => Conv::X86Stdcall,
2816-
Fastcall => Conv::X86Fastcall,
2817-
Vectorcall => Conv::X86VectorCall,
2819+
Fastcall { .. } => Conv::X86Fastcall,
2820+
Vectorcall { .. } => Conv::X86VectorCall,
28182821
Thiscall { .. } => Conv::X86ThisCall,
28192822
C { .. } => Conv::C,
28202823
Unadjusted => Conv::C,
2821-
Win64 => Conv::X86_64Win64,
2822-
SysV64 => Conv::X86_64SysV,
2823-
Aapcs => Conv::ArmAapcs,
2824+
Win64 { .. } => Conv::X86_64Win64,
2825+
SysV64 { .. } => Conv::X86_64SysV,
2826+
Aapcs { .. } => Conv::ArmAapcs,
28242827
CCmseNonSecureCall => Conv::CCmseNonSecureCall,
28252828
PtxKernel => Conv::PtxKernel,
28262829
Msp430Interrupt => Conv::Msp430Intr,
@@ -2831,7 +2834,7 @@ pub fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi) -> Conv {
28312834
Wasm => Conv::C,
28322835

28332836
// These API constants ought to be more specific...
2834-
Cdecl => Conv::C,
2837+
Cdecl { .. } => Conv::C,
28352838
}
28362839
}
28372840

compiler/rustc_target/src/abi/call/mod.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -658,22 +658,24 @@ impl<'a, Ty> FnAbi<'a, Ty> {
658658

659659
match &cx.target_spec().arch[..] {
660660
"x86" => {
661-
let flavor = if abi == spec::abi::Abi::Fastcall {
661+
let flavor = if let spec::abi::Abi::Fastcall { .. } = abi {
662662
x86::Flavor::Fastcall
663663
} else {
664664
x86::Flavor::General
665665
};
666666
x86::compute_abi_info(cx, self, flavor);
667667
}
668-
"x86_64" => {
669-
if abi == spec::abi::Abi::SysV64 {
670-
x86_64::compute_abi_info(cx, self);
671-
} else if abi == spec::abi::Abi::Win64 || cx.target_spec().is_like_windows {
672-
x86_win64::compute_abi_info(self);
673-
} else {
674-
x86_64::compute_abi_info(cx, self);
668+
"x86_64" => match abi {
669+
spec::abi::Abi::SysV64 { .. } => x86_64::compute_abi_info(cx, self),
670+
spec::abi::Abi::Win64 { .. } => x86_win64::compute_abi_info(self),
671+
_ => {
672+
if cx.target_spec().is_like_windows {
673+
x86_win64::compute_abi_info(self)
674+
} else {
675+
x86_64::compute_abi_info(cx, self)
676+
}
675677
}
676-
}
678+
},
677679
"aarch64" => aarch64::compute_abi_info(cx, self),
678680
"amdgpu" => amdgpu::compute_abi_info(cx, self),
679681
"arm" => arm::compute_abi_info(cx, self),

compiler/rustc_target/src/spec/abi.rs

+49-37
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ pub enum Abi {
1313
// churn. The specific values are meaningless.
1414
Rust,
1515
C { unwind: bool },
16-
Cdecl,
16+
Cdecl { unwind: bool },
1717
Stdcall { unwind: bool },
18-
Fastcall,
19-
Vectorcall,
18+
Fastcall { unwind: bool },
19+
Vectorcall { unwind: bool },
2020
Thiscall { unwind: bool },
21-
Aapcs,
22-
Win64,
23-
SysV64,
21+
Aapcs { unwind: bool },
22+
Win64 { unwind: bool },
23+
SysV64 { unwind: bool },
2424
PtxKernel,
2525
Msp430Interrupt,
2626
X86Interrupt,
@@ -50,16 +50,22 @@ const AbiDatas: &[AbiData] = &[
5050
AbiData { abi: Abi::Rust, name: "Rust" },
5151
AbiData { abi: Abi::C { unwind: false }, name: "C" },
5252
AbiData { abi: Abi::C { unwind: true }, name: "C-unwind" },
53-
AbiData { abi: Abi::Cdecl, name: "cdecl" },
53+
AbiData { abi: Abi::Cdecl { unwind: false }, name: "cdecl" },
54+
AbiData { abi: Abi::Cdecl { unwind: true }, name: "cdecl-unwind" },
5455
AbiData { abi: Abi::Stdcall { unwind: false }, name: "stdcall" },
5556
AbiData { abi: Abi::Stdcall { unwind: true }, name: "stdcall-unwind" },
56-
AbiData { abi: Abi::Fastcall, name: "fastcall" },
57-
AbiData { abi: Abi::Vectorcall, name: "vectorcall" },
57+
AbiData { abi: Abi::Fastcall { unwind: false }, name: "fastcall" },
58+
AbiData { abi: Abi::Fastcall { unwind: true }, name: "fastcall-unwind" },
59+
AbiData { abi: Abi::Vectorcall { unwind: false }, name: "vectorcall" },
60+
AbiData { abi: Abi::Vectorcall { unwind: true }, name: "vectorcall-unwind" },
5861
AbiData { abi: Abi::Thiscall { unwind: false }, name: "thiscall" },
5962
AbiData { abi: Abi::Thiscall { unwind: true }, name: "thiscall-unwind" },
60-
AbiData { abi: Abi::Aapcs, name: "aapcs" },
61-
AbiData { abi: Abi::Win64, name: "win64" },
62-
AbiData { abi: Abi::SysV64, name: "sysv64" },
63+
AbiData { abi: Abi::Aapcs { unwind: false }, name: "aapcs" },
64+
AbiData { abi: Abi::Aapcs { unwind: true }, name: "aapcs-unwind" },
65+
AbiData { abi: Abi::Win64 { unwind: false }, name: "win64" },
66+
AbiData { abi: Abi::Win64 { unwind: true }, name: "win64-unwind" },
67+
AbiData { abi: Abi::SysV64 { unwind: false }, name: "sysv64" },
68+
AbiData { abi: Abi::SysV64 { unwind: true }, name: "sysv64-unwind" },
6369
AbiData { abi: Abi::PtxKernel, name: "ptx-kernel" },
6470
AbiData { abi: Abi::Msp430Interrupt, name: "msp430-interrupt" },
6571
AbiData { abi: Abi::X86Interrupt, name: "x86-interrupt" },
@@ -101,32 +107,38 @@ impl Abi {
101107
C { unwind: false } => 1,
102108
C { unwind: true } => 2,
103109
// Platform-specific ABIs
104-
Cdecl => 3,
105-
Stdcall { unwind: false } => 4,
106-
Stdcall { unwind: true } => 5,
107-
Fastcall => 6,
108-
Vectorcall => 7,
109-
Thiscall { unwind: false } => 8,
110-
Thiscall { unwind: true } => 9,
111-
Aapcs => 10,
112-
Win64 => 11,
113-
SysV64 => 12,
114-
PtxKernel => 13,
115-
Msp430Interrupt => 14,
116-
X86Interrupt => 15,
117-
AmdGpuKernel => 16,
118-
EfiApi => 17,
119-
AvrInterrupt => 18,
120-
AvrNonBlockingInterrupt => 19,
121-
CCmseNonSecureCall => 20,
122-
Wasm => 21,
110+
Cdecl { unwind: false } => 3,
111+
Cdecl { unwind: true } => 4,
112+
Stdcall { unwind: false } => 5,
113+
Stdcall { unwind: true } => 6,
114+
Fastcall { unwind: false } => 7,
115+
Fastcall { unwind: true } => 8,
116+
Vectorcall { unwind: false } => 9,
117+
Vectorcall { unwind: true } => 10,
118+
Thiscall { unwind: false } => 11,
119+
Thiscall { unwind: true } => 12,
120+
Aapcs { unwind: false } => 13,
121+
Aapcs { unwind: true } => 14,
122+
Win64 { unwind: false } => 15,
123+
Win64 { unwind: true } => 16,
124+
SysV64 { unwind: false } => 17,
125+
SysV64 { unwind: true } => 18,
126+
PtxKernel => 19,
127+
Msp430Interrupt => 20,
128+
X86Interrupt => 21,
129+
AmdGpuKernel => 22,
130+
EfiApi => 23,
131+
AvrInterrupt => 24,
132+
AvrNonBlockingInterrupt => 25,
133+
CCmseNonSecureCall => 26,
134+
Wasm => 27,
123135
// Cross-platform ABIs
124-
System { unwind: false } => 22,
125-
System { unwind: true } => 23,
126-
RustIntrinsic => 24,
127-
RustCall => 25,
128-
PlatformIntrinsic => 26,
129-
Unadjusted => 27,
136+
System { unwind: false } => 28,
137+
System { unwind: true } => 29,
138+
RustIntrinsic => 30,
139+
RustCall => 31,
140+
PlatformIntrinsic => 32,
141+
Unadjusted => 33,
130142
};
131143
debug_assert!(
132144
AbiDatas

compiler/rustc_target/src/spec/mod.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -1559,15 +1559,15 @@ impl Target {
15591559
Abi::Stdcall { unwind }
15601560
}
15611561
Abi::System { unwind } => Abi::C { unwind },
1562-
Abi::EfiApi if self.arch == "x86_64" => Abi::Win64,
1562+
Abi::EfiApi if self.arch == "x86_64" => Abi::Win64 { unwind: false },
15631563
Abi::EfiApi => Abi::C { unwind: false },
15641564

15651565
// See commentary in `is_abi_supported`.
15661566
Abi::Stdcall { .. } | Abi::Thiscall { .. } if self.arch == "x86" => abi,
15671567
Abi::Stdcall { unwind } | Abi::Thiscall { unwind } => Abi::C { unwind },
1568-
Abi::Fastcall if self.arch == "x86" => abi,
1569-
Abi::Vectorcall if ["x86", "x86_64"].contains(&&self.arch[..]) => abi,
1570-
Abi::Fastcall | Abi::Vectorcall => Abi::C { unwind: false },
1568+
Abi::Fastcall { .. } if self.arch == "x86" => abi,
1569+
Abi::Vectorcall { .. } if ["x86", "x86_64"].contains(&&self.arch[..]) => abi,
1570+
Abi::Fastcall { unwind } | Abi::Vectorcall { unwind } => Abi::C { unwind },
15711571

15721572
abi => abi,
15731573
}
@@ -1584,12 +1584,12 @@ impl Target {
15841584
| RustCall
15851585
| PlatformIntrinsic
15861586
| Unadjusted
1587-
| Cdecl
1587+
| Cdecl { .. }
15881588
| EfiApi => true,
15891589
X86Interrupt => ["x86", "x86_64"].contains(&&self.arch[..]),
1590-
Aapcs => "arm" == self.arch,
1590+
Aapcs { .. } => "arm" == self.arch,
15911591
CCmseNonSecureCall => ["arm", "aarch64"].contains(&&self.arch[..]),
1592-
Win64 | SysV64 => self.arch == "x86_64",
1592+
Win64 { .. } | SysV64 { .. } => self.arch == "x86_64",
15931593
PtxKernel => self.arch == "nvptx64",
15941594
Msp430Interrupt => self.arch == "msp430",
15951595
AmdGpuKernel => self.arch == "amdgcn",
@@ -1626,13 +1626,13 @@ impl Target {
16261626
// > convention is used.
16271627
//
16281628
// -- https://docs.microsoft.com/en-us/cpp/cpp/argument-passing-and-naming-conventions
1629-
Stdcall { .. } | Fastcall | Vectorcall if self.is_like_windows => true,
1629+
Stdcall { .. } | Fastcall { .. } | Vectorcall { .. } if self.is_like_windows => true,
16301630
// Outside of Windows we want to only support these calling conventions for the
16311631
// architectures for which these calling conventions are actually well defined.
1632-
Stdcall { .. } | Fastcall if self.arch == "x86" => true,
1633-
Vectorcall if ["x86", "x86_64"].contains(&&self.arch[..]) => true,
1632+
Stdcall { .. } | Fastcall { .. } if self.arch == "x86" => true,
1633+
Vectorcall { .. } if ["x86", "x86_64"].contains(&&self.arch[..]) => true,
16341634
// Return a `None` for other cases so that we know to emit a future compat lint.
1635-
Stdcall { .. } | Fastcall | Vectorcall => return None,
1635+
Stdcall { .. } | Fastcall { .. } | Vectorcall { .. } => return None,
16361636
})
16371637
}
16381638

compiler/rustc_typeck/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ use bounds::Bounds;
122122
fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi, span: Span) {
123123
match (decl.c_variadic, abi) {
124124
// The function has the correct calling convention, or isn't a "C-variadic" function.
125-
(false, _) | (true, Abi::C { .. }) | (true, Abi::Cdecl) => {}
125+
(false, _) | (true, Abi::C { .. }) | (true, Abi::Cdecl { .. }) => {}
126126
// The function is a "C-variadic" function with an incorrect calling convention.
127127
(true, _) => {
128128
let mut err = struct_span_err!(

src/doc/unstable-book/src/language-features/c-unwind.md

+14-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,20 @@ The tracking issue for this feature is: [#74990]
66

77
------------------------
88

9-
Introduces four new ABI strings: "C-unwind", "stdcall-unwind",
10-
"thiscall-unwind", and "system-unwind". These enable unwinding from other
11-
languages (such as C++) into Rust frames and from Rust into other languages.
9+
Introduces new ABI strings:
10+
- "C-unwind"
11+
- "cdecl-unwind"
12+
- "stdcall-unwind"
13+
- "fastcall-unwind"
14+
- "vectorcall-unwind"
15+
- "thiscall-unwind"
16+
- "aapcs-unwind"
17+
- "win64-unwind"
18+
- "sysv64-unwind"
19+
- "system-unwind"
20+
21+
These enable unwinding from other languages (such as C++) into Rust frames and
22+
from Rust into other languages.
1223

1324
See [RFC 2945] for more information.
1425

0 commit comments

Comments
 (0)