bitfields: inconsistent size between --opaque-type and not (both wrong)

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

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
cpp, rust
Domain
tooling

Research direction

Start by reproducing the NV_INFOFRAME_VIDEO example with bindgen 0.72.1, both normally and with --opaque-type, and compare the generated Rust size and alignment assertions with clang and MSVC results from the linked Godbolt example. Done means both paths agree on the correct 32-bit integer layout and the generated size and alignment assertions pass.

Written by the indexing model from the issue text.

Description

bindgen version: 0.72.1

for the following struct

typedef struct
{
    NvU32 vic                     : 8;
    NvU32 pixelRepeat             : 5;
    NvU32 colorSpace              : 3;
    NvU32 colorimetry             : 3;
    NvU32 extendedColorimetry     : 4;
    NvU32 rgbQuantizationRange    : 3;
    NvU32 yccQuantizationRange    : 3;
    NvU32 itContent               : 2;
    NvU32 contentTypes            : 3;
    NvU32 scanInfo                : 3;
    NvU32 activeFormatInfoPresent : 2;
    NvU32 activeFormatAspectRatio : 5;
    NvU32 picAspectRatio          : 3;
    NvU32 nonuniformScaling       : 3;
    NvU32 barInfo                 : 3;
    NvU32 top_bar                 : 17;
    NvU32 bottom_bar              : 17;
    NvU32 left_bar                : 17;
    NvU32 right_bar               : 17;
    NvU32 Future17                : 2;
    NvU32 Future47                : 2;
} NV_INFOFRAME_VIDEO;

bindgen gives:

  • a 23 * 8 size struct (which doesn't pass assertions) normally
  • a 4 * 32 size struct (which is wrong) with --opaque-type

The right size would be probably [32; 6] because this is a struct built with 32 bit integers (so aligned on 4 bytes) as both latest clang and msvc report: godbolt.

Notably bindgen outputs the right alignment (#[repr(align(4))]) but then ignores it when computing what the actual size of the struct should be.

normal output

#[repr(C)]
pub struct NV_INFOFRAME_VIDEO {
    pub _bitfield_align_1: [u32; 0],
    pub _bitfield_1: __BindgenBitfieldUnit<[u8; 23usize]>,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of NV_INFOFRAME_VIDEO"][::core::mem::size_of::<NV_INFOFRAME_VIDEO>() - 16usize];
    ["Alignment of NV_INFOFRAME_VIDEO"][::core::mem::align_of::<NV_INFOFRAME_VIDEO>() - 4usize];
};

output with --opaque-type

#[repr(C)]
#[repr(align(4))]
pub struct NV_INFOFRAME_VIDEO {
    pub _bindgen_opaque_blob: [u32; 4usize],
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of NV_INFOFRAME_VIDEO"][::core::mem::size_of::<NV_INFOFRAME_VIDEO>() - 16usize];
    ["Alignment of NV_INFOFRAME_VIDEO"][::core::mem::align_of::<NV_INFOFRAME_VIDEO>() - 4usize];
};
Dominant language
Rust
Stars
5.3k
Forks
846
Avg merge
2d 6h
Merged PRs (30d)
11

Getting set up

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.

More from rust-lang/rust-bindgen

All issues in rust-lang/rust-bindgen

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.