Skip to content

Commit 8e1d82e

Browse files
authored
Unrolled build for rust-lang#115499
Rollup merge of rust-lang#115499 - msizanoen1:riscv-fix-transparent-union-abi, r=bjorn3 rustc_target/riscv: Fix passing of transparent unions with only one non-ZST member This ensures that `MaybeUninit<T>` has the same ABI as `T` when passed through an `extern "C"` function. Fixes rust-lang#115481. r? `@RalfJung`
2 parents 42f5828 + 4d4c13b commit 8e1d82e

File tree

4 files changed

+24
-2
lines changed

4 files changed

+24
-2
lines changed

compiler/rustc_middle/src/ty/layout.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,10 @@ where
11181118
fn is_unit(this: TyAndLayout<'tcx>) -> bool {
11191119
matches!(this.ty.kind(), ty::Tuple(list) if list.len() == 0)
11201120
}
1121+
1122+
fn is_transparent(this: TyAndLayout<'tcx>) -> bool {
1123+
matches!(this.ty.kind(), ty::Adt(def, _) if def.repr().transparent())
1124+
}
11211125
}
11221126

11231127
/// Calculates whether a function's ABI can unwind or not.

compiler/rustc_target/src/abi/call/riscv.rs

+11
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,17 @@ where
8989
}
9090
FieldsShape::Union(_) => {
9191
if !arg_layout.is_zst() {
92+
if arg_layout.is_transparent() {
93+
let non_1zst_elem = arg_layout.non_1zst_field(cx).expect("not exactly one non-1-ZST field in non-ZST repr(transparent) union").1;
94+
return should_use_fp_conv_helper(
95+
cx,
96+
&non_1zst_elem,
97+
xlen,
98+
flen,
99+
field1_kind,
100+
field2_kind,
101+
);
102+
}
92103
return Err(CannotUseFpConv);
93104
}
94105
}

compiler/rustc_target/src/abi/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ pub trait TyAbiInterface<'a, C>: Sized + std::fmt::Debug {
6666
fn is_never(this: TyAndLayout<'a, Self>) -> bool;
6767
fn is_tuple(this: TyAndLayout<'a, Self>) -> bool;
6868
fn is_unit(this: TyAndLayout<'a, Self>) -> bool;
69+
fn is_transparent(this: TyAndLayout<'a, Self>) -> bool;
6970
}
7071

7172
impl<'a, Ty> TyAndLayout<'a, Ty> {
@@ -136,6 +137,13 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
136137
Ty::is_unit(self)
137138
}
138139

140+
pub fn is_transparent<C>(self) -> bool
141+
where
142+
Ty: TyAbiInterface<'a, C>,
143+
{
144+
Ty::is_transparent(self)
145+
}
146+
139147
pub fn offset_of_subfield<C>(self, cx: &C, indices: impl Iterator<Item = usize>) -> Size
140148
where
141149
Ty: TyAbiInterface<'a, C>,

tests/ui/abi/compatibility.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use std::ptr::NonNull;
1010
// Hence there are `cfg` throughout this test to disable parts of it on those targets.
1111
// sparc64: https://github.com/rust-lang/rust/issues/115336
1212
// mips64: https://github.com/rust-lang/rust/issues/115404
13-
// riscv64: https://github.com/rust-lang/rust/issues/115481
1413
// loongarch64: https://github.com/rust-lang/rust/issues/115509
1514

1615
macro_rules! assert_abi_compatible {
@@ -110,7 +109,7 @@ macro_rules! test_transparent {
110109
test_abi_compatible!(wrap1, $t, Wrapper1<$t>);
111110
test_abi_compatible!(wrap2, $t, Wrapper2<$t>);
112111
test_abi_compatible!(wrap3, $t, Wrapper3<$t>);
113-
#[cfg(not(any(target_arch = "riscv64", target_arch = "loongarch64")))]
112+
#[cfg(not(target_arch = "loongarch64"))]
114113
test_abi_compatible!(wrap4, $t, WrapperUnion<$t>);
115114
}
116115
};

0 commit comments

Comments
 (0)