On 02/25/2014 01:53 PM, Jason Merrill wrote:
The primary bug under discussion in 53808 has been fixed separately, but
it also pointed out that once devirtualization resolves the delete to
use the bar destructor, we ought to be able to inline that destructor.
So if we're devirtualizing, always add a virtual defaulted dtor to the
list of functions to be synthesized.

But this caused bug 60347: turns out that we shouldn't do this unless the vtable (and thus the contents of the vtable) are used.

Tested x86_64-pc-linux-gnu, applying to trunk.


commit 0e5db39431e8f66255a2566f22054878b18baf08
Author: Jason Merrill <ja...@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.

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index f61dc9d..b46391b 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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);
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 194a797..3ae2b5c 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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));
diff --git a/gcc/testsuite/g++.dg/template/dtor9.C b/gcc/testsuite/g++.dg/template/dtor9.C
new file mode 100644
index 0000000..fd71389
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/dtor9.C
@@ -0,0 +1,12 @@
+// PR c++/60347
+
+struct A;
+
+template <class T>
+struct B
+{
+  T* p;
+  virtual ~B() { p->~T(); }
+};
+
+struct C: B<A> { };

Reply via email to