diff options
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.patch | 62 |
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 + |