summaryrefslogtreecommitdiff
path: root/user/rust/0008-Fix-zero-sized-aggregate-ABI-on-powerpc.patch
blob: ee6a7f5c1c60b1a2458074d5fa4a02f137b8e21f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
From e734014aa61cc130e180600b8cb9fdb57909e843 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Wed, 4 Sep 2019 20:44:30 -0500
Subject: [PATCH 08/18] Fix zero-sized aggregate ABI on powerpc

For targets that pass zero-sized aggregates indirectly (generally
those that pass all aggregates indirectly), we must allocate a register
for passing the address of the ZST. Clean up the existing cases and add
powerpc, which requires this as well.

While there are not currently musl targets for s390x or sparc64, they
would have the same ABI as gnu targets, so remove the env == "gnu" check
in the Linux case.

Ideally, since it is a property of the C ABI, the `!rust_abi` case would
be handled entirely in `adjust_c_abi`. However, that would require
updating each implementation of `compute_abi_info` to handle ZSTs.
---
 src/librustc/ty/layout.rs | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 19c753bc304..b0e1b391e4b 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -2660,12 +2660,11 @@ where
         };
 
         let target = &cx.tcx().sess.target.target;
-        let win_x64_gnu =
-            target.target_os == "windows" && target.arch == "x86_64" && target.target_env == "gnu";
-        let linux_s390x =
-            target.target_os == "linux" && target.arch == "s390x" && target.target_env == "gnu";
-        let linux_sparc64 =
-            target.target_os == "linux" && target.arch == "sparc64" && target.target_env == "gnu";
+        let indirect_zst = match target.arch.as_ref() {
+            "powerpc" | "s390x" | "sparc64" => true,
+            "x86_64" => target.target_os == "windows" && target.target_env == "gnu",
+            _ => false,
+        };
         let rust_abi = match sig.abi {
             RustIntrinsic | PlatformIntrinsic | Rust | RustCall => true,
             _ => false,
@@ -2735,11 +2734,10 @@ where
             let is_return = arg_idx.is_none();
             let mut arg = mk_arg_type(ty, arg_idx);
             if arg.layout.is_zst() {
-                // For some forsaken reason, x86_64-pc-windows-gnu
-                // doesn't ignore zero-sized struct arguments.
-                // The same is true for s390x-unknown-linux-gnu
-                // and sparc64-unknown-linux-gnu.
-                if is_return || rust_abi || (!win_x64_gnu && !linux_s390x && !linux_sparc64) {
+                // FIXME: The C ABI case should be handled in adjust_for_cabi.
+                // Zero-sized struct arguments cannot be ignored in the C ABI
+                // if they are passed indirectly.
+                if is_return || rust_abi || !indirect_zst {
                     arg.mode = PassMode::Ignore(IgnoreMode::Zst);
                 }
             }
-- 
2.21.0