Skip to content

Commit 2433965

Browse files
committed
Pessimistically assume that blacklisted types do not implement Default
1 parent 72ed4fc commit 2433965

File tree

3 files changed

+81
-38
lines changed

3 files changed

+81
-38
lines changed

src/ir/analysis/derive_default.rs

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ impl<'ctx, 'gen> CannotDeriveDefault<'ctx, 'gen> {
8787

8888
ConstrainResult::Changed
8989
}
90+
91+
fn is_not_default(&self, id: ItemId) -> bool {
92+
self.cannot_derive_default.contains(&id) ||
93+
!self.ctx.whitelisted_items().contains(&id)
94+
}
9095
}
9196

9297
impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
@@ -153,6 +158,11 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
153158
return ConstrainResult::Same;
154159
}
155160

161+
if !self.ctx.whitelisted_items().contains(&id) {
162+
trace!(" blacklisted items pessimistically cannot derive Default");
163+
return ConstrainResult::Same;
164+
}
165+
156166
let item = self.ctx.resolve_item(id);
157167
let ty = match item.as_type() {
158168
Some(ty) => ty,
@@ -213,7 +223,7 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
213223
}
214224

215225
TypeKind::Array(t, len) => {
216-
if self.cannot_derive_default.contains(&t) {
226+
if self.is_not_default(t) {
217227
trace!(
218228
" arrays of T for which we cannot derive Default \
219229
also cannot derive Default"
@@ -233,7 +243,7 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
233243
TypeKind::ResolvedTypeRef(t) |
234244
TypeKind::TemplateAlias(t, _) |
235245
TypeKind::Alias(t) => {
236-
if self.cannot_derive_default.contains(&t) {
246+
if self.is_not_default(t) {
237247
trace!(
238248
" aliases and type refs to T which cannot derive \
239249
Default also cannot derive Default"
@@ -280,7 +290,7 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
280290
let bases_cannot_derive =
281291
info.base_members().iter().any(|base| {
282292
!self.ctx.whitelisted_items().contains(&base.ty) ||
283-
self.cannot_derive_default.contains(&base.ty)
293+
self.is_not_default(base.ty)
284294
});
285295
if bases_cannot_derive {
286296
trace!(
@@ -296,14 +306,14 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
296306
!self.ctx.whitelisted_items().contains(
297307
&data.ty(),
298308
) ||
299-
self.cannot_derive_default.contains(&data.ty())
309+
self.is_not_default(data.ty())
300310
}
301311
Field::Bitfields(ref bfu) => {
302312
bfu.bitfields().iter().any(|b| {
303313
!self.ctx.whitelisted_items().contains(
304314
&b.ty(),
305315
) ||
306-
self.cannot_derive_default.contains(&b.ty())
316+
self.is_not_default(b.ty())
307317
})
308318
}
309319
});
@@ -319,45 +329,34 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDefault<'ctx, 'gen> {
319329
}
320330

321331
TypeKind::TemplateInstantiation(ref template) => {
322-
if self.ctx.whitelisted_items().contains(
323-
&template.template_definition(),
324-
)
325-
{
326-
let args_cannot_derive =
327-
template.template_arguments().iter().any(|arg| {
328-
self.cannot_derive_default.contains(&arg)
329-
});
330-
if args_cannot_derive {
331-
trace!(
332-
" template args cannot derive Default, so \
333-
insantiation can't either"
334-
);
335-
return self.insert(id);
336-
}
337-
338-
assert!(
339-
!template.template_definition().is_opaque(self.ctx, &()),
340-
"The early ty.is_opaque check should have handled this case"
332+
let args_cannot_derive =
333+
template.template_arguments().iter().any(|arg| {
334+
self.is_not_default(*arg)
335+
});
336+
if args_cannot_derive {
337+
trace!(
338+
" template args cannot derive Default, so \
339+
insantiation can't either"
341340
);
342-
let def_cannot_derive =
343-
self.cannot_derive_default.contains(&template
344-
.template_definition());
345-
if def_cannot_derive {
346-
trace!(
347-
" template definition cannot derive Default, so \
348-
insantiation can't either"
349-
);
350-
return self.insert(id);
351-
}
341+
return self.insert(id);
342+
}
352343

353-
trace!(" template instantiation can derive Default");
354-
ConstrainResult::Same
355-
} else {
344+
assert!(
345+
!template.template_definition().is_opaque(self.ctx, &()),
346+
"The early ty.is_opaque check should have handled this case"
347+
);
348+
let def_cannot_derive =
349+
self.is_not_default(template.template_definition());
350+
if def_cannot_derive {
356351
trace!(
357-
" blacklisted template instantiation cannot derive default"
352+
" template definition cannot derive Default, so \
353+
insantiation can't either"
358354
);
359355
return self.insert(id);
360356
}
357+
358+
trace!(" template instantiation can derive Default");
359+
ConstrainResult::Same
361360
}
362361

363362
TypeKind::Opaque => {
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
4+
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
5+
6+
pub struct BlacklistMe(u8);
7+
8+
/// Because this type contains a blacklisted type, it should not derive
9+
/// Default. Instead, we should emit a `mem::zeroed` implementation.
10+
#[repr(C)]
11+
pub struct ShouldNotDeriveDefault {
12+
pub a: BlacklistMe,
13+
}
14+
#[test]
15+
fn bindgen_test_layout_ShouldNotDeriveDefault() {
16+
assert_eq!(::std::mem::size_of::<ShouldNotDeriveDefault>() , 1usize ,
17+
concat ! ( "Size of: " , stringify ! ( ShouldNotDeriveDefault )
18+
));
19+
assert_eq! (::std::mem::align_of::<ShouldNotDeriveDefault>() , 1usize ,
20+
concat ! (
21+
"Alignment of " , stringify ! ( ShouldNotDeriveDefault ) ));
22+
assert_eq! (unsafe {
23+
& ( * ( 0 as * const ShouldNotDeriveDefault ) ) . a as * const
24+
_ as usize } , 0usize , concat ! (
25+
"Alignment of field: " , stringify ! ( ShouldNotDeriveDefault
26+
) , "::" , stringify ! ( a ) ));
27+
}
28+
impl Default for ShouldNotDeriveDefault {
29+
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
30+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// bindgen-flags: --blacklist-type BlacklistMe --raw-line 'pub struct BlacklistMe(u8);'
2+
3+
// Note that we do not explicitly provide the `--with-derive-default` flag
4+
// above, since it is added by the test runner implicitly.
5+
6+
struct BlacklistMe {};
7+
8+
/**
9+
* Because this type contains a blacklisted type, it should not derive
10+
* Default. Instead, we should emit a `mem::zeroed` implementation.
11+
*/
12+
struct ShouldNotDeriveDefault {
13+
BlacklistMe a;
14+
};

0 commit comments

Comments
 (0)