diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2017-07-12 12:08:55 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-07-12 12:08:55 -0700 |
commit | 104bd521010f46c5b38597df253dd7b5c357333f (patch) | |
tree | 4a1b77c746c1af595503fe8227ba5b17d6a8ec7b | |
parent | a00db0446f7296891c2c78bd19cdbff825e1a18f (diff) | |
parent | 8b3dfaaef76eb311503c22b117d67f055d839ffe (diff) |
Auto merge of #808 - fitzgen:issue-807-opaque-types-methods-getting-generated, r=emilio
Fix tracing of opaque types
This makes tracing opaque types' edges match what we codegen for opaque types. Although we still generate constructors, methods, etc for opaque types (just not fields and base members) we were not tracing them.
Fixes #807
This miiight be related to https://bugzilla.mozilla.org/show_bug.cgi?id=1366050 too.
r? @emilio
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; +}; |