rust-lang / rust-lang/rust-bindgen
Wrong code generated for union with bitfields
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 5.3k
- Forks
- 829
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 15
Description
The below outputs are with bindgen 0.71.1 (no flags) on x86_64-pc-windows-msvc.
Consider the union below. There are two issues:
- The accessors for
bitfld_bandbitfld_cuse bit offsets of 4 and 8, respectively, while they should be 0. - The generated type has the wrong size, resulting in a compile error. The C type has size 4 and alignment 1, but the generated type has size 2. (On
x86_64-unknown-linux-gnuit happens to compile(!) because the alignment is 4 which makes the size also 4.) Therefore, padding needs to be added.
Don't ask me why someone put a bitfield in a union. (The case I found was an anonymous union in a struct, but that doesn't seem to make a difference.)
Header file
union Union {
int bitfld_a : 4;
int bitfld_b : 4;
int bitfld_c : 4;
};
Generated code (excerpt)
#[repr(C)]
#[derive(Copy, Clone)]
pub union Union {
pub _bitfield_align_1: [u8; 0],
pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>,
// ^^^^^^ should be 4usize
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
["Size of Union"][::std::mem::size_of::<Union>() - 4usize];
["Alignment of Union"][::std::mem::align_of::<Union>() - 1usize];
};
impl Union {
// ...
pub fn bitfld_b(&self) -> ::std::os::raw::c_int {
unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 4u8) as u32) }
// ^^^^^^ should be 0usize
}
// ...
}
Compile error
error[E0080]: evaluation of constant value failed
--> bindings.rs:148:23
|
148 | ["Size of Union"][::std::mem::size_of::<Union>() - 4usize];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `2_usize - 4_usize`, which would overflow
Full output
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the issue from the C union in the report with bindgen 0.71.1, then inspect the generated bindings.rs output and the bitfield layout/accessor generation path. Add regression coverage for the union case and verify that the generated accessors use the correct offsets and that the type has size 4 and alignment 1.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, rust
- Domain
- compilers, devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100