class.c (build_vbase_offset_vbtl_entries): Look for non-primary base of which we...
authorNathan Sidwell <nathan@codesourcery.com>
Wed, 25 Jul 2001 08:52:32 +0000 (08:52 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Wed, 25 Jul 2001 08:52:32 +0000 (08:52 +0000)
cp:
* class.c (build_vbase_offset_vbtl_entries): Look for
non-primary base of which we are a sub vtable.
testsuite:
* g++.old-deja/g++.abi/vbase8-5.C: New test.

From-SVN: r44336

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.old-deja/g++.abi/vbase8-5.C [new file with mode: 0644]

index 8e10f731a1a3b92255a663871344efef22bf2a63..08e91be10b26bcc35ad7949cb76f71da1e9fa9e0 100644 (file)
@@ -1,3 +1,8 @@
+2001-07-25  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * class.c (build_vbase_offset_vbtl_entries): Look for
+       non-primary base of which we are a sub vtable.
+
 2001-07-24  Phil Edwards  <pme@sources.redhat.com>
 
        * semantics.c (finish_this_expr):  Remove unused code.
index be04e89e7d3a2f6b3c377e1fe4b4362938047e06..f6729541b49d63c6085b68a3b0b25803bbeb8945 100644 (file)
@@ -7671,6 +7671,7 @@ build_vbase_offset_vtbl_entries (binfo, vid)
 {
   tree vbase;
   tree t;
+  tree non_primary_binfo;
 
   /* If there are no virtual baseclasses, then there is nothing to
      do.  */
@@ -7678,6 +7679,30 @@ build_vbase_offset_vtbl_entries (binfo, vid)
     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));
@@ -7729,7 +7754,8 @@ build_vbase_offset_vtbl_entries (binfo, vid)
         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));
+      delta = size_diffop (BINFO_OFFSET (b), BINFO_OFFSET (non_primary_binfo));
+      
       *vid->last_init 
        = build_tree_list (NULL_TREE,
                           fold (build1 (NOP_EXPR, 
index add7b2c9d4d862a952cb4289ab154f55b8c005a0..bf7fe1c542be38b7777b18180ad8f59ec10ae214 100644 (file)
@@ -1,3 +1,7 @@
+2001-07-25  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * g++.old-deja/g++.abi/vbase8-5.C: New test.
+
 2001-07-24  Jason Merrill  <jason_merrill@redhat.com>
 
        * lib/scanasm.exp (scan-assembler*): Don't take "testcase" argument.
diff --git a/gcc/testsuite/g++.old-deja/g++.abi/vbase8-5.C b/gcc/testsuite/g++.old-deja/g++.abi/vbase8-5.C
new file mode 100644 (file)
index 0000000..ea96e85
--- /dev/null
@@ -0,0 +1,79 @@
+// 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;
+}