Skip to content

Wrong layout for packed struct with bitfields #981

Open
@helloqirun

Description

@helloqirun

I am using this script https://gist.github.com/fitzgen/187381e358f60efa8194d0b276b4d11a.

The hashtag for my bindgen version is 4dd4ac7 .

$ ./b.sh bindgen abc.h

clang-4.0: warning: treating 'c-header' input as 'c++-header' when in C++ mode, this behavior is deprecated [-Wdeprecated]
ERROR:bindgen::codegen::struct_layout: Calculated wrong layout for _bindgen_ty_1, too more 3 bytes
error[E0530]: function parameters cannot shadow statics
 --> /tmp/bindings-Og3Z2F.rs:3:1686
  |
3 | # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct a { pub _bitfield_1 : u8 , pub __bindgen_padding_0 : [ u8 ; 3usize ] , pub __bindgen_align : [ u32 ; 0usize ] , } # [ test ] fn bindgen_test_layout_a ( ) { assert_eq ! ( :: std :: mem :: size_of :: < a > ( ) , 4usize , concat ! ( "Size of: " , stringify ! ( a ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < a > ( ) , 4usize , concat ! ( "Alignment of " , stringify ! ( a ) ) ) ; } impl Clone for a { fn clone ( & self ) -> Self { * self } } impl a { # [ inline ] pub fn b ( & self ) -> :: std :: os :: raw :: c_uint { let mut unit_field_val : u8 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u8 as * mut u8 , :: std :: mem :: size_of :: < u8 > ( ) , ) } ; let mask = 7u64 as u8 ; let val = ( unit_field_val & mask ) >> 0usize ; unsafe { :: std :: mem :: transmute ( val as u32 ) } } # [ inline ] pub fn set_b ( & mut self , val : :: std :: os :: raw :: c_uint ) { let mask = 7u64 as u8 ; let val = val as u32 as u8 ; let mut unit_field_val : u8 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u8 as * mut u8 , :: std :: mem :: size_of :: < u8 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 0usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u8 > ( ) , ) ; } } # [ inline ] pub fn new_bitfield_1 ( b : :: std :: os :: raw :: c_uint ) -> u8 { ( 0 | ( ( b as u32 as u8 ) << 0usize ) & ( 7u64 as u8 ) ) } } # [ repr ( C , packed ) ] # [ derive ( Debug , Copy ) ] pub struct _bindgen_ty_1 { pub _bitfield_1 : [ u32 ; 2usize ] , pub __bindgen_align : [ u8 ; 0usize ] , } # [ test ] fn bindgen_test_layout__bindgen_ty_1 ( ) { assert_eq ! ( :: std :: mem :: size_of :: < _bindgen_ty_1 > ( ) , 5usize , concat ! ( "Size of: " , stringify ! ( _bindgen_ty_1 ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < _bindgen_ty_1 > ( ) , 1usize , concat ! ( "Alignment of " , stringify ! ( _bindgen_ty_1 ) ) ) ; } impl Clone for _bindgen_ty_1 { fn clone ( & self ) -> Self { * self } } impl _bindgen_ty_1 { # [ inline ] pub fn new_bitfield_1 ( ) -> u64 { 0 } } extern "C" {
  |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      ^ cannot be named the same as a static
4 |  # [ link_name = "b" ]
5 |  pub static mut  b  :  _bindgen_ty_1 ;
  |  ------------------------------------- a static `b` is defined here

error: aborting due to previous error

Interesting: bindgen emitted Rust code that won't compile!

$ cat abc.h

struct a {
  unsigned b : 3;
};
struct __attribute__((packed)) {
  unsigned : 6;
  unsigned : 32;
} b;

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions