Skip to content

Commit 308071a

Browse files
committed
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.
1 parent e2fa952 commit 308071a

File tree

1 file changed

+9
-11
lines changed

1 file changed

+9
-11
lines changed

src/librustc/ty/layout.rs

+9-11
Original file line numberDiff line numberDiff line change
@@ -2642,12 +2642,11 @@ where
26422642
};
26432643

26442644
let target = &cx.tcx().sess.target.target;
2645-
let win_x64_gnu =
2646-
target.target_os == "windows" && target.arch == "x86_64" && target.target_env == "gnu";
2647-
let linux_s390x =
2648-
target.target_os == "linux" && target.arch == "s390x" && target.target_env == "gnu";
2649-
let linux_sparc64 =
2650-
target.target_os == "linux" && target.arch == "sparc64" && target.target_env == "gnu";
2645+
let indirect_zst = match target.arch.as_ref() {
2646+
"powerpc" | "s390x" | "sparc64" => true,
2647+
"x86_64" => target.target_os == "windows" && target.target_env == "gnu",
2648+
_ => false,
2649+
};
26512650
let rust_abi = match sig.abi {
26522651
RustIntrinsic | PlatformIntrinsic | Rust | RustCall => true,
26532652
_ => false,
@@ -2709,11 +2708,10 @@ where
27092708
let is_return = arg_idx.is_none();
27102709
let mut arg = mk_arg_type(ty, arg_idx);
27112710
if arg.layout.is_zst() {
2712-
// For some forsaken reason, x86_64-pc-windows-gnu
2713-
// doesn't ignore zero-sized struct arguments.
2714-
// The same is true for s390x-unknown-linux-gnu
2715-
// and sparc64-unknown-linux-gnu.
2716-
if is_return || rust_abi || (!win_x64_gnu && !linux_s390x && !linux_sparc64) {
2711+
// FIXME: The C ABI case should be handled in adjust_for_cabi.
2712+
// Zero-sized struct arguments cannot be ignored in the C ABI
2713+
// if they are passed indirectly.
2714+
if is_return || rust_abi || !indirect_zst {
27172715
arg.mode = PassMode::Ignore;
27182716
}
27192717
}

0 commit comments

Comments
 (0)