Input C/C++ Header
enum class E : unsigned __int128 { HEX = ~(unsigned __int128)0 };
int take(E e, int t);
unsigned sz(void);
Bindgen Invocation
$ bindgen input.h --no-rustfmt-bindings --enable-cxx-namespaces -- -x c++ -std=c++17
Actual Results
The generated type is correct (u128). The generated constant is u64::MAX, not u128::MAX:
pub const E_HEX: E = 18446744073709551615;
pub type E = u128;
C++ E::HEX is all-ones in both halves. Rust E_HEX has hi = 0.
take returns (hi != 0) + (lo != 0) + t. sizeof is 16 on both sides. bindgen exit 0, rustc exit 0:
C: v=12 lo=18446744073709551615 hi=18446744073709551615 sz=16
Rust: v=11 lo=18446744073709551615 hi=0 sz=16
build_builtin_ty already maps CXType_UInt128 → IntKind::U128. enum_val_unsigned() is Option<u64> via clang_getEnumConstantDeclUnsignedValue, so the high half is dropped while still emitting a typed u128 constant.
This is not #3416 (packed bitfield accessors shifting a 65-bit window in u64).
Expected Results
E_HEX should be ~(unsigned __int128)0 as u128 (all-ones), or bindgen should not emit a silently truncated value as a u128 constant.
Environment
bindgen current main: 77cbc72
bindgen: 0.73.1
clang: Apple clang 21.0.0
rustc: 1.97.1
target: aarch64-apple-darwin
Input C/C++ Header
Bindgen Invocation
$ bindgen input.h --no-rustfmt-bindings --enable-cxx-namespaces -- -x c++ -std=c++17Actual Results
The generated type is correct (
u128). The generated constant isu64::MAX, notu128::MAX:C++
E::HEXis all-ones in both halves. RustE_HEXhashi = 0.takereturns(hi != 0) + (lo != 0) + t.sizeofis 16 on both sides. bindgen exit 0, rustc exit 0:build_builtin_tyalready mapsCXType_UInt128→IntKind::U128.enum_val_unsigned()isOption<u64>viaclang_getEnumConstantDeclUnsignedValue, so the high half is dropped while still emitting a typedu128constant.This is not #3416 (packed bitfield accessors shifting a 65-bit window in
u64).Expected Results
E_HEXshould be~(unsigned __int128)0asu128(all-ones), or bindgen should not emit a silently truncated value as au128constant.Environment