From 56c23d64fd6f00a9ee12486afb3b865ac8f9679b Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Sat, 14 Jan 2023 02:28:41 +0000 Subject: [PATCH 1/3] 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 ddac1b0abb..7c9711a6cb 100644 --- a/bindgen/codegen/struct_layout.rs +++ b/bindgen/codegen/struct_layout.rs @@ -152,9 +152,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 b01a2c7b50aea6f3e15023537f8b2f0ee6f31c64 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Sat, 14 Jan 2023 02:37:00 +0000 Subject: [PATCH 2/3] 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 680b25d8fd..f9a67b4baf 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield-32bit-overflow.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield-32bit-overflow.rs @@ -91,7 +91,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 e9c1a76d1c..0b54426d33 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield-method-same-name.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield-method-same-name.rs @@ -91,7 +91,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 4baca11214..e1e7558f63 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield_align.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield_align.rs @@ -316,7 +316,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 aa11f80c51..3d83d312ba 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield_align_2.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield_align_2.rs @@ -101,7 +101,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 42fa3c4cb4..4cd33cd56e 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield_method_mangling.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield_method_mangling.rs @@ -92,7 +92,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 27cd90f140..b2079ba0d7 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs @@ -91,7 +91,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 32f4310e49..ddb84c2268 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1034.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1034.rs @@ -91,7 +91,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 d91dd8fa5c..91eddd6187 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 @@ -91,7 +91,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 e133ed85ba..227f66f8fd 100644 --- a/bindgen-tests/tests/expectations/tests/issue-1947.rs +++ b/bindgen-tests/tests/expectations/tests/issue-1947.rs @@ -94,7 +94,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 1a633844f2..12329fb2aa 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 @@ -93,7 +93,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 a812e90560..55dc156d22 100644 --- a/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs +++ b/bindgen-tests/tests/expectations/tests/jsval_layout_opaque.rs @@ -189,7 +189,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 b439499355..ef4fb6b4b7 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 @@ -237,7 +237,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 2f063b5b38..f0e7cbee0e 100644 --- a/bindgen-tests/tests/expectations/tests/only_bitfields.rs +++ b/bindgen-tests/tests/expectations/tests/only_bitfields.rs @@ -91,7 +91,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 9e07a1dfcd..cc0ee1c8c3 100644 --- a/bindgen-tests/tests/expectations/tests/union_bitfield.rs +++ b/bindgen-tests/tests/expectations/tests/union_bitfield.rs @@ -148,7 +148,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 e81b3bef50..cd44427189 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 @@ -98,7 +98,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 6ce6ed2282..3ae3a31ace 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 @@ -146,7 +146,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 bec7f31af1481ba5ddec4bc319be0397b9f4a3db Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Sat, 14 Jan 2023 02:43:45 +0000 Subject: [PATCH 3/3] 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 b2079ba0d7..f25123ef29 100644 --- a/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs +++ b/bindgen-tests/tests/expectations/tests/bitfield_pragma_packed.rs @@ -209,3 +209,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