aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/class.c8
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/abi/vthunk1.C45
4 files changed, 59 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b1f52f3..ed40395 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index f4aae8e..42c03713 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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))
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8c8670e..67650f0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..73a0b13
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/vthunk1.C
@@ -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;
+}