From c5dc73c72530c922bab9128ffbc9f006bf7771ef Mon Sep 17 00:00:00 2001 From: Emilio Cobos Álvarez Date: Wed, 23 Mar 2016 03:18:59 +0100 Subject: gen: Don't generate tests for empty structs or classes Since the reported size is 1 byte even though it should be 0. --- src/gen.rs | 13 ++++++++++++- src/parser.rs | 1 + src/types.rs | 2 ++ tests/headers/class_no_members.hpp | 15 +++++++++++++++ 4 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 tests/headers/class_no_members.hpp diff --git a/src/gen.rs b/src/gen.rs index a6ab7118..d4bd277c 100644 --- a/src/gen.rs +++ b/src/gen.rs @@ -1068,6 +1068,7 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: &str, ci: CompInfo) -> Vec })); } + let field_count = fields.len(); let variant_data = if fields.is_empty() { ast::VariantData::Unit(ast::DUMMY_NODE_ID) } else { @@ -1136,7 +1137,17 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: &str, ci: CompInfo) -> Vec } // Template args have incomplete type in general - if ci.args.is_empty() { + // + // XXX if x is a class without members, C++ still will report + // sizeof(x) == 1, since it requires to be adressable. + // + // We maybe should add a dummy byte if it's the case, but... + // That could play wrong with inheritance. + // + // So for now don't generate a test if the struct/class is empty + // or has only empty bases. + if ci.args.is_empty() && field_count > 0 && + (ci.has_nonempty_base || ci.base_members < field_count) { extra.push(mk_test_fn(ctx, name, &layout)); } diff --git a/src/parser.rs b/src/parser.rs index d0d23895..538d5d9c 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -685,6 +685,7 @@ fn visit_composite(cursor: &Cursor, parent: &Cursor, ci.members.push(CompMember::Field(field)); } if let TComp(ref info) = ty { + ci.has_nonempty_base |= !info.borrow().members.is_empty(); ci.typedefs.extend(info.borrow().typedefs.clone().into_iter()); } ci.base_members += 1; diff --git a/src/types.rs b/src/types.rs index 1207d309..166457ec 100644 --- a/src/types.rs +++ b/src/types.rs @@ -283,6 +283,7 @@ pub struct CompInfo { pub ref_template: Option, pub has_vtable: bool, pub has_destructor: bool, + pub has_nonempty_base: bool, pub hide: bool, pub base_members: usize, pub layout: Layout, @@ -318,6 +319,7 @@ impl CompInfo { ref_template: None, has_vtable: false, has_destructor: false, + has_nonempty_base: false, hide: false, base_members: 0, layout: layout, diff --git a/tests/headers/class_no_members.hpp b/tests/headers/class_no_members.hpp new file mode 100644 index 00000000..a1f4d2a4 --- /dev/null +++ b/tests/headers/class_no_members.hpp @@ -0,0 +1,15 @@ + +class whatever { +}; + +class whatever_child: public whatever { +}; + +class whatever_child_with_member: public whatever { +public: + int m_member; +}; + +static_assert(sizeof(whatever) == 1, "Testing!"); +static_assert(sizeof(whatever_child) == 1, "Testing!"); +static_assert(sizeof(whatever_child_with_member) == 4, "Testing!"); -- cgit v1.2.3