Skip to content

Commit 675a103

Browse files
committed
on Windows, consistently pass ZST by-ref
1 parent d760bb6 commit 675a103

File tree

4 files changed

+22
-57
lines changed

4 files changed

+22
-57
lines changed

compiler/rustc_target/src/callconv/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -665,11 +665,11 @@ impl<'a, Ty> FnAbi<'a, Ty> {
665665
"x86_64" => match abi {
666666
ExternAbi::SysV64 { .. } => x86_64::compute_abi_info(cx, self),
667667
ExternAbi::Win64 { .. } | ExternAbi::Vectorcall { .. } => {
668-
x86_win64::compute_abi_info(cx, self, abi)
668+
x86_win64::compute_abi_info(cx, self)
669669
}
670670
_ => {
671671
if cx.target_spec().is_like_windows {
672-
x86_win64::compute_abi_info(cx, self, abi)
672+
x86_win64::compute_abi_info(cx, self)
673673
} else {
674674
x86_64::compute_abi_info(cx, self)
675675
}

compiler/rustc_target/src/callconv/x86_win64.rs

+8-14
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
use rustc_abi::{BackendRepr, ExternAbi, Float, Primitive};
1+
use rustc_abi::{BackendRepr, Float, Primitive};
22

33
use crate::abi::call::{ArgAbi, FnAbi, Reg};
44
use crate::spec::HasTargetSpec;
55

66
// Win64 ABI: https://docs.microsoft.com/en-us/cpp/build/parameter-passing
77

8-
pub(crate) fn compute_abi_info<Ty>(
9-
cx: &impl HasTargetSpec,
10-
fn_abi: &mut FnAbi<'_, Ty>,
11-
abi: ExternAbi,
12-
) {
8+
pub(crate) fn compute_abi_info<Ty>(_cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) {
139
let fixup = |a: &mut ArgAbi<'_, Ty>| {
1410
match a.layout.backend_repr {
1511
BackendRepr::Uninhabited | BackendRepr::Memory { sized: false } => {}
@@ -48,16 +44,14 @@ pub(crate) fn compute_abi_info<Ty>(
4844
// Windows ABIs do not talk about ZST since such types do not exist in MSVC.
4945
// In that sense we can do whatever we want here, and maybe we should throw an error
5046
// (but of course that would be a massive breaking change now).
51-
// We try to match clang and gcc, so we make windows-gnu and the native
52-
// Windows ABIs (i.e., everything except for `extern "C"`) pass ZST via
53-
// pointer indirection. windows-msvc `extern "C"` still skips ZST.
54-
if (cx.target_spec().os == "windows" && cx.target_spec().env == "gnu")
55-
|| !matches!(abi, ExternAbi::C { .. })
56-
{
57-
arg.make_indirect_from_ignore();
58-
}
47+
// We try to match clang and gcc (which allow ZST is their windows-gnu targets), so we
48+
// pass ZST via pointer indirection.
49+
arg.make_indirect_from_ignore();
5950
continue;
6051
}
6152
fixup(arg);
6253
}
54+
// FIXME: We should likely also do something about ZST return types, similar to above.
55+
// However, that's non-trivial due to `()`.
56+
// See <https://github.com/rust-lang/unsafe-code-guidelines/issues/552>.
6357
}

compiler/rustc_ty_utils/src/abi.rs

+5-34
Original file line numberDiff line numberDiff line change
@@ -267,10 +267,8 @@ fn fn_sig_for_fn_abi<'tcx>(
267267

268268
#[inline]
269269
fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: ExternAbi, c_variadic: bool) -> Conv {
270-
let target = &tcx.sess.target;
271-
272270
use rustc_abi::ExternAbi::*;
273-
match target.adjust_abi(abi, c_variadic) {
271+
match tcx.sess.target.adjust_abi(abi, c_variadic) {
274272
RustIntrinsic | Rust | RustCall => Conv::Rust,
275273

276274
// This is intentionally not using `Conv::Cold`, as that has to preserve
@@ -281,37 +279,10 @@ fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: ExternAbi, c_variadic: bool) -> Conv
281279
System { .. } => bug!("system abi should be selected elsewhere"),
282280
EfiApi => bug!("eficall abi should be selected elsewhere"),
283281

284-
// See commentary in `is_abi_supported`: we map these to "C" on targets
285-
// where they do not make sense.
286-
Stdcall { .. } => {
287-
if target.arch == "x86" {
288-
Conv::X86Stdcall
289-
} else {
290-
Conv::C
291-
}
292-
}
293-
Fastcall { .. } => {
294-
if target.arch == "x86" {
295-
Conv::X86Fastcall
296-
} else {
297-
Conv::C
298-
}
299-
}
300-
Vectorcall { .. } => {
301-
if ["x86", "x86_64"].contains(&&target.arch[..]) {
302-
Conv::X86VectorCall
303-
} else {
304-
Conv::C
305-
}
306-
}
307-
Thiscall { .. } => {
308-
if target.arch == "x86" {
309-
Conv::X86ThisCall
310-
} else {
311-
Conv::C
312-
}
313-
}
314-
282+
Stdcall { .. } => Conv::X86Stdcall,
283+
Fastcall { .. } => Conv::X86Fastcall,
284+
Vectorcall { .. } => Conv::X86VectorCall,
285+
Thiscall { .. } => Conv::X86ThisCall,
315286
C { .. } => Conv::C,
316287
Unadjusted => Conv::C,
317288
Win64 { .. } => Conv::X86_64Win64,

tests/codegen/abi-win64-zst.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,16 @@ trait Sized {}
2323
// Make sure the argument is always passed when explicitly requesting a Windows ABI.
2424
// Our goal here is to match clang: <https://clang.godbolt.org/z/Wr4jMWq3P>.
2525

26-
// CHECK: define win64cc void @pass_zst_win64(ptr {{.*}})
26+
// CHECK: define win64cc void @pass_zst_win64(ptr {{[^,]*}})
2727
#[no_mangle]
2828
extern "win64" fn pass_zst_win64(_: ()) {}
2929

30-
// CHECK: define x86_vectorcallcc void @pass_zst_vectorcall(ptr {{.*}})
30+
// CHECK: define x86_vectorcallcc void @pass_zst_vectorcall(ptr {{[^,]*}})
3131
#[no_mangle]
3232
extern "vectorcall" fn pass_zst_vectorcall(_: ()) {}
3333

34-
// windows-gnu: define void @pass_zst_fastcall(ptr {{.*}})
35-
// windows-msvc: define void @pass_zst_fastcall(ptr {{.*}})
34+
// windows-gnu: define void @pass_zst_fastcall(ptr {{[^,]*}})
35+
// windows-msvc: define void @pass_zst_fastcall(ptr {{[^,]*}})
3636
#[no_mangle]
3737
#[cfg(windows)] // "fastcall" is not valid on 64bit Linux
3838
extern "fastcall" fn pass_zst_fastcall(_: ()) {}
@@ -43,10 +43,10 @@ extern "fastcall" fn pass_zst_fastcall(_: ()) {}
4343
#[no_mangle]
4444
extern "sysv64" fn pass_zst_sysv64(_: ()) {}
4545

46-
// For `extern "C"` functions, ZST are ignored on windows-msvc.
46+
// For `extern "C"` functions, ZST are ignored on Linux put passed on Windows.
4747

4848
// linux: define void @pass_zst_c()
49-
// windows-msvc: define void @pass_zst_c()
50-
// windows-gnu: define void @pass_zst_c(ptr {{.*}})
49+
// windows-msvc: define void @pass_zst_c(ptr {{[^,]*}})
50+
// windows-gnu: define void @pass_zst_c(ptr {{[^,]*}})
5151
#[no_mangle]
5252
extern "C" fn pass_zst_c(_: ()) {}

0 commit comments

Comments
 (0)