63 lines
2.8 KiB
Diff
63 lines
2.8 KiB
Diff
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
|
|
|