From ba9a991fd34106f884ee46cb3dee1b2169015b13 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Fri, 25 Oct 2002 06:01:55 +0000 Subject: [PATCH] class.c (end_of_base): New method. * class.c (end_of_base): New method. (end_of_class): Use it. Check indirect virtual bases. * g++.dg/abi/empty9.C: New test. From-SVN: r58521 --- gcc/cp/ChangeLog | 3 +++ gcc/cp/class.c | 54 +++++++++++++++++++++++++++------------ gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/g++.dg/abi/empty9.C | 16 ++++++++++++ 4 files changed, 60 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/g++.dg/abi/empty9.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a9dc6c8..e90cb24 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2002-10-24 Mark Mitchell + * class.c (end_of_base): New method. + (end_of_class): Use it. Check indirect virtual bases. + * class.c (check_field_decls): Fix typo. 2002-10-23 Mark Mitchell diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 20be4eb..c4b49b0 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -210,6 +210,7 @@ static bool contains_empty_class_p (tree); static tree dfs_base_derived_from (tree, void *); static bool base_derived_from (tree, tree); static int empty_base_at_nonzero_offset_p (tree, tree, splay_tree); +static tree end_of_base (tree); /* Macros for dfs walking during vtt construction. See dfs_ctor_vtable_bases_queue_p, dfs_build_secondary_vptr_vtt_inits @@ -4699,6 +4700,25 @@ layout_virtual_bases (record_layout_info rli, splay_tree offsets) } /* Returns the offset of the byte just past the end of the base class + BINFO. */ + +static tree +end_of_base (tree binfo) +{ + tree size; + + if (is_empty_class (BINFO_TYPE (binfo))) + /* An empty class has zero CLASSTYPE_SIZE_UNIT, but we need to + allocate some space for it. It cannot have virtual bases, so + TYPE_SIZE_UNIT is fine. */ + size = TYPE_SIZE_UNIT (BINFO_TYPE (binfo)); + else + size = CLASSTYPE_SIZE_UNIT (BINFO_TYPE (binfo)); + + return size_binop (PLUS_EXPR, BINFO_OFFSET (binfo), size); +} + +/* Returns the offset of the byte just past the end of the base class with the highest offset in T. If INCLUDE_VIRTUALS_P is zero, then only non-virtual bases are included. */ @@ -4708,35 +4728,35 @@ end_of_class (t, include_virtuals_p) int include_virtuals_p; { tree result = size_zero_node; + tree binfo; + tree offset; int i; for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); ++i) { - tree base_binfo; - tree offset; - tree size; - - base_binfo = BINFO_BASETYPE (TYPE_BINFO (t), i); + binfo = BINFO_BASETYPE (TYPE_BINFO (t), i); if (!include_virtuals_p - && TREE_VIA_VIRTUAL (base_binfo) - && !BINFO_PRIMARY_P (base_binfo)) + && TREE_VIA_VIRTUAL (binfo) + && !BINFO_PRIMARY_P (binfo)) continue; - if (is_empty_class (BINFO_TYPE (base_binfo))) - /* An empty class has zero CLASSTYPE_SIZE_UNIT, but we need to - allocate some space for it. It cannot have virtual bases, - so TYPE_SIZE_UNIT is fine. */ - size = TYPE_SIZE_UNIT (BINFO_TYPE (base_binfo)); - else - size = CLASSTYPE_SIZE_UNIT (BINFO_TYPE (base_binfo)); - offset = size_binop (PLUS_EXPR, - BINFO_OFFSET (base_binfo), - size); + offset = end_of_base (binfo); if (INT_CST_LT_UNSIGNED (result, offset)) result = offset; } + /* G++ 3.2 did not check indirect virtual bases. */ + if (abi_version_at_least (2) && include_virtuals_p) + for (binfo = CLASSTYPE_VBASECLASSES (t); + binfo; + binfo = TREE_CHAIN (binfo)) + { + offset = end_of_base (TREE_VALUE (binfo)); + if (INT_CST_LT_UNSIGNED (result, offset)) + result = offset; + } + return result; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9823511..6ba32d8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2002-10-24 Mark Mitchell + + * g++.dg/abi/empty9.C: New test. + 2002-10-24 Richard Henderson * g++.dg/inherit/thunk1.C: Enable for ia64. diff --git a/gcc/testsuite/g++.dg/abi/empty9.C b/gcc/testsuite/g++.dg/abi/empty9.C new file mode 100644 index 0000000..757bf6c --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/empty9.C @@ -0,0 +1,16 @@ +// { dg-do run { target i?86-*-* } } +// { dg-options "-w -fabi-version=0" } + +struct E1 {}; +struct E2 : public E1 { + virtual void f (); +}; +struct E3 : virtual public E1 { +}; +struct S : public E2, virtual public E3 { +}; + +int main () { + if (sizeof (S) != 12) + return 1; +} -- 2.7.4