diff options
author | Bastian Köcher <git@kchr.de> | 2017-08-13 18:10:56 +0200 |
---|---|---|
committer | Bastian Köcher <git@kchr.de> | 2017-08-14 13:19:56 +0200 |
commit | 7603eb1926ba8fcecfcac4d7bb55269703406c53 (patch) | |
tree | 36a4593fffd45c9baab5abfe919637ad66a9e8ba | |
parent | 8c71eed3ad740d736c8d6425c3910cf0e06e8004 (diff) |
Fixes alignment errors with new Rust union type
This fix creates a new private field with the required aligned size. This new
private field ensures that the union has the required size.
27 files changed, 81 insertions, 8 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 3f5ceaaa..886f3860 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 a5781eab..72f2a8a9 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::<rte_thash_tuple>() , 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 5eaf6a80..02a3d314 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 df24a0cb..d1c51f29 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 bfaf566a..75d65bca 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 63911afb..683f5c09 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 781f0758..21a08233 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 cda3248a..e052b4d5 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 d27f6bb1..962cc52f 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 3fb25786..2cfd88ab 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 eeb36756..a43ba4ee 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 43c3e19c..af25e4e4 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 b85da989..ef7a9365 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 d886e1fe..044b8eaa 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 0151d434..cb8779bd 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 d33f4b07..a0404ac9 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 9d1638fd..90319ee6 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 ae854042..f6418fd6 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 7a0e8643..e6247bec 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 03aa892c..955548a0 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 9f8b6713..29dbe7dc 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 7aef96e9..6d0c381e 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 cf7006ed..4e0f4a18 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 c500ff75..9e86f429 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 82f22a24..7ba8afcb 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 76f3c35b..09c6a86e 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 20cd04f5..cca4d285 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 |