commit 0e5db39431e8f66255a2566f22054878b18baf08
Author: Jason Merrill <jason@redhat.com>
Date: Wed Feb 26 15:40:42 2014 -0500
PR c++/60347
PR lto/53808
* class.c (clone_function_decl): Don't note_vague_linkage_fn.
* init.c (build_vtbl_address): Do it here.
@@ -4584,10 +4584,6 @@ clone_function_decl (tree fn, int update_method_vec_p)
destructor. */
if (DECL_VIRTUAL_P (fn))
{
- if (DECL_DEFAULTED_FN (fn) && flag_devirtualize)
- /* Make sure the destructor gets synthesized so that it can be
- inlined after devirtualization. */
- note_vague_linkage_fn (fn);
clone = build_clone (fn, deleting_dtor_identifier);
if (update_method_vec_p)
add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
@@ -1123,7 +1123,13 @@ build_vtbl_address (tree binfo)
/* Figure out what vtable BINFO's vtable is based on, and mark it as
used. */
vtbl = get_vtbl_decl_for_binfo (binfo_for);
- TREE_USED (vtbl) = 1;
+ if (tree dtor = CLASSTYPE_DESTRUCTORS (DECL_CONTEXT (vtbl)))
+ if (!TREE_USED (vtbl) && DECL_VIRTUAL_P (dtor) && DECL_DEFAULTED_FN (dtor))
+ /* Make sure the destructor gets synthesized so that it can be
+ inlined after devirtualization even if the vtable is never
+ emitted. */
+ note_vague_linkage_fn (dtor);
+ TREE_USED (vtbl) = true;
/* Now compute the address to use when initializing the vptr. */
vtbl = unshare_expr (BINFO_VTABLE (binfo_for));
new file mode 100644
@@ -0,0 +1,12 @@
+// PR c++/60347
+
+struct A;
+
+template <class T>
+struct B
+{
+ T* p;
+ virtual ~B() { p->~T(); }
+};
+
+struct C: B<A> { };