diff mbox

C++ PATCH for lto/53808 (devirtualization of defaulted virtual dtor)

Message ID 530E5D6E.9000408@redhat.com
State New
Headers show

Commit Message

Jason Merrill Feb. 26, 2014, 9:32 p.m. UTC
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.

Comments

Jan Hubicka Feb. 26, 2014, 11:33 p.m. UTC | #1
> 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.

The ipa-devirt type inheritance builder will use any vtable it finds in DECL_BINFO
of types that it knows about. It starts with types of virtual methods and virtual tables
in the symbol table (so we should be sure that TREE_USED is set for vtable that is
associated with virtual method is set when virtual method itself is used).
But it will drop in also all base types of those types and then it will take types
found in OBJ_TYPE_REF & types from variables and type arguments.

Are all those safe?  I tried to describe this in
http://hubicka.blogspot.ca/2014/02/devirtualization-in-c-part-3-building.html

Honza
diff mbox

Patch

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.

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> { };