Skip to content

ObjC ARC __weak struct fields are passed by value (Copy) instead of the hidden-pointer ABI #3463

Description

@lwz23

Input C/C++ Header

typedef struct objc_object *id;

typedef struct {
    __weak id w;
    int t;
} W;

int takeW(W s, int z);
int takeWp(id p, int t);
id box7(void);

Bindgen Invocation

$ bindgen input.h --no-rustfmt-bindings -- -x objective-c -fobjc-arc

Actual Results

bindgen emits a Copy by-value struct. Layout tests compile (size_of::<W>() == 16).

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct W {
    pub w: id,
    pub t: ::std::os::raw::c_int,
}

unsafe extern "C" {
    pub fn takeW(s: W, z: ::std::os::raw::c_int) -> ::std::os::raw::c_int;
    pub fn takeWp(p: id, t: ::std::os::raw::c_int) -> ::std::os::raw::c_int;
}

An __weak field makes the record nontrivial for calls under ARC. Clang passes takeW indirectly (objc_copyWeak / hidden pointer). rustc passes [2 x i64] in registers.

On Darwin aarch64, s.t = 10, z = 1:

C  takeW(s, 1) = 11    takeWp(o, 10) = 11
Rust takeW(s, 1) = 10    takeWp(o, 10) = 11

The thin __weak id parameter matches. Only the by-value struct disagrees.

This is not #778 (C++ Itanium user-destructor “non-trivial for the purposes of calls”). It is a C struct with an ObjC ARC ownership qualifier. bindgen has no __weak / objc_ownership handling.

Expected Results

A record with an __weak field should not be passed as a Copy by-value argument. Clang’s calling convention for that type is a hidden pointer; the generated signature should match that (or bindgen should refuse to emit a by-value Copy binding).

Environment

bindgen current main: 77cbc72
bindgen:              0.73.1
clang:                Apple clang 21.0.0
rustc:                1.97.1
target:               aarch64-apple-darwin

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions