rust-lang / rust-lang/rust-bindgen

`enum class : unsigned __int128` enumerator constants are truncated to `u64`

Open
#3,465 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
5.3k
Forks
829
Avg merge
1d 1h
Merged PRs (30d)
15

Description

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_UInt128IntKind::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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing enum constant generation through enum_val_unsigned() and compare it with build_builtin_ty(), which already maps CXType_UInt128 to IntKind::U128. Reproduce the issue with the provided C++ header and bindgen invocation, then verify that the generated E_HEX preserves both halves of the u128 value without silent truncation.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, rust
Domain
compilers, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.