[backport gcc-4.9/trunk r197375 <mikpe@it.uu.se>]

gcc/cp/

2013-04-02  Jason Merrill  <jason@redhat.com>

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

--- gcc-4.8.0/gcc/cp/decl.c.~1~	2013-03-14 14:09:11.000000000 +0100
+++ gcc-4.8.0/gcc/cp/decl.c	2013-05-09 19:05:24.124595540 +0200
@@ -13501,6 +13501,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 ();
--- gcc-4.8.0/gcc/testsuite/g++.dg/opt/vt2.C.~1~	2013-05-09 19:05:24.124595540 +0200
+++ gcc-4.8.0/gcc/testsuite/g++.dg/opt/vt2.C	2013-05-09 19:05:24.124595540 +0200
@@ -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()
+{
+}
