Skip to content

__attribute__((noreturn)) on a returned function pointer makes take itself -> ! #3489

Description

@lwz23

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

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