summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/codegen/impl_debug.rs13
-rw-r--r--src/codegen/impl_partialeq.rs10
-rw-r--r--src/codegen/mod.rs12
-rw-r--r--src/ir/comp.rs21
-rw-r--r--tests/expectations/tests/bitfield_large_overflow.rs1
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;
}
-