rust-lang / rust-lang/rust-bindgen
__attribute__((noreturn)) on a returned function pointer makes take itself -> !
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
void (__attribute__((noreturn)) *take(int t))(int);
Bindgen Invocation
$ bindgen input.h -- -x c -std=gnu11
Actual Results
bindgen exits 0 and emits:
unsafe extern "C" {
pub fn take(t: ::std::os::raw::c_int) -> !;
}
The attribute is on the returned function pointer, not on take. take returns a pointer.
libclang's type spelling is void (*(int))(int) __attribute__((noreturn)). FunctionSig::from_ty looks for __attribute__((noreturn)) at paren-depth 0 and sets is_divergent.
Without the attribute, bindgen emits Option<unsafe extern "C" fn(t: c_int)>. void take(int t) __attribute__((noreturn)); correctly becomes -> !.
#2715 / #2716 fixed the argument shape void foo(__attribute__((noreturn)) void (*arg)(void)); (foo(arg: Option<fn() -> !>), no outer -> !). That check skips attributes inside argument parentheses. On a returned pointer clang puts the attribute at the end of the spelling (depth 0), so the same check still fires.
Expected Results
take should return a function pointer (the pointee can be fn(c_int) -> !). It should not be -> !.
Environment
bindgen: 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
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
Start at FunctionSig::from_ty and reproduce the issue with the supplied C header and bindgen invocation. Check how attribute((noreturn)) is classified at different parenthesis depths, then verify that take returns a function pointer while only the pointee remains divergent, matching the expected Rust binding.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, cpp, rust
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 74/100