diff options
author | Nick Fitzgerald <fitzgen@gmail.com> | 2017-09-05 13:18:55 -0700 |
---|---|---|
committer | Nick Fitzgerald <fitzgen@gmail.com> | 2017-09-06 13:46:58 -0700 |
commit | a3a4635ec96009ebd0394f0797bf231af0142249 (patch) | |
tree | 5423ec5874da90294c26b2eb13a57fcd618bc08e | |
parent | aab7413f54d86e1bb74dca81d13596b526176762 (diff) |
Pessimistically assume that blacklisted types do not implement Default
-rw-r--r-- | src/ir/analysis/derive_default.rs | 75 | ||||
-rw-r--r-- | tests/expectations/tests/derive-default-and-blacklist.rs | 30 | ||||
-rw-r--r-- | tests/headers/derive-default-and-blacklist.hpp | 14 |
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; +}; |