Skip to content

Commit e6516e3

Browse files
committed
Whitelist inner types of whitelisted types even with no-recursive-whitelisting.
This fixes issue #1285 where inner types were code generated but not properly processed by the derive analysis.
1 parent fb069e9 commit e6516e3

File tree

4 files changed

+95
-6
lines changed

4 files changed

+95
-6
lines changed

src/ir/context.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2291,7 +2291,11 @@ impl BindgenContext {
22912291
if self.options().whitelist_recursively {
22922292
traversal::all_edges
22932293
} else {
2294-
traversal::no_edges
2294+
// Only follow InnerType edges from the whitelisted roots.
2295+
// Such inner types (e.g. anonymous structs/unions) are
2296+
// always emitted by codegen, and they need to be whitelisted
2297+
// to make sure they are processed by e.g. the derive analysis.
2298+
traversal::only_inner_type_edges
22952299
};
22962300

22972301
let whitelisted = WhitelistedItemsTraversal::new(

src/ir/traversal.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -201,11 +201,13 @@ pub fn all_edges(_: &BindgenContext, _: Edge) -> bool {
201201
true
202202
}
203203

204-
/// A `TraversalPredicate` implementation that never follows any edges, and
205-
/// therefore traversals using this predicate will only visit the traversal's
206-
/// roots.
207-
pub fn no_edges(_: &BindgenContext, _: Edge) -> bool {
208-
false
204+
/// A `TraversalPredicate` implementation that only follows
205+
/// `EdgeKind::InnerType` edges, and therefore traversals using this predicate
206+
/// will only visit the traversal's roots and their inner types. This is used
207+
/// in no-recursive-whitelist mode, where inner types such as anonymous
208+
/// structs/unions still need to be processed.
209+
pub fn only_inner_type_edges(_: &BindgenContext, edge: Edge) -> bool {
210+
edge.kind == EdgeKind::InnerType
209211
}
210212

211213
/// A `TraversalPredicate` implementation that only follows edges to items that
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
4+
5+
#[repr(C)]
6+
pub struct foo {
7+
pub bar: foo__bindgen_ty_1,
8+
}
9+
#[repr(C)]
10+
pub union foo__bindgen_ty_1 {
11+
pub a: ::std::os::raw::c_uint,
12+
pub b: ::std::os::raw::c_ushort,
13+
_bindgen_union_align: u32,
14+
}
15+
#[test]
16+
fn bindgen_test_layout_foo__bindgen_ty_1() {
17+
assert_eq!(
18+
::std::mem::size_of::<foo__bindgen_ty_1>(),
19+
4usize,
20+
concat!("Size of: ", stringify!(foo__bindgen_ty_1))
21+
);
22+
assert_eq!(
23+
::std::mem::align_of::<foo__bindgen_ty_1>(),
24+
4usize,
25+
concat!("Alignment of ", stringify!(foo__bindgen_ty_1))
26+
);
27+
assert_eq!(
28+
unsafe { &(*(::std::ptr::null::<foo__bindgen_ty_1>())).a as *const _ as usize },
29+
0usize,
30+
concat!(
31+
"Offset of field: ",
32+
stringify!(foo__bindgen_ty_1),
33+
"::",
34+
stringify!(a)
35+
)
36+
);
37+
assert_eq!(
38+
unsafe { &(*(::std::ptr::null::<foo__bindgen_ty_1>())).b as *const _ as usize },
39+
0usize,
40+
concat!(
41+
"Offset of field: ",
42+
stringify!(foo__bindgen_ty_1),
43+
"::",
44+
stringify!(b)
45+
)
46+
);
47+
}
48+
impl Default for foo__bindgen_ty_1 {
49+
fn default() -> Self {
50+
unsafe { ::std::mem::zeroed() }
51+
}
52+
}
53+
#[test]
54+
fn bindgen_test_layout_foo() {
55+
assert_eq!(
56+
::std::mem::size_of::<foo>(),
57+
4usize,
58+
concat!("Size of: ", stringify!(foo))
59+
);
60+
assert_eq!(
61+
::std::mem::align_of::<foo>(),
62+
4usize,
63+
concat!("Alignment of ", stringify!(foo))
64+
);
65+
assert_eq!(
66+
unsafe { &(*(::std::ptr::null::<foo>())).bar as *const _ as usize },
67+
0usize,
68+
concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar))
69+
);
70+
}
71+
impl Default for foo {
72+
fn default() -> Self {
73+
unsafe { ::std::mem::zeroed() }
74+
}
75+
}

tests/headers/issue-1285.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// bindgen-flags: --with-derive-hash --no-recursive-whitelist --whitelist-type "foo"
2+
3+
struct foo {
4+
union {
5+
unsigned int a;
6+
unsigned short b;
7+
} bar;
8+
};

0 commit comments

Comments
 (0)