diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 3f5ceaaa43..886f386032 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1612,14 +1612,20 @@ impl CodeGenerator for CompInfo { ); } - if is_union && !self.can_be_rust_union(ctx) { + if is_union { let layout = layout.expect("Unable to get layout information?"); let ty = BlobTyBuilder::new(layout).build(); - let field = StructFieldBuilder::named("bindgen_union_field") - .pub_() - .build_ty(ty); + + let field = if self.can_be_rust_union(ctx) { + StructFieldBuilder::named("_bindgen_union_align") + .build_ty(ty) + } else { + struct_layout.saw_union(layout); - struct_layout.saw_union(layout); + StructFieldBuilder::named("bindgen_union_field") + .pub_() + .build_ty(ty) + }; fields.push(field); } diff --git a/tests/expectations/tests/16-byte-alignment.rs b/tests/expectations/tests/16-byte-alignment.rs index a5781eabfb..72f2a8a900 100644 --- a/tests/expectations/tests/16-byte-alignment.rs +++ b/tests/expectations/tests/16-byte-alignment.rs @@ -16,6 +16,7 @@ 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, Hash)] @@ -108,6 +109,7 @@ 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, Hash)] @@ -188,3 +190,31 @@ impl Clone for rte_ipv6_tuple { impl Default for rte_ipv6_tuple { fn default() -> Self { unsafe { ::std::mem::zeroed() } } } +#[repr(C)] +#[derive(Copy)] +pub union rte_thash_tuple { + pub v4: rte_ipv4_tuple, + pub v6: rte_ipv6_tuple, + _bindgen_union_align: [u8; 48usize], +} +#[test] +fn bindgen_test_layout_rte_thash_tuple() { + assert_eq!(::std::mem::size_of::() , 48usize , concat ! ( + "Size of: " , stringify ! ( rte_thash_tuple ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const rte_thash_tuple ) ) . v4 as * const _ as + usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( rte_thash_tuple ) , + "::" , stringify ! ( v4 ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const rte_thash_tuple ) ) . v6 as * const _ as + usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( rte_thash_tuple ) , + "::" , stringify ! ( v6 ) )); +} +impl Clone for rte_thash_tuple { + fn clone(&self) -> Self { *self } +} +impl Default for rte_thash_tuple { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} diff --git a/tests/expectations/tests/anon_struct_in_union.rs b/tests/expectations/tests/anon_struct_in_union.rs index 5eaf6a80db..02a3d3148c 100644 --- a/tests/expectations/tests/anon_struct_in_union.rs +++ b/tests/expectations/tests/anon_struct_in_union.rs @@ -13,6 +13,7 @@ pub struct s { #[derive(Copy)] pub union s__bindgen_ty_1 { pub field: s__bindgen_ty_1_inner, + _bindgen_union_align: u32, } #[repr(C)] #[derive(Debug, Default, Copy, Hash)] diff --git a/tests/expectations/tests/anon_union.rs b/tests/expectations/tests/anon_union.rs index df24a0cbfb..d1c51f2964 100644 --- a/tests/expectations/tests/anon_union.rs +++ b/tests/expectations/tests/anon_union.rs @@ -30,6 +30,7 @@ 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 { unsafe { ::std::mem::zeroed() } } diff --git a/tests/expectations/tests/class.rs b/tests/expectations/tests/class.rs index bfaf566a02..75d65bca48 100644 --- a/tests/expectations/tests/class.rs +++ b/tests/expectations/tests/class.rs @@ -180,6 +180,7 @@ 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 63911afb67..683f5c092a 100644 --- a/tests/expectations/tests/class_with_inner_struct.rs +++ b/tests/expectations/tests/class_with_inner_struct.rs @@ -41,6 +41,7 @@ impl Clone for A_Segment { #[derive(Copy)] 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() { @@ -64,6 +65,7 @@ impl Default for A__bindgen_ty_1 { #[derive(Copy)] 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() { @@ -169,6 +171,7 @@ 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)] diff --git a/tests/expectations/tests/issue-493.rs b/tests/expectations/tests/issue-493.rs index 781f0758fc..21a08233eb 100644 --- a/tests/expectations/tests/issue-493.rs +++ b/tests/expectations/tests/issue-493.rs @@ -63,6 +63,7 @@ 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 { unsafe { ::std::mem::zeroed() } } diff --git a/tests/expectations/tests/jsval_layout_opaque.rs b/tests/expectations/tests/jsval_layout_opaque.rs index cda3248af5..e052b4d599 100644 --- a/tests/expectations/tests/jsval_layout_opaque.rs +++ b/tests/expectations/tests/jsval_layout_opaque.rs @@ -81,6 +81,7 @@ pub union jsval_layout { pub asPtr: *mut ::std::os::raw::c_void, pub asWord: usize, pub asUIntPtr: usize, + _bindgen_union_align: u64, } #[repr(C)] #[derive(Debug, Copy, Hash)] @@ -199,6 +200,7 @@ 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 d27f6bb16c..962cc52f33 100644 --- a/tests/expectations/tests/layout_eth_conf.rs +++ b/tests/expectations/tests/layout_eth_conf.rs @@ -1529,6 +1529,7 @@ 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 3fb2578643..2cfd88ab46 100644 --- a/tests/expectations/tests/layout_mbuf.rs +++ b/tests/expectations/tests/layout_mbuf.rs @@ -92,6 +92,7 @@ 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() { @@ -124,6 +125,7 @@ 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)] #[derive(Debug, Default, Copy, Hash)] @@ -462,6 +464,7 @@ 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)] @@ -474,6 +477,7 @@ pub struct rte_mbuf__bindgen_ty_3__bindgen_ty_1 { 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, Hash)] @@ -639,6 +643,7 @@ 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() { @@ -671,6 +676,7 @@ 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)] #[derive(Debug, Default, Copy, Hash)] diff --git a/tests/expectations/tests/struct_with_anon_union.rs b/tests/expectations/tests/struct_with_anon_union.rs index eeb367561d..a43ba4eef7 100644 --- a/tests/expectations/tests/struct_with_anon_union.rs +++ b/tests/expectations/tests/struct_with_anon_union.rs @@ -14,6 +14,7 @@ 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 43c3e19cee..af25e4e497 100644 --- a/tests/expectations/tests/struct_with_anon_unnamed_union.rs +++ b/tests/expectations/tests/struct_with_anon_unnamed_union.rs @@ -14,6 +14,7 @@ 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 b85da98915..ef7a936570 100644 --- a/tests/expectations/tests/struct_with_nesting.rs +++ b/tests/expectations/tests/struct_with_nesting.rs @@ -16,6 +16,7 @@ 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, Hash)] diff --git a/tests/expectations/tests/typeref.rs b/tests/expectations/tests/typeref.rs index d886e1fe62..044b8eaaaa 100644 --- a/tests/expectations/tests/typeref.rs +++ b/tests/expectations/tests/typeref.rs @@ -68,6 +68,7 @@ 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 { unsafe { ::std::mem::zeroed() } } diff --git a/tests/expectations/tests/union-in-ns.rs b/tests/expectations/tests/union-in-ns.rs index 0151d43454..cb8779bd3c 100644 --- a/tests/expectations/tests/union-in-ns.rs +++ b/tests/expectations/tests/union-in-ns.rs @@ -12,6 +12,7 @@ pub mod root { #[derive(Copy)] 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_dtor.rs b/tests/expectations/tests/union_dtor.rs index d33f4b079b..a0404ac939 100644 --- a/tests/expectations/tests/union_dtor.rs +++ b/tests/expectations/tests/union_dtor.rs @@ -8,6 +8,7 @@ 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 9d1638fd80..90319ee6bd 100644 --- a/tests/expectations/tests/union_fields.rs +++ b/tests/expectations/tests/union_fields.rs @@ -10,6 +10,7 @@ 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 ae854042b3..f6418fd6b2 100644 --- a/tests/expectations/tests/union_template.rs +++ b/tests/expectations/tests/union_template.rs @@ -14,6 +14,7 @@ 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 { unsafe { ::std::mem::zeroed() } } @@ -22,6 +23,7 @@ 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 { unsafe { ::std::mem::zeroed() } } @@ -33,6 +35,7 @@ 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 { unsafe { ::std::mem::zeroed() } } diff --git a/tests/expectations/tests/union_with_anon_struct.rs b/tests/expectations/tests/union_with_anon_struct.rs index 7a0e864335..e6247bec8a 100644 --- a/tests/expectations/tests/union_with_anon_struct.rs +++ b/tests/expectations/tests/union_with_anon_struct.rs @@ -8,6 +8,7 @@ #[derive(Copy)] pub union foo { pub bar: foo__bindgen_ty_1, + _bindgen_union_align: [u32; 2usize], } #[repr(C)] #[derive(Debug, Default, Copy, Hash)] diff --git a/tests/expectations/tests/union_with_anon_struct_bitfield.rs b/tests/expectations/tests/union_with_anon_struct_bitfield.rs index 03aa892ccd..955548a004 100644 --- a/tests/expectations/tests/union_with_anon_struct_bitfield.rs +++ b/tests/expectations/tests/union_with_anon_struct_bitfield.rs @@ -9,6 +9,7 @@ pub union foo { pub a: ::std::os::raw::c_int, pub __bindgen_anon_1: foo__bindgen_ty_1, + _bindgen_union_align: u32, } #[repr(C)] #[derive(Debug, Default, Copy, Hash)] diff --git a/tests/expectations/tests/union_with_anon_union.rs b/tests/expectations/tests/union_with_anon_union.rs index 9f8b671378..29dbe7dc2e 100644 --- a/tests/expectations/tests/union_with_anon_union.rs +++ b/tests/expectations/tests/union_with_anon_union.rs @@ -8,12 +8,14 @@ #[derive(Copy)] pub union foo { pub bar: foo__bindgen_ty_1, + _bindgen_union_align: u32, } #[repr(C)] #[derive(Copy)] 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 7aef96e936..6d0c381e40 100644 --- a/tests/expectations/tests/union_with_anon_unnamed_struct.rs +++ b/tests/expectations/tests/union_with_anon_unnamed_struct.rs @@ -9,6 +9,7 @@ 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, Hash)] diff --git a/tests/expectations/tests/union_with_anon_unnamed_union.rs b/tests/expectations/tests/union_with_anon_unnamed_union.rs index cf7006ed02..4e0f4a18ba 100644 --- a/tests/expectations/tests/union_with_anon_unnamed_union.rs +++ b/tests/expectations/tests/union_with_anon_unnamed_union.rs @@ -9,12 +9,14 @@ 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)] 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 c500ff7550..9e86f42906 100644 --- a/tests/expectations/tests/union_with_big_member.rs +++ b/tests/expectations/tests/union_with_big_member.rs @@ -9,6 +9,7 @@ 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() { @@ -38,6 +39,7 @@ 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() { @@ -67,6 +69,7 @@ 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 82f22a2440..7ba8afcb41 100644 --- a/tests/expectations/tests/union_with_nesting.rs +++ b/tests/expectations/tests/union_with_nesting.rs @@ -9,6 +9,7 @@ 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)] @@ -21,6 +22,7 @@ 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() { @@ -56,6 +58,7 @@ 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 76f3c35bdb..09c6a86e3d 100644 --- a/tests/expectations/tests/use-core.rs +++ b/tests/expectations/tests/use-core.rs @@ -45,6 +45,7 @@ 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/16-byte-alignment.h b/tests/headers/16-byte-alignment.h index 20cd04f5c7..cca4d285ab 100644 --- a/tests/headers/16-byte-alignment.h +++ b/tests/headers/16-byte-alignment.h @@ -28,10 +28,7 @@ struct rte_ipv6_tuple { }; }; -// TODO(tmfink) uncomment once test passes -#if 0 union rte_thash_tuple { struct rte_ipv4_tuple v4; struct rte_ipv6_tuple v6; } __attribute__((aligned(16))); -#endif