summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ir/comp.rs25
-rw-r--r--tests/expectations/tests/issue-801-opaque-sloppiness.rs9
-rw-r--r--tests/expectations/tests/issue-807-opaque-types-methods-being-generated.rs110
-rw-r--r--tests/headers/issue-807-opaque-types-methods-being-generated.hpp36
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;
+};