Skip to content

Wrong layout for packed struct with bitfields #981

Open
@helloqirun

Description

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;

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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