diff options
4 files changed, 167 insertions, 13 deletions
diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 6dfc9980..bc2d675d 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -1582,19 +1582,6 @@ impl Trace for CompInfo { tracer.visit_kind(ty, EdgeKind::InnerType); } - // We unconditionally trace `CompInfo`'s template parameters and inner - // types for the the usage analysis. However, we don't want to continue - // tracing anything else, if this type is marked opaque. - if item.is_opaque(context, &()) { - return; - } - - for base in self.base_members() { - tracer.visit_kind(base.ty, EdgeKind::BaseMember); - } - - self.fields.trace(context, tracer, &()); - for &var in self.inner_vars() { tracer.visit_kind(var, EdgeKind::InnerVar); } @@ -1606,5 +1593,17 @@ impl Trace for CompInfo { for &ctor in self.constructors() { tracer.visit_kind(ctor, EdgeKind::Constructor); } + + // Base members and fields are not generated for opaque types (but all + // of the above things are) so stop here. + if item.is_opaque(context, &()) { + return; + } + + for base in self.base_members() { + tracer.visit_kind(base.ty, EdgeKind::BaseMember); + } + + self.fields.trace(context, tracer, &()); } } diff --git a/tests/expectations/tests/issue-801-opaque-sloppiness.rs b/tests/expectations/tests/issue-801-opaque-sloppiness.rs index 29ec7795..7a7afb86 100644 --- a/tests/expectations/tests/issue-801-opaque-sloppiness.rs +++ b/tests/expectations/tests/issue-801-opaque-sloppiness.rs @@ -5,6 +5,11 @@ #[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct A { + _unused: [u8; 0], +} +#[repr(C)] #[derive(Debug, Default, Copy)] pub struct B { pub _bindgen_opaque_blob: u8, @@ -19,6 +24,10 @@ fn bindgen_test_layout_B() { impl Clone for B { fn clone(&self) -> Self { *self } } +extern "C" { + #[link_name = "_ZN1B1aE"] + pub static mut B_a: A; +} #[repr(C)] #[derive(Debug, Default, Copy)] pub struct C { diff --git a/tests/expectations/tests/issue-807-opaque-types-methods-being-generated.rs b/tests/expectations/tests/issue-807-opaque-types-methods-being-generated.rs new file mode 100644 index 00000000..f22a9612 --- /dev/null +++ b/tests/expectations/tests/issue-807-opaque-types-methods-being-generated.rs @@ -0,0 +1,110 @@ +/* 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 Pupper { + pub _address: u8, +} +#[test] +fn bindgen_test_layout_Pupper() { + assert_eq!(::std::mem::size_of::<Pupper>() , 1usize , concat ! ( + "Size of: " , stringify ! ( Pupper ) )); + assert_eq! (::std::mem::align_of::<Pupper>() , 1usize , concat ! ( + "Alignment of " , stringify ! ( Pupper ) )); +} +impl Clone for Pupper { + fn clone(&self) -> Self { *self } +} +#[repr(C)] +#[derive(Debug, Default, Copy)] +pub struct Doggo { + pub _address: u8, +} +#[test] +fn bindgen_test_layout_Doggo() { + assert_eq!(::std::mem::size_of::<Doggo>() , 1usize , concat ! ( + "Size of: " , stringify ! ( Doggo ) )); + assert_eq! (::std::mem::align_of::<Doggo>() , 1usize , concat ! ( + "Alignment of " , stringify ! ( Doggo ) )); +} +impl Clone for Doggo { + fn clone(&self) -> Self { *self } +} +#[repr(C)] +#[derive(Debug, Default, Copy)] +pub struct SuchWow { + pub _address: u8, +} +#[test] +fn bindgen_test_layout_SuchWow() { + assert_eq!(::std::mem::size_of::<SuchWow>() , 1usize , concat ! ( + "Size of: " , stringify ! ( SuchWow ) )); + assert_eq! (::std::mem::align_of::<SuchWow>() , 1usize , concat ! ( + "Alignment of " , stringify ! ( SuchWow ) )); +} +impl Clone for SuchWow { + fn clone(&self) -> Self { *self } +} +#[repr(C)] +#[derive(Debug, Default, Copy)] +pub struct Opaque { + pub _bindgen_opaque_blob: u8, +} +#[test] +fn bindgen_test_layout_Opaque() { + assert_eq!(::std::mem::size_of::<Opaque>() , 1usize , concat ! ( + "Size of: " , stringify ! ( Opaque ) )); + assert_eq! (::std::mem::align_of::<Opaque>() , 1usize , concat ! ( + "Alignment of " , stringify ! ( Opaque ) )); +} +extern "C" { + #[link_name = "_ZN6Opaque17eleven_out_of_tenEv"] + pub fn Opaque_eleven_out_of_ten(this: *mut Opaque) -> SuchWow; +} +extern "C" { + #[link_name = "_ZN6OpaqueC1E6Pupper"] + pub fn Opaque_Opaque(this: *mut Opaque, pup: Pupper); +} +impl Clone for Opaque { + fn clone(&self) -> Self { *self } +} +impl Opaque { + #[inline] + pub unsafe fn eleven_out_of_ten(&mut self) -> SuchWow { + Opaque_eleven_out_of_ten(self) + } + #[inline] + pub unsafe fn new(pup: Pupper) -> Self { + let mut __bindgen_tmp = ::std::mem::uninitialized(); + Opaque_Opaque(&mut __bindgen_tmp, pup); + __bindgen_tmp + } +} +extern "C" { + #[link_name = "_ZN6Opaque11MAJESTIC_AFE"] + pub static mut Opaque_MAJESTIC_AF: Doggo; +} +#[repr(C)] +#[derive(Debug, Default, Copy)] +pub struct Whitelisted { + pub some_member: Opaque, +} +#[test] +fn bindgen_test_layout_Whitelisted() { + assert_eq!(::std::mem::size_of::<Whitelisted>() , 1usize , concat ! ( + "Size of: " , stringify ! ( Whitelisted ) )); + assert_eq! (::std::mem::align_of::<Whitelisted>() , 1usize , concat ! ( + "Alignment of " , stringify ! ( Whitelisted ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const Whitelisted ) ) . some_member as * const + _ as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( Whitelisted ) , "::" , + stringify ! ( some_member ) )); +} +impl Clone for Whitelisted { + fn clone(&self) -> Self { *self } +} diff --git a/tests/headers/issue-807-opaque-types-methods-being-generated.hpp b/tests/headers/issue-807-opaque-types-methods-being-generated.hpp new file mode 100644 index 00000000..bdb7cd53 --- /dev/null +++ b/tests/headers/issue-807-opaque-types-methods-being-generated.hpp @@ -0,0 +1,36 @@ +// bindgen-flags: --whitelist-type Whitelisted --opaque-type Opaque -- -std=c++11 + +// These types are not explicitly whitelisted, but are reachable through the +// opaque type. +class Pupper {}; +class Doggo {}; +class SuchWow {}; + +// These types are not whitelisted, and would be reachable through `Opaque` if +// it were not marked opaque, but since it is, there should be no bindings +// generated for them. +class NoBindingsShouldBeGeneratedForMe1 {}; +class NoBindingsShouldBeGeneratedForMe2 {}; + +// Exercise the different kinds of outgoing edges from an opaque type. +class Opaque + // Base member edge. + : public NoBindingsShouldBeGeneratedForMe1 { + +protected: + // Field edge. + NoBindingsShouldBeGeneratedForMe2 field; + + // Constructor edge. + Opaque(Pupper pup); + + // Inner static variable edge. + static Doggo MAJESTIC_AF; + + // Method edge. + SuchWow eleven_out_of_ten(); +}; + +class Whitelisted { + Opaque some_member; +}; |