This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[C++ PATCH], fix some vbase layout


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;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]