Commit bf1cb49e by Jason Merrill Committed by Jason Merrill

re PR c++/43120 (Virtual inheritance with covariant return type confuses GCC)

	PR c++/43120
	* class.c (update_vtable_entry_for_fn): Fix handling of dummy
	virtual bases for covariant thunks.

From-SVN: r161954
parent 02de68e1
2010-07-08 Jason Merrill <jason@redhat.com>
PR c++/43120
* class.c (update_vtable_entry_for_fn): Fix handling of dummy
virtual bases for covariant thunks.
2010-07-08 Manuel López-Ibáñez <manu@gcc.gnu.org> 2010-07-08 Manuel López-Ibáñez <manu@gcc.gnu.org>
* cp-tree.h: Do not include toplev.h. * cp-tree.h: Do not include toplev.h.
2010-07-06 Jason Merrill <jason@redhat.com> 2010-07-06 Jason Merrill <jason@redhat.com>
PR c++/44703 PR c++/44703
......
...@@ -2058,8 +2058,9 @@ get_vcall_index (tree fn, tree type) ...@@ -2058,8 +2058,9 @@ get_vcall_index (tree fn, tree type)
} }
/* Update an entry in the vtable for BINFO, which is in the hierarchy /* Update an entry in the vtable for BINFO, which is in the hierarchy
dominated by T. FN has been overridden in BINFO; VIRTUALS points to the dominated by T. FN is the old function; VIRTUALS points to the
corresponding position in the BINFO_VIRTUALS list. */ corresponding position in the new BINFO_VIRTUALS list. IX is the index
of that entry in the list. */
static void static void
update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
...@@ -2252,9 +2253,11 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, ...@@ -2252,9 +2253,11 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
virtual_base = probe; virtual_base = probe;
if (virtual_base) if (virtual_base)
/* Even if we find a virtual base, the correct delta is /* OK, first_defn got this function from a (possibly lost) primary
between the overrider and the binfo we're building a vtable virtual base, so we're going to use the vcall offset for that
for. */ primary virtual base. But the caller is passing a first_defn*,
not a virtual_base*, so the correct delta is the delta between
first_defn* and itself, i.e. zero. */
goto virtual_covariant; goto virtual_covariant;
} }
...@@ -2272,12 +2275,12 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, ...@@ -2272,12 +2275,12 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
entry in our vtable. Except possibly in a constructor vtable, entry in our vtable. Except possibly in a constructor vtable,
if we happen to get our primary back. In that case, the offset if we happen to get our primary back. In that case, the offset
will be zero, as it will be a primary base. */ will be zero, as it will be a primary base. */
virtual_covariant:
delta = size_zero_node; delta = size_zero_node;
else else
/* The `this' pointer needs to be adjusted from pointing to /* The `this' pointer needs to be adjusted from pointing to
BINFO to pointing at the base where the final overrider BINFO to pointing at the base where the final overrider
appears. */ appears. */
virtual_covariant:
delta = size_diffop_loc (input_location, delta = size_diffop_loc (input_location,
convert (ssizetype, convert (ssizetype,
BINFO_OFFSET (TREE_VALUE (overrider))), BINFO_OFFSET (TREE_VALUE (overrider))),
......
2010-07-08 Jason Merrill <jason@redhat.com>
PR c++/43120
* g++.dg/inherit/covariant17.C: New.
* g++.dg/abi/covariant1.C: Actually test for the bug.
2010-07-08 H.J. Lu <hongjiu.lu@intel.com> 2010-07-08 H.J. Lu <hongjiu.lu@intel.com>
PR rtl-optimization/44838 PR rtl-optimization/44838
......
...@@ -16,6 +16,11 @@ struct c12 : c11 { }; ...@@ -16,6 +16,11 @@ struct c12 : c11 { };
struct c14 : struct c14 :
virtual c12, virtual c12,
virtual c11 { virtual c12* f17(); }; virtual c11 { virtual void f(); c12* f17(); };
// { dg-final { scan-assembler-not "\n_ZTch0_v0_n16_N3c143f17Ev\[: \t\n\]" } } void c14::f() { }
// { dg-final { scan-assembler "_ZTcv0_n12_v0_n16_N3c143f17Ev" { target ilp32 } } }
// { dg-final { scan-assembler-not "_ZTch0_v0_n16_N3c143f17Ev" } }
// { dg-final { scan-assembler "_ZTcv0_n24_v0_n32_N3c143f17Ev" { target lp64 } } }
// { dg-final { scan-assembler-not "_ZTch0_v0_n32_N3c143f17Ev" } }
// PR c++/43120
// { dg-do run }
extern "C" void abort ();
struct A {
int a;
A(int a_) : a(a_) {}
A(const A &other) { }
virtual void dummy() {}
};
struct B {
virtual B *clone() const = 0;
};
struct C : public virtual B {
virtual B *clone() const = 0;
};
struct E* ep;
struct E : public A, public C {
E(int a_) : A(a_) { ep = this; }
virtual E *clone() const {
if (this != ep)
abort();
return new E(*this);
}
};
int main() {
E *a = new E(123);
B *c = a;
B *d = c->clone();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment