rust-lang / rust-lang/rust-bindgen

`aarch64_vector_pcs` function pointers become a zero-sized opaque; rustc drops the argument

Open
#3,475 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
5.3k
Forks
829
Avg merge
1d 1h
Merged PRs (30d)
15

Description

Input C/C++ Header
typedef int (*fp)(int) __attribute__((aarch64_vector_pcs));
int apply(fp f, int x);
Bindgen Invocation
$ bindgen input.h -- -std=gnu11
Actual Results

bindgen 0.72.1 and 0.73.1 both turn the function-pointer type into a zero-sized opaque blob:

pub type fp = __BindgenOpaqueArray<[u32; 0]>;
pub fn apply(f: fp, x: c_int) -> c_int;

aarch64_vector_pcs is CXCallingConv_AArch64VectorCall, which get_abi maps to Abi::Vectorcall. On a stable rustc that ABI is UnsupportedAbi, so the function-pointer type becomes a 0-size opaque instead of *mut c_void / Option<unsafe extern "C" fn(i32) -> i32>. rustc then drops the ZST from the FFI signature:

; clang
define i32 @apply(ptr noundef %0, i32 noundef %1)

; rustc of the generated bindings (twice)
declare i32 @apply(i32)

A C caller apply(dummy, 7) passes the function pointer and 7. Generated Rust apply(Default::default(), 7) becomes apply(7) and the 7 lands in the pointer register.

This is not #727 / #2693: those abort or skip when the function itself has an unknown/unsupported CC. Here bindgen exits 0 and emits a callable apply with the wrong arity.

The same 0-size opaque happens for an aarch64_vector_pcs function-pointer field (struct S { int (*fp)(int,int) __attribute__((aarch64_vector_pcs)); int t; }fp is [u32; 0] at offset 0 with t still at offset 8).

Expected Results

If vectorcall is not available, still emit a pointer-sized function-pointer type (or skip apply with a warning), not a ZST that rustc deletes from the signature.

Environment
bindgen: 0.72.1 and 0.73.1 (rust-lang/rust-bindgen 77cbc723)
clang/libclang: Homebrew clang 21.1.8
rustc: 1.97.1
target: aarch64-apple-darwin
OS: macOS

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at get_abi, where CXCallingConv_AArch64VectorCall becomes Abi::Vectorcall, then trace how UnsupportedAbi is represented for function-pointer types and fields. Reproduce the provided header with bindgen and inspect the generated Rust and LLVM signature. Done means unsupported vectorcall pointers remain pointer-sized or the declaration is skipped with a warning instead of losing an argument.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, rust
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.