Skip to content

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

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions