Skip to content

riscv64gc-unknown-linux-gnu extern "C" ABI violates repr(transparent) on unions #115481

Closed
@RalfJung

Description

@RalfJung
Member

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

added
I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness
O-riscvTarget: RISC-V architecture
A-ABIArea: Concerning the application binary interface (ABI)
on Sep 2, 2023
added
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
I-prioritizeIssue: Indicates that prioritization has been requested for this issue.
on Sep 2, 2023
RalfJung

RalfJung commented on Sep 2, 2023

@RalfJung
MemberAuthor

I think the fix will have to be to treat repr(transparent) unions specially somewhere around here

FieldsShape::Union(_) => {
if !arg_layout.is_zst() {
return Err(CannotUseFpConv);
}
}

RalfJung

RalfJung commented on Sep 3, 2023

@RalfJung
MemberAuthor
msizanoen1

msizanoen1 commented on Sep 3, 2023

@msizanoen1
Contributor

@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? (If repr(transparent) on unions turns out to be incompatible with ABIs that have struct content destructuring semantics that depends on the types of the field in the struct (e.g. the RISC-V C psABI) then we definitely have a bigger problem.)

RalfJung

RalfJung commented on Sep 3, 2023

@RalfJung
MemberAuthor

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.

added
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
on Sep 4, 2023

23 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ABIArea: Concerning the application binary interface (ABI)I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessO-riscvTarget: RISC-V architectureP-mediumMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Participants

      @RalfJung@apiraino@tgross35@rustbot@Noratrieb

      Issue actions

        riscv64gc-unknown-linux-gnu `extern "C"` ABI violates repr(transparent) on unions · Issue #115481 · rust-lang/rust