diff options
-rw-r--r-- | src/ir/context.rs | 6 | ||||
-rw-r--r-- | src/ir/traversal.rs | 12 | ||||
-rw-r--r-- | tests/expectations/tests/issue-1285.rs | 75 | ||||
-rw-r--r-- | tests/headers/issue-1285.h | 8 |
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 |