From 1602e123f7cb2c34c84afe65f9d2be9a7f6a0ef4 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Sat, 14 Jan 2023 02:28:41 +0000 Subject: [PATCH 1/4] Consider alignment contribution from bitfields --- bindgen/codegen/struct_layout.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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_ From a5276e6f60ba968004cb036f2d7c5801a0f63b4b Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Sat, 14 Jan 2023 02:37:00 +0000 Subject: [PATCH 2/4] Bless tests --- .../tests/expectations/tests/bitfield-32bit-overflow.rs | 2 +- .../tests/expectations/tests/bitfield-method-same-name.rs | 2 +- bindgen-tests/tests/expectations/tests/bitfield_align.rs | 1 - bindgen-tests/tests/expectations/tests/bitfield_align_2.rs | 1 - .../tests/expectations/tests/bitfield_method_mangling.rs | 1 - .../tests/expectations/tests/bitfield_pragma_packed.rs | 2 +- bindgen-tests/tests/expectations/tests/issue-1034.rs | 2 +- .../expectations/tests/issue-1076-unnamed-bitfield-alignment.rs | 2 +- bindgen-tests/tests/expectations/tests/issue-1947.rs | 1 - .../tests/expectations/tests/issue-739-pointer-wide-bitfield.rs | 1 - bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs | 1 - .../tests/expectations/tests/jsval_layout_opaque_1_0.rs | 1 - bindgen-tests/tests/expectations/tests/only_bitfields.rs | 2 +- bindgen-tests/tests/expectations/tests/union_bitfield.rs | 1 - .../tests/expectations/tests/union_with_anon_struct_bitfield.rs | 1 - .../expectations/tests/union_with_anon_struct_bitfield_1_0.rs | 1 - 16 files changed, 6 insertions(+), 16 deletions(-) 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..51190c5237 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], 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() { From c8ce29c1db67bbc1e6e068e99c87f644b6abb675 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Sat, 14 Jan 2023 02:43:45 +0000 Subject: [PATCH 3/4] Additional test for using bitfield in struct nested within packed struct --- .../tests/bitfield_pragma_packed.rs | 95 +++++++++++++++++++ .../tests/headers/bitfield_pragma_packed.h | 11 +++ 2 files changed, 106 insertions(+) diff --git a/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs b/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs index 51190c5237..4062a564a1 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs @@ -215,3 +215,98 @@ 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/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 From c47ba2b22c35aa3fcbc9ad0051ea2e5eb9f70e70 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Thu, 2 Nov 2023 21:17:10 +0000 Subject: [PATCH 4/4] Additional test bless --- .../tests/bitfield_pragma_packed.rs | 55 +++++++++---------- .../tests/default_visibility_crate.rs | 2 +- .../tests/default_visibility_private.rs | 2 +- ...bility_private_respects_cxx_access_spec.rs | 2 +- 4 files changed, 30 insertions(+), 31 deletions(-) diff --git a/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs b/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs index 4062a564a1..e3168f51ea 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs @@ -226,20 +226,18 @@ fn bindgen_test_layout_Inner() { assert_eq!( ::std::mem::size_of::(), 4usize, - concat!("Size of: ", stringify!(Inner)) + concat!("Size of: ", stringify!(Inner)), ); assert_eq!( ::std::mem::align_of::(), 2usize, - concat!("Alignment of ", stringify!(Inner)) + 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) - } + 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) { @@ -250,9 +248,7 @@ impl Inner { } #[inline] pub fn b(&self) -> ::std::os::raw::c_ushort { - unsafe { - ::std::mem::transmute(self._bitfield_1.get(16usize, 16u8) as u16) - } + 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) { @@ -266,16 +262,25 @@ impl Inner { 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 - }); + 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 } } @@ -286,27 +291,21 @@ pub struct Outer { } #[test] fn bindgen_test_layout_Outer() { - const UNINIT: ::std::mem::MaybeUninit = - ::std::mem::MaybeUninit::uninit(); + 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)) + concat!("Size of: ", stringify!(Outer)), ); assert_eq!( ::std::mem::align_of::(), 1usize, - concat!("Alignment of ", stringify!(Outer)) + 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) - ) + 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],