From 3cfdb4bafc954044c9955c8278471784cde78a0f Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Tue, 12 Dec 2023 17:28:00 +0000 Subject: [PATCH 1/2] Use field align if it's smaller than pack align Fixes #2695 --- bindgen/codegen/struct_layout.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bindgen/codegen/struct_layout.rs b/bindgen/codegen/struct_layout.rs index 83d7836118..a62da69534 100644 --- a/bindgen/codegen/struct_layout.rs +++ b/bindgen/codegen/struct_layout.rs @@ -212,7 +212,10 @@ impl<'a> StructLayoutTracker<'a> { 0 } else if !self.is_packed { self.padding_bytes(field_layout) - } else if let Some(l) = self.known_type_layout { + } else if let Some(mut l) = self.known_type_layout { + if field_layout.align < l.align { + l.align = field_layout.align; + } self.padding_bytes(l) } else { 0 From a31110dd5b0defbc3d4a84015e1897d49d07206b Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Fri, 12 Jan 2024 23:32:49 +0000 Subject: [PATCH 2/2] add a test case for issue #2695 --- .../tests/expectations/tests/issue-2695.rs | 45 +++++++++++++++++++ bindgen-tests/tests/headers/issue-2695.h | 10 +++++ 2 files changed, 55 insertions(+) create mode 100644 bindgen-tests/tests/expectations/tests/issue-2695.rs create mode 100644 bindgen-tests/tests/headers/issue-2695.h diff --git a/bindgen-tests/tests/expectations/tests/issue-2695.rs b/bindgen-tests/tests/expectations/tests/issue-2695.rs new file mode 100644 index 0000000000..ed559fb606 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/issue-2695.rs @@ -0,0 +1,45 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(C, packed(2))] +#[derive(Debug, Default, Copy, Clone)] +pub struct Test { + pub x: ::std::os::raw::c_ulong, + pub a: ::std::os::raw::c_char, + pub b: ::std::os::raw::c_char, + pub c: ::std::os::raw::c_char, + pub __bindgen_padding_0: u8, +} +#[test] +fn bindgen_test_layout_Test() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 12usize, + concat!("Size of: ", stringify!(Test)), + ); + assert_eq!( + ::std::mem::align_of::(), + 2usize, + concat!("Alignment of ", stringify!(Test)), + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(Test), "::", stringify!(x)), + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).a) as usize - ptr as usize }, + 8usize, + concat!("Offset of field: ", stringify!(Test), "::", stringify!(a)), + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).b) as usize - ptr as usize }, + 9usize, + concat!("Offset of field: ", stringify!(Test), "::", stringify!(b)), + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).c) as usize - ptr as usize }, + 10usize, + concat!("Offset of field: ", stringify!(Test), "::", stringify!(c)), + ); +} diff --git a/bindgen-tests/tests/headers/issue-2695.h b/bindgen-tests/tests/headers/issue-2695.h new file mode 100644 index 0000000000..4fbcc39bf8 --- /dev/null +++ b/bindgen-tests/tests/headers/issue-2695.h @@ -0,0 +1,10 @@ +// bindgen-flags: --explicit-padding + +#pragma pack(2) + +struct Test { + unsigned long x; + char a; + char b; + char c; +};