rust-lang / rust-lang/rust-bindgen
--wrap-static-fns generates invalid C for pointer-to-array parameters and returns
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
static inline int (*phase8_array_identity(int (*value)[4]))[4] {
return value;
}
Bindgen Invocation
$ bindgen input.h \
--wrap-static-fns \
--wrap-static-fns-path wrapper \
--rust-target 1.75 \
--no-layout-tests \
--no-rustfmt-bindings \
--output bindings.rs
Actual Results
The Rust declaration has the expected pointer-to-array type:
extern "C" {
#[link_name = "phase8_array_identity__extern"]
pub fn phase8_array_identity(
value: *mut [::std::os::raw::c_int; 4usize],
) -> *mut [::std::os::raw::c_int; 4usize];
}
The generated wrapper.c does not preserve the C declarator:
int * [4] phase8_array_identity__extern(int *value [4]) {
return phase8_array_identity(value);
}
Clang rejects it:
error: brackets are not allowed here
error: function cannot return array type 'int *[4]'
error: incompatible pointer types passing 'int **' to parameter of type 'int (*)[4]'
The parameter is wrong as well as the return type. In a parameter list,
int *value[4] is adjusted to int **; it is not int (*)[4].
Expected Results
The generated wrapper needs parentheses around the pointer declarators:
int (*phase8_array_identity__extern(int (*value)[4]))[4] {
return phase8_array_identity(value);
}
I compiled that wrapper and linked it to a Rust caller using the generated
bindings.rs without edits. The direct C caller and the Rust caller both
printed:
identity=1 sum=10 first=1 last=4
Environment
bindgen current main: 9d26c6eddeff9192ddedb563192abe3128fc5aae
bindgen release: 0.72.1
clang: 15.0.7
rustc: 1.75.0
target: x86_64-unknown-linux-gnu
The same generated C compile failure occurs with current main and 0.72.1,
at both O0 and O2.
Additional notes
This looks like a declarator serialization problem. The array serializer
appends [length], while the pointer serializer pushes * onto the type
string. That is not enough to represent cases where the * must be
parenthesized.
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 bindgen invocation from the issue and inspect wrapper.c alongside bindings.rs, focusing on the array and pointer declarator serializers described in the report. Done means the wrapper preserves parentheses for pointer-to-array parameters and returns, compiles with Clang, and the direct C and Rust callers produce identity=1 sum=10 first=1 last=4.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, rust
- Domain
- compilers, tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100