cp:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 31 Jul 2001 08:56:09 +0000 (08:56 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 31 Jul 2001 08:56:09 +0000 (08:56 +0000)
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.

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

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

index b1f52f3..ed40395 100644 (file)
@@ -1,5 +1,11 @@
 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
        the shared virtual base, so preserving inheritance graph order.
 
index f4aae8e..42c0371 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 8c8670e..67650f0 100644 (file)
@@ -1,5 +1,9 @@
 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.
 
 2001-07-31  Neil Booth  <neil@cat.daikokuya.demon.co.uk>
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;
+}