cp:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 27 Jul 2001 15:12:49 +0000 (15:12 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 27 Jul 2001 15:12:49 +0000 (15:12 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@44425 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 361b20d..6a02eb6 100644 (file)
@@ -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.
 
index 18ade13..7f2ea60 100644 (file)
@@ -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);
 }
 
index 4753dc2..87d3d79 100644 (file)
@@ -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 (file)
index 0000000..0da6446
--- /dev/null
@@ -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;
+}