diff options
-rw-r--r-- | src/codegen/mod.rs | 24 | ||||
-rw-r--r-- | tests/expectations/tests/issue-801-opaque-sloppiness.rs | 40 | ||||
-rw-r--r-- | tests/headers/issue-801-opaque-sloppiness.hpp | 11 |
3 files changed, 68 insertions, 7 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 50ebebf2..0621ea62 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1571,7 +1571,8 @@ impl CodeGenerator for CompInfo { } // Yeah, sorry about that. - if item.is_opaque(ctx, &()) { + let is_opaque = item.is_opaque(ctx, &()); + if is_opaque { fields.clear(); methods.clear(); @@ -1613,7 +1614,14 @@ impl CodeGenerator for CompInfo { // NOTE: This check is conveniently here to avoid the dummy fields we // may add for unused template parameters. if self.is_unsized(ctx) { - let has_address = layout.map_or(true, |l| l.size != 0); + 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 = BlobTyBuilder::new(Layout::new(1, 1)).build(); let field = StructFieldBuilder::named("_address") @@ -1670,9 +1678,11 @@ impl CodeGenerator for CompInfo { } if used_template_params.is_none() { - for var in self.inner_vars() { - ctx.resolve_item(*var) - .codegen(ctx, result, whitelisted_items, &()); + if !is_opaque { + for var in self.inner_vars() { + ctx.resolve_item(*var) + .codegen(ctx, result, whitelisted_items, &()); + } } if ctx.options().layout_tests { @@ -1707,8 +1717,8 @@ impl CodeGenerator for CompInfo { }) .count() > 1; - let should_skip_field_offset_checks = item.is_opaque(ctx, &()) || - too_many_base_vtables; + let should_skip_field_offset_checks = + is_opaque || too_many_base_vtables; let check_field_offset = if should_skip_field_offset_checks { None diff --git a/tests/expectations/tests/issue-801-opaque-sloppiness.rs b/tests/expectations/tests/issue-801-opaque-sloppiness.rs new file mode 100644 index 00000000..29ec7795 --- /dev/null +++ b/tests/expectations/tests/issue-801-opaque-sloppiness.rs @@ -0,0 +1,40 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] + + +#[repr(C)] +#[derive(Debug, Default, Copy)] +pub struct B { + pub _bindgen_opaque_blob: u8, +} +#[test] +fn bindgen_test_layout_B() { + assert_eq!(::std::mem::size_of::<B>() , 1usize , concat ! ( + "Size of: " , stringify ! ( B ) )); + assert_eq! (::std::mem::align_of::<B>() , 1usize , concat ! ( + "Alignment of " , stringify ! ( B ) )); +} +impl Clone for B { + fn clone(&self) -> Self { *self } +} +#[repr(C)] +#[derive(Debug, Default, Copy)] +pub struct C { + pub b: B, +} +#[test] +fn bindgen_test_layout_C() { + assert_eq!(::std::mem::size_of::<C>() , 1usize , concat ! ( + "Size of: " , stringify ! ( C ) )); + assert_eq! (::std::mem::align_of::<C>() , 1usize , concat ! ( + "Alignment of " , stringify ! ( C ) )); + assert_eq! (unsafe { & ( * ( 0 as * const C ) ) . b as * const _ as usize + } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( C ) , "::" , stringify + ! ( b ) )); +} +impl Clone for C { + fn clone(&self) -> Self { *self } +} diff --git a/tests/headers/issue-801-opaque-sloppiness.hpp b/tests/headers/issue-801-opaque-sloppiness.hpp new file mode 100644 index 00000000..503bba39 --- /dev/null +++ b/tests/headers/issue-801-opaque-sloppiness.hpp @@ -0,0 +1,11 @@ +// bindgen-flags: --opaque-type "B" --whitelist-type "C" + +class A; + +class B { + static A a; +}; + +class C { + B b; +}; |