summaryrefslogtreecommitdiff
path: root/user/rust/0008-Fix-zero-sized-aggregate-ABI-on-powerpc.patch
diff options
context:
space:
mode:
Diffstat (limited to 'user/rust/0008-Fix-zero-sized-aggregate-ABI-on-powerpc.patch')
-rw-r--r--user/rust/0008-Fix-zero-sized-aggregate-ABI-on-powerpc.patch62
1 files changed, 62 insertions, 0 deletions
diff --git a/user/rust/0008-Fix-zero-sized-aggregate-ABI-on-powerpc.patch b/user/rust/0008-Fix-zero-sized-aggregate-ABI-on-powerpc.patch
new file mode 100644
index 000000000..c3da394a7
--- /dev/null
+++ b/user/rust/0008-Fix-zero-sized-aggregate-ABI-on-powerpc.patch
@@ -0,0 +1,62 @@
+From f67f0ab40f1328e04916512b9af858ca1b7faa24 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/16] 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 4af26e19b37..163db9778e5 100644
+--- a/src/librustc/ty/layout.rs
++++ b/src/librustc/ty/layout.rs
+@@ -2667,12 +2667,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,
+@@ -2742,11 +2741,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
+