This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH], fix some vbase layout
- To: gcc-patches at gcc dot gnu dot org
- Subject: [C++ PATCH], fix some vbase layout
- From: Nathan Sidwell <nathan at codesourcery dot com>
- Date: Tue, 24 Jul 2001 13:11:58 +0100
- CC: mark at codesourcery dot com
- Organization: Codesourcery LLC
Mark,
this fixes one bug in the vtable layout. Setting the vbase offsets
goes wrong inside the sub-vtable for a lost primary base. There is
code to catch this in build_vcall_offset_vtbl_entries, but not
in build_vbase_offset_vtbl_entries. This copies it there.
We runaround over the class hierarchy 3 times generating
1) vbase offsets
2) vcall offsets
3) virtual function pointers
all of these need to do the same primary-base kind of jig. Once we've
got all this working, it might be sensible to combine these 3 separate
passes into one routine which does all three for a particular base
(returning three separate lists), which are then stitched together.
And there's the rtti generation which has the same stuff, without
the base-ctor case).
there are other bugs remaining.
booted & tested on i686-pc-linux-gnu, ok for mainline?
nathan
--
Dr Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2001-07-24 Nathan Sidwell <nathan@codesourcery.com>
* class.c (build_vbase_offset_vbtl_entries): Look for
non-primary base of which we are a sub vtable.
Index: class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.396
diff -c -3 -p -r1.396 class.c
*** class.c 2001/07/21 09:42:17 1.396
--- class.c 2001/07/24 07:54:34
*************** build_vbase_offset_vtbl_entries (binfo,
*** 7671,7676 ****
--- 7753,7759 ----
{
tree vbase;
tree t;
+ tree non_primary_binfo;
/* If there are no virtual baseclasses, then there is nothing to
do. */
*************** build_vbase_offset_vtbl_entries (binfo,
*** 7678,7684 ****
--- 7761,7791 ----
return;
t = vid->derived;
+
+ /* We might be a primary base class. Go up the inheritance hierarchy
+ until we find the most derived class of which we are a primary base:
+ it is the offset of that which we need to use. */
+ non_primary_binfo = binfo;
+ while (BINFO_INHERITANCE_CHAIN (non_primary_binfo))
+ {
+ tree b;
+ /* If we have reached a virtual base, then it must be a primary
+ base (possibly multi-level) of vid->binfo, or we wouldn't
+ have called build_vcall_and_vbase_vtbl_entries for it. But it
+ might be a lost primary, so just skip down to vid->binfo. */
+ if (TREE_VIA_VIRTUAL (non_primary_binfo))
+ {
+ non_primary_binfo = vid->binfo;
+ break;
+ }
+
+ b = BINFO_INHERITANCE_CHAIN (non_primary_binfo);
+ if (get_primary_binfo (b) != non_primary_binfo)
+ break;
+ non_primary_binfo = b;
+ }
+
/* Go through the virtual bases, adding the offsets. */
for (vbase = TYPE_BINFO (BINFO_TYPE (binfo));
vbase;
*************** build_vbase_offset_vtbl_entries (binfo,
*** 7729,7735 ****
The vbase offsets go in reverse inheritance-graph order, and
we are walking in inheritance graph order so these end up in
the right order. */
! delta = size_diffop (BINFO_OFFSET (b), BINFO_OFFSET (binfo));
*vid->last_init
= build_tree_list (NULL_TREE,
fold (build1 (NOP_EXPR,
--- 7836,7843 ----
The vbase offsets go in reverse inheritance-graph order, and
we are walking in inheritance graph order so these end up in
the right order. */
! delta = size_diffop (BINFO_OFFSET (b), BINFO_OFFSET (non_primary_binfo));
!
*vid->last_init
= build_tree_list (NULL_TREE,
fold (build1 (NOP_EXPR,
// Special g++ Options: -w
// Copyright (C) 2001 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 24 Jul 2001 <nathan@codesourcery.com>
// Origin stefan@space.twc.de
// Bug 3145 case 5. Horribly complicated class hierarchy
class C0
{};
class C1
: virtual public C0
{};
class C2
: public C0
, virtual public C1
{};
class C3
: virtual public C0
, virtual public C2
, public C1
{};
class C4
: virtual public C0
, virtual public C2
, virtual public C1
, virtual public C3
{};
class C5
: virtual public C3
, virtual public C2
, virtual public C0
, public C4
, virtual public C1
{};
class C6
: public C0
, virtual public C3
, public C4
, virtual public C5
, public C1
{};
class C7
: virtual public C3
, public C5
, public C2
, virtual public C4
, public C6
, public C0
{};
class C8
: virtual public C2
, public C5
, public C7
, public C1
, public C0
, public C4
, public C3
{};
class C9
: public C3
, public C2
, virtual public C6
, public C8
, virtual 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;
}