mirror of git://gcc.gnu.org/git/gcc.git
re PR c++/60566 (r208573 omits needed thunks)
PR c++/60566 PR c++/58678 * class.c (build_vtbl_initializer): Handle abstract dtors here. * search.c (get_pure_virtuals): Not here. From-SVN: r208845
This commit is contained in:
parent
3a2700f61b
commit
d74db8ff1c
|
|
@ -1,5 +1,10 @@
|
||||||
2014-03-25 Jason Merrill <jason@redhat.com>
|
2014-03-25 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
|
PR c++/60566
|
||||||
|
PR c++/58678
|
||||||
|
* class.c (build_vtbl_initializer): Handle abstract dtors here.
|
||||||
|
* search.c (get_pure_virtuals): Not here.
|
||||||
|
|
||||||
PR c++/60375
|
PR c++/60375
|
||||||
* parser.c (cp_parser_lambda_expression): Don't parse the body of
|
* parser.c (cp_parser_lambda_expression): Don't parse the body of
|
||||||
a lambda in unevaluated context.
|
a lambda in unevaluated context.
|
||||||
|
|
|
||||||
|
|
@ -9017,6 +9017,16 @@ build_vtbl_initializer (tree binfo,
|
||||||
if (!TARGET_VTABLE_USES_DESCRIPTORS)
|
if (!TARGET_VTABLE_USES_DESCRIPTORS)
|
||||||
init = fold_convert (vfunc_ptr_type_node,
|
init = fold_convert (vfunc_ptr_type_node,
|
||||||
build_fold_addr_expr (fn));
|
build_fold_addr_expr (fn));
|
||||||
|
/* Don't refer to a virtual destructor from a constructor
|
||||||
|
vtable or a vtable for an abstract class, since destroying
|
||||||
|
an object under construction is undefined behavior and we
|
||||||
|
don't want it to be considered a candidate for speculative
|
||||||
|
devirtualization. But do create the thunk for ABI
|
||||||
|
compliance. */
|
||||||
|
if (DECL_DESTRUCTOR_P (fn_original)
|
||||||
|
&& (CLASSTYPE_PURE_VIRTUALS (DECL_CONTEXT (fn_original))
|
||||||
|
|| orig_binfo != binfo))
|
||||||
|
init = size_zero_node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2115,22 +2115,6 @@ get_pure_virtuals (tree type)
|
||||||
which it is a primary base will contain vtable entries for the
|
which it is a primary base will contain vtable entries for the
|
||||||
pure virtuals in the base class. */
|
pure virtuals in the base class. */
|
||||||
dfs_walk_once (TYPE_BINFO (type), NULL, dfs_get_pure_virtuals, type);
|
dfs_walk_once (TYPE_BINFO (type), NULL, dfs_get_pure_virtuals, type);
|
||||||
|
|
||||||
/* Treat a virtual destructor in an abstract class as pure even if it
|
|
||||||
isn't declared as pure; there is no way it would be called through the
|
|
||||||
vtable except during construction, which causes undefined behavior. */
|
|
||||||
if (CLASSTYPE_PURE_VIRTUALS (type)
|
|
||||||
&& TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
|
|
||||||
{
|
|
||||||
tree dtor = CLASSTYPE_DESTRUCTORS (type);
|
|
||||||
if (dtor && DECL_VIRTUAL_P (dtor) && !DECL_PURE_VIRTUAL_P (dtor))
|
|
||||||
{
|
|
||||||
tree clone;
|
|
||||||
DECL_PURE_VIRTUAL_P (dtor) = true;
|
|
||||||
FOR_EACH_CLONE (clone, dtor)
|
|
||||||
DECL_PURE_VIRTUAL_P (clone) = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Debug info for C++ classes can get very large; try to avoid
|
/* Debug info for C++ classes can get very large; try to avoid
|
||||||
|
|
|
||||||
|
|
@ -1261,7 +1261,7 @@ get_polymorphic_call_info (tree fndecl,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the function is constructor or destructor, then
|
/* If the function is constructor or destructor, then
|
||||||
the type is possibly in consturction, but we know
|
the type is possibly in construction, but we know
|
||||||
it is not derived type. */
|
it is not derived type. */
|
||||||
if (DECL_CXX_CONSTRUCTOR_P (fndecl)
|
if (DECL_CXX_CONSTRUCTOR_P (fndecl)
|
||||||
|| DECL_CXX_DESTRUCTOR_P (fndecl))
|
|| DECL_CXX_DESTRUCTOR_P (fndecl))
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
// PR c++/60566
|
||||||
|
// We need to emit the construction vtable thunk for ~C even if we aren't
|
||||||
|
// going to use it.
|
||||||
|
|
||||||
|
struct A
|
||||||
|
{
|
||||||
|
virtual void f() = 0;
|
||||||
|
virtual ~A() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct B: virtual A { int i; };
|
||||||
|
struct C: virtual A { int i; ~C(); };
|
||||||
|
|
||||||
|
C::~C() {}
|
||||||
|
|
||||||
|
int main() {}
|
||||||
|
|
||||||
|
// { dg-final { scan-assembler "_ZTv0_n32_N1CD1Ev" } }
|
||||||
|
|
@ -37,5 +37,5 @@ main()
|
||||||
{
|
{
|
||||||
class C c;
|
class C c;
|
||||||
}
|
}
|
||||||
/* { dg-final { scan-ipa-dump "Discovered a virtual call to" "cp" } } */
|
/* { dg-final { scan-ipa-dump "Discovered a virtual call to" "cp" { xfail *-*-* } } } */
|
||||||
/* { dg-final { cleanup-ipa-dump "cp" } } */
|
/* { dg-final { cleanup-ipa-dump "cp" } } */
|
||||||
|
|
|
||||||
|
|
@ -45,5 +45,5 @@ main()
|
||||||
{
|
{
|
||||||
class C c;
|
class C c;
|
||||||
}
|
}
|
||||||
/* { dg-final { scan-ipa-dump "Discovered a virtual call to" "cp" } } */
|
/* { dg-final { scan-ipa-dump "Discovered a virtual call to" "cp" { xfail *-*-* } } } */
|
||||||
/* { dg-final { cleanup-ipa-dump "cp" } } */
|
/* { dg-final { cleanup-ipa-dump "cp" } } */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue