rust-bindgen icon indicating copy to clipboard operation
rust-bindgen copied to clipboard

Generating uint64_t value fails when the value is greater than 0x7fffffffffffffff and has braces.

Open anolivetree opened this issue 1 year ago • 2 comments

Input C/C++ Header


#include <stdint.h>
#include <limits.h>

static const uint32_t val1 = 0x7fffffff;
static const uint32_t val2 = 0x80000000;
static const uint32_t val3 = 0xffffffff;
static const uint64_t val4 = 0x7fffffffffffffff;
static const uint64_t val5 = 0x8000000000000000;
static const uint64_t val6 = 0xffffffffffffffff;

static const uint32_t val7 = (0x7fffffff);
static const uint32_t val8 = (0x80000000);
static const uint32_t val9 = (0xffffffff);
static const uint64_t val10 = (0x7fffffffffffffff);
static const uint64_t val11 = (0x8000000000000000);
static const uint64_t val12 = (0xffffffffffffffff);

static const uint64_t val13 = (uint64_t)ULONG_MAX;
static const uint64_t val14 = (uint64_t)0xffffffffffffffff;

Bindgen Invocation

fn main() {
    println!("cargo:rerun-if-changed=header.h");

    let bindings = bindgen::Builder::default()
        .header("header.h")
        .allowlist_recursively(false)
        .allowlist_var("val1")
        .allowlist_var("val2")
        .allowlist_var("val3")
        .allowlist_var("val4")
        .allowlist_var("val5")
        .allowlist_var( "val6")
        .allowlist_var( "val7")
        .allowlist_var( "val8")
        .allowlist_var( "val9")
        .allowlist_var( "val10")
        .allowlist_var( "val11")
        .allowlist_var( "val12")
        .allowlist_var( "val13")
        .allowlist_var( "val14")
        .parse_callbacks(Box::new(bindgen::CargoCallbacks))
        .generate()
        .expect("Unable to generate bindings");

    // Write the bindings to the $OUT_DIR/bindings.rs file.
    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Couldn't write bindings!");
}

Actual Results

/* automatically generated by rust-bindgen 0.66.1 */

pub const val1: u32 = 2147483647;
pub const val2: u32 = 2147483648;
pub const val3: u32 = 4294967295;
pub const val4: u64 = 9223372036854775807;
pub const val5: u64 = 9223372036854775808;
pub const val6: u64 = 18446744073709551615;
pub const val7: u32 = 2147483647;
pub const val8: u32 = 2147483648;
pub const val9: u32 = 4294967295;
pub const val10: u64 = 9223372036854775807;
extern "C" {
    pub static val11: u64;
}
extern "C" {
    pub static val12: u64;
}
extern "C" {
    pub static val13: u64;
}
extern "C" {
    pub static val14: u64;
}

Expected Results

pub const val1: u32 = 2147483647;
pub const val2: u32 = 2147483648;
pub const val3: u32 = 4294967295;
pub const val4: u64 = 9223372036854775807;
pub const val5: u64 = 9223372036854775808;
pub const val6: u64 = 18446744073709551615;
pub const val7: u32 = 2147483647;
pub const val8: u32 = 2147483648;
pub const val9: u32 = 4294967295;
pub const val10: u64 = 9223372036854775807;
pub const val11: u64 = 9223372036854775808;
pub const val12: u64 = 18446744073709551615;
pub const val13: u64 = 18446744073709551615;
pub const val14: u64 = 18446744073709551615;

anolivetree avatar Sep 02 '23 07:09 anolivetree

This happens because any non-trivial literal is treated as an expression so (literal) will trigger a clang evaluation and bindgen ignores constants that would be truncated to fit in a i64. I'll give it a go to see what happens.

pvdrz avatar Sep 06 '23 21:09 pvdrz