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.
commit dcad5dc2a92840dee3bf153448ed2ccb4ace3b46
Author: Jason Merrill <ja...@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()
+{
+}