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
This commit is contained in:
parent
02de68e16b
commit
bf1cb49eb6
@ -1,7 +1,13 @@
|
||||
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>
|
||||
|
||||
* cp-tree.h: Do not include toplev.h.
|
||||
|
||||
|
||||
2010-07-06 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/44703
|
||||
|
@ -2058,8 +2058,9 @@ get_vcall_index (tree fn, tree type)
|
||||
}
|
||||
|
||||
/* 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
|
||||
corresponding position in the BINFO_VIRTUALS list. */
|
||||
dominated by T. FN is the old function; VIRTUALS points to the
|
||||
corresponding position in the new BINFO_VIRTUALS list. IX is the index
|
||||
of that entry in the list. */
|
||||
|
||||
static void
|
||||
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;
|
||||
|
||||
if (virtual_base)
|
||||
/* Even if we find a virtual base, the correct delta is
|
||||
between the overrider and the binfo we're building a vtable
|
||||
for. */
|
||||
/* OK, first_defn got this function from a (possibly lost) primary
|
||||
virtual base, so we're going to use the vcall offset for that
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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,
|
||||
if we happen to get our primary back. In that case, the offset
|
||||
will be zero, as it will be a primary base. */
|
||||
virtual_covariant:
|
||||
delta = size_zero_node;
|
||||
else
|
||||
/* The `this' pointer needs to be adjusted from pointing to
|
||||
BINFO to pointing at the base where the final overrider
|
||||
appears. */
|
||||
virtual_covariant:
|
||||
delta = size_diffop_loc (input_location,
|
||||
convert (ssizetype,
|
||||
BINFO_OFFSET (TREE_VALUE (overrider))),
|
||||
|
@ -1,3 +1,9 @@
|
||||
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>
|
||||
|
||||
PR rtl-optimization/44838
|
||||
|
@ -16,6 +16,11 @@ struct c12 : c11 { };
|
||||
|
||||
struct c14 :
|
||||
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" } }
|
||||
|
40
gcc/testsuite/g++.dg/inherit/covariant17.C
Normal file
40
gcc/testsuite/g++.dg/inherit/covariant17.C
Normal file
@ -0,0 +1,40 @@
|
||||
// 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user