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
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.
(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
/* 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))
{
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>
--- /dev/null
+// { 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;
+}