From: mmitchel Date: Fri, 25 Oct 2002 06:01:55 +0000 (+0000) Subject: * class.c (end_of_base): New method. X-Git-Tag: upstream/4.9.2~83712 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=29639fe244d6297749686a7949f38ee138b2bf33;p=platform%2Fupstream%2Flinaro-gcc.git * class.c (end_of_base): New method. (end_of_class): Use it. Check indirect virtual bases. * g++.dg/abi/empty9.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@58521 138bc75d-0d04-0410-961f-82ee72b054a4 --- 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; +}