diff options
| author | msizanoen <msizanoen@qtmlabs.xyz> | 2023-09-03 15:58:21 +0700 |
|---|---|---|
| committer | msizanoen <msizanoen@qtmlabs.xyz> | 2023-09-19 12:06:33 +0200 |
| commit | 751ecde0640f1d079515964e72e2646e82cb25f4 (patch) | |
| tree | 2f04ddbee8e786e5505cd3f099a3520fa63e0daf /compiler/rustc_target/src/abi | |
| parent | ae9c330629f1fb03a636cb8af367fead024793db (diff) | |
| download | rust-751ecde0640f1d079515964e72e2646e82cb25f4.tar.gz rust-751ecde0640f1d079515964e72e2646e82cb25f4.zip | |
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 https://github.com/rust-lang/rust/issues/115481.
Diffstat (limited to 'compiler/rustc_target/src/abi')
| -rw-r--r-- | compiler/rustc_target/src/abi/call/riscv.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/mod.rs | 8 |
2 files changed, 19 insertions, 0 deletions
diff --git a/compiler/rustc_target/src/abi/call/riscv.rs b/compiler/rustc_target/src/abi/call/riscv.rs index d90dce2a087..93a2045632a 100644 --- a/compiler/rustc_target/src/abi/call/riscv.rs +++ b/compiler/rustc_target/src/abi/call/riscv.rs @@ -89,6 +89,17 @@ where } FieldsShape::Union(_) => { if !arg_layout.is_zst() { + if arg_layout.is_transparent() { + 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; + return should_use_fp_conv_helper( + cx, + &non_1zst_elem, + xlen, + flen, + field1_kind, + field2_kind, + ); + } return Err(CannotUseFpConv); } } diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 636adcf6b17..74fe98920c4 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -66,6 +66,7 @@ pub trait TyAbiInterface<'a, C>: Sized + std::fmt::Debug { fn is_never(this: TyAndLayout<'a, Self>) -> bool; fn is_tuple(this: TyAndLayout<'a, Self>) -> bool; fn is_unit(this: TyAndLayout<'a, Self>) -> bool; + fn is_transparent(this: TyAndLayout<'a, Self>) -> bool; } impl<'a, Ty> TyAndLayout<'a, Ty> { @@ -136,6 +137,13 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { Ty::is_unit(self) } + pub fn is_transparent<C>(self) -> bool + where + Ty: TyAbiInterface<'a, C>, + { + Ty::is_transparent(self) + } + pub fn offset_of_subfield<C>(self, cx: &C, indices: impl Iterator<Item = usize>) -> Size where Ty: TyAbiInterface<'a, C>, |
