re PR c++/34949 (Dead code in empty destructors.)
authorJason Merrill <jason@redhat.com>
Tue, 2 Apr 2013 21:09:38 +0000 (17:09 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 2 Apr 2013 21:09:38 +0000 (17:09 -0400)
PR c++/34949
* decl.c (begin_destructor_body): Clobber the object in a cleanup.

From-SVN: r197375

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/g++.dg/opt/vt2.C [new file with mode: 0644]

index 7b73e0329318ad5225b24fcaf4e801f04baf1dc5..1b847a9acc0e548ea664b8a5fa50d79d47a813dc 100644 (file)
@@ -1,3 +1,8 @@
+2013-04-02  Jason Merrill  <jason@redhat.com>
+
+       PR c++/34949
+       * decl.c (begin_destructor_body): Clobber the object in a cleanup.
+
 2013-04-02  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * friend.c (do_friend): Use COMPLETE_OR_OPEN_TYPE_P.
index 40200b005f9f3eaaea9291936a636aecf537df05..70137f4a7fc3b79024c598c939089438b6095a7e 100644 (file)
@@ -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 (file)
index 0000000..a77db38
--- /dev/null
@@ -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()
+{
+}