Skip to content

analysis: Account for template instantiations of opaque types in the derive debug analysis. #842

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions src/ir/analysis/derive_debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use super::{ConstrainResult, MonotoneFramework};
use std::collections::HashSet;
use std::collections::HashMap;
use ir::context::{BindgenContext, ItemId};
use ir::item::IsOpaque;
use ir::traversal::EdgeKind;
use ir::ty::RUST_DERIVE_IN_ARRAY_LIMIT;
use ir::ty::TypeKind;
Expand Down Expand Up @@ -260,19 +261,23 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDebug<'ctx, 'gen> {
return self.insert(id);
}

let ty_cannot_derive = template.template_definition()
let template_definition = template.template_definition()
.into_resolver()
.through_type_refs()
.through_type_aliases()
.resolve(self.ctx)
.resolve(self.ctx);

let ty_cannot_derive = template_definition
.as_type()
.expect("Instantiations of a non-type?")
.as_comp()
.and_then(|c| {
// For non-type template parameters, we generate an opaque
// blob, and in this case the instantiation has a better
// idea of the layout than the definition does.
if c.has_non_type_template_params() {
// For non-type template parameters, or opaque template
// definitions, we generate an opaque blob, and in this
// case the instantiation has a better idea of the
// layout than the definition does.
if template_definition.is_opaque(self.ctx, &()) ||
c.has_non_type_template_params() {
let opaque = ty.layout(self.ctx)
.or_else(|| {
self.ctx
Expand Down
41 changes: 41 additions & 0 deletions tests/expectations/tests/opaque-template-inst-member.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* automatically generated by rust-bindgen */


#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]


#[repr(C)]
#[derive(Copy, Clone)]
pub struct OpaqueTemplate {
}
impl Default for OpaqueTemplate {
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole point was to ensure that this doesn't derive debug, right?

pub struct ContainsOpaqueTemplate {
pub mBlah: [u32; 11usize],
pub mBaz: ::std::os::raw::c_int,
}
#[test]
fn bindgen_test_layout_ContainsOpaqueTemplate() {
assert_eq!(::std::mem::size_of::<ContainsOpaqueTemplate>() , 48usize ,
concat ! ( "Size of: " , stringify ! ( ContainsOpaqueTemplate )
));
assert_eq! (::std::mem::align_of::<ContainsOpaqueTemplate>() , 4usize ,
concat ! (
"Alignment of " , stringify ! ( ContainsOpaqueTemplate ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ContainsOpaqueTemplate ) ) . mBlah as *
const _ as usize } , 0usize , concat ! (
"Alignment of field: " , stringify ! ( ContainsOpaqueTemplate
) , "::" , stringify ! ( mBlah ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ContainsOpaqueTemplate ) ) . mBaz as *
const _ as usize } , 44usize , concat ! (
"Alignment of field: " , stringify ! ( ContainsOpaqueTemplate
) , "::" , stringify ! ( mBaz ) ));
}
impl Clone for ContainsOpaqueTemplate {
fn clone(&self) -> Self { *self }
}
12 changes: 12 additions & 0 deletions tests/headers/opaque-template-inst-member.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// bindgen-flags: --opaque-type 'OpaqueTemplate'

template<typename T>
class OpaqueTemplate {
T mData;
bool mCannotDebug[40];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think instantiating with T = bool so that alignment is lower, or replace bool mCabnnotDebug[40] with unsigned long long mCannotDebug[40] should do the trick.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or s/40/400/

};

class ContainsOpaqueTemplate {
OpaqueTemplate<int> mBlah;
int mBaz;
};