From 5ae948dc2baac9b45e02a85d8f1575418c37d719 Mon Sep 17 00:00:00 2001 From: Vegard Eriksen Date: Thu, 2 Oct 2025 13:58:04 +0200 Subject: [PATCH] Allow constant expressions that doesn't fit in i64. Fixes #2618 --- .../tests/expectations/tests/issue-2618.rs | 13 +++++++++++++ bindgen-tests/tests/headers/issue-2618.h | 18 ++++++++++++++++++ bindgen/clang.rs | 3 ++- bindgen/ir/int.rs | 5 ----- bindgen/ir/var.rs | 2 +- 5 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 bindgen-tests/tests/expectations/tests/issue-2618.rs create mode 100644 bindgen-tests/tests/headers/issue-2618.h diff --git a/bindgen-tests/tests/expectations/tests/issue-2618.rs b/bindgen-tests/tests/expectations/tests/issue-2618.rs new file mode 100644 index 0000000000..ecac1ec81e --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-2618.rs @@ -0,0 +1,13 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +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; diff --git a/bindgen-tests/tests/headers/issue-2618.h b/bindgen-tests/tests/headers/issue-2618.h new file mode 100644 index 0000000000..841ff61d77 --- /dev/null +++ b/bindgen-tests/tests/headers/issue-2618.h @@ -0,0 +1,18 @@ +// bindgen-flags: --allowlist-var "val[0-9]+" + +typedef __UINT32_TYPE__ uint32_t; +typedef __UINT64_TYPE__ uint64_t; + +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); diff --git a/bindgen/clang.rs b/bindgen/clang.rs index 1e8326ed82..9e614da9f8 100644 --- a/bindgen/clang.rs +++ b/bindgen/clang.rs @@ -2351,10 +2351,11 @@ impl EvalResult { if unsafe { clang_EvalResult_isUnsignedInt(self.x) } != 0 { let value = unsafe { clang_EvalResult_getAsUnsigned(self.x) }; - if value > i64::MAX as c_ulonglong { + if value > u64::MAX as c_ulonglong { return None; } + // Do a wrapping cast to i64. This will be losslessly cast back to u64 later. return Some(value as i64); } diff --git a/bindgen/ir/int.rs b/bindgen/ir/int.rs index ed18a99949..217fc11efa 100644 --- a/bindgen/ir/int.rs +++ b/bindgen/ir/int.rs @@ -120,9 +120,4 @@ impl IntKind { _ => return None, }) } - - /// Whether this type's signedness matches the value. - pub(crate) fn signedness_matches(&self, val: i64) -> bool { - val >= 0 || self.is_signed() - } } diff --git a/bindgen/ir/var.rs b/bindgen/ir/var.rs index 45f4ba1ba0..9d72dcf06e 100644 --- a/bindgen/ir/var.rs +++ b/bindgen/ir/var.rs @@ -341,7 +341,7 @@ impl ClangSubItemParser for Var { }; let mut val = cursor.evaluate().and_then(|v| v.as_int()); - if val.is_none() || !kind.signedness_matches(val.unwrap()) { + if val.is_none() { val = get_integer_literal_from_cursor(&cursor); }