summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ir/context.rs6
-rw-r--r--src/ir/traversal.rs12
-rw-r--r--tests/expectations/tests/issue-1285.rs75
-rw-r--r--tests/headers/issue-1285.h8
4 files changed, 95 insertions, 6 deletions
diff --git a/src/ir/context.rs b/src/ir/context.rs
index b453378d..8f8b6158 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -2291,7 +2291,11 @@ impl BindgenContext {
if self.options().whitelist_recursively {
traversal::all_edges
} else {
- traversal::no_edges
+ // Only follow InnerType edges from the whitelisted roots.
+ // Such inner types (e.g. anonymous structs/unions) are
+ // always emitted by codegen, and they need to be whitelisted
+ // to make sure they are processed by e.g. the derive analysis.
+ traversal::only_inner_type_edges
};
let whitelisted = WhitelistedItemsTraversal::new(
diff --git a/src/ir/traversal.rs b/src/ir/traversal.rs
index 491a15f8..c37b0b5f 100644
--- a/src/ir/traversal.rs
+++ b/src/ir/traversal.rs
@@ -201,11 +201,13 @@ pub fn all_edges(_: &BindgenContext, _: Edge) -> bool {
true
}
-/// A `TraversalPredicate` implementation that never follows any edges, and
-/// therefore traversals using this predicate will only visit the traversal's
-/// roots.
-pub fn no_edges(_: &BindgenContext, _: Edge) -> bool {
- false
+/// A `TraversalPredicate` implementation that only follows
+/// `EdgeKind::InnerType` edges, and therefore traversals using this predicate
+/// will only visit the traversal's roots and their inner types. This is used
+/// in no-recursive-whitelist mode, where inner types such as anonymous
+/// structs/unions still need to be processed.
+pub fn only_inner_type_edges(_: &BindgenContext, edge: Edge) -> bool {
+ edge.kind == EdgeKind::InnerType
}
/// A `TraversalPredicate` implementation that only follows edges to items that
diff --git a/tests/expectations/tests/issue-1285.rs b/tests/expectations/tests/issue-1285.rs
new file mode 100644
index 00000000..7b2c0ae9
--- /dev/null
+++ b/tests/expectations/tests/issue-1285.rs
@@ -0,0 +1,75 @@
+/* automatically generated by rust-bindgen */
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+#[repr(C)]
+pub struct foo {
+ pub bar: foo__bindgen_ty_1,
+}
+#[repr(C)]
+pub union foo__bindgen_ty_1 {
+ pub a: ::std::os::raw::c_uint,
+ pub b: ::std::os::raw::c_ushort,
+ _bindgen_union_align: u32,
+}
+#[test]
+fn bindgen_test_layout_foo__bindgen_ty_1() {
+ assert_eq!(
+ ::std::mem::size_of::<foo__bindgen_ty_1>(),
+ 4usize,
+ concat!("Size of: ", stringify!(foo__bindgen_ty_1))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<foo__bindgen_ty_1>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(foo__bindgen_ty_1))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<foo__bindgen_ty_1>())).a as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(foo__bindgen_ty_1),
+ "::",
+ stringify!(a)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<foo__bindgen_ty_1>())).b as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(foo__bindgen_ty_1),
+ "::",
+ stringify!(b)
+ )
+ );
+}
+impl Default for foo__bindgen_ty_1 {
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
+}
+#[test]
+fn bindgen_test_layout_foo() {
+ assert_eq!(
+ ::std::mem::size_of::<foo>(),
+ 4usize,
+ concat!("Size of: ", stringify!(foo))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<foo>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(foo))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<foo>())).bar as *const _ as usize },
+ 0usize,
+ concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar))
+ );
+}
+impl Default for foo {
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
+}
diff --git a/tests/headers/issue-1285.h b/tests/headers/issue-1285.h
new file mode 100644
index 00000000..7fb742ec
--- /dev/null
+++ b/tests/headers/issue-1285.h
@@ -0,0 +1,8 @@
+// bindgen-flags: --with-derive-hash --no-recursive-whitelist --whitelist-type "foo"
+
+struct foo {
+ union {
+ unsigned int a;
+ unsigned short b;
+ } bar;
+}; \ No newline at end of file