Closed
Description
The types (i32, f32)
and MaybeUninit<T>
do not have the same ABI, as demonstrated by this testcase:
#![feature(rustc_attrs)]
type T = (i32, f32);
#[rustc_abi(debug)]
extern "C" fn test1(_x: T) {}
#[rustc_abi(debug)]
extern "C" fn test2(_x: std::mem::MaybeUninit<T>) {}
fn main() {}
The first is
mode: Cast(
CastTarget {
prefix: [
Some(
Reg {
kind: Integer,
size: Size(4 bytes),
},
),
None,
None,
None,
None,
None,
None,
None,
],
rest: Uniform {
unit: Reg {
kind: Float,
size: Size(4 bytes),
},
total: Size(4 bytes),
},
attrs: ArgAttributes {
regular: (empty),
arg_ext: None,
pointee_size: Size(0 bytes),
pointee_align: None,
},
},
false,
),
The second is
mode: Cast(
CastTarget {
prefix: [
None,
None,
None,
None,
None,
None,
None,
None,
],
rest: Uniform {
unit: Reg {
kind: Integer,
size: Size(8 bytes),
},
total: Size(8 bytes),
},
attrs: ArgAttributes {
regular: (empty),
arg_ext: None,
pointee_size: Size(0 bytes),
pointee_align: None,
},
},
false,
),
Not sure whom to ping for RISC-V issues.
Activity
RalfJung commentedon Sep 2, 2023
I think the fix will have to be to treat repr(transparent) unions specially somewhere around here
rust/compiler/rustc_target/src/abi/call/riscv.rs
Lines 90 to 94 in 1bd0430
RalfJung commentedon Sep 3, 2023
Cc @msizanoen1
msizanoen1 commentedon Sep 3, 2023
@RalfJung I'm afraid that the semantics of
#[repr(transparent)]
on unions are not clearly defined enough to figure out exactly how they should be specially treated (which variant should be used? etc.). Can you ping other people who have more knowledge on this? (Ifrepr(transparent)
on unions turns out to be incompatible with ABIs that havestruct
content destructuring semantics that depends on the types of the field in thestruct
(e.g. the RISC-V C psABI) then we definitely have a bigger problem.)RalfJung commentedon Sep 3, 2023
I have no idea who would know anything about RISC-V calling conventions. 🤷 and no other ABI is failing this test.
Basically, when the ABI description says "unions do X", then this should only apply to repr(C) and repr(Rust) unions. A repr(transparent) union must be treated exactly like its non-ZST field.
extern "C"
ABI violates repr(transparent) on unions #115509rustc_target/riscv: Fix passing of transparent unions with only one n…
23 remaining items