summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Geller <oliver.geller@rochester.edu>2017-10-04 18:24:58 -0400
committerOliver Geller <oliver.geller@rochester.edu>2017-10-04 19:14:28 -0400
commitaa27283d7ed482613897ea115345c6531fb24db3 (patch)
tree17ddb582ce38ec3235864ba16bb3a2b5e53ae2f2
parent2930a85388db97461b3c4dc678c3ad119c10d2a3 (diff)
Make bitfields larger than type opaque.
-rw-r--r--src/ir/comp.rs21
-rw-r--r--src/ir/context.rs4
-rw-r--r--tests/expectations/tests/bitfield_large_overflow.rs23
-rw-r--r--tests/headers/bitfield_large_overflow.hpp2
4 files changed, 37 insertions, 13 deletions
diff --git a/src/ir/comp.rs b/src/ir/comp.rs
index 69dc8e58..80c2bde1 100644
--- a/src/ir/comp.rs
+++ b/src/ir/comp.rs
@@ -1473,8 +1473,25 @@ impl DotAttributes for CompInfo {
impl IsOpaque for CompInfo {
type Extra = ();
- fn is_opaque(&self, _: &BindgenContext, _: &()) -> bool {
- self.has_non_type_template_params
+ fn is_opaque(&self, ctx: &BindgenContext, _: &()) -> bool {
+ // Early return to avoid extra computation
+ if self.has_non_type_template_params {
+ return true
+ }
+
+ self.fields().iter().any(|f| match *f {
+ Field::DataMember(_) => {
+ false
+ },
+ Field::Bitfields(ref unit) => {
+ unit.bitfields().iter().any(|bf| {
+ let bitfield_layout = ctx.resolve_type(bf.ty())
+ .layout(ctx)
+ .expect("Bitfield without layout? Gah!");
+ bf.width() / 8 > bitfield_layout.size as u32
+ })
+ }
+ })
}
}
diff --git a/src/ir/context.rs b/src/ir/context.rs
index 27a34162..e9a9b504 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -1137,8 +1137,6 @@ impl BindgenContext {
{
self.in_codegen = true;
- self.assert_no_dangling_references();
-
if !self.collected_typerefs() {
self.resolve_typerefs();
self.compute_bitfield_units();
@@ -1147,8 +1145,6 @@ impl BindgenContext {
self.deanonymize_fields();
- // And assert once again, because resolving type refs and processing
- // replacements both mutate the IR graph.
self.assert_no_dangling_references();
// Compute the whitelisted set after processing replacements and
diff --git a/tests/expectations/tests/bitfield_large_overflow.rs b/tests/expectations/tests/bitfield_large_overflow.rs
index 108e3288..fb2029ea 100644
--- a/tests/expectations/tests/bitfield_large_overflow.rs
+++ b/tests/expectations/tests/bitfield_large_overflow.rs
@@ -5,13 +5,26 @@
#[repr(C)]
+#[derive(Debug, Default, Copy)]
pub struct _bindgen_ty_1 {
- pub _bitfield_1: [u8; 128usize],
- pub __bindgen_align: [u64; 0usize],
+ pub _bindgen_opaque_blob: [u64; 10usize],
}
-impl Default for _bindgen_ty_1 {
- fn default() -> Self {
- unsafe { ::std::mem::zeroed() }
+#[test]
+fn bindgen_test_layout__bindgen_ty_1() {
+ assert_eq!(
+ ::std::mem::size_of::<_bindgen_ty_1>(),
+ 80usize,
+ concat!("Size of: ", stringify!(_bindgen_ty_1))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<_bindgen_ty_1>(),
+ 8usize,
+ concat!("Alignment of ", stringify!(_bindgen_ty_1))
+ );
+}
+impl Clone for _bindgen_ty_1 {
+ fn clone(&self) -> Self {
+ *self
}
}
extern "C" {
diff --git a/tests/headers/bitfield_large_overflow.hpp b/tests/headers/bitfield_large_overflow.hpp
index 227829b8..9e040ae3 100644
--- a/tests/headers/bitfield_large_overflow.hpp
+++ b/tests/headers/bitfield_large_overflow.hpp
@@ -1,5 +1,3 @@
-// bindgen-flags: --no-layout-tests
-
struct {
unsigned : 632;
} a;