Skip to content

clang_macro_fallback() silently skipped when using header_contents() #3351

@zRedShift

Description

@zRedShift

clang_macro_fallback() silently produces no output when headers are provided via header_contents() instead of header().

try_ensure_fallback_translation_unit() in bindgen/ir/context.rs only checks input_headers (populated by .header()). When the user uses .header_contents() instead, input_headers is empty, the slice pattern match fails, and the function returns None. No error, no warning — the fallback is silently skipped for every macro.

Additionally, Builder::generate() uses std::mem::take() on input_header_contents before passing options to Bindings::generate(), so even if the fallback code checked input_header_contents, it would find it empty.

Reproduction:

let bindings = bindgen::Builder::default()
    .header_contents("wrapper.h", r#"
        #define UINT32_C(c) c ## U
        #define MY_CONST UINT32_C(42)
    "#)
    .clang_macro_fallback()
    .generate()
    .unwrap();

// MY_CONST is silently missing from the output

Impact: Common in build scripts that construct wrapper headers dynamically rather than writing them to disk. The user gets no constants from function-like macro invocations (e.g. UINT32_C, _IOR, _IOW) with no indication anything went wrong.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions