rust-lang / rust-lang/rust-bindgen
`matrix_type` values are passed with the wrong ABI in generated bindings
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 float m2 __attribute__((matrix_type(2, 2)));
m2 add(m2 a, m2 b);
float first(m2 a);
m2 make(float a00, float a10, float a01, float a11);
make writes column-major entries r[0][0]=a00, r[1][0]=a10, r[0][1]=a01, r[1][1]=a11. add is a+b. first returns a[0][0].
Bindgen Invocation
$ bindgen input.h --rust-target 1.75 --no-rustfmt-bindings --output bindings.rs -- -fenable-matrix
-fenable-matrix is required for clang to accept matrix_type.
Actual Results
Both 0.72.1 and current main emit an opaque 16-byte integer array and still generate by-value extern "C" functions:
pub type m2 = __BindgenOpaqueArray<u32, 4usize>; // 0.72.1
// current main: __BindgenOpaqueArray<[u32; 4usize]>
extern "C" {
pub fn add(a: m2, b: m2) -> m2;
pub fn first(a: m2) -> f32;
pub fn make(a00: f32, a10: f32, a01: f32, a11: f32) -> m2;
}
clang-15's AST still has the matrix type (ConstantMatrixType 'float __attribute__((matrix_type(2, 2)))'), and the same clang lowers the C functions to a float vector:
define <4 x float> @make(float, float, float, float)
define float @first(<4 x float>)
define <4 x float> @add(<4 x float>, <4 x float>)
A Rust caller using the generated binding, linked against that clang object, gets a { i64, i64 } ABI instead:
declare { i64, i64 } @make(float, float, float, float)
declare { i64, i64 } @add({ i64, i64 }, { i64, i64 })
declare float @first({ i64, i64 })
sizeof(m2) is 16 on both sides (_Alignof(m2) is 4), so the generated layout tests would not catch this.
Direct C:
c first_a=1.000000 first_c=11.000000 sizeof=16 align=4
Rust through the binding, same lib.o:
r first_a=-136854030000000 first_c=-136853630000000 sizeof=16
The Rust numbers change between runs. Nothing is printed on the way; rustc accepts the binding.
Expected Results
Either:
- emit a type that rustc will pass the way clang passes
<4 x float>, or - refuse to generate by-value functions that take or return
matrix_typevalues, instead of substituting an opaque integer array.
A pointer-only API would also be acceptable if by-value FFI cannot be represented.
Environment
bindgen current main: 25b23474496e78f6a1fbf1c02cb66f11e4d176d0
bindgen release: 0.72.1
clang: Ubuntu clang 15.0.7
rustc: 1.75.0
target: x86_64-unknown-linux-gnu
The same ABI mismatch occurs with current main and 0.72.1.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the issue with input.h, the shown bindgen invocation, clang 15, and the linked lib.o. Compare bindings.rs and the generated LLVM declarations with clang's <4 x float> ABI. Done means matrix_type by-value functions use a compatible Rust ABI, or generation refuses them instead of emitting opaque integer arrays.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, cpp, rust
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100