diff --git a/bindgen-tests/tests/expectations/tests/bitfield-32bit-overflow.rs b/bindgen-tests/tests/expectations/tests/bitfield-32bit-overflow.rs index cf04543654..ea126bbbc1 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield-32bit-overflow.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield-32bit-overflow.rs @@ -83,7 +83,7 @@ where } } } -#[repr(C, packed)] +#[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct MuchBitfield { pub _bitfield_align_1: [u8; 0], diff --git a/bindgen-tests/tests/expectations/tests/bitfield-method-same-name.rs b/bindgen-tests/tests/expectations/tests/bitfield-method-same-name.rs index 8cd1997a93..ce3ea41e75 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield-method-same-name.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield-method-same-name.rs @@ -83,7 +83,7 @@ where } } } -#[repr(C, packed)] +#[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Foo { pub _bitfield_align_1: [u8; 0], diff --git a/bindgen-tests/tests/expectations/tests/bitfield_align.rs b/bindgen-tests/tests/expectations/tests/bitfield_align.rs index 559038ed3e..8002327981 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield_align.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield_align.rs @@ -332,7 +332,6 @@ impl A { } } #[repr(C)] -#[repr(align(4))] #[derive(Debug, Default, Copy, Clone)] pub struct B { pub _bitfield_align_1: [u32; 0], diff --git a/bindgen-tests/tests/expectations/tests/bitfield_align_2.rs b/bindgen-tests/tests/expectations/tests/bitfield_align_2.rs index dc49137e9b..963d86f9be 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield_align_2.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield_align_2.rs @@ -93,7 +93,6 @@ pub enum MyEnum { FOUR = 3, } #[repr(C)] -#[repr(align(8))] #[derive(Debug, Copy, Clone)] pub struct TaggedPtr { pub _bitfield_align_1: [u64; 0], diff --git a/bindgen-tests/tests/expectations/tests/bitfield_method_mangling.rs b/bindgen-tests/tests/expectations/tests/bitfield_method_mangling.rs index ea1502eb61..7104682ea8 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield_method_mangling.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield_method_mangling.rs @@ -84,7 +84,6 @@ where } } #[repr(C)] -#[repr(align(4))] #[derive(Debug, Default, Copy, Clone)] pub struct mach_msg_type_descriptor_t { pub _bitfield_align_1: [u32; 0], diff --git a/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs b/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs index c37b42f2fd..e3168f51ea 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs @@ -83,7 +83,7 @@ where } } } -#[repr(C, packed)] +#[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Struct { pub _bitfield_align_1: [u8; 0], @@ -215,3 +215,97 @@ impl Struct { __bindgen_bitfield_unit } } +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Inner { + pub _bitfield_align_1: [u16; 0], + pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, +} +#[test] +fn bindgen_test_layout_Inner() { + assert_eq!( + ::std::mem::size_of::(), + 4usize, + concat!("Size of: ", stringify!(Inner)), + ); + assert_eq!( + ::std::mem::align_of::(), + 2usize, + concat!("Alignment of ", stringify!(Inner)), + ); +} +impl Inner { + #[inline] + pub fn a(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(0usize, 16u8) as u16) } + } + #[inline] + pub fn set_a(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(0usize, 16u8, val as u64) + } + } + #[inline] + pub fn b(&self) -> ::std::os::raw::c_ushort { + unsafe { ::std::mem::transmute(self._bitfield_1.get(16usize, 16u8) as u16) } + } + #[inline] + pub fn set_b(&mut self, val: ::std::os::raw::c_ushort) { + unsafe { + let val: u16 = ::std::mem::transmute(val); + self._bitfield_1.set(16usize, 16u8, val as u64) + } + } + #[inline] + pub fn new_bitfield_1( + a: ::std::os::raw::c_ushort, + b: ::std::os::raw::c_ushort, + ) -> __BindgenBitfieldUnit<[u8; 4usize]> { + let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 4usize]> = Default::default(); + __bindgen_bitfield_unit + .set( + 0usize, + 16u8, + { + let a: u16 = unsafe { ::std::mem::transmute(a) }; + a as u64 + }, + ); + __bindgen_bitfield_unit + .set( + 16usize, + 16u8, + { + let b: u16 = unsafe { ::std::mem::transmute(b) }; + b as u64 + }, + ); + __bindgen_bitfield_unit + } +} +#[repr(C, packed)] +#[derive(Debug, Default, Copy, Clone)] +pub struct Outer { + pub inner: Inner, +} +#[test] +fn bindgen_test_layout_Outer() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 4usize, + concat!("Size of: ", stringify!(Outer)), + ); + assert_eq!( + ::std::mem::align_of::(), + 1usize, + concat!("Alignment of ", stringify!(Outer)), + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).inner) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(Outer), "::", stringify!(inner)), + ); +} diff --git a/bindgen-tests/tests/expectations/tests/default_visibility_crate.rs b/bindgen-tests/tests/expectations/tests/default_visibility_crate.rs index f75a06e984..aef1a61a08 100644 --- a/bindgen-tests/tests/expectations/tests/default_visibility_crate.rs +++ b/bindgen-tests/tests/expectations/tests/default_visibility_crate.rs @@ -89,7 +89,7 @@ pub struct Point { pub(crate) x: ::std::os::raw::c_int, pub(crate) y: ::std::os::raw::c_int, } -#[repr(C, packed)] +#[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Color { pub(crate) _bitfield_align_1: [u8; 0], diff --git a/bindgen-tests/tests/expectations/tests/default_visibility_private.rs b/bindgen-tests/tests/expectations/tests/default_visibility_private.rs index 9bd6409f4f..8b3099c0d8 100644 --- a/bindgen-tests/tests/expectations/tests/default_visibility_private.rs +++ b/bindgen-tests/tests/expectations/tests/default_visibility_private.rs @@ -89,7 +89,7 @@ pub struct Point { x: ::std::os::raw::c_int, y: ::std::os::raw::c_int, } -#[repr(C, packed)] +#[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Color { _bitfield_align_1: [u8; 0], diff --git a/bindgen-tests/tests/expectations/tests/default_visibility_private_respects_cxx_access_spec.rs b/bindgen-tests/tests/expectations/tests/default_visibility_private_respects_cxx_access_spec.rs index a8b0d29733..29fbb3a893 100644 --- a/bindgen-tests/tests/expectations/tests/default_visibility_private_respects_cxx_access_spec.rs +++ b/bindgen-tests/tests/expectations/tests/default_visibility_private_respects_cxx_access_spec.rs @@ -89,7 +89,7 @@ pub struct Point { pub x: ::std::os::raw::c_int, pub y: ::std::os::raw::c_int, } -#[repr(C, packed)] +#[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct Color { _bitfield_align_1: [u8; 0], diff --git a/bindgen-tests/tests/expectations/tests/issue-1034.rs b/bindgen-tests/tests/expectations/tests/issue-1034.rs index 0bd7647aa0..7848090fba 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1034.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1034.rs @@ -83,7 +83,7 @@ where } } } -#[repr(C, packed)] +#[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct S2 { pub _bitfield_align_1: [u8; 0], diff --git a/bindgen-tests/tests/expectations/tests/issue-1076-unnamed-bitfield-alignment.rs b/bindgen-tests/tests/expectations/tests/issue-1076-unnamed-bitfield-alignment.rs index d88806954f..89c09cc62f 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1076-unnamed-bitfield-alignment.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1076-unnamed-bitfield-alignment.rs @@ -83,7 +83,7 @@ where } } } -#[repr(C, packed)] +#[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct S1 { pub _bitfield_align_1: [u8; 0], diff --git a/bindgen-tests/tests/expectations/tests/issue-1947.rs b/bindgen-tests/tests/expectations/tests/issue-1947.rs index 24aa354814..be623357d0 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1947.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1947.rs @@ -86,7 +86,6 @@ where pub type U8 = ::std::os::raw::c_uchar; pub type U16 = ::std::os::raw::c_ushort; #[repr(C)] -#[repr(align(2))] #[derive(Debug, Default, Copy, Clone)] pub struct V56AMDY { pub _bitfield_align_1: [u16; 0], diff --git a/bindgen-tests/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs b/bindgen-tests/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs index adea1cbe56..7bc9933697 100644 --- a/bindgen-tests/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/issue-739-pointer-wide-bitfield.rs @@ -85,7 +85,6 @@ where } } #[repr(C)] -#[repr(align(8))] #[derive(Debug, Default, Copy, Clone)] pub struct Foo { pub _bitfield_align_1: [u64; 0], diff --git a/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs b/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs index 735cebfb25..576f57586a 100644 --- a/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs +++ b/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs @@ -181,7 +181,6 @@ pub union jsval_layout { pub asUIntPtr: usize, } #[repr(C)] -#[repr(align(8))] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct jsval_layout__bindgen_ty_1 { pub _bitfield_align_1: [u64; 0], diff --git a/bindgen-tests/tests/expectations/tests/jsval_layout_opaque_1_0.rs b/bindgen-tests/tests/expectations/tests/jsval_layout_opaque_1_0.rs index 2e64796b5f..0889b65232 100644 --- a/bindgen-tests/tests/expectations/tests/jsval_layout_opaque_1_0.rs +++ b/bindgen-tests/tests/expectations/tests/jsval_layout_opaque_1_0.rs @@ -229,7 +229,6 @@ pub struct jsval_layout { pub struct jsval_layout__bindgen_ty_1 { pub _bitfield_align_1: [u64; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 8usize]>, - pub __bindgen_align: [u64; 0usize], } #[test] fn bindgen_test_layout_jsval_layout__bindgen_ty_1() { diff --git a/bindgen-tests/tests/expectations/tests/only_bitfields.rs b/bindgen-tests/tests/expectations/tests/only_bitfields.rs index 42ea60f1aa..fe216f4b56 100644 --- a/bindgen-tests/tests/expectations/tests/only_bitfields.rs +++ b/bindgen-tests/tests/expectations/tests/only_bitfields.rs @@ -83,7 +83,7 @@ where } } } -#[repr(C, packed)] +#[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct C { pub _bitfield_align_1: [u8; 0], diff --git a/bindgen-tests/tests/expectations/tests/union_bitfield.rs b/bindgen-tests/tests/expectations/tests/union_bitfield.rs index 096c0371a6..7f4bd37f35 100644 --- a/bindgen-tests/tests/expectations/tests/union_bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/union_bitfield.rs @@ -142,7 +142,6 @@ impl U4 { } } #[repr(C)] -#[repr(align(4))] #[derive(Copy, Clone)] pub union B { pub _bitfield_align_1: [u32; 0], diff --git a/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield.rs b/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield.rs index 2f99027158..48a1bda9dc 100644 --- a/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield.rs @@ -90,7 +90,6 @@ pub union foo { pub __bindgen_anon_1: foo__bindgen_ty_1, } #[repr(C)] -#[repr(align(4))] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] pub struct foo__bindgen_ty_1 { pub _bitfield_align_1: [u32; 0], diff --git a/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield_1_0.rs b/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield_1_0.rs index dec7fc29ea..530cb7ea6a 100644 --- a/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield_1_0.rs +++ b/bindgen-tests/tests/expectations/tests/union_with_anon_struct_bitfield_1_0.rs @@ -138,7 +138,6 @@ pub struct foo { pub struct foo__bindgen_ty_1 { pub _bitfield_align_1: [u32; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, - pub __bindgen_align: [u32; 0usize], } #[test] fn bindgen_test_layout_foo__bindgen_ty_1() { diff --git a/bindgen-tests/tests/headers/bitfield_pragma_packed.h b/bindgen-tests/tests/headers/bitfield_pragma_packed.h index b4011ca844..c18b80ddfc 100644 --- a/bindgen-tests/tests/headers/bitfield_pragma_packed.h +++ b/bindgen-tests/tests/headers/bitfield_pragma_packed.h @@ -7,3 +7,14 @@ struct Struct { unsigned char e : 8; }; #pragma pack(pop) + +struct Inner { + unsigned short a: 16; + unsigned short b: 16; +}; + +#pragma pack(push, 1) +struct Outer { + struct Inner inner; +}; +#pragma pop diff --git a/bindgen/codegen/struct_layout.rs b/bindgen/codegen/struct_layout.rs index 5673060361..83d7836118 100644 --- a/bindgen/codegen/struct_layout.rs +++ b/bindgen/codegen/struct_layout.rs @@ -156,9 +156,7 @@ impl<'a> StructLayoutTracker<'a> { self.latest_field_layout = Some(layout); self.last_field_was_bitfield = true; - // NB: We intentionally don't update the max_field_align here, since our - // bitfields code doesn't necessarily guarantee it, so we need to - // actually generate the dummy alignment. + self.max_field_align = cmp::max(self.max_field_align, layout.align); } /// Returns a padding field if necessary for a given new field _before_