Skip to content

Avoid recursing infinitely with CRTP while looking for a destructor. #23

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 25, 2016
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
9 changes: 4 additions & 5 deletions src/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,8 +480,7 @@ fn gen_globals(mut ctx: &mut GenCtx,
(Some(l), Some(lg)) if l.size == lg.size => {},
(None, None) => {},
_ => {
// XXX real logger
println!("warning: substituted type for {} does not match its size", g.name());
warn!("warning: substituted type for {} does not match its size", g.name());
}
}
g = substituted;
Expand All @@ -492,7 +491,7 @@ fn gen_globals(mut ctx: &mut GenCtx,

let mut pending_translations = std::mem::replace(&mut ctx.current_module_mut().translations, HashMap::new());
for (name, g) in pending_translations.drain() {
println!("warning: generating definition for not found type: {}", name);
warn!("warning: generating definition for not found type: {}", name);
gen_global(ctx, g, &mut defs);
}

Expand Down Expand Up @@ -983,7 +982,7 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: &str, ci: CompInfo) -> Vec<P<ast::Item>
let is_translatable = cty_is_translatable(&f_ty);
if !is_translatable || f_ty.is_opaque() {
if !is_translatable {
println!("{}::{} not translatable, void: {}", ci.name, f.name, f_ty == TVoid);
warn!("{}::{} not translatable, void: {}", ci.name, f.name, f_ty == TVoid);
}
if let Some(layout) = f_ty.layout() {
fields.push(mk_blob_field(ctx, &f_name, &layout));
Expand Down Expand Up @@ -1326,7 +1325,7 @@ fn enum_size_to_rust_type_name(signed: bool, size: usize) -> &'static str {
(true, 8) => "i64",
(false, 8) => "u64",
_ => {
println!("invalid enum decl: signed: {}, size: {}", signed, size);
warn!("invalid enum decl: signed: {}, size: {}", signed, size);
"i32"
}
}
Expand Down
24 changes: 20 additions & 4 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,9 +440,12 @@ pub struct CompInfo {
pub was_unnamed: bool,
/// Set of static vars declared inside this class.
pub vars: Vec<Global>,
/// Used to detect if we've run in a can_derive_debug cycle while
/// cycling around the template arguments.
/// Used to detect if we've run in a can_derive_debug cycle while cycling
/// around the template arguments.
detect_derive_debug_cycle: Cell<bool>,
/// Used to detect if we've run in a has_destructor cycle while cycling
/// around the template arguments.
detect_has_destructor_cycle: Cell<bool>,
}

static mut UNNAMED_COUNTER: u32 = 0;
Expand Down Expand Up @@ -490,6 +493,7 @@ impl CompInfo {
has_non_type_template_params: false,
was_unnamed: was_unnamed,
detect_derive_debug_cycle: Cell::new(false),
detect_has_destructor_cycle: Cell::new(false),
}
}

Expand Down Expand Up @@ -548,7 +552,15 @@ impl CompInfo {
}

pub fn has_destructor(&self) -> bool {
self.has_destructor || match self.kind {
if self.detect_has_destructor_cycle.get() {
warn!("Cycle detected looking for destructors: {}!", self.name);
// Assume no destructor, since we don't have an explicit one.
return false;
}

self.detect_has_destructor_cycle.set(true);

let has_destructor = self.has_destructor || match self.kind {
CompKind::Union => false,
CompKind::Struct => {
// NB: We can't rely on a type with type parameters
Expand All @@ -570,7 +582,11 @@ impl CompInfo {
_ => false,
})
}
}
};

self.detect_has_destructor_cycle.set(false);

has_destructor
}

pub fn can_derive_copy(&self) -> bool {
Expand Down
29 changes: 29 additions & 0 deletions tests/expectations/crtp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/* automatically generated by rust-bindgen */


#![allow(non_snake_case)]


#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Base<T> {
pub _phantom0: ::std::marker::PhantomData<T>,
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct Derived {
pub _base: Base<Derived>,
}
impl ::std::clone::Clone for Derived {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
#[derive(Debug)]
pub struct BaseWithDestructor<T> {
pub _phantom0: ::std::marker::PhantomData<T>,
}
#[repr(C)]
#[derive(Debug)]
pub struct DerivedFromBaseWithDestructor {
pub _base: BaseWithDestructor<DerivedFromBaseWithDestructor>,
}
14 changes: 14 additions & 0 deletions tests/headers/crtp.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// bindgen-flags: -no-type-renaming

template<class T>
class Base {};

class Derived : public Base<Derived> {};

template<class T>
class BaseWithDestructor {
~BaseWithDestructor();
};

class DerivedFromBaseWithDestructor :
public BaseWithDestructor<DerivedFromBaseWithDestructor> {};