diff options
41 files changed, 143 insertions, 129 deletions
diff --git a/bindgen-integration/src/lib.rs b/bindgen-integration/src/lib.rs index 0d698961..4b288afd 100755 --- a/bindgen-integration/src/lib.rs +++ b/bindgen-integration/src/lib.rs @@ -260,8 +260,6 @@ fn test_macro_customintkind_path() { assert!(v.is::<MacroInteger>()) } -// https://github.com/rust-lang/rust-bindgen/issues/1973 -#[cfg_attr(target_arch = "aarch64", should_panic)] // This line should be removed after the bug linked above is fixed #[test] fn test_homogeneous_aggregate_float_union() { unsafe { diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index cad2f47e..6a7660f6 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1219,7 +1219,7 @@ impl<'a> FieldCodegen<'a> for FieldData { ty.append_implicit_template_params(ctx, field_item); // NB: If supported, we use proper `union` types. - let ty = if parent.is_union() && !parent.can_be_rust_union(ctx) { + let ty = if parent.is_union() && !struct_layout.is_rust_union() { result.saw_bindgen_union(); if ctx.options().enable_cxx_namespaces { quote! { @@ -1263,12 +1263,10 @@ impl<'a> FieldCodegen<'a> for FieldData { .expect("Each field should have a name in codegen!"); let field_ident = ctx.rust_ident_raw(field_name.as_str()); - if !parent.is_union() { - if let Some(padding_field) = - struct_layout.pad_field(&field_name, field_ty, self.offset()) - { - fields.extend(Some(padding_field)); - } + if let Some(padding_field) = + struct_layout.saw_field(&field_name, field_ty, self.offset()) + { + fields.extend(Some(padding_field)); } let is_private = (!self.is_public() && @@ -1433,7 +1431,7 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit { let layout = self.layout(); let unit_field_ty = helpers::bitfield_unit(ctx, layout); let field_ty = { - if parent.is_union() && !parent.can_be_rust_union(ctx) { + if parent.is_union() && !struct_layout.is_rust_union() { result.saw_bindgen_union(); if ctx.options().enable_cxx_namespaces { quote! { @@ -1571,7 +1569,7 @@ impl<'a> FieldCodegen<'a> for Bitfield { _accessor_kind: FieldAccessorKind, parent: &CompInfo, _result: &mut CodegenResult, - _struct_layout: &mut StructLayoutTracker, + struct_layout: &mut StructLayoutTracker, _fields: &mut F, methods: &mut M, (unit_field_name, bitfield_representable_as_int): (&'a str, &mut bool), @@ -1612,7 +1610,7 @@ impl<'a> FieldCodegen<'a> for Bitfield { self.is_public() && !fields_should_be_private, ); - if parent.is_union() && !parent.can_be_rust_union(ctx) { + if parent.is_union() && !struct_layout.is_rust_union() { methods.extend(Some(quote! { #[inline] #access_spec fn #getter_name(&self) -> #bitfield_ty { @@ -1768,15 +1766,53 @@ impl CodeGenerator for CompInfo { } } - let is_union = self.kind() == CompKind::Union; - let layout = item.kind().expect_type().layout(ctx); - - let mut explicit_align = None; if is_opaque { // Opaque item should not have generated methods, fields. debug_assert!(fields.is_empty()); debug_assert!(methods.is_empty()); + } + let is_union = self.kind() == CompKind::Union; + let layout = item.kind().expect_type().layout(ctx); + let zero_sized = item.is_zero_sized(ctx); + let forward_decl = self.is_forward_declaration(); + + let mut explicit_align = None; + + // C++ requires every struct to be addressable, so what C++ compilers do + // is making the struct 1-byte sized. + // + // This is apparently not the case for C, see: + // https://github.com/rust-lang/rust-bindgen/issues/551 + // + // Just get the layout, and assume C++ if not. + // + // NOTE: This check is conveniently here to avoid the dummy fields we + // may add for unused template parameters. + if !forward_decl && zero_sized { + let has_address = if is_opaque { + // Generate the address field if it's an opaque type and + // couldn't determine the layout of the blob. + layout.is_none() + } else { + layout.map_or(true, |l| l.size != 0) + }; + + if has_address { + let layout = Layout::new(1, 1); + let ty = helpers::blob(ctx, Layout::new(1, 1)); + struct_layout.saw_field_with_layout( + "_address", + layout, + /* offset = */ Some(0), + ); + fields.push(quote! { + pub _address: #ty, + }); + } + } + + if is_opaque { match layout { Some(l) => { explicit_align = Some(l.align); @@ -1790,7 +1826,7 @@ impl CodeGenerator for CompInfo { warn!("Opaque type without layout! Expect dragons!"); } } - } else if !is_union && !item.is_zero_sized(ctx) { + } else if !is_union && !zero_sized { if let Some(padding_field) = layout.and_then(|layout| struct_layout.pad_struct(layout)) { @@ -1815,57 +1851,26 @@ impl CodeGenerator for CompInfo { } } } - } else if is_union && !self.is_forward_declaration() { + } else if is_union && !forward_decl { // TODO(emilio): It'd be nice to unify this with the struct path // above somehow. let layout = layout.expect("Unable to get layout information?"); - struct_layout.saw_union(layout); - if struct_layout.requires_explicit_align(layout) { explicit_align = Some(layout.align); } - let ty = helpers::blob(ctx, layout); - fields.push(if self.can_be_rust_union(ctx) { - quote! { - _bindgen_union_align: #ty , - } - } else { - quote! { + if !struct_layout.is_rust_union() { + let ty = helpers::blob(ctx, layout); + fields.push(quote! { pub bindgen_union_field: #ty , - } - }); + }) + } } - // C++ requires every struct to be addressable, so what C++ compilers do - // is making the struct 1-byte sized. - // - // This is apparently not the case for C, see: - // https://github.com/rust-lang/rust-bindgen/issues/551 - // - // Just get the layout, and assume C++ if not. - // - // NOTE: This check is conveniently here to avoid the dummy fields we - // may add for unused template parameters. - if self.is_forward_declaration() { + if forward_decl { fields.push(quote! { _unused: [u8; 0], }); - } else if item.is_zero_sized(ctx) { - let has_address = if is_opaque { - // Generate the address field if it's an opaque type and - // couldn't determine the layout of the blob. - layout.is_none() - } else { - layout.map_or(true, |l| l.size != 0) - }; - - if has_address { - let ty = helpers::blob(ctx, Layout::new(1, 1)); - fields.push(quote! { - pub _address: #ty, - }); - } } let mut generic_param_names = vec![]; @@ -1963,7 +1968,7 @@ impl CodeGenerator for CompInfo { attributes.push(attributes::derives(&derives)) } - let mut tokens = if is_union && self.can_be_rust_union(ctx) { + let mut tokens = if is_union && struct_layout.is_rust_union() { quote! { #( #attributes )* pub union #canonical_ident diff --git a/src/codegen/struct_layout.rs b/src/codegen/struct_layout.rs index 4536e889..2e4b9735 100644 --- a/src/codegen/struct_layout.rs +++ b/src/codegen/struct_layout.rs @@ -19,6 +19,7 @@ pub struct StructLayoutTracker<'a> { comp: &'a CompInfo, is_packed: bool, known_type_layout: Option<Layout>, + is_rust_union: bool, latest_offset: usize, padding_count: usize, latest_field_layout: Option<Layout>, @@ -89,12 +90,15 @@ impl<'a> StructLayoutTracker<'a> { ) -> Self { let known_type_layout = ty.layout(ctx); let is_packed = comp.is_packed(ctx, known_type_layout.as_ref()); + let is_rust_union = comp.is_union() && + comp.can_be_rust_union(ctx, known_type_layout.as_ref()); StructLayoutTracker { name, ctx, comp, is_packed, known_type_layout, + is_rust_union, latest_offset: 0, padding_count: 0, latest_field_layout: None, @@ -103,6 +107,10 @@ impl<'a> StructLayoutTracker<'a> { } } + pub fn is_rust_union(&self) -> bool { + self.is_rust_union + } + pub fn saw_vtable(&mut self) { debug!("saw vtable for {}", self.name); @@ -143,18 +151,9 @@ impl<'a> StructLayoutTracker<'a> { // actually generate the dummy alignment. } - pub fn saw_union(&mut self, layout: Layout) { - debug!("saw union for {}: {:?}", self.name, layout); - self.align_to_latest_field(layout); - - self.latest_offset += self.padding_bytes(layout) + layout.size; - self.latest_field_layout = Some(layout); - self.max_field_align = cmp::max(self.max_field_align, layout.align); - } - - /// Add a padding field if necessary for a given new field _before_ adding - /// that field. - pub fn pad_field( + /// Returns a padding field if necessary for a given new field _before_ + /// adding that field. + pub fn saw_field( &mut self, field_name: &str, field_ty: &Type, @@ -181,15 +180,27 @@ impl<'a> StructLayoutTracker<'a> { } } } + self.saw_field_with_layout(field_name, field_layout, field_offset) + } + pub fn saw_field_with_layout( + &mut self, + field_name: &str, + field_layout: Layout, + field_offset: Option<usize>, + ) -> Option<proc_macro2::TokenStream> { let will_merge_with_bitfield = self.align_to_latest_field(field_layout); + let is_union = self.comp.is_union(); let padding_bytes = match field_offset { Some(offset) if offset / 8 > self.latest_offset => { offset / 8 - self.latest_offset } _ => { - if will_merge_with_bitfield || field_layout.align == 0 { + if will_merge_with_bitfield || + field_layout.align == 0 || + is_union + { 0 } else if !self.is_packed { self.padding_bytes(field_layout) @@ -203,7 +214,7 @@ impl<'a> StructLayoutTracker<'a> { self.latest_offset += padding_bytes; - let padding_layout = if self.is_packed { + let padding_layout = if self.is_packed || is_union { None } else { // Otherwise the padding is useless. diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 60b1e2f0..52dcddd5 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -1642,7 +1642,12 @@ impl CompInfo { /// Requirements: /// 1. Current RustTarget allows for `untagged_union` /// 2. Each field can derive `Copy` - pub fn can_be_rust_union(&self, ctx: &BindgenContext) -> bool { + /// 3. It's not zero-sized. + pub fn can_be_rust_union( + &self, + ctx: &BindgenContext, + layout: Option<&Layout>, + ) -> bool { if !ctx.options().rust_features().untagged_union { return false; } @@ -1651,12 +1656,22 @@ impl CompInfo { return false; } - self.fields().iter().all(|f| match *f { + let all_can_copy = self.fields().iter().all(|f| match *f { Field::DataMember(ref field_data) => { field_data.ty().can_derive_copy(ctx) } Field::Bitfields(_) => true, - }) + }); + + if !all_can_copy { + return false; + } + + if layout.map_or(false, |l| l.size == 0) { + return false; + } + + true } } diff --git a/tests/expectations/tests/16-byte-alignment.rs b/tests/expectations/tests/16-byte-alignment.rs index 00d311a5..0bb92fd1 100644 --- a/tests/expectations/tests/16-byte-alignment.rs +++ b/tests/expectations/tests/16-byte-alignment.rs @@ -17,7 +17,6 @@ pub struct rte_ipv4_tuple { pub union rte_ipv4_tuple__bindgen_ty_1 { pub __bindgen_anon_1: rte_ipv4_tuple__bindgen_ty_1__bindgen_ty_1, pub sctp_tag: u32, - _bindgen_union_align: u32, } #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] @@ -159,7 +158,6 @@ pub struct rte_ipv6_tuple { pub union rte_ipv6_tuple__bindgen_ty_1 { pub __bindgen_anon_1: rte_ipv6_tuple__bindgen_ty_1__bindgen_ty_1, pub sctp_tag: u32, - _bindgen_union_align: u32, } #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] @@ -295,7 +293,6 @@ impl Default for rte_ipv6_tuple { pub union rte_thash_tuple { pub v4: rte_ipv4_tuple, pub v6: rte_ipv6_tuple, - _bindgen_union_align: [u128; 3usize], } #[test] fn bindgen_test_layout_rte_thash_tuple() { diff --git a/tests/expectations/tests/anon-fields-prefix.rs b/tests/expectations/tests/anon-fields-prefix.rs index 38baa2fd..f358dbd8 100644 --- a/tests/expectations/tests/anon-fields-prefix.rs +++ b/tests/expectations/tests/anon-fields-prefix.rs @@ -11,7 +11,6 @@ pub union color { pub u1: color__bindgen_ty_1, pub u2: color__bindgen_ty_2, pub v3: [::std::os::raw::c_uchar; 3usize], - _bindgen_union_align: [u8; 3usize], } #[repr(C)] #[derive(Debug, Default, Copy, Clone)] diff --git a/tests/expectations/tests/anon_struct_in_union.rs b/tests/expectations/tests/anon_struct_in_union.rs index 8d0035d6..008ab611 100644 --- a/tests/expectations/tests/anon_struct_in_union.rs +++ b/tests/expectations/tests/anon_struct_in_union.rs @@ -14,7 +14,6 @@ pub struct s { #[derive(Copy, Clone)] pub union s__bindgen_ty_1 { pub field: s__bindgen_ty_1_inner, - _bindgen_union_align: u32, } #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] diff --git a/tests/expectations/tests/anon_union.rs b/tests/expectations/tests/anon_union.rs index 02344063..386d8fad 100644 --- a/tests/expectations/tests/anon_union.rs +++ b/tests/expectations/tests/anon_union.rs @@ -35,7 +35,6 @@ pub struct TErrorResult_DOMExceptionInfo { pub union TErrorResult__bindgen_ty_1 { pub mMessage: *mut TErrorResult_Message, pub mDOMExceptionInfo: *mut TErrorResult_DOMExceptionInfo, - _bindgen_union_align: u64, } impl Default for TErrorResult__bindgen_ty_1 { fn default() -> Self { diff --git a/tests/expectations/tests/class.rs b/tests/expectations/tests/class.rs index c03f1274..b13b3c81 100644 --- a/tests/expectations/tests/class.rs +++ b/tests/expectations/tests/class.rs @@ -340,7 +340,6 @@ impl Default for IncompleteArrayNonCopiable { pub union Union { pub d: f32, pub i: ::std::os::raw::c_int, - _bindgen_union_align: u32, } #[test] fn bindgen_test_layout_Union() { diff --git a/tests/expectations/tests/class_with_inner_struct.rs b/tests/expectations/tests/class_with_inner_struct.rs index 8d21b674..eab54118 100644 --- a/tests/expectations/tests/class_with_inner_struct.rs +++ b/tests/expectations/tests/class_with_inner_struct.rs @@ -59,7 +59,6 @@ fn bindgen_test_layout_A_Segment() { #[derive(Copy, Clone)] pub union A__bindgen_ty_1 { pub f: ::std::os::raw::c_int, - _bindgen_union_align: u32, } #[test] fn bindgen_test_layout_A__bindgen_ty_1() { @@ -95,7 +94,6 @@ impl Default for A__bindgen_ty_1 { #[derive(Copy, Clone)] pub union A__bindgen_ty_2 { pub d: ::std::os::raw::c_int, - _bindgen_union_align: u32, } #[test] fn bindgen_test_layout_A__bindgen_ty_2() { @@ -247,7 +245,6 @@ pub struct C { pub union C__bindgen_ty_1 { pub mFunc: C__bindgen_ty_1__bindgen_ty_1, pub __bindgen_anon_1: C__bindgen_ty_1__bindgen_ty_2, - _bindgen_union_align: [u32; 4usize], } #[repr(C)] #[derive(Debug, Default, Copy, Clone, PartialEq)] diff --git a/tests/expectations/tests/derive-debug-mangle-name.rs b/tests/expectations/tests/derive-debug-mangle-name.rs index 4b4ae27b..d7f5c892 100644 --- a/tests/expectations/tests/derive-debug-mangle-name.rs +++ b/tests/expectations/tests/derive-debug-mangle-name.rs @@ -17,7 +17,6 @@ pub struct perf_event_attr { pub union perf_event_attr__bindgen_ty_1 { pub b: ::std::os::raw::c_int, pub c: ::std::os::raw::c_int, - _bindgen_union_align: u32, } #[test] fn bindgen_test_layout_perf_event_attr__bindgen_ty_1() { diff --git a/tests/expectations/tests/derive-partialeq-anonfield.rs b/tests/expectations/tests/derive-partialeq-anonfield.rs index 3486641d..8834ca32 100644 --- a/tests/expectations/tests/derive-partialeq-anonfield.rs +++ b/tests/expectations/tests/derive-partialeq-anonfield.rs @@ -12,9 +12,10 @@ pub struct rte_mbuf { pub __bindgen_anon_1: rte_mbuf__bindgen_ty_1, } #[repr(C)] +#[repr(align(1))] #[derive(Copy, Clone)] -pub union rte_mbuf__bindgen_ty_1 { - _bindgen_union_align: [u8; 0usize], +pub struct rte_mbuf__bindgen_ty_1 { + pub bindgen_union_field: [u8; 0usize], } #[test] fn bindgen_test_layout_rte_mbuf__bindgen_ty_1() { diff --git a/tests/expectations/tests/derive-partialeq-pointer.rs b/tests/expectations/tests/derive-partialeq-pointer.rs index 55bd782f..1964e373 100644 --- a/tests/expectations/tests/derive-partialeq-pointer.rs +++ b/tests/expectations/tests/derive-partialeq-pointer.rs @@ -41,7 +41,6 @@ pub struct c { #[repr(C)] #[derive(Copy, Clone)] pub union c__bindgen_ty_1 { - _bindgen_union_align: u8, pub _address: u8, } #[test] diff --git a/tests/expectations/tests/derive-partialeq-union.rs b/tests/expectations/tests/derive-partialeq-union.rs index e873d134..b2ccb2e8 100644 --- a/tests/expectations/tests/derive-partialeq-union.rs +++ b/tests/expectations/tests/derive-partialeq-union.rs @@ -11,7 +11,6 @@ pub union ShouldNotDerivePartialEq { pub a: ::std::os::raw::c_char, pub b: ::std::os::raw::c_int, - _bindgen_union_align: u32, } #[test] fn bindgen_test_layout_ShouldNotDerivePartialEq() { diff --git a/tests/expectations/tests/issue-1285.rs b/tests/expectations/tests/issue-1285.rs index 3e0da41b..4ca84527 100644 --- a/tests/expectations/tests/issue-1285.rs +++ b/tests/expectations/tests/issue-1285.rs @@ -15,7 +15,6 @@ pub struct foo { pub union foo__bindgen_ty_1 { pub a: ::std::os::raw::c_uint, pub b: ::std::os::raw::c_ushort, - _bindgen_union_align: u32, } #[test] fn bindgen_test_layout_foo__bindgen_ty_1() { diff --git a/tests/expectations/tests/issue-1498.rs b/tests/expectations/tests/issue-1498.rs index 72bf7f7c..b14f06c8 100644 --- a/tests/expectations/tests/issue-1498.rs +++ b/tests/expectations/tests/issue-1498.rs @@ -30,7 +30,6 @@ pub union rte_memseg__bindgen_ty_1 { pub addr: *mut ::std::os::raw::c_void, ///< Makes sure addr is always 64 bits pub addr_64: u64, - _bindgen_union_align: u64, } #[test] fn bindgen_test_layout_rte_memseg__bindgen_ty_1() { diff --git a/tests/expectations/tests/issue-493.rs b/tests/expectations/tests/issue-493.rs index 867e3d17..d17fbecc 100644 --- a/tests/expectations/tests/issue-493.rs +++ b/tests/expectations/tests/issue-493.rs @@ -84,7 +84,6 @@ pub struct basic_string___short { pub union basic_string___short__bindgen_ty_1 { pub __size_: ::std::os::raw::c_uchar, pub __lx: basic_string_value_type, - _bindgen_union_align: u8, } impl Default for basic_string___short__bindgen_ty_1 { fn default() -> Self { @@ -97,6 +96,7 @@ impl Default for basic_string___short { } } #[repr(C)] +#[repr(align(1))] pub struct basic_string___ulx { pub __lx: __BindgenUnionField<basic_string___long>, pub __lxx: __BindgenUnionField<basic_string___short>, @@ -129,6 +129,7 @@ pub struct basic_string___rep { pub __bindgen_anon_1: basic_string___rep__bindgen_ty_1, } #[repr(C)] +#[repr(align(1))] pub struct basic_string___rep__bindgen_ty_1 { pub __l: __BindgenUnionField<basic_string___long>, pub __s: __BindgenUnionField<basic_string___short>, diff --git a/tests/expectations/tests/jsval_layout_opaque.rs b/tests/expectations/tests/jsval_layout_opaque.rs index 92ae978d..8a3d7f39 100644 --- a/tests/expectations/tests/jsval_layout_opaque.rs +++ b/tests/expectations/tests/jsval_layout_opaque.rs @@ -188,7 +188,6 @@ pub union jsval_layout { pub asPtr: *mut ::std::os::raw::c_void, pub asWord: size_t, pub asUIntPtr: usize, - _bindgen_union_align: u64, } #[repr(C)] #[repr(align(8))] @@ -271,7 +270,6 @@ pub union jsval_layout__bindgen_ty_2__bindgen_ty_1 { pub i32_: i32, pub u32_: u32, pub why: JSWhyMagic, - _bindgen_union_align: u32, } #[test] fn bindgen_test_layout_jsval_layout__bindgen_ty_2__bindgen_ty_1() { diff --git a/tests/expectations/tests/layout_eth_conf.rs b/tests/expectations/tests/layout_eth_conf.rs index 34db2c4a..fe8b92fe 100644 --- a/tests/expectations/tests/layout_eth_conf.rs +++ b/tests/expectations/tests/layout_eth_conf.rs @@ -2011,7 +2011,6 @@ pub union rte_eth_conf__bindgen_ty_2 { pub vmdq_dcb_tx_conf: rte_eth_vmdq_dcb_tx_conf, pub dcb_tx_conf: rte_eth_dcb_tx_conf, pub vmdq_tx_conf: rte_eth_vmdq_tx_conf, - _bindgen_union_align: [u32; 3usize], } #[test] fn bindgen_test_layout_rte_eth_conf__bindgen_ty_2() { diff --git a/tests/expectations/tests/layout_mbuf.rs b/tests/expectations/tests/layout_mbuf.rs index a7f71a30..bc456a18 100644 --- a/tests/expectations/tests/layout_mbuf.rs +++ b/tests/expectations/tests/layout_mbuf.rs @@ -189,7 +189,6 @@ pub union rte_mbuf__bindgen_ty_1 { pub refcnt_atomic: rte_atomic16_t, ///< Non-atomically accessed refcnt pub refcnt: u16, - _bindgen_union_align: u16, } #[test] fn bindgen_test_layout_rte_mbuf__bindgen_ty_1() { @@ -241,7 +240,6 @@ pub union rte_mbuf__bindgen_ty_2 { ///< L2/L3/L4 and tunnel information. pub packet_type: u32, pub __bindgen_anon_1: rte_mbuf__bindgen_ty_2__bindgen_ty_1, - _bindgen_union_align: u32, } #[repr(C)] #[repr(align(4))] @@ -449,7 +447,6 @@ pub union rte_mbuf__bindgen_ty_3 { pub sched: rte_mbuf__bindgen_ty_3__bindgen_ty_2, ///< User defined tags. See rte_distributor_process() pub usr: u32, - _bindgen_union_align: [u32; 2usize], } #[repr(C)] #[derive(Copy, Clone)] @@ -463,7 +460,6 @@ pub union rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1 { pub __bindgen_anon_1: rte_mbuf__bindgen_ty_3__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1, pub lo: u32, - _bindgen_union_align: u32, } #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] @@ -686,7 +682,6 @@ pub union rte_mbuf__bindgen_ty_4 { pub userdata: *mut ::std::os::raw::c_void, ///< Allow 8-byte userdata on 32-bit pub udata64: u64, - _bindgen_union_align: u64, } #[test] fn bindgen_test_layout_rte_mbuf__bindgen_ty_4() { @@ -738,7 +733,6 @@ pub union rte_mbuf__bindgen_ty_5 { ///< combined for easy fetch pub tx_offload: u64, pub __bindgen_anon_1: rte_mbuf__bindgen_ty_5__bindgen_ty_1, - _bindgen_union_align: u64, } #[repr(C)] #[repr(align(8))] diff --git a/tests/expectations/tests/libclang-9/class.rs b/tests/expectations/tests/libclang-9/class.rs index baa851b9..beea517e 100644 --- a/tests/expectations/tests/libclang-9/class.rs +++ b/tests/expectations/tests/libclang-9/class.rs @@ -536,7 +536,6 @@ impl Default for IncompleteArrayNonCopiable { pub union Union { pub d: f32, pub i: ::std::os::raw::c_int, - _bindgen_union_align: u32, } #[test] fn bindgen_test_layout_Union() { diff --git a/tests/expectations/tests/private_fields.rs b/tests/expectations/tests/private_fields.rs index f5edccae..d5371e1c 100644 --- a/tests/expectations/tests/private_fields.rs +++ b/tests/expectations/tests/private_fields.rs @@ -481,7 +481,6 @@ pub struct WithAnonUnion { #[repr(C)] #[derive(Copy, Clone)] pub union WithAnonUnion__bindgen_ty_1 { - _bindgen_union_align: u8, pub _address: u8, } #[test] diff --git a/tests/expectations/tests/struct_with_anon_union.rs b/tests/expectations/tests/struct_with_anon_union.rs index 3e0da41b..4ca84527 100644 --- a/tests/expectations/tests/struct_with_anon_union.rs +++ b/tests/expectations/tests/struct_with_anon_union.rs @@ -15,7 +15,6 @@ pub struct foo { pub union foo__bindgen_ty_1 { pub a: ::std::os::raw::c_uint, pub b: ::std::os::raw::c_ushort, - _bindgen_union_align: u32, } #[test] fn bindgen_test_layout_foo__bindgen_ty_1() { diff --git a/tests/expectations/tests/struct_with_anon_unnamed_union.rs b/tests/expectations/tests/struct_with_anon_unnamed_union.rs index 5aeb51c3..5d03b7fb 100644 --- a/tests/expectations/tests/struct_with_anon_unnamed_union.rs +++ b/tests/expectations/tests/struct_with_anon_unnamed_union.rs @@ -15,7 +15,6 @@ pub struct foo { pub union foo__bindgen_ty_1 { pub a: ::std::os::raw::c_uint, pub b: ::std::os::raw::c_ushort, - _bindgen_union_align: u32, } #[test] fn bindgen_test_layout_foo__bindgen_ty_1() { diff --git a/tests/expectations/tests/struct_with_nesting.rs b/tests/expectations/tests/struct_with_nesting.rs index 07583235..a98bd8ca 100644 --- a/tests/expectations/tests/struct_with_nesting.rs +++ b/tests/expectations/tests/struct_with_nesting.rs @@ -17,7 +17,6 @@ pub union foo__bindgen_ty_1 { pub b: ::std::os::raw::c_uint, pub __bindgen_anon_1: foo__bindgen_ty_1__bindgen_ty_1, pub __bindgen_anon_2: foo__bindgen_ty_1__bindgen_ty_2, - _bindgen_union_align: u32, } #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] diff --git a/tests/expectations/tests/typeref.rs b/tests/expectations/tests/typeref.rs index 6155ff33..b62ce929 100644 --- a/tests/expectations/tests/typeref.rs +++ b/tests/expectations/tests/typeref.rs @@ -62,7 +62,6 @@ pub struct mozilla_StyleShapeSource { pub union mozilla_StyleShapeSource__bindgen_ty_1 { pub mPosition: *mut mozilla_Position, pub mFragmentOrURL: *mut mozilla_FragmentOrURL, - _bindgen_union_align: u64, } impl Default for mozilla_StyleShapeSource__bindgen_ty_1 { fn default() -> Self { diff --git a/tests/expectations/tests/union-align.rs b/tests/expectations/tests/union-align.rs index e9c3de52..7151ba45 100644 --- a/tests/expectations/tests/union-align.rs +++ b/tests/expectations/tests/union-align.rs @@ -10,7 +10,6 @@ #[derive(Copy, Clone)] pub union Bar { pub foo: ::std::os::raw::c_uchar, - _bindgen_union_align: u128, } #[test] fn bindgen_test_layout_Bar() { @@ -35,3 +34,32 @@ impl Default for Bar { unsafe { ::std::mem::zeroed() } } } +#[repr(C)] +#[repr(align(16))] +#[derive(Copy, Clone)] +pub union Baz { + pub bar: Bar, +} +#[test] +fn bindgen_test_layout_Baz() { + assert_eq!( + ::std::mem::size_of::<Baz>(), + 16usize, + concat!("Size of: ", stringify!(Baz)) + ); + assert_eq!( + ::std::mem::align_of::<Baz>(), + 16usize, + concat!("Alignment of ", stringify!(Baz)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<Baz>())).bar as *const _ as usize }, + 0usize, + concat!("Offset of field: ", stringify!(Baz), "::", stringify!(bar)) + ); +} +impl Default for Baz { + fn default() -> Self { + unsafe { ::std::mem::zeroed() } + } +} diff --git a/tests/expectations/tests/union-in-ns.rs b/tests/expectations/tests/union-in-ns.rs index 2ff76bb8..abb330b8 100644 --- a/tests/expectations/tests/union-in-ns.rs +++ b/tests/expectations/tests/union-in-ns.rs @@ -13,7 +13,6 @@ pub mod root { #[derive(Copy, Clone)] pub union bar { pub baz: ::std::os::raw::c_int, - _bindgen_union_align: u32, } #[test] fn bindgen_test_layout_bar() { diff --git a/tests/expectations/tests/union_bitfield.rs b/tests/expectations/tests/union_bitfield.rs index 22c0de85..cf3595ec 100644 --- a/tests/expectations/tests/union_bitfield.rs +++ b/tests/expectations/tests/union_bitfield.rs @@ -92,11 +92,11 @@ where } } #[repr(C)] +#[repr(align(4))] #[derive(Copy, Clone)] pub union U4 { pub _bitfield_align_1: [u8; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>, - _bindgen_union_align: u32, } #[test] fn bindgen_test_layout_U4() { @@ -144,11 +144,11 @@ impl U4 { } } #[repr(C)] +#[repr(align(4))] #[derive(Copy, Clone)] pub union B { pub _bitfield_align_1: [u32; 0], pub _bitfield_1: __BindgenBitfieldUnit<[u8; 4usize]>, - _bindgen_union_align: u32, } #[test] fn bindgen_test_layout_B() { diff --git a/tests/expectations/tests/union_dtor.rs b/tests/expectations/tests/union_dtor.rs index dd3635e1..a06e8ccf 100644 --- a/tests/expectations/tests/union_dtor.rs +++ b/tests/expectations/tests/union_dtor.rs @@ -9,7 +9,6 @@ pub union UnionWithDtor { pub mFoo: ::std::os::raw::c_int, pub mBar: *mut ::std::os::raw::c_void, - _bindgen_union_align: u64, } #[test] fn bindgen_test_layout_UnionWithDtor() { diff --git a/tests/expectations/tests/union_fields.rs b/tests/expectations/tests/union_fields.rs index d0bc26c2..e605b0bc 100644 --- a/tests/expectations/tests/union_fields.rs +++ b/tests/expectations/tests/union_fields.rs @@ -11,7 +11,6 @@ pub union nsStyleUnion { pub mInt: ::std::os::raw::c_int, pub mFloat: f32, pub mPointer: *mut ::std::os::raw::c_void, - _bindgen_union_align: u64, } #[test] fn bindgen_test_layout_nsStyleUnion() { diff --git a/tests/expectations/tests/union_template.rs b/tests/expectations/tests/union_template.rs index fcef30c9..6a366f9e 100644 --- a/tests/expectations/tests/union_template.rs +++ b/tests/expectations/tests/union_template.rs @@ -15,7 +15,6 @@ pub struct NastyStruct { pub union NastyStruct__bindgen_ty_1 { pub mFoo: *mut ::std::os::raw::c_void, pub mDummy: ::std::os::raw::c_ulong, - _bindgen_union_align: u64, } impl Default for NastyStruct__bindgen_ty_1 { fn default() -> Self { @@ -26,7 +25,6 @@ impl Default for NastyStruct__bindgen_ty_1 { pub union NastyStruct__bindgen_ty_2 { pub wat: ::std::os::raw::c_short, pub wut: *mut ::std::os::raw::c_int, - _bindgen_union_align: u64, } impl Default for NastyStruct__bindgen_ty_2 { fn default() -> Self { @@ -42,7 +40,6 @@ impl Default for NastyStruct { pub union Whatever { pub mTPtr: *mut ::std::os::raw::c_void, pub mInt: ::std::os::raw::c_int, - _bindgen_union_align: u64, } impl Default for Whatever { fn default() -> Self { diff --git a/tests/expectations/tests/union_with_anon_struct.rs b/tests/expectations/tests/union_with_anon_struct.rs index 8113ae09..7d061cec 100644 --- a/tests/expectations/tests/union_with_anon_struct.rs +++ b/tests/expectations/tests/union_with_anon_struct.rs @@ -9,7 +9,6 @@ #[derive(Copy, Clone)] pub union foo { pub bar: foo__bindgen_ty_1, - _bindgen_union_align: [u32; 2usize], } #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] diff --git a/tests/expectations/tests/union_with_anon_struct_bitfield.rs b/tests/expectations/tests/union_with_anon_struct_bitfield.rs index 445a97ef..2e3e6415 100644 --- a/tests/expectations/tests/union_with_anon_struct_bitfield.rs +++ b/tests/expectations/tests/union_with_anon_struct_bitfield.rs @@ -96,7 +96,6 @@ where pub union foo { pub a: ::std::os::raw::c_int, pub __bindgen_anon_1: foo__bindgen_ty_1, - _bindgen_union_align: u32, } #[repr(C)] #[repr(align(4))] diff --git a/tests/expectations/tests/union_with_anon_union.rs b/tests/expectations/tests/union_with_anon_union.rs index 89756d44..83e4801a 100644 --- a/tests/expectations/tests/union_with_anon_union.rs +++ b/tests/expectations/tests/union_with_anon_union.rs @@ -9,14 +9,12 @@ #[derive(Copy, Clone)] pub union foo { pub bar: foo__bindgen_ty_1, - _bindgen_union_align: u32, } #[repr(C)] #[derive(Copy, Clone)] pub union foo__bindgen_ty_1 { pub a: ::std::os::raw::c_uint, pub b: ::std::os::raw::c_ushort, - _bindgen_union_align: u32, } #[test] fn bindgen_test_layout_foo__bindgen_ty_1() { diff --git a/tests/expectations/tests/union_with_anon_unnamed_struct.rs b/tests/expectations/tests/union_with_anon_unnamed_struct.rs index 7f1d794f..5802f563 100644 --- a/tests/expectations/tests/union_with_anon_unnamed_struct.rs +++ b/tests/expectations/tests/union_with_anon_unnamed_struct.rs @@ -10,7 +10,6 @@ pub union pixel { pub rgba: ::std::os::raw::c_uint, pub __bindgen_anon_1: pixel__bindgen_ty_1, - _bindgen_union_align: u32, } #[repr(C)] #[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)] diff --git a/tests/expectations/tests/union_with_anon_unnamed_union.rs b/tests/expectations/tests/union_with_anon_unnamed_union.rs index 1720b82f..fc465737 100644 --- a/tests/expectations/tests/union_with_anon_unnamed_union.rs +++ b/tests/expectations/tests/union_with_anon_unnamed_union.rs @@ -10,14 +10,12 @@ pub union foo { pub a: ::std::os::raw::c_uint, pub __bindgen_anon_1: foo__bindgen_ty_1, - _bindgen_union_align: u32, } #[repr(C)] #[derive(Copy, Clone)] pub union foo__bindgen_ty_1 { pub b: ::std::os::raw::c_ushort, pub c: ::std::os::raw::c_uchar, - _bindgen_union_align: u16, } #[test] fn bindgen_test_layout_foo__bindgen_ty_1() { diff --git a/tests/expectations/tests/union_with_big_member.rs b/tests/expectations/tests/union_with_big_member.rs index ebfe7656..6425c114 100644 --- a/tests/expectations/tests/union_with_big_member.rs +++ b/tests/expectations/tests/union_with_big_member.rs @@ -10,7 +10,6 @@ pub union WithBigArray { pub a: ::std::os::raw::c_int, pub b: [::std::os::raw::c_int; 33usize], - _bindgen_union_align: [u32; 33usize], } #[test] fn bindgen_test_layout_WithBigArray() { @@ -59,7 +58,6 @@ impl Default for WithBigArray { pub union WithBigArray2 { pub a: ::std::os::raw::c_int, pub b: [::std::os::raw::c_char; 33usize], - _bindgen_union_align: [u32; 9usize], } #[test] fn bindgen_test_layout_WithBigArray2() { @@ -108,7 +106,6 @@ impl Default for WithBigArray2 { pub union WithBigMember { pub a: ::std::os::raw::c_int, pub b: WithBigArray, - _bindgen_union_align: [u32; 33usize], } #[test] fn bindgen_test_layout_WithBigMember() { diff --git a/tests/expectations/tests/union_with_nesting.rs b/tests/expectations/tests/union_with_nesting.rs index c1403d2c..55045f2f 100644 --- a/tests/expectations/tests/union_with_nesting.rs +++ b/tests/expectations/tests/union_with_nesting.rs @@ -10,7 +10,6 @@ pub union foo { pub a: ::std::os::raw::c_uint, pub __bindgen_anon_1: foo__bindgen_ty_1, - _bindgen_union_align: u32, } #[repr(C)] #[derive(Copy, Clone)] @@ -23,7 +22,6 @@ pub struct foo__bindgen_ty_1 { pub union foo__bindgen_ty_1__bindgen_ty_1 { pub b1: ::std::os::raw::c_ushort, pub b2: ::std::os::raw::c_ushort, - _bindgen_union_align: u16, } #[test] fn bindgen_test_layout_foo__bindgen_ty_1__bindgen_ty_1() { @@ -74,7 +72,6 @@ impl Default for foo__bindgen_ty_1__bindgen_ty_1 { pub union foo__bindgen_ty_1__bindgen_ty_2 { pub c1: ::std::os::raw::c_ushort, pub c2: ::std::os::raw::c_ushort, - _bindgen_union_align: u16, } #[test] fn bindgen_test_layout_foo__bindgen_ty_1__bindgen_ty_2() { diff --git a/tests/expectations/tests/use-core.rs b/tests/expectations/tests/use-core.rs index 89c631eb..4cb2851f 100644 --- a/tests/expectations/tests/use-core.rs +++ b/tests/expectations/tests/use-core.rs @@ -52,7 +52,6 @@ impl Default for foo { pub union _bindgen_ty_1 { pub bar: ::std::os::raw::c_int, pub baz: ::std::os::raw::c_long, - _bindgen_union_align: u64, } #[test] fn bindgen_test_layout__bindgen_ty_1() { diff --git a/tests/headers/union-align.h b/tests/headers/union-align.h index 94e60ef1..9557b279 100644 --- a/tests/headers/union-align.h +++ b/tests/headers/union-align.h @@ -3,3 +3,8 @@ union Bar { unsigned char foo; } __attribute__ ((__aligned__ (16))); + + +union Baz { + union Bar bar; +}; |