about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2025-01-08 15:32:09 +0100
committerRalf Jung <post@ralfj.de>2025-01-12 13:32:36 +0100
commit675a1036cae37acdcd553dc58ee17299414e8b3d (patch)
treec2879198c033649f84a27225bc65727c3ef2b2c6
parentd760bb66033c3b5688fbdd96119a31adc5f7441c (diff)
downloadrust-675a1036cae37acdcd553dc58ee17299414e8b3d.tar.gz
rust-675a1036cae37acdcd553dc58ee17299414e8b3d.zip
on Windows, consistently pass ZST by-ref
-rw-r--r--compiler/rustc_target/src/callconv/mod.rs4
-rw-r--r--compiler/rustc_target/src/callconv/x86_win64.rs22
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs39
-rw-r--r--tests/codegen/abi-win64-zst.rs14
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(_: ()) {}