diff options
-rw-r--r-- | src/codegen/impl_debug.rs | 13 | ||||
-rw-r--r-- | src/codegen/impl_partialeq.rs | 10 | ||||
-rw-r--r-- | src/codegen/mod.rs | 12 | ||||
-rw-r--r-- | src/ir/comp.rs | 21 | ||||
-rw-r--r-- | tests/expectations/tests/bitfield_large_overflow.rs | 1 |
5 files changed, 30 insertions, 27 deletions
diff --git a/src/codegen/impl_debug.rs b/src/codegen/impl_debug.rs index 7ef108da..2ebcaf1a 100644 --- a/src/codegen/impl_debug.rs +++ b/src/codegen/impl_debug.rs @@ -95,11 +95,14 @@ impl<'a> ImplDebug<'a> for BitfieldUnit { if i > 0 { format_string.push_str(", "); } - format_string.push_str(&format!("{} : {{:?}}", bu.name())); - let name_ident = ctx.rust_ident_raw(bu.name()); - tokens.push(quote! { - self.#name_ident () - }); + + if let Some(name) = bu.name() { + format_string.push_str(&format!("{} : {{:?}}", name)); + let name_ident = ctx.rust_ident_raw(name); + tokens.push(quote! { + self.#name_ident () + }); + } } Some((format_string, tokens)) diff --git a/src/codegen/impl_partialeq.rs b/src/codegen/impl_partialeq.rs index 7ac96003..65023e25 100644 --- a/src/codegen/impl_partialeq.rs +++ b/src/codegen/impl_partialeq.rs @@ -51,10 +51,12 @@ pub fn gen_partialeq_impl( tokens.push(gen_field(ctx, ty_item, name)); } Field::Bitfields(ref bu) => for bitfield in bu.bitfields() { - let name_ident = ctx.rust_ident_raw(bitfield.name()); - tokens.push(quote! { - self.#name_ident () == other.#name_ident () - }); + if let Some(name) = bitfield.name() { + let name_ident = ctx.rust_ident_raw(name); + tokens.push(quote! { + self.#name_ident () == other.#name_ident () + }); + } }, } } diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 9ccd79c1..5e4bb5fe 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1185,6 +1185,10 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit { let mut ctor_impl = quote! { 0 }; for bf in self.bitfields() { + // Codegen not allowed for anonymous bitfields + if bf.name().is_none() { + continue; + } bf.codegen( ctx, fields_should_be_private, @@ -1198,7 +1202,7 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit { (&unit_field_name, unit_field_int_ty.clone()), ); - let param_name = bitfield_getter_name(ctx, parent, bf.name()); + let param_name = bitfield_getter_name(ctx, parent, bf.name().unwrap()); let bitfield_ty_item = ctx.resolve_item(bf.ty()); let bitfield_ty = bitfield_ty_item.expect_type(); let bitfield_ty = @@ -1307,9 +1311,11 @@ impl<'a> FieldCodegen<'a> for Bitfield { F: Extend<quote::Tokens>, M: Extend<quote::Tokens>, { + // Should never be called with name() as None, as codegen can't be done + // on an anonymous bitfield let prefix = ctx.trait_prefix(); - let getter_name = bitfield_getter_name(ctx, parent, self.name()); - let setter_name = bitfield_setter_name(ctx, parent, self.name()); + let getter_name = bitfield_getter_name(ctx, parent, self.name().unwrap()); + let setter_name = bitfield_setter_name(ctx, parent, self.name().unwrap()); let unit_field_ident = quote::Ident::new(unit_field_name); let bitfield_ty_item = ctx.resolve_item(self.ty()); diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 6a90bcbf..69dc8e58 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -276,7 +276,7 @@ impl DotAttributes for Bitfield { writeln!( out, "<tr><td>{} : {}</td><td>{:?}</td></tr>", - self.name(), + self.name().unwrap_or("(anonymous)"), self.width(), self.ty() ) @@ -298,7 +298,6 @@ impl Bitfield { /// Construct a new bitfield. fn new(offset_into_unit: usize, raw: RawField) -> Bitfield { assert!(raw.bitfield().is_some()); - assert!(raw.name().is_some()); Bitfield { offset_into_unit: offset_into_unit, @@ -332,11 +331,6 @@ impl Bitfield { pub fn width(&self) -> u32 { self.data.bitfield().unwrap() } - - /// Get the name of this bitfield. - pub fn name(&self) -> &str { - self.data.name().unwrap() - } } impl FieldMethods for Bitfield { @@ -581,13 +575,12 @@ fn bitfields_to_allocation_units<E, I>( } } - // Only keep named bitfields around. Unnamed bitfields (with > 0 - // bitsize) are used for padding. Because the `Bitfield` struct stores - // the bit-offset into its allocation unit where its bits begin, we - // don't need any padding bits hereafter. - if bitfield.name().is_some() { - bitfields_in_unit.push(Bitfield::new(offset, bitfield)); - } + // Always keep all bitfields around. While unnamed bitifields are used + // for padding (and usually not needed hereafter), large unnamed + // bitfields over their types size cause weird allocation size behavior from clang. + // Therefore, all bitfields needed to be kept around in order to check for this + // and make the struct opaque in this case + bitfields_in_unit.push(Bitfield::new(offset, bitfield)); max_align = cmp::max(max_align, bitfield_align); diff --git a/tests/expectations/tests/bitfield_large_overflow.rs b/tests/expectations/tests/bitfield_large_overflow.rs index 523570e4..108e3288 100644 --- a/tests/expectations/tests/bitfield_large_overflow.rs +++ b/tests/expectations/tests/bitfield_large_overflow.rs @@ -18,4 +18,3 @@ extern "C" { #[link_name = "a"] pub static mut a: _bindgen_ty_1; } - |