diff options
author | Mark Mitchell <mark@codesourcery.com> | 2002-10-25 06:01:55 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2002-10-25 06:01:55 +0000 |
commit | ba9a991fd34106f884ee46cb3dee1b2169015b13 (patch) | |
tree | abed8f7f410b2a41e121c0be01b3d0ad3011079b | |
parent | ca7c2b85296ad76d29df2519a0977b26a5135aff (diff) | |
download | gcc-ba9a991fd34106f884ee46cb3dee1b2169015b13.zip gcc-ba9a991fd34106f884ee46cb3dee1b2169015b13.tar.gz gcc-ba9a991fd34106f884ee46cb3dee1b2169015b13.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/cp/class.c | 54 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/empty9.C | 16 |
4 files changed, 60 insertions, 17 deletions
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 <mark@codesourcery.com> + * 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 <mark@codesourcery.com> 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 <mark@codesourcery.com> + + * g++.dg/abi/empty9.C: New test. + 2002-10-24 Richard Henderson <rth@redhat.com> * 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; +} |