C++ PATCH for c++/34949 (destructor clobbers object)

Submitted by Jason Merrill on April 2, 2013, 9:09 p.m.

Details

Message ID 515B48F9.5080805@redhat.com
State New
Headers show

Commit Message

Jason Merrill April 2, 2013, 9:09 p.m.
Now that Jakub has checked in support for MEM_REF clobbers, we can use 
that to let the front end tell the back end that nothing in an object is 
interesting after the destructor is complete.  This should allow us to 
optimize away assignments to vtable pointers if the destructor doesn't 
use them, and so on.

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

Patch hide | download patch | download mbox

commit dcad5dc2a92840dee3bf153448ed2ccb4ace3b46
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Apr 2 17:05:34 2013 -0400

    	PR c++/34949
    	* decl.c (begin_destructor_body): Clobber the object in a cleanup.

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 40200b0..70137f4 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -13555,6 +13555,14 @@  begin_destructor_body (void)
       initialize_vtbl_ptrs (current_class_ptr);
       finish_compound_stmt (compound_stmt);
 
+      /* Insert a cleanup to let the back end know that the object is dead
+	 when we exit the destructor, either normally or via exception.  */
+      tree clobber = build_constructor (current_class_type, NULL);
+      TREE_THIS_VOLATILE (clobber) = true;
+      tree exprstmt = build2 (MODIFY_EXPR, current_class_type,
+			      current_class_ref, clobber);
+      finish_decl_cleanup (NULL_TREE, exprstmt);
+
       /* And insert cleanups for our bases and members so that they
 	 will be properly destroyed if we throw.  */
       push_base_cleanups ();
diff --git a/gcc/testsuite/g++.dg/opt/vt2.C b/gcc/testsuite/g++.dg/opt/vt2.C
new file mode 100644
index 0000000..a77db38
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/vt2.C
@@ -0,0 +1,24 @@ 
+// PR c++/34949
+// { dg-options "-O3" }
+// { dg-final { scan-assembler-not "mov\[^\n\]*_ZTV" { target i?86-*-* x86_64-*-* } } }
+
+class Foo
+{
+public:
+  virtual ~Foo();
+};
+
+Foo::~Foo()
+{
+}
+
+
+class Bar : public Foo
+{
+public:
+  virtual ~Bar();
+};
+
+Bar::~Bar()
+{
+}