diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2001-07-27 15:12:49 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2001-07-27 15:12:49 +0000 |
commit | 0ab142b0273f6b8f76386e524702c969b7609afe (patch) | |
tree | 9a1ca077f80ae1edb19df119baaea738f59a70d6 /gcc | |
parent | d60d223b176c68cf2559eed8244977f935b39be9 (diff) | |
download | gcc-0ab142b0273f6b8f76386e524702c969b7609afe.zip gcc-0ab142b0273f6b8f76386e524702c969b7609afe.tar.gz gcc-0ab142b0273f6b8f76386e524702c969b7609afe.tar.bz2 |
class.c (mark_primary_virtual_base): Don't adjust base offsets here.
cp:
* class.c (mark_primary_virtual_base): Don't adjust base
offsets here.
(dfs_unshared_virtual_bases): Adjust them here.
(mark_primary_bases): Explain why we adjust at the end.
testsuite:
* g++.dg/abi/vbase8-21.C: New test.
From-SVN: r44425
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/class.c | 31 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/vbase8-21.C | 75 |
4 files changed, 106 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 361b20d..6a02eb6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,12 @@ 2001-07-27 Nathan Sidwell <nathan@codesourcery.com> + * class.c (mark_primary_virtual_base): Don't adjust base + offsets here. + (dfs_unshared_virtual_bases): Adjust them here. + (mark_primary_bases): Explain why we adjust at the end. + +2001-07-27 Nathan Sidwell <nathan@codesourcery.com> + * class.c (finish_struct_1): When copying the primary base's VFIELD, make sure we find it is at offset zero. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 18ade13..7f2ea60 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1523,7 +1523,6 @@ mark_primary_virtual_base (binfo, base_binfo, type) tree type; { tree shared_binfo = binfo_for_vbase (BINFO_TYPE (base_binfo), type); - tree delta; if (BINFO_PRIMARY_P (shared_binfo)) { @@ -1542,12 +1541,6 @@ mark_primary_virtual_base (binfo, base_binfo, type) if (base_binfo != shared_binfo) force_canonical_binfo (base_binfo, shared_binfo, type, NULL); - delta = size_diffop (BINFO_OFFSET (binfo), BINFO_OFFSET (base_binfo)); - if (!integer_zerop (delta)) - { - propagate_binfo_offsets (base_binfo, delta, type); - BINFO_OFFSET (base_binfo) = BINFO_OFFSET (binfo); - } return base_binfo; } @@ -1580,7 +1573,7 @@ static tree dfs_unshared_virtual_bases (binfo, data) my_friendly_assert (unshared_base != binfo, 20010612); BINFO_LOST_PRIMARY_P (binfo) = BINFO_LOST_PRIMARY_P (unshared_base); if (!BINFO_LOST_PRIMARY_P (binfo)) - BINFO_PRIMARY_BASE_OF (get_primary_binfo (binfo)) = binfo; + BINFO_PRIMARY_BASE_OF (get_primary_binfo (binfo)) = binfo; } if (binfo != TYPE_BINFO (t)) @@ -1588,6 +1581,17 @@ static tree dfs_unshared_virtual_bases (binfo, data) base binfos. That information is bogus, make sure we don't try and use it. */ BINFO_VTABLE (binfo) = NULL_TREE; + + /* If this is a virtual primary base, make sure its offset matches + that which it is primary for. */ + if (BINFO_PRIMARY_P (binfo) && TREE_VIA_VIRTUAL (binfo) && + binfo_for_vbase (BINFO_TYPE (binfo), t) == binfo) + { + tree delta = size_diffop (BINFO_OFFSET (BINFO_PRIMARY_BASE_OF (binfo)), + BINFO_OFFSET (binfo)); + if (!integer_zerop (delta)) + propagate_binfo_offsets (binfo, delta, t); + } BINFO_UNSHARED_MARKED (binfo) = 0; return NULL; @@ -1621,9 +1625,14 @@ mark_primary_bases (type) BINFO_UNSHARED_MARKED (binfo) = 1; } - /* There could remain unshared morally virtual bases which were not visited - in the inheritance graph walk. These bases will have lost their - virtual primary base (should they have one). We must now find them. */ + /* There could remain unshared morally virtual bases which were not + visited in the inheritance graph walk. These bases will have lost + their virtual primary base (should they have one). We must now + find them. Also we must fix up the BINFO_OFFSETs of primary + virtual bases. We could not do that as we went along, as they + were originally copied from the bases we inherited from by + unshare_base_binfos. That may have decided differently about + where a virtual primary base went. */ dfs_walk (TYPE_BINFO (type), dfs_unshared_virtual_bases, NULL, type); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4753dc2..87d3d799 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2001-07-27 Nathan Sidwell <nathan@codesourcery.com> + * g++.dg/abi/vbase8-21.C: New test. + +2001-07-27 Nathan Sidwell <nathan@codesourcery.com> + * g++.dg/abi/vbase8-10.C: New test. 2001-07-27 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE> diff --git a/gcc/testsuite/g++.dg/abi/vbase8-21.C b/gcc/testsuite/g++.dg/abi/vbase8-21.C new file mode 100644 index 0000000..0da6446 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/vbase8-21.C @@ -0,0 +1,75 @@ +// { dg-options -w } +// { dg-do run } + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 26 Jul 2001 <nathan@codesourcery.com> + +// Origin stefan@space.twc.de +// Bug 3145 case 10. Horribly complicated class hierarchy + +class C0 +{}; +class C1 + : virtual public C0 +{}; +class C2 + : virtual public C1 + , virtual public C0 +{}; +class C3 + : virtual public C2 + , virtual public C1 +{}; +class C4 + : virtual public C2 + , public C0 + , public C1 +{}; +class C5 + : virtual public C0 + , public C2 + , virtual public C1 + , virtual public C3 + , virtual public C4 +{}; +class C6 + : virtual public C1 + , virtual public C3 + , public C0 + , public C2 + , virtual public C4 +{}; +class C7 + : virtual public C5 + , public C2 + , public C6 + , virtual public C0 + , public C3 +{}; +class C8 + : virtual public C5 + , public C7 + , virtual public C0 + , virtual public C2 + , virtual public C6 +{}; +class C9 + : virtual public C2 + , virtual public C4 + , public C1 + , virtual public C0 + , public C7 + , public C5 +{}; +main() { + C0 c0; + C1 c1; + C2 c2; + C3 c3; + C4 c4; + C5 c5; + C6 c6; + C7 c7; + C8 c8; + C9 c9; +} |