diff --git a/bindgen-tests/tests/expectations/tests/bitfield-linux-32.rs b/bindgen-tests/tests/expectations/tests/bitfield-linux-32.rs index 8b0b37b481..177a31805c 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield-linux-32.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield-linux-32.rs @@ -145,19 +145,13 @@ where } } } -#[repr(C, packed(4))] +#[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Test { pub foo: u64, - pub _bitfield_align_1: [u64; 0], + pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>, } -#[allow(clippy::unnecessary_operation, clippy::identity_op)] -const _: () = { - ["Size of Test"][::std::mem::size_of::() - 16usize]; - ["Alignment of Test"][::std::mem::align_of::() - 4usize]; - ["Offset of field: Test::foo"][::std::mem::offset_of!(Test, foo) - 0usize]; -}; impl Test { #[inline] pub fn x(&self) -> u64 { diff --git a/bindgen-tests/tests/expectations/tests/bitfield_align.rs b/bindgen-tests/tests/expectations/tests/bitfield_align.rs index 5f1321bbb1..d3404e9708 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield_align.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield_align.rs @@ -745,7 +745,7 @@ impl B { pub struct C { pub x: ::std::os::raw::c_uchar, pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>, pub baz: ::std::os::raw::c_uint, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -772,7 +772,7 @@ impl C { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 3usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u32, ) @@ -783,7 +783,7 @@ impl C { unsafe { let val: u32 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 3usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 0usize, @@ -808,7 +808,7 @@ impl C { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 3usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 1u8) as u32, ) @@ -819,7 +819,7 @@ impl C { unsafe { let val: u32 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 3usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 1usize, @@ -832,8 +832,8 @@ impl C { pub fn new_bitfield_1( b1: ::std::os::raw::c_uint, b2: ::std::os::raw::c_uint, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + ) -> __BindgenBitfieldUnit<[u8; 3usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, @@ -860,8 +860,7 @@ impl C { #[derive(Debug, Default, Copy, Clone)] pub struct Date1 { pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>, - pub __bindgen_padding_0: u8, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { @@ -885,7 +884,7 @@ impl Date1 { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 3usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 3u8) as u16, ) @@ -896,7 +895,7 @@ impl Date1 { unsafe { let val: u16 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 3usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 0usize, @@ -921,7 +920,7 @@ impl Date1 { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 3usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 3usize, 6u8) as u16, ) @@ -932,7 +931,7 @@ impl Date1 { unsafe { let val: u16 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 3usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 3usize, @@ -957,7 +956,7 @@ impl Date1 { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 3usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 9usize, 5u8) as u16, ) @@ -968,7 +967,7 @@ impl Date1 { unsafe { let val: u16 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 3usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 9usize, @@ -993,7 +992,7 @@ impl Date1 { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 3usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 16usize, 8u8) as u16, ) @@ -1004,7 +1003,7 @@ impl Date1 { unsafe { let val: u16 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 3usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 16usize, @@ -1019,8 +1018,8 @@ impl Date1 { nMonthDay: ::std::os::raw::c_ushort, nMonth: ::std::os::raw::c_ushort, nYear: ::std::os::raw::c_ushort, - ) -> __BindgenBitfieldUnit<[u8; 3usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = Default::default(); + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, diff --git a/bindgen-tests/tests/expectations/tests/bitfield_pack_offset.rs b/bindgen-tests/tests/expectations/tests/bitfield_pack_offset.rs new file mode 100644 index 0000000000..3719879333 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/bitfield_pack_offset.rs @@ -0,0 +1,509 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit { + storage: Storage, +} +impl __BindgenBitfieldUnit { + #[inline] + pub const fn new(storage: Storage) -> Self { + Self { storage } + } +} +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + fn extract_bit(byte: u8, index: usize) -> bool { + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + byte & mask == mask + } + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; + } + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self.set_bit(index + bit_offset, val_bit_is_set); + } + } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct A { + pub name: [::std::os::raw::c_uchar; 7usize], + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>, + pub maxYield: ::std::os::raw::c_uchar, + pub _bitfield_align_2: [u8; 0], + pub _bitfield_2: __BindgenBitfieldUnit<[u8; 5usize]>, + pub description1: *const ::std::os::raw::c_uchar, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of A"][::std::mem::size_of::() - 24usize]; + ["Alignment of A"][::std::mem::align_of::() - 8usize]; + ["Offset of field: A::name"][::std::mem::offset_of!(A, name) - 0usize]; + ["Offset of field: A::maxYield"][::std::mem::offset_of!(A, maxYield) - 10usize]; + [ + "Offset of field: A::description1", + ][::std::mem::offset_of!(A, description1) - 16usize]; +}; +impl Default for A { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl A { + #[inline] + pub fn firmness(&self) -> ::std::os::raw::c_uchar { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 4u8) as u8) } + } + #[inline] + pub fn set_firmness(&mut self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 4u8, val as u64) + } + } + #[inline] + pub unsafe fn firmness_raw(this: *const Self) -> ::std::os::raw::c_uchar { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 4u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_firmness_raw(this: *mut Self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 4u8, + val as u64, + ) + } + } + #[inline] + pub fn color(&self) -> ::std::os::raw::c_uchar { + unsafe { ::std::mem::transmute(self._bitfield_1.get(4usize, 4u8) as u8) } + } + #[inline] + pub fn set_color(&mut self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_1.set(4usize, 4u8, val as u64) + } + } + #[inline] + pub unsafe fn color_raw(this: *const Self) -> ::std::os::raw::c_uchar { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 4usize, 4u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_color_raw(this: *mut Self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 4usize, + 4u8, + val as u64, + ) + } + } + #[inline] + pub fn weedsBonus(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(8usize, 3u8) as u16) } + } + #[inline] + pub fn set_weedsBonus(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(8usize, 3u8, val as u64) + } + } + #[inline] + pub unsafe fn weedsBonus_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 8usize, 3u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_weedsBonus_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 8usize, + 3u8, + val as u64, + ) + } + } + #[inline] + pub fn pestsBonus(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(11usize, 3u8) as u16) } + } + #[inline] + pub fn set_pestsBonus(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(11usize, 3u8, val as u64) + } + } + #[inline] + pub unsafe fn pestsBonus_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 11usize, 3u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_pestsBonus_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 11usize, + 3u8, + val as u64, + ) + } + } + #[inline] + pub fn size(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(14usize, 10u8) as u16) } + } + #[inline] + pub fn set_size(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(14usize, 10u8, val as u64) + } + } + #[inline] + pub unsafe fn size_raw(this: *const Self) -> ::std::os::raw::c_ushort { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 14usize, 10u8) + as u16, + ) + } + } + #[inline] + pub unsafe fn set_size_raw(this: *mut Self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 3usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 14usize, + 10u8, + val as u64, + ) + } + } + #[inline] + pub fn new_bitfield_1( + firmness: ::std::os::raw::c_uchar, + color: ::std::os::raw::c_uchar, + weedsBonus: ::std::os::raw::c_ushort, + pestsBonus: ::std::os::raw::c_ushort, + size: ::std::os::raw::c_ushort, + ) -> __BindgenBitfieldUnit<[u8; 3usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 4u8, + { + let firmness: u8 = unsafe { ::std::mem::transmute(firmness) }; + firmness as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 4usize, + 4u8, + { + let color: u8 = unsafe { ::std::mem::transmute(color) }; + color as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 8usize, + 3u8, + { + let weedsBonus: u16 = unsafe { ::std::mem::transmute(weedsBonus) }; + weedsBonus as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 11usize, + 3u8, + { + let pestsBonus: u16 = unsafe { ::std::mem::transmute(pestsBonus) }; + pestsBonus as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 14usize, + 10u8, + { + let size: u16 = unsafe { ::std::mem::transmute(size) }; + size as u64 + }, + ); + __bindgen_bitfield_unit + } + #[inline] + pub fn minYield(&self) -> ::std::os::raw::c_uchar { + unsafe { ::std::mem::transmute(self._bitfield_2.get(0usize, 4u8) as u8) } + } + #[inline] + pub fn set_minYield(&mut self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_2.set(0usize, 4u8, val as u64) + } + } + #[inline] + pub unsafe fn minYield_raw(this: *const Self) -> ::std::os::raw::c_uchar { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 0usize, 4u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_minYield_raw(this: *mut Self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_2), + 0usize, + 4u8, + val as u64, + ) + } + } + #[inline] + pub fn waterBonus(&self) -> ::std::os::raw::c_uchar { + unsafe { ::std::mem::transmute(self._bitfield_2.get(4usize, 4u8) as u8) } + } + #[inline] + pub fn set_waterBonus(&mut self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + self._bitfield_2.set(4usize, 4u8, val as u64) + } + } + #[inline] + pub unsafe fn waterBonus_raw(this: *const Self) -> ::std::os::raw::c_uchar { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 4usize, 4u8) as u8, + ) + } + } + #[inline] + pub unsafe fn set_waterBonus_raw(this: *mut Self, val: ::std::os::raw::c_uchar) { + unsafe { + let val: u8 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 5usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_2), + 4usize, + 4u8, + val as u64, + ) + } + } + #[inline] + pub fn new_bitfield_2( + minYield: ::std::os::raw::c_uchar, + waterBonus: ::std::os::raw::c_uchar, + ) -> __BindgenBitfieldUnit<[u8; 5usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 5usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 4u8, + { + let minYield: u8 = unsafe { ::std::mem::transmute(minYield) }; + minYield as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 4usize, + 4u8, + { + let waterBonus: u8 = unsafe { ::std::mem::transmute(waterBonus) }; + waterBonus as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/blocklist_bitfield_unit.rs b/bindgen-tests/tests/expectations/tests/blocklist_bitfield_unit.rs index fc9f9a38c7..7eaf45cc99 100644 --- a/bindgen-tests/tests/expectations/tests/blocklist_bitfield_unit.rs +++ b/bindgen-tests/tests/expectations/tests/blocklist_bitfield_unit.rs @@ -7,7 +7,7 @@ use bitfields::*; pub struct C { pub x: ::std::os::raw::c_uchar, pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 3usize]>, pub baz: ::std::os::raw::c_uint, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -34,7 +34,7 @@ impl C { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 3usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u32, ) @@ -45,7 +45,7 @@ impl C { unsafe { let val: u32 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 3usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 0usize, @@ -70,7 +70,7 @@ impl C { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 3usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 1u8) as u32, ) @@ -81,7 +81,7 @@ impl C { unsafe { let val: u32 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 3usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 1usize, @@ -94,8 +94,8 @@ impl C { pub fn new_bitfield_1( b1: ::std::os::raw::c_uint, b2: ::std::os::raw::c_uint, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + ) -> __BindgenBitfieldUnit<[u8; 3usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 3usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, diff --git a/bindgen-tests/tests/expectations/tests/derive-bitfield-method-same-name.rs b/bindgen-tests/tests/expectations/tests/derive-bitfield-method-same-name.rs index 05e66a72bc..d6e832b0bf 100644 --- a/bindgen-tests/tests/expectations/tests/derive-bitfield-method-same-name.rs +++ b/bindgen-tests/tests/expectations/tests/derive-bitfield-method-same-name.rs @@ -95,8 +95,7 @@ where pub struct Foo { pub large: [::std::os::raw::c_int; 33usize], pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, - pub __bindgen_padding_0: u16, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, } #[test] fn bindgen_test_layout_Foo() { @@ -173,8 +172,8 @@ impl Foo { #[inline] pub fn new_bitfield_1( type__bindgen_bitfield: ::std::os::raw::c_char, - ) -> __BindgenBitfieldUnit<[u8; 2usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default(); + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, diff --git a/bindgen-tests/tests/expectations/tests/derive-debug-bitfield-1-51.rs b/bindgen-tests/tests/expectations/tests/derive-debug-bitfield-1-51.rs index 351d3b31e5..1971fb9c85 100644 --- a/bindgen-tests/tests/expectations/tests/derive-debug-bitfield-1-51.rs +++ b/bindgen-tests/tests/expectations/tests/derive-debug-bitfield-1-51.rs @@ -149,7 +149,7 @@ where #[derive(Debug, Copy, Clone)] pub struct C { pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, pub large_array: [::std::os::raw::c_int; 50usize], } #[test] @@ -190,7 +190,7 @@ impl C { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u8, ) } @@ -200,7 +200,7 @@ impl C { unsafe { let val: u8 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 0usize, @@ -225,7 +225,7 @@ impl C { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 7u8) as u8, ) } @@ -235,7 +235,7 @@ impl C { unsafe { let val: u8 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 1usize, @@ -245,8 +245,8 @@ impl C { } } #[inline] - pub fn new_bitfield_1(a: bool, b: bool) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + pub fn new_bitfield_1(a: bool, b: bool) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, diff --git a/bindgen-tests/tests/expectations/tests/derive-debug-bitfield-core.rs b/bindgen-tests/tests/expectations/tests/derive-debug-bitfield-core.rs index edcb4e2a02..3a8814818c 100644 --- a/bindgen-tests/tests/expectations/tests/derive-debug-bitfield-core.rs +++ b/bindgen-tests/tests/expectations/tests/derive-debug-bitfield-core.rs @@ -92,7 +92,7 @@ where #[derive(Copy, Clone)] pub struct C { pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, pub large_array: [::std::os::raw::c_int; 50usize], } #[test] @@ -145,8 +145,8 @@ impl C { } } #[inline] - pub fn new_bitfield_1(a: bool, b: bool) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + pub fn new_bitfield_1(a: bool, b: bool) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, diff --git a/bindgen-tests/tests/expectations/tests/derive-debug-bitfield.rs b/bindgen-tests/tests/expectations/tests/derive-debug-bitfield.rs index e266880509..ba56442f2c 100644 --- a/bindgen-tests/tests/expectations/tests/derive-debug-bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/derive-debug-bitfield.rs @@ -91,7 +91,7 @@ where #[derive(Copy, Clone)] pub struct C { pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, pub large_array: [::std::os::raw::c_int; 50usize], } #[test] @@ -161,8 +161,8 @@ impl C { } } #[inline] - pub fn new_bitfield_1(a: bool, b: bool) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + pub fn new_bitfield_1(a: bool, b: bool) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, diff --git a/bindgen-tests/tests/expectations/tests/derive-partialeq-bitfield.rs b/bindgen-tests/tests/expectations/tests/derive-partialeq-bitfield.rs index eaf3f45e5f..c5549c3bb0 100644 --- a/bindgen-tests/tests/expectations/tests/derive-partialeq-bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/derive-partialeq-bitfield.rs @@ -91,7 +91,7 @@ where #[derive(Copy, Clone)] pub struct C { pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, pub large_array: [::std::os::raw::c_int; 50usize], } #[test] @@ -145,8 +145,8 @@ impl C { } } #[inline] - pub fn new_bitfield_1(a: bool, b: bool) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + pub fn new_bitfield_1(a: bool, b: bool) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, diff --git a/bindgen-tests/tests/expectations/tests/divide-by-zero-in-struct-layout.rs b/bindgen-tests/tests/expectations/tests/divide-by-zero-in-struct-layout.rs index e01a9b3c72..f7569d9fa3 100644 --- a/bindgen-tests/tests/expectations/tests/divide-by-zero-in-struct-layout.rs +++ b/bindgen-tests/tests/expectations/tests/divide-by-zero-in-struct-layout.rs @@ -149,13 +149,13 @@ where #[derive(Debug, Default, Copy, Clone)] pub struct WithBitfield { pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, pub a: ::std::os::raw::c_uint, } impl WithBitfield { #[inline] - pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + pub fn new_bitfield_1() -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); __bindgen_bitfield_unit } } diff --git a/bindgen-tests/tests/expectations/tests/field-visibility-callback.rs b/bindgen-tests/tests/expectations/tests/field-visibility-callback.rs index aebc04f03b..ca810928e7 100644 --- a/bindgen-tests/tests/expectations/tests/field-visibility-callback.rs +++ b/bindgen-tests/tests/expectations/tests/field-visibility-callback.rs @@ -151,8 +151,7 @@ pub struct my_struct { pub a: ::std::os::raw::c_int, private_b: ::std::os::raw::c_int, _bitfield_align_1: [u8; 0], - _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, - __bindgen_padding_0: [u8; 3usize], + _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { @@ -180,7 +179,7 @@ impl my_struct { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u32, ) @@ -191,7 +190,7 @@ impl my_struct { unsafe { let val: u32 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 0usize, @@ -216,7 +215,7 @@ impl my_struct { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 1u8) as u32, ) @@ -227,7 +226,7 @@ impl my_struct { unsafe { let val: u32 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 1usize, @@ -240,8 +239,8 @@ impl my_struct { fn new_bitfield_1( c: ::std::os::raw::c_int, private_d: ::std::os::raw::c_int, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, diff --git a/bindgen-tests/tests/expectations/tests/field-visibility.rs b/bindgen-tests/tests/expectations/tests/field-visibility.rs index 3e43755a57..1d9feed731 100644 --- a/bindgen-tests/tests/expectations/tests/field-visibility.rs +++ b/bindgen-tests/tests/expectations/tests/field-visibility.rs @@ -150,8 +150,7 @@ where #[derive(Debug, Default, Copy, Clone)] pub struct my_struct1 { _bitfield_align_1: [u8; 0], - _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, - __bindgen_padding_0: [u8; 3usize], + _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { @@ -175,7 +174,7 @@ impl my_struct1 { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u32, ) @@ -186,7 +185,7 @@ impl my_struct1 { unsafe { let val: u32 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 0usize, @@ -196,8 +195,8 @@ impl my_struct1 { } } #[inline] - fn new_bitfield_1(a: ::std::os::raw::c_int) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + fn new_bitfield_1(a: ::std::os::raw::c_int) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, @@ -215,8 +214,7 @@ impl my_struct1 { #[derive(Debug, Default, Copy, Clone)] pub struct my_struct2 { pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, - pub __bindgen_padding_0: [u8; 3usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { @@ -240,7 +238,7 @@ impl my_struct2 { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u32, ) @@ -251,7 +249,7 @@ impl my_struct2 { unsafe { let val: u32 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 0usize, @@ -263,8 +261,8 @@ impl my_struct2 { #[inline] pub fn new_bitfield_1( a: ::std::os::raw::c_int, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, diff --git a/bindgen-tests/tests/expectations/tests/incomplete-array-padding.rs b/bindgen-tests/tests/expectations/tests/incomplete-array-padding.rs index 6e9f6e7753..56c17a692b 100644 --- a/bindgen-tests/tests/expectations/tests/incomplete-array-padding.rs +++ b/bindgen-tests/tests/expectations/tests/incomplete-array-padding.rs @@ -179,7 +179,7 @@ impl ::std::fmt::Debug for __IncompleteArrayField { #[derive(Debug)] pub struct foo { pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>, pub b: __IncompleteArrayField<*mut ::std::os::raw::c_void>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -214,7 +214,7 @@ impl foo { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 8usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u8, ) } @@ -224,7 +224,7 @@ impl foo { unsafe { let val: u8 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 8usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 0usize, @@ -236,8 +236,8 @@ impl foo { #[inline] pub fn new_bitfield_1( a: ::std::os::raw::c_char, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + ) -> __BindgenBitfieldUnit<[u8; 8usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, diff --git a/bindgen-tests/tests/expectations/tests/issue-1947.rs b/bindgen-tests/tests/expectations/tests/issue-1947.rs index cceb42d8c5..f6d4e1080b 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1947.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1947.rs @@ -154,7 +154,7 @@ pub struct V56AMDY { pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, pub MADK: U8, pub MABR: U8, - pub _bitfield_align_2: [u16; 0], + pub _bitfield_align_2: [u8; 0], pub _bitfield_2: __BindgenBitfieldUnit<[u8; 3usize]>, pub _rB_: U8, } diff --git a/bindgen-tests/tests/expectations/tests/issue-743.rs b/bindgen-tests/tests/expectations/tests/issue-743.rs new file mode 100644 index 0000000000..228105d1a5 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-743.rs @@ -0,0 +1,225 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct __BindgenBitfieldUnit { + storage: Storage, +} +impl __BindgenBitfieldUnit { + #[inline] + pub const fn new(storage: Storage) -> Self { + Self { storage } + } +} +impl __BindgenBitfieldUnit +where + Storage: AsRef<[u8]> + AsMut<[u8]>, +{ + #[inline] + fn extract_bit(byte: u8, index: usize) -> bool { + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + byte & mask == mask + } + #[inline] + pub fn get_bit(&self, index: usize) -> bool { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = self.storage.as_ref()[byte_index]; + Self::extract_bit(byte, index) + } + #[inline] + pub unsafe fn raw_get_bit(this: *const Self, index: usize) -> bool { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + *(core::ptr::addr_of!((*this).storage) as *const u8) + .offset(byte_index as isize) + }; + Self::extract_bit(byte, index) + } + #[inline] + fn change_bit(byte: u8, index: usize, val: bool) -> u8 { + let bit_index = if cfg!(target_endian = "big") { + 7 - (index % 8) + } else { + index % 8 + }; + let mask = 1 << bit_index; + if val { byte | mask } else { byte & !mask } + } + #[inline] + pub fn set_bit(&mut self, index: usize, val: bool) { + debug_assert!(index / 8 < self.storage.as_ref().len()); + let byte_index = index / 8; + let byte = &mut self.storage.as_mut()[byte_index]; + *byte = Self::change_bit(*byte, index, val); + } + #[inline] + pub unsafe fn raw_set_bit(this: *mut Self, index: usize, val: bool) { + debug_assert!(index / 8 < core::mem::size_of::()); + let byte_index = index / 8; + let byte = unsafe { + (core::ptr::addr_of_mut!((*this).storage) as *mut u8) + .offset(byte_index as isize) + }; + unsafe { *byte = Self::change_bit(*byte, index, val) }; + } + #[inline] + pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if self.get_bit(i + bit_offset) { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] + pub unsafe fn raw_get(this: *const Self, bit_offset: usize, bit_width: u8) -> u64 { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + let mut val = 0; + for i in 0..(bit_width as usize) { + if unsafe { Self::raw_get_bit(this, i + bit_offset) } { + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + val |= 1 << index; + } + } + val + } + #[inline] + pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < self.storage.as_ref().len()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + self.set_bit(index + bit_offset, val_bit_is_set); + } + } + #[inline] + pub unsafe fn raw_set(this: *mut Self, bit_offset: usize, bit_width: u8, val: u64) { + debug_assert!(bit_width <= 64); + debug_assert!(bit_offset / 8 < core::mem::size_of::()); + debug_assert!( + (bit_offset + (bit_width as usize)) / 8 <= core::mem::size_of::(), + ); + for i in 0..(bit_width as usize) { + let mask = 1 << i; + let val_bit_is_set = val & mask == mask; + let index = if cfg!(target_endian = "big") { + bit_width as usize - 1 - i + } else { + i + }; + unsafe { Self::raw_set_bit(this, index + bit_offset, val_bit_is_set) }; + } + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct S { + pub p: *mut ::std::os::raw::c_void, + pub b: bool, + pub _bitfield_align_1: [u8; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 7usize]>, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of S"][::std::mem::size_of::() - 16usize]; + ["Alignment of S"][::std::mem::align_of::() - 8usize]; + ["Offset of field: S::p"][::std::mem::offset_of!(S, p) - 0usize]; + ["Offset of field: S::b"][::std::mem::offset_of!(S, b) - 8usize]; +}; +impl Default for S { + fn default() -> Self { + let mut s = ::std::mem::MaybeUninit::::uninit(); + unsafe { + ::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +impl S { + #[inline] + pub fn u(&self) -> ::std::os::raw::c_uint { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 16u8) as u32) } + } + #[inline] + pub fn set_u(&mut self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 16u8, val as u64) + } + } + #[inline] + pub unsafe fn u_raw(this: *const Self) -> ::std::os::raw::c_uint { + unsafe { + ::std::mem::transmute( + <__BindgenBitfieldUnit< + [u8; 7usize], + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 16u8) + as u32, + ) + } + } + #[inline] + pub unsafe fn set_u_raw(this: *mut Self, val: ::std::os::raw::c_uint) { + unsafe { + let val: u32 = ::std::mem::transmute(val); + <__BindgenBitfieldUnit< + [u8; 7usize], + >>::raw_set( + ::std::ptr::addr_of_mut!((*this)._bitfield_1), + 0usize, + 16u8, + val as u64, + ) + } + } + #[inline] + pub fn new_bitfield_1( + u: ::std::os::raw::c_uint, + ) -> __BindgenBitfieldUnit<[u8; 7usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 7usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 16u8, + { + let u: u32 = unsafe { ::std::mem::transmute(u) }; + u as u64 + }, + ); + __bindgen_bitfield_unit + } +} diff --git a/bindgen-tests/tests/expectations/tests/layout_align.rs b/bindgen-tests/tests/expectations/tests/layout_align.rs index 18662d4c83..3dda9760d2 100644 --- a/bindgen-tests/tests/expectations/tests/layout_align.rs +++ b/bindgen-tests/tests/expectations/tests/layout_align.rs @@ -225,8 +225,7 @@ pub struct rte_eth_link { ///< ETH_SPEED_NUM_ pub link_speed: u32, pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, - pub __bindgen_padding_0: [u8; 3usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { @@ -253,7 +252,7 @@ impl rte_eth_link { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u16, ) @@ -264,7 +263,7 @@ impl rte_eth_link { unsafe { let val: u16 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 0usize, @@ -289,7 +288,7 @@ impl rte_eth_link { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 1u8) as u16, ) @@ -300,7 +299,7 @@ impl rte_eth_link { unsafe { let val: u16 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 1usize, @@ -325,7 +324,7 @@ impl rte_eth_link { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 2usize, 1u8) as u16, ) @@ -336,7 +335,7 @@ impl rte_eth_link { unsafe { let val: u16 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 2usize, @@ -350,8 +349,8 @@ impl rte_eth_link { link_duplex: u16, link_autoneg: u16, link_status: u16, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, diff --git a/bindgen-tests/tests/expectations/tests/layout_eth_conf.rs b/bindgen-tests/tests/expectations/tests/layout_eth_conf.rs index 4a62ddbea3..0b54689f72 100644 --- a/bindgen-tests/tests/expectations/tests/layout_eth_conf.rs +++ b/bindgen-tests/tests/expectations/tests/layout_eth_conf.rs @@ -426,8 +426,7 @@ pub struct rte_eth_txmode { pub mq_mode: rte_eth_tx_mq_mode, pub pvid: u16, pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, - pub __bindgen_padding_0: u8, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, } #[test] fn bindgen_test_layout_rte_eth_txmode() { @@ -502,8 +501,8 @@ impl rte_eth_txmode { hw_vlan_reject_tagged: u8, hw_vlan_reject_untagged: u8, hw_vlan_insert_pvid: u8, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + ) -> __BindgenBitfieldUnit<[u8; 2usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, diff --git a/bindgen-tests/tests/expectations/tests/layout_mbuf.rs b/bindgen-tests/tests/expectations/tests/layout_mbuf.rs index cb3698812b..091f510823 100644 --- a/bindgen-tests/tests/expectations/tests/layout_mbuf.rs +++ b/bindgen-tests/tests/expectations/tests/layout_mbuf.rs @@ -824,7 +824,7 @@ pub union rte_mbuf__bindgen_ty_5 { #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] pub struct rte_mbuf__bindgen_ty_5__bindgen_ty_1 { pub _bitfield_align_1: [u16; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 7usize]>, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { @@ -852,7 +852,7 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 7usize], + [u8; 8usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 7u8) as u64, ) @@ -863,7 +863,7 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { unsafe { let val: u64 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 7usize], + [u8; 8usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 0usize, @@ -888,7 +888,7 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 7usize], + [u8; 8usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 7usize, 9u8) as u64, ) @@ -899,7 +899,7 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { unsafe { let val: u64 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 7usize], + [u8; 8usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 7usize, @@ -924,7 +924,7 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 7usize], + [u8; 8usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 16usize, 8u8) as u64, ) @@ -935,7 +935,7 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { unsafe { let val: u64 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 7usize], + [u8; 8usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 16usize, @@ -960,7 +960,7 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 7usize], + [u8; 8usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 24usize, 16u8) as u64, ) @@ -971,7 +971,7 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { unsafe { let val: u64 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 7usize], + [u8; 8usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 24usize, @@ -996,7 +996,7 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 7usize], + [u8; 8usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 40usize, 9u8) as u64, ) @@ -1007,7 +1007,7 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { unsafe { let val: u64 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 7usize], + [u8; 8usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 40usize, @@ -1032,7 +1032,7 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 7usize], + [u8; 8usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 49usize, 7u8) as u64, ) @@ -1043,7 +1043,7 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { unsafe { let val: u64 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 7usize], + [u8; 8usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 49usize, @@ -1060,8 +1060,8 @@ impl rte_mbuf__bindgen_ty_5__bindgen_ty_1 { tso_segsz: u64, outer_l3_len: u64, outer_l2_len: u64, - ) -> __BindgenBitfieldUnit<[u8; 7usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 7usize]> = Default::default(); + ) -> __BindgenBitfieldUnit<[u8; 8usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 8usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, diff --git a/bindgen-tests/tests/expectations/tests/private_fields.rs b/bindgen-tests/tests/expectations/tests/private_fields.rs index a5d9e84499..903e42f865 100644 --- a/bindgen-tests/tests/expectations/tests/private_fields.rs +++ b/bindgen-tests/tests/expectations/tests/private_fields.rs @@ -163,8 +163,7 @@ const _: () = { #[derive(Debug, Default, Copy, Clone)] pub struct PrivateBitFields { pub _bitfield_align_1: [u8; 0], - _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, - pub __bindgen_padding_0: [u8; 3usize], + _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { @@ -190,7 +189,7 @@ impl PrivateBitFields { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 4u8) as u32, ) @@ -201,7 +200,7 @@ impl PrivateBitFields { unsafe { let val: u32 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 0usize, @@ -226,7 +225,7 @@ impl PrivateBitFields { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 4usize, 4u8) as u32, ) @@ -237,7 +236,7 @@ impl PrivateBitFields { unsafe { let val: u32 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 4usize, @@ -250,8 +249,8 @@ impl PrivateBitFields { fn new_bitfield_1( a: ::std::os::raw::c_uint, b: ::std::os::raw::c_uint, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, @@ -278,8 +277,7 @@ impl PrivateBitFields { #[derive(Debug, Default, Copy, Clone)] pub struct PublicBitFields { pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, - pub __bindgen_padding_0: [u8; 3usize], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { @@ -303,7 +301,7 @@ impl PublicBitFields { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 4u8) as u32, ) @@ -314,7 +312,7 @@ impl PublicBitFields { unsafe { let val: u32 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 0usize, @@ -339,7 +337,7 @@ impl PublicBitFields { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 4usize, 4u8) as u32, ) @@ -350,7 +348,7 @@ impl PublicBitFields { unsafe { let val: u32 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 4usize, @@ -363,8 +361,8 @@ impl PublicBitFields { pub fn new_bitfield_1( a: ::std::os::raw::c_uint, b: ::std::os::raw::c_uint, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, @@ -391,8 +389,7 @@ impl PublicBitFields { #[derive(Debug, Default, Copy, Clone)] pub struct MixedBitFields { pub _bitfield_align_1: [u8; 0], - _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, - pub __bindgen_padding_0: [u8; 3usize], + _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { @@ -416,7 +413,7 @@ impl MixedBitFields { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 4u8) as u32, ) @@ -427,7 +424,7 @@ impl MixedBitFields { unsafe { let val: u32 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 0usize, @@ -452,7 +449,7 @@ impl MixedBitFields { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 4usize, 4u8) as u32, ) @@ -463,7 +460,7 @@ impl MixedBitFields { unsafe { let val: u32 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 4usize, @@ -476,8 +473,8 @@ impl MixedBitFields { fn new_bitfield_1( a: ::std::os::raw::c_uint, d: ::std::os::raw::c_uint, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, @@ -629,8 +626,7 @@ pub struct Override { b: ::std::os::raw::c_uint, private_c: ::std::os::raw::c_uint, pub _bitfield_align_1: [u8; 0], - _bitfield_1: __BindgenBitfieldUnit<[u8; 2usize]>, - pub __bindgen_padding_0: u16, + _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { @@ -659,7 +655,7 @@ impl Override { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 2usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 4u8) as u32, ) @@ -670,7 +666,7 @@ impl Override { unsafe { let val: u32 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 2usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 0usize, @@ -695,7 +691,7 @@ impl Override { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 2usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 4usize, 4u8) as u32, ) @@ -706,7 +702,7 @@ impl Override { unsafe { let val: u32 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 2usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 4usize, @@ -731,7 +727,7 @@ impl Override { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 2usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 8usize, 4u8) as u32, ) @@ -742,7 +738,7 @@ impl Override { unsafe { let val: u32 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 2usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 8usize, @@ -756,8 +752,8 @@ impl Override { bf_a: ::std::os::raw::c_uint, bf_b: ::std::os::raw::c_uint, private_bf_c: ::std::os::raw::c_uint, - ) -> __BindgenBitfieldUnit<[u8; 2usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default(); + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, diff --git a/bindgen-tests/tests/expectations/tests/struct_with_bitfields.rs b/bindgen-tests/tests/expectations/tests/struct_with_bitfields.rs index 23588ee7da..80e16f2d79 100644 --- a/bindgen-tests/tests/expectations/tests/struct_with_bitfields.rs +++ b/bindgen-tests/tests/expectations/tests/struct_with_bitfields.rs @@ -149,9 +149,9 @@ where #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] pub struct bitfield { pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, pub e: ::std::os::raw::c_int, - pub _bitfield_align_2: [u32; 0], + pub _bitfield_align_2: [u8; 0], pub _bitfield_2: __BindgenBitfieldUnit<[u8; 8usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] @@ -177,7 +177,7 @@ impl bitfield { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u16, ) @@ -188,7 +188,7 @@ impl bitfield { unsafe { let val: u16 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 0usize, @@ -213,7 +213,7 @@ impl bitfield { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 1usize, 1u8) as u16, ) @@ -224,7 +224,7 @@ impl bitfield { unsafe { let val: u16 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 1usize, @@ -249,7 +249,7 @@ impl bitfield { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 2usize, 1u8) as u16, ) @@ -260,7 +260,7 @@ impl bitfield { unsafe { let val: u16 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 2usize, @@ -285,7 +285,7 @@ impl bitfield { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 6usize, 2u8) as u16, ) @@ -296,7 +296,7 @@ impl bitfield { unsafe { let val: u16 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 6usize, @@ -311,8 +311,8 @@ impl bitfield { b: ::std::os::raw::c_ushort, c: ::std::os::raw::c_ushort, d: ::std::os::raw::c_ushort, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, diff --git a/bindgen-tests/tests/expectations/tests/timex.rs b/bindgen-tests/tests/expectations/tests/timex.rs index 3d25971315..04bdf44281 100644 --- a/bindgen-tests/tests/expectations/tests/timex.rs +++ b/bindgen-tests/tests/expectations/tests/timex.rs @@ -171,7 +171,7 @@ impl Default for timex { #[derive(Debug, Copy, Clone)] pub struct timex_named { pub tai: ::std::os::raw::c_int, - pub _bitfield_align_1: [u32; 0], + pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 44usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] diff --git a/bindgen-tests/tests/expectations/tests/union_bitfield.rs b/bindgen-tests/tests/expectations/tests/union_bitfield.rs index 70da5c3b02..6927922be9 100644 --- a/bindgen-tests/tests/expectations/tests/union_bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/union_bitfield.rs @@ -150,7 +150,7 @@ where #[derive(Copy, Clone)] pub union U4 { pub _bitfield_align_1: [u8; 0], - pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { @@ -183,7 +183,7 @@ impl U4 { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u32, ) @@ -194,7 +194,7 @@ impl U4 { unsafe { let val: u32 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 1usize], + [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), 0usize, @@ -206,8 +206,8 @@ impl U4 { #[inline] pub fn new_bitfield_1( derp: ::std::os::raw::c_uint, - ) -> __BindgenBitfieldUnit<[u8; 1usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 1usize]> = Default::default(); + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, @@ -279,13 +279,13 @@ impl B { } #[inline] pub fn bar(&self) -> ::std::os::raw::c_uchar { - unsafe { ::std::mem::transmute(self._bitfield_1.get(31usize, 1u8) as u8) } + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 1u8) as u8) } } #[inline] pub fn set_bar(&mut self, val: ::std::os::raw::c_uchar) { unsafe { let val: u8 = ::std::mem::transmute(val); - self._bitfield_1.set(31usize, 1u8, val as u64) + self._bitfield_1.set(0usize, 1u8, val as u64) } } #[inline] @@ -294,8 +294,7 @@ impl B { ::std::mem::transmute( <__BindgenBitfieldUnit< [u8; 4usize], - >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 31usize, 1u8) - as u8, + >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_1), 0usize, 1u8) as u8, ) } } @@ -307,7 +306,7 @@ impl B { [u8; 4usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_1), - 31usize, + 0usize, 1u8, val as u64, ) @@ -330,7 +329,7 @@ impl B { ); __bindgen_bitfield_unit .set( - 31usize, + 0usize, 1u8, { let bar: u8 = unsafe { ::std::mem::transmute(bar) }; diff --git a/bindgen-tests/tests/expectations/tests/weird_bitfields.rs b/bindgen-tests/tests/expectations/tests/weird_bitfields.rs index 17accb01d9..aaba9b120f 100644 --- a/bindgen-tests/tests/expectations/tests/weird_bitfields.rs +++ b/bindgen-tests/tests/expectations/tests/weird_bitfields.rs @@ -156,7 +156,7 @@ pub enum nsStyleSVGOpacitySource { #[derive(Debug, Copy, Clone)] pub struct Weird { pub mStrokeDasharrayLength: ::std::os::raw::c_uint, - pub _bitfield_align_1: [u16; 0], + pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, pub mClipRule: ::std::os::raw::c_uchar, pub mColorInterpolation: ::std::os::raw::c_uchar, @@ -170,8 +170,7 @@ pub struct Weird { pub mTextAnchor: ::std::os::raw::c_uchar, pub mTextRendering: ::std::os::raw::c_uchar, pub _bitfield_align_2: [u8; 0], - pub _bitfield_2: __BindgenBitfieldUnit<[u8; 2usize]>, - pub __bindgen_padding_0: [u8; 3usize], + pub _bitfield_2: __BindgenBitfieldUnit<[u8; 5usize]>, } #[allow(clippy::unnecessary_operation, clippy::identity_op)] const _: () = { @@ -338,7 +337,7 @@ impl Weird { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 2usize], + [u8; 5usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 0usize, 3u8) as u32, ) @@ -352,7 +351,7 @@ impl Weird { unsafe { let val: u32 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 2usize], + [u8; 5usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_2), 0usize, @@ -379,7 +378,7 @@ impl Weird { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 2usize], + [u8; 5usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 3usize, 3u8) as u32, ) @@ -393,7 +392,7 @@ impl Weird { unsafe { let val: u32 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 2usize], + [u8; 5usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_2), 3usize, @@ -418,7 +417,7 @@ impl Weird { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 2usize], + [u8; 5usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 6usize, 1u8) as u8, ) } @@ -428,7 +427,7 @@ impl Weird { unsafe { let val: u8 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 2usize], + [u8; 5usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_2), 6usize, @@ -453,7 +452,7 @@ impl Weird { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 2usize], + [u8; 5usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 7usize, 1u8) as u8, ) } @@ -463,7 +462,7 @@ impl Weird { unsafe { let val: u8 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 2usize], + [u8; 5usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_2), 7usize, @@ -488,7 +487,7 @@ impl Weird { unsafe { ::std::mem::transmute( <__BindgenBitfieldUnit< - [u8; 2usize], + [u8; 5usize], >>::raw_get(::std::ptr::addr_of!((*this)._bitfield_2), 8usize, 1u8) as u8, ) } @@ -498,7 +497,7 @@ impl Weird { unsafe { let val: u8 = ::std::mem::transmute(val); <__BindgenBitfieldUnit< - [u8; 2usize], + [u8; 5usize], >>::raw_set( ::std::ptr::addr_of_mut!((*this)._bitfield_2), 8usize, @@ -514,8 +513,8 @@ impl Weird { mStrokeDasharrayFromObject: bool, mStrokeDashoffsetFromObject: bool, mStrokeWidthFromObject: bool, - ) -> __BindgenBitfieldUnit<[u8; 2usize]> { - let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default(); + ) -> __BindgenBitfieldUnit<[u8; 5usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 5usize]> = Default::default(); __bindgen_bitfield_unit .set( 0usize, diff --git a/bindgen-tests/tests/headers/bitfield-linux-32.hpp b/bindgen-tests/tests/headers/bitfield-linux-32.hpp index b9a480df15..71ee6a7e1d 100644 --- a/bindgen-tests/tests/headers/bitfield-linux-32.hpp +++ b/bindgen-tests/tests/headers/bitfield-linux-32.hpp @@ -1,4 +1,4 @@ -// bindgen-flags: -- --target=i586-unknown-linux +// bindgen-flags: --no-layout-tests -- --target=i586-unknown-linux typedef unsigned long long uint64_t; diff --git a/bindgen-tests/tests/headers/bitfield_pack_offset.h b/bindgen-tests/tests/headers/bitfield_pack_offset.h new file mode 100644 index 0000000000..5118a64642 --- /dev/null +++ b/bindgen-tests/tests/headers/bitfield_pack_offset.h @@ -0,0 +1,21 @@ +struct A { + const unsigned char name[7]; /* 0 7 */ + unsigned char firmness:4; /* 7: 0 1 */ + unsigned char color:4; /* 7: 4 1 */ + unsigned short weedsBonus:3; /* 8: 0 2 */ + unsigned short pestsBonus:3; /* 8: 3 2 */ + unsigned short size:10; /* 8: 6 2 */ + unsigned char maxYield; /* 10 1 */ + unsigned char minYield:4; /* 11: 0 1 */ + unsigned char waterBonus:4; /* 11: 4 1 */ + + /* XXX 4 bytes hole, try to pack */ + + const unsigned char * description1; /* 16 8 */ + + /* size: 24, cachelines: 1, members: 10 */ + /* sum members: 16, holes: 1, sum holes: 4 */ + /* sum bitfield members: 32 bits (4 bytes) */ + /* last cacheline: 24 bytes */ +}; + diff --git a/bindgen-tests/tests/headers/issue-743.h b/bindgen-tests/tests/headers/issue-743.h new file mode 100644 index 0000000000..1f8e0ccd78 --- /dev/null +++ b/bindgen-tests/tests/headers/issue-743.h @@ -0,0 +1,6 @@ + +struct S { + void *p; + _Bool b; + unsigned u : 16; +}; \ No newline at end of file diff --git a/bindgen-tests/tests/headers/union_bitfield.h b/bindgen-tests/tests/headers/union_bitfield.h index 990729574a..4592a8973a 100644 --- a/bindgen-tests/tests/headers/union_bitfield.h +++ b/bindgen-tests/tests/headers/union_bitfield.h @@ -1,10 +1,10 @@ // bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --impl-partialeq union U4 { - unsigned derp : 1; + unsigned int derp:1; /* 0: 0 4 */ }; union B { - unsigned foo : 31; - unsigned char bar : 1; + unsigned int foo:31; /* 0: 0 4 */ + unsigned char bar:1; /* 0: 0 1 */ }; diff --git a/bindgen/ir/comp.rs b/bindgen/ir/comp.rs index 655e0f1fa5..af8c816410 100644 --- a/bindgen/ir/comp.rs +++ b/bindgen/ir/comp.rs @@ -481,6 +481,7 @@ fn raw_fields_to_fields_and_bitfield_units( ctx: &BindgenContext, raw_fields: I, packed: bool, + parent_layout: Option<&Layout>, ) -> Result<(Vec, bool), ()> where I: IntoIterator, @@ -504,20 +505,26 @@ where // Now gather all the consecutive bitfields. Only consecutive bitfields // may potentially share a bitfield allocation unit with each other in // the Itanium C++ ABI. - let mut bitfields = raw_fields - .by_ref() - .peeking_take_while(|f| f.bitfield_width().is_some()) - .peekable(); - - if bitfields.peek().is_none() { + if raw_fields.peek().is_none() { break; } + let mut bitfields = Vec::new(); + while let Some(field) = raw_fields.peek() { + if field.bitfield_width().is_some() { + bitfields.push(raw_fields.next().unwrap()); + } else { + break; + } + } + let next_non_bitfield = raw_fields.peek(); bitfields_to_allocation_units( ctx, &mut bitfield_unit_count, &mut fields, bitfields, + next_non_bitfield, + parent_layout, packed, )?; } @@ -537,6 +544,8 @@ fn bitfields_to_allocation_units( bitfield_unit_count: &mut usize, fields: &mut E, raw_bitfields: I, + next_non_bitfield: Option<&RawField>, + parent_layout: Option<&Layout>, packed: bool, ) -> Result<(), ()> where @@ -586,6 +595,8 @@ where let mut unit_size_in_bits = 0; let mut unit_align = 0; let mut bitfields_in_unit = vec![]; + // Offset into the previous member, where the bitfields begin at + let mut bitfields_bit_begin_off = 0; // TODO(emilio): Determine this from attributes or pragma ms_struct // directives. Also, perhaps we should check if the target is MSVC? @@ -595,42 +606,41 @@ where let bitfield_width = bitfield.bitfield_width().unwrap() as usize; let bitfield_layout = ctx.resolve_type(bitfield.ty()).layout(ctx).ok_or(())?; - let bitfield_size = bitfield_layout.size; let bitfield_align = bitfield_layout.align; + // bitfield offset of struct/union + let bitfield_offset = bitfield.offset().unwrap(); - let mut offset = unit_size_in_bits; - if !packed { - if is_ms_struct { - if unit_size_in_bits != 0 && - (bitfield_width == 0 || - bitfield_width > unfilled_bits_in_unit) - { - // We've reached the end of this allocation unit, so flush it - // and its bitfields. - unit_size_in_bits = - align_to(unit_size_in_bits, unit_align * 8); - flush_allocation_unit( - fields, - bitfield_unit_count, - unit_size_in_bits, - unit_align, - mem::take(&mut bitfields_in_unit), - packed, - ); + if unit_size_in_bits == 0 { + bitfields_bit_begin_off = bitfield_offset; + } - // Now we're working on a fresh bitfield allocation unit, so reset - // the current unit size and alignment. - offset = 0; - unit_align = 0; - } - } else if offset != 0 && - (bitfield_width == 0 || - (offset & (bitfield_align * 8 - 1)) + bitfield_width > - bitfield_size * 8) - { - offset = align_to(offset, bitfield_align * 8); - } + if !packed + && is_ms_struct + && (unit_size_in_bits != 0 + && (bitfield_width == 0 + || bitfield_width > unfilled_bits_in_unit)) + { + // We've reached the end of this allocation unit, so flush it + // and its bitfields. + unit_size_in_bits = align_to(unit_size_in_bits, unit_align * 8); + flush_allocation_unit( + fields, + bitfield_unit_count, + unit_size_in_bits, + unit_align, + mem::take(&mut bitfields_in_unit), + packed, + ); + + // Now we're working on a fresh bitfield allocation unit, so reset + // the current unit size and alignment. + unit_align = 0; + bitfields_bit_begin_off = bitfield_offset; + // uncomment when support msvc + // unit_size_in_bits = 0; } + // depended clang report field offset, manual calculates sometime not true + let offset = bitfield_offset - bitfields_bit_begin_off; // According to the x86[-64] ABI spec: "Unnamed bit-fields’ types do not // affect the alignment of a structure or union". This makes sense: such @@ -643,8 +653,15 @@ where // NB: The `bitfield_width` here is completely, absolutely // intentional. Alignment of the allocation unit is based on the // maximum bitfield width, not (directly) on the bitfields' types' - // alignment. - unit_align = cmp::max(unit_align, bitfield_width); + // alignment. this is only available in bitfields start of structure + if bitfields_bit_begin_off == 0 { + unit_align = cmp::max(unit_align, bitfield_width); + } else { + // if bitfields is not start of structure, due to the presence + // of backward embedding, we can't use max alignment as the + // start of the bitfields: default set to u8 + unit_align = u8::BITS as usize; + } } // Always keep all bitfields around. While unnamed bitifields are used @@ -663,12 +680,23 @@ where unfilled_bits_in_unit = data_size - unit_size_in_bits; } + let final_bit_size = if let Some(next_field) = next_non_bitfield { + next_field + .offset() + .map_or(unit_size_in_bits, |off| off - bitfields_bit_begin_off) + } else if let Some(parent_layout_) = parent_layout { + // if the bitfield is an end of structure, use bitfields start to the structure end + parent_layout_.size * (u8::BITS as usize) - bitfields_bit_begin_off + } else { + unit_size_in_bits + }; + if unit_size_in_bits != 0 { // Flush the last allocation unit and its bitfields. flush_allocation_unit( fields, bitfield_unit_count, - unit_size_in_bits, + final_bit_size, unit_align, bitfields_in_unit, packed, @@ -715,7 +743,12 @@ impl CompFields { } } - fn compute_bitfield_units(&mut self, ctx: &BindgenContext, packed: bool) { + fn compute_bitfield_units( + &mut self, + ctx: &BindgenContext, + packed: bool, + parent_layout: Option<&Layout>, + ) { let raws = match *self { CompFields::Before(ref mut raws) => mem::take(raws), _ => { @@ -723,7 +756,12 @@ impl CompFields { } }; - let result = raw_fields_to_fields_and_bitfield_units(ctx, raws, packed); + let result = raw_fields_to_fields_and_bitfield_units( + ctx, + raws, + packed, + parent_layout, + ); match result { Ok((fields, has_bitfield_units)) => { @@ -1699,7 +1737,13 @@ impl CompInfo { layout: Option<&Layout>, ) { let packed = self.is_packed(ctx, layout); - self.fields.compute_bitfield_units(ctx, packed); + let parent_layout = layout.map(|l| Layout { + size: l.size, + align: l.align, + packed, + }); + self.fields + .compute_bitfield_units(ctx, packed, parent_layout.as_ref()); } /// Assign for each anonymous field a generated name.