summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Fitzgerald <fitzgen@gmail.com>2017-09-05 13:18:55 -0700
committerNick Fitzgerald <fitzgen@gmail.com>2017-09-06 13:46:58 -0700
commita3a4635ec96009ebd0394f0797bf231af0142249 (patch)
tree5423ec5874da90294c26b2eb13a57fcd618bc08e
parentaab7413f54d86e1bb74dca81d13596b526176762 (diff)
Pessimistically assume that blacklisted types do not implement Default
-rw-r--r--src/ir/analysis/derive_default.rs75
-rw-r--r--tests/expectations/tests/derive-default-and-blacklist.rs30
-rw-r--r--tests/headers/derive-default-and-blacklist.hpp14
3 files changed, 81 insertions, 38 deletions
diff --git a/src/ir/analysis/derive_default.rs b/src/ir/analysis/derive_default.rs
index 74e05cd6..34c34cfe 100644
--- a/src/ir/analysis/derive_default.rs
+++ b/src/ir/analysis/derive_default.rs
@@ -87,6 +87,11 @@ impl<'ctx, 'gen> CannotDeriveDefault<'ctx, 'gen> {
ConstrainResult::Changed
}
+
+ fn is_not_default(&self, id: ItemId) -> bool {
+ self.cannot_derive_default.contains(&id) ||
+ !self.ctx.whitelisted_items().contains(&id)
+ }
}
impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
@@ -153,6 +158,11 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
return ConstrainResult::Same;
}
+ if !self.ctx.whitelisted_items().contains(&id) {
+ trace!(" blacklisted items pessimistically cannot derive Default");
+ return ConstrainResult::Same;
+ }
+
let item = self.ctx.resolve_item(id);
let ty = match item.as_type() {
Some(ty) => ty,
@@ -213,7 +223,7 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
}
TypeKind::Array(t, len) => {
- if self.cannot_derive_default.contains(&t) {
+ if self.is_not_default(t) {
trace!(
" arrays of T for which we cannot derive Default \
also cannot derive Default"
@@ -233,7 +243,7 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) => {
- if self.cannot_derive_default.contains(&t) {
+ if self.is_not_default(t) {
trace!(
" aliases and type refs to T which cannot derive \
Default also cannot derive Default"
@@ -280,7 +290,7 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
let bases_cannot_derive =
info.base_members().iter().any(|base| {
!self.ctx.whitelisted_items().contains(&base.ty) ||
- self.cannot_derive_default.contains(&base.ty)
+ self.is_not_default(base.ty)
});
if bases_cannot_derive {
trace!(
@@ -296,14 +306,14 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
!self.ctx.whitelisted_items().contains(
&data.ty(),
) ||
- self.cannot_derive_default.contains(&data.ty())
+ self.is_not_default(data.ty())
}
Field::Bitfields(ref bfu) => {
bfu.bitfields().iter().any(|b| {
!self.ctx.whitelisted_items().contains(
&b.ty(),
) ||
- self.cannot_derive_default.contains(&b.ty())
+ self.is_not_default(b.ty())
})
}
});
@@ -319,45 +329,34 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
}
TypeKind::TemplateInstantiation(ref template) => {
- if self.ctx.whitelisted_items().contains(
- &template.template_definition(),
- )
- {
- let args_cannot_derive =
- template.template_arguments().iter().any(|arg| {
- self.cannot_derive_default.contains(&arg)
- });
- if args_cannot_derive {
- trace!(
- " template args cannot derive Default, so \
- insantiation can't either"
- );
- return self.insert(id);
- }
-
- assert!(
- !template.template_definition().is_opaque(self.ctx, &()),
- "The early ty.is_opaque check should have handled this case"
+ let args_cannot_derive =
+ template.template_arguments().iter().any(|arg| {
+ self.is_not_default(*arg)
+ });
+ if args_cannot_derive {
+ trace!(
+ " template args cannot derive Default, so \
+ insantiation can't either"
);
- let def_cannot_derive =
- self.cannot_derive_default.contains(&template
- .template_definition());
- if def_cannot_derive {
- trace!(
- " template definition cannot derive Default, so \
- insantiation can't either"
- );
- return self.insert(id);
- }
+ return self.insert(id);
+ }
- trace!(" template instantiation can derive Default");
- ConstrainResult::Same
- } else {
+ assert!(
+ !template.template_definition().is_opaque(self.ctx, &()),
+ "The early ty.is_opaque check should have handled this case"
+ );
+ let def_cannot_derive =
+ self.is_not_default(template.template_definition());
+ if def_cannot_derive {
trace!(
- " blacklisted template instantiation cannot derive default"
+ " template definition cannot derive Default, so \
+ insantiation can't either"
);
return self.insert(id);
}
+
+ trace!(" template instantiation can derive Default");
+ ConstrainResult::Same
}
TypeKind::Opaque => {
diff --git a/tests/expectations/tests/derive-default-and-blacklist.rs b/tests/expectations/tests/derive-default-and-blacklist.rs
new file mode 100644
index 00000000..e811bd05
--- /dev/null
+++ b/tests/expectations/tests/derive-default-and-blacklist.rs
@@ -0,0 +1,30 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+pub struct BlacklistMe(u8);
+
+/// Because this type contains a blacklisted type, it should not derive
+/// Default. Instead, we should emit a `mem::zeroed` implementation.
+#[repr(C)]
+pub struct ShouldNotDeriveDefault {
+ pub a: BlacklistMe,
+}
+#[test]
+fn bindgen_test_layout_ShouldNotDeriveDefault() {
+ assert_eq!(::std::mem::size_of::<ShouldNotDeriveDefault>() , 1usize ,
+ concat ! ( "Size of: " , stringify ! ( ShouldNotDeriveDefault )
+ ));
+ assert_eq! (::std::mem::align_of::<ShouldNotDeriveDefault>() , 1usize ,
+ concat ! (
+ "Alignment of " , stringify ! ( ShouldNotDeriveDefault ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const ShouldNotDeriveDefault ) ) . a as * const
+ _ as usize } , 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( ShouldNotDeriveDefault
+ ) , "::" , stringify ! ( a ) ));
+}
+impl Default for ShouldNotDeriveDefault {
+ fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+}
diff --git a/tests/headers/derive-default-and-blacklist.hpp b/tests/headers/derive-default-and-blacklist.hpp
new file mode 100644
index 00000000..7a2b7505
--- /dev/null
+++ b/tests/headers/derive-default-and-blacklist.hpp
@@ -0,0 +1,14 @@
+// bindgen-flags: --blacklist-type BlacklistMe --raw-line 'pub struct BlacklistMe(u8);'
+
+// Note that we do not explicitly provide the `--with-derive-default` flag
+// above, since it is added by the test runner implicitly.
+
+struct BlacklistMe {};
+
+/**
+ * Because this type contains a blacklisted type, it should not derive
+ * Default. Instead, we should emit a `mem::zeroed` implementation.
+ */
+struct ShouldNotDeriveDefault {
+ BlacklistMe a;
+};