Skip to content

extern "C" fn ABI on aarch64 violates repr(transparent) #115664

Closed
@RalfJung

Description

@RalfJung

On aarch64-unknown-linux-gnu (a tier 1 target), consider this testcase:

#![feature(rustc_attrs)]

type T = (f32, f32, f32);

#[repr(transparent)]
struct Wrapper2<T>((), T);

#[rustc_abi(debug)]
extern "C" fn test1(_x: T) {}

#[rustc_abi(debug)]
extern "C" fn test2(_x: Wrapper2<T>) {}

fn main() {}

test1 passes its argument as

                   mode: Cast(
                       CastTarget {
                           prefix: [
                               None,
                               None,
                               None,
                               None,
                               None,
                               None,
                               None,
                               None,
                           ],
                           rest: Uniform {
                               unit: Reg {
                                   kind: Float,
                                   size: Size(4 bytes),
                               },
                               total: Size(12 bytes),
                           },
                           attrs: ArgAttributes {
                               regular: (empty),
                               arg_ext: None,
                               pointee_size: Size(0 bytes),
                               pointee_align: None,
                           },
                       },
                       false,
                   ),

test2 uses

                   mode: Cast(
                       CastTarget {
                           prefix: [
                               None,
                               None,
                               None,
                               None,
                               None,
                               None,
                               None,
                               None,
                           ],
                           rest: Uniform {
                               unit: Reg {
                                   kind: Integer,
                                   size: Size(8 bytes),
                               },
                               total: Size(12 bytes),
                           },
                           attrs: ArgAttributes {
                               regular: (empty),
                               arg_ext: None,
                               pointee_size: Size(0 bytes),
                               pointee_align: None,
                           },
                       },
                       false,
                   ),

IOW, test1 uses float registers and test2 uses int registers. This violates our promise that repr(transparent) types are ABI-compatible.

I think this might indicate a bug in the homogeneous_aggregate function? At least I don't see anything in the aarch64 adjustment that would be obviously wrong.

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-AArch64Armv8-A or later processors in AArch64 mode

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions