re PR c++/3631 (another linking problem with virtual derivation)
authorNathan Sidwell <nathan@codesourcery.com>
Tue, 31 Jul 2001 08:56:09 +0000 (08:56 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Tue, 31 Jul 2001 08:56:09 +0000 (08:56 +0000)
cp:
PR c++/3631
* class.c (update_vtable_entry_for_fn): The fixed adjustment
of a virtual thunk should be from declaring base.
testsuite:
* g++.dg/abi/vthunk1.C: New test.

From-SVN: r44509

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

index b1f52f3c71e0f2ffff02f5cccf0d598c29b700e3..ed4039538b742ccfee72e89d77b7f447c90bfb2b 100644 (file)
@@ -1,3 +1,9 @@
+2001-07-31  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/3631
+       * class.c (update_vtable_entry_for_fn): The fixed adjustment
+       of a virtual thunk should be from declaring base.
+
 2001-07-31  Nathan Sidwell  <nathan@codesourcery.com>
 
        * class.c (dfs_ctor_vtable_bases_queue_p): Always walk into
index f4aae8ef3d5d5e470f11b17fc4e383cff57f1645..42c0371302119ec1773bfd4b24bdf145cc856b5a 100644 (file)
@@ -2563,10 +2563,10 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
      (or one of its primary bases, which are at the same offset).  */
 
   if (virtual_base)
-    /* The `this' pointer needs to be adjusted to the nearest virtual
-       base.  */
+    /* The `this' pointer needs to be adjusted from the declaration to
+       the nearest virtual base.  */
     delta = size_diffop (BINFO_OFFSET (virtual_base),
-                        BINFO_OFFSET (binfo));
+                        BINFO_OFFSET (first_defn));
   else
     {
       /* The `this' pointer needs to be adjusted from pointing to
@@ -2580,7 +2580,7 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
          /* We'll need a thunk.  But if we have a (perhaps formerly)
             primary virtual base, we have a vcall slot for this function,
             so we can use it rather than create a non-virtual thunk.  */
-
+         
          b = get_primary_binfo (first_defn);
          for (; b; b = get_primary_binfo (b))
            {
index 8c8670e42cdc7a3fcaaab03f462e7d73597dd39d..67650f0f84e6f01abf6ff13cf3477955a249d6e4 100644 (file)
@@ -1,3 +1,7 @@
+2001-07-31  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * g++.dg/abi/vthunk1.C: New test.
+
 2001-07-31  Nathan Sidwell  <nathan@codesourcery.com>
 
        * g++.dg/abi/vbase8-22.C: New test.
diff --git a/gcc/testsuite/g++.dg/abi/vthunk1.C b/gcc/testsuite/g++.dg/abi/vthunk1.C
new file mode 100644 (file)
index 0000000..73a0b13
--- /dev/null
@@ -0,0 +1,45 @@
+// { dg-do link }
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 29 Jul 2001 <nathan@codesourcery.com>
+
+// Origin snyder@fnal.gov
+// Bug 3631. We mis-calculated the non-virtual part of a virtual
+// thunk. Leading to a link failure, in this case.
+
+struct A { virtual ~A () {} };
+
+struct B : virtual public A
+{
+  virtual void destroy() {}
+};
+
+class C : virtual public B {};
+class D : virtual public C {};
+class E : public virtual A {};
+
+struct F : virtual public B, virtual public E
+{
+  virtual void destroy() = 0;
+};
+
+struct G : public virtual F
+{
+  virtual void destroy() {}
+};
+
+class H : virtual public C, virtual public F {};
+class I : virtual public D, virtual public H {};
+class J : public virtual G, public virtual H {};
+
+class K : public virtual I, public virtual J
+{
+  public:
+  virtual ~K();
+};
+K::~K() {}
+
+int main ()
+{
+  return 0;
+}