summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbindgen-integration/src/lib.rs2
-rw-r--r--src/codegen/mod.rs113
-rw-r--r--src/codegen/struct_layout.rs39
-rw-r--r--src/ir/comp.rs21
-rw-r--r--tests/expectations/tests/16-byte-alignment.rs3
-rw-r--r--tests/expectations/tests/anon-fields-prefix.rs1
-rw-r--r--tests/expectations/tests/anon_struct_in_union.rs1
-rw-r--r--tests/expectations/tests/anon_union.rs1
-rw-r--r--tests/expectations/tests/class.rs1
-rw-r--r--tests/expectations/tests/class_with_inner_struct.rs3
-rw-r--r--tests/expectations/tests/derive-debug-mangle-name.rs1
-rw-r--r--tests/expectations/tests/derive-partialeq-anonfield.rs5
-rw-r--r--tests/expectations/tests/derive-partialeq-pointer.rs1
-rw-r--r--tests/expectations/tests/derive-partialeq-union.rs1
-rw-r--r--tests/expectations/tests/issue-1285.rs1
-rw-r--r--tests/expectations/tests/issue-1498.rs1
-rw-r--r--tests/expectations/tests/issue-493.rs3
-rw-r--r--tests/expectations/tests/jsval_layout_opaque.rs2
-rw-r--r--tests/expectations/tests/layout_eth_conf.rs1
-rw-r--r--tests/expectations/tests/layout_mbuf.rs6
-rw-r--r--tests/expectations/tests/libclang-9/class.rs1
-rw-r--r--tests/expectations/tests/private_fields.rs1
-rw-r--r--tests/expectations/tests/struct_with_anon_union.rs1
-rw-r--r--tests/expectations/tests/struct_with_anon_unnamed_union.rs1
-rw-r--r--tests/expectations/tests/struct_with_nesting.rs1
-rw-r--r--tests/expectations/tests/typeref.rs1
-rw-r--r--tests/expectations/tests/union-align.rs30
-rw-r--r--tests/expectations/tests/union-in-ns.rs1
-rw-r--r--tests/expectations/tests/union_bitfield.rs4
-rw-r--r--tests/expectations/tests/union_dtor.rs1
-rw-r--r--tests/expectations/tests/union_fields.rs1
-rw-r--r--tests/expectations/tests/union_template.rs3
-rw-r--r--tests/expectations/tests/union_with_anon_struct.rs1
-rw-r--r--tests/expectations/tests/union_with_anon_struct_bitfield.rs1
-rw-r--r--tests/expectations/tests/union_with_anon_union.rs2
-rw-r--r--tests/expectations/tests/union_with_anon_unnamed_struct.rs1
-rw-r--r--tests/expectations/tests/union_with_anon_unnamed_union.rs2
-rw-r--r--tests/expectations/tests/union_with_big_member.rs3
-rw-r--r--tests/expectations/tests/union_with_nesting.rs3
-rw-r--r--tests/expectations/tests/use-core.rs1
-rw-r--r--tests/headers/union-align.h5
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;
+};