diff options
| author | Ralf Jung <post@ralfj.de> | 2025-01-08 15:32:09 +0100 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2025-01-12 13:32:36 +0100 |
| commit | 675a1036cae37acdcd553dc58ee17299414e8b3d (patch) | |
| tree | c2879198c033649f84a27225bc65727c3ef2b2c6 | |
| parent | d760bb66033c3b5688fbdd96119a31adc5f7441c (diff) | |
| download | rust-675a1036cae37acdcd553dc58ee17299414e8b3d.tar.gz rust-675a1036cae37acdcd553dc58ee17299414e8b3d.zip | |
on Windows, consistently pass ZST by-ref
| -rw-r--r-- | compiler/rustc_target/src/callconv/mod.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_target/src/callconv/x86_win64.rs | 22 | ||||
| -rw-r--r-- | compiler/rustc_ty_utils/src/abi.rs | 39 | ||||
| -rw-r--r-- | tests/codegen/abi-win64-zst.rs | 14 |
4 files changed, 22 insertions, 57 deletions
diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index 288a73685f6..6a3899e66e7 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -665,11 +665,11 @@ impl<'a, Ty> FnAbi<'a, Ty> { "x86_64" => match abi { ExternAbi::SysV64 { .. } => x86_64::compute_abi_info(cx, self), ExternAbi::Win64 { .. } | ExternAbi::Vectorcall { .. } => { - x86_win64::compute_abi_info(cx, self, abi) + x86_win64::compute_abi_info(cx, self) } _ => { if cx.target_spec().is_like_windows { - x86_win64::compute_abi_info(cx, self, abi) + x86_win64::compute_abi_info(cx, self) } else { x86_64::compute_abi_info(cx, self) } diff --git a/compiler/rustc_target/src/callconv/x86_win64.rs b/compiler/rustc_target/src/callconv/x86_win64.rs index 96dcac09f12..0944bda2687 100644 --- a/compiler/rustc_target/src/callconv/x86_win64.rs +++ b/compiler/rustc_target/src/callconv/x86_win64.rs @@ -1,15 +1,11 @@ -use rustc_abi::{BackendRepr, ExternAbi, Float, Primitive}; +use rustc_abi::{BackendRepr, Float, Primitive}; use crate::abi::call::{ArgAbi, FnAbi, Reg}; use crate::spec::HasTargetSpec; // Win64 ABI: https://docs.microsoft.com/en-us/cpp/build/parameter-passing -pub(crate) fn compute_abi_info<Ty>( - cx: &impl HasTargetSpec, - fn_abi: &mut FnAbi<'_, Ty>, - abi: ExternAbi, -) { +pub(crate) fn compute_abi_info<Ty>(_cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) { let fixup = |a: &mut ArgAbi<'_, Ty>| { match a.layout.backend_repr { BackendRepr::Uninhabited | BackendRepr::Memory { sized: false } => {} @@ -48,16 +44,14 @@ pub(crate) fn compute_abi_info<Ty>( // Windows ABIs do not talk about ZST since such types do not exist in MSVC. // In that sense we can do whatever we want here, and maybe we should throw an error // (but of course that would be a massive breaking change now). - // We try to match clang and gcc, so we make windows-gnu and the native - // Windows ABIs (i.e., everything except for `extern "C"`) pass ZST via - // pointer indirection. windows-msvc `extern "C"` still skips ZST. - if (cx.target_spec().os == "windows" && cx.target_spec().env == "gnu") - || !matches!(abi, ExternAbi::C { .. }) - { - arg.make_indirect_from_ignore(); - } + // We try to match clang and gcc (which allow ZST is their windows-gnu targets), so we + // pass ZST via pointer indirection. + arg.make_indirect_from_ignore(); continue; } fixup(arg); } + // FIXME: We should likely also do something about ZST return types, similar to above. + // However, that's non-trivial due to `()`. + // See <https://github.com/rust-lang/unsafe-code-guidelines/issues/552>. } diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 7732f893302..b63534880d1 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -267,10 +267,8 @@ fn fn_sig_for_fn_abi<'tcx>( #[inline] fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: ExternAbi, c_variadic: bool) -> Conv { - let target = &tcx.sess.target; - use rustc_abi::ExternAbi::*; - match target.adjust_abi(abi, c_variadic) { + match tcx.sess.target.adjust_abi(abi, c_variadic) { RustIntrinsic | Rust | RustCall => Conv::Rust, // 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 System { .. } => bug!("system abi should be selected elsewhere"), EfiApi => bug!("eficall abi should be selected elsewhere"), - // See commentary in `is_abi_supported`: we map these to "C" on targets - // where they do not make sense. - Stdcall { .. } => { - if target.arch == "x86" { - Conv::X86Stdcall - } else { - Conv::C - } - } - Fastcall { .. } => { - if target.arch == "x86" { - Conv::X86Fastcall - } else { - Conv::C - } - } - Vectorcall { .. } => { - if ["x86", "x86_64"].contains(&&target.arch[..]) { - Conv::X86VectorCall - } else { - Conv::C - } - } - Thiscall { .. } => { - if target.arch == "x86" { - Conv::X86ThisCall - } else { - Conv::C - } - } - + Stdcall { .. } => Conv::X86Stdcall, + Fastcall { .. } => Conv::X86Fastcall, + Vectorcall { .. } => Conv::X86VectorCall, + Thiscall { .. } => Conv::X86ThisCall, C { .. } => Conv::C, Unadjusted => Conv::C, Win64 { .. } => Conv::X86_64Win64, diff --git a/tests/codegen/abi-win64-zst.rs b/tests/codegen/abi-win64-zst.rs index 2f80e908dbc..dd361898144 100644 --- a/tests/codegen/abi-win64-zst.rs +++ b/tests/codegen/abi-win64-zst.rs @@ -23,16 +23,16 @@ trait Sized {} // Make sure the argument is always passed when explicitly requesting a Windows ABI. // Our goal here is to match clang: <https://clang.godbolt.org/z/Wr4jMWq3P>. -// CHECK: define win64cc void @pass_zst_win64(ptr {{.*}}) +// CHECK: define win64cc void @pass_zst_win64(ptr {{[^,]*}}) #[no_mangle] extern "win64" fn pass_zst_win64(_: ()) {} -// CHECK: define x86_vectorcallcc void @pass_zst_vectorcall(ptr {{.*}}) +// CHECK: define x86_vectorcallcc void @pass_zst_vectorcall(ptr {{[^,]*}}) #[no_mangle] extern "vectorcall" fn pass_zst_vectorcall(_: ()) {} -// windows-gnu: define void @pass_zst_fastcall(ptr {{.*}}) -// windows-msvc: define void @pass_zst_fastcall(ptr {{.*}}) +// windows-gnu: define void @pass_zst_fastcall(ptr {{[^,]*}}) +// windows-msvc: define void @pass_zst_fastcall(ptr {{[^,]*}}) #[no_mangle] #[cfg(windows)] // "fastcall" is not valid on 64bit Linux extern "fastcall" fn pass_zst_fastcall(_: ()) {} @@ -43,10 +43,10 @@ extern "fastcall" fn pass_zst_fastcall(_: ()) {} #[no_mangle] extern "sysv64" fn pass_zst_sysv64(_: ()) {} -// For `extern "C"` functions, ZST are ignored on windows-msvc. +// For `extern "C"` functions, ZST are ignored on Linux put passed on Windows. // linux: define void @pass_zst_c() -// windows-msvc: define void @pass_zst_c() -// windows-gnu: define void @pass_zst_c(ptr {{.*}}) +// windows-msvc: define void @pass_zst_c(ptr {{[^,]*}}) +// windows-gnu: define void @pass_zst_c(ptr {{[^,]*}}) #[no_mangle] extern "C" fn pass_zst_c(_: ()) {} |
