diff --git a/src/ir/analysis/derive.rs b/src/ir/analysis/derive.rs index fa4ce795..dac95586 100644 --- a/src/ir/analysis/derive.rs +++ b/src/ir/analysis/derive.rs @@ -138,8 +138,9 @@ impl<'ctx> CannotDerive<'ctx> { } fn constrain_type(&mut self, item: &Item, ty: &Type) -> CanDerive { - if !self.ctx.allowlisted_items().contains(&item.id()) { - trace!( + if !self.ctx.options().derive_ignore_blocklist && + !self.ctx.allowlisted_items().contains(&item.id()) + { trace!( " cannot derive {} for blocklisted type", self.derive_trait ); diff --git a/src/lib.rs b/src/lib.rs index 0716b42f..804b965d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -549,6 +549,10 @@ impl Builder { output_vector.push("--respect-cxx-access-specs".into()); } + if self.options.derive_ignore_blocklist { + output_vector.push("--derive-ignore-blocklist".into()); + } + // Add clang arguments output_vector.push("--".into()); @@ -1568,6 +1572,12 @@ impl Builder { self.options.respect_cxx_access_specs = doit; self } + + /// Ignore the type blocklist when computing type derive information + pub fn derive_ignore_blocklist(mut self, doit: bool) -> Self { + self.options.derive_ignore_blocklist = doit; + self + } } /// Configuration options for generated bindings. @@ -1859,6 +1869,9 @@ struct BindgenOptions { /// Only make generated bindings `pub` if the items would be publically accessible /// by C++. respect_cxx_access_specs: bool, + + /// Ignore the type blocklist when computing type derive information + derive_ignore_blocklist: bool, } /// TODO(emilio): This is sort of a lie (see the error message that results from @@ -1996,6 +2009,7 @@ impl Default for BindgenOptions { wasm_import_module_name: None, dynamic_library_name: None, respect_cxx_access_specs: false, + derive_ignore_blocklist: false, } } } diff --git a/src/options.rs b/src/options.rs index 2289ad09..f1c26fd8 100644 --- a/src/options.rs +++ b/src/options.rs @@ -503,6 +503,9 @@ where Arg::with_name("respect-cxx-access-specs") .long("respect-cxx-access-specs") .help("Makes generated bindings `pub` only for items if the items are publically accessible in C++."), + Arg::with_name("derive-ignore-blocklist") + .long("derive-ignore-blocklist") + .help("Ignore the type blocklist when computing type derive information"), ]) // .args() .get_matches_from(args); @@ -929,6 +932,10 @@ where builder = builder.respect_cxx_access_specs(true); } + if matches.is_present("derive-ignore-blocklist") { + builder = builder.derive_ignore_blocklist(true); + } + let verbose = matches.is_present("verbose"); Ok((builder, output, verbose)) diff --git a/tests/expectations/tests/issue-1454.rs b/tests/expectations/tests/issue-1454.rs new file mode 100644 index 00000000..e8df8da9 --- /dev/null +++ b/tests/expectations/tests/issue-1454.rs @@ -0,0 +1,81 @@ +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] + +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct rlimit; + +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct my_rlimit_conf { + pub core: rlimit, + pub cpu: rlimit, + pub data: rlimit, + pub fsize: rlimit, +} +#[test] +fn bindgen_test_layout_my_rlimit_conf() { + assert_eq!( + ::std::mem::size_of::(), + 0usize, + concat!("Size of: ", stringify!(my_rlimit_conf)) + ); + assert_eq!( + ::std::mem::align_of::(), + 1usize, + concat!("Alignment of ", stringify!(my_rlimit_conf)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).core as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(my_rlimit_conf), + "::", + stringify!(core) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).cpu as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(my_rlimit_conf), + "::", + stringify!(cpu) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).data as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(my_rlimit_conf), + "::", + stringify!(data) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).fsize as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(my_rlimit_conf), + "::", + stringify!(fsize) + ) + ); +} diff --git a/tests/headers/issue-1454.h b/tests/headers/issue-1454.h new file mode 100644 index 00000000..ce137b92 --- /dev/null +++ b/tests/headers/issue-1454.h @@ -0,0 +1,12 @@ +// bindgen-flags: --no-recursive-allowlist --allowlist-type "my_rlimit_conf" --derive-ignore-blocklist --raw-line "#[repr(C)] #[derive(Debug, Default, Copy, Clone)] pub struct rlimit;" + +struct rlimit {}; + +typedef struct +{ + struct rlimit core; + struct rlimit cpu; + struct rlimit data; + struct rlimit fsize; +} +my_rlimit_conf;