Skip to content

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

Closed

Description

@RalfJung

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

  1. 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
  2. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on Sep 2, 2023
  3. 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);
    }
    }

  4. RalfJung commented on Sep 3, 2023

    @RalfJung
    MemberAuthor
  5. 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.)

  6. 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.

  7. added
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    and removed
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Sep 4, 2023
  8. apiraino commented on Sep 4, 2023

    @apiraino
    Contributor

    WG-prioritization assigning priority (Zulip discussion).

    @rustbot label -I-prioritize +P-medium

  9. 4 remaining items

  10. added 3 commits that reference this issue on Sep 7, 2023
  11. added a commit that references this issue on Sep 19, 2023
  12. added a commit that references this issue on Sep 19, 2023
  13. tgross35 commented on Sep 19, 2023

    @tgross35
    Member

    @RalfJung now that this is fixed, is there a CI test to catch regressions?

  14. RalfJung commented on Sep 19, 2023

    @RalfJung
    MemberAuthor

    There is a test in tests/ui/abi/compatibility.rs but we don't run tests for riscv, since it's a tier 2 target.

  15. RalfJung commented on Sep 19, 2023

    @RalfJung
    MemberAuthor

    Also see #115609 for another ABI issue that affects riscv (and more).

  16. tgross35 commented on Sep 19, 2023

    @tgross35
    Member

    Are tier 2 tests run once before release or anything like that? It seems like at least a subset of tests (this one) are important enough that we should raise a red flag if we brake them somehow on any targets. But that doesn't fit well into the tiering structure...

  17. RalfJung commented on Sep 20, 2023

    @RalfJung
    MemberAuthor

    I'm not aware of any process like that. Part of the point of being tier 2 is not to burden all contributors with keeping the target working, is it? If we do want to accept that burden, we could consider running something like ./x.py test codegen && ./x.py test ui --test-args abi for tier 2 targets.

    But having this discussion in a closed issue makes little sense. Do you want to open a new issue or Zulip thread for discussing tier 2 target test coverage?

  18. RalfJung commented on Sep 21, 2023

    @RalfJung
    MemberAuthor

    Inspired by #116004 I found a way to have a test for this: #116030.

  19. tgross35 commented on Sep 21, 2023

    @tgross35
    Member

    Awesome! Thanks for the update here

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

      Development

      No branches or pull requests

      Issue actions