diff mbox

[C++] Fix -flifetime-dse bug in dtors too (PR c++/70272)

Message ID 20160317141127.GL3017@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek March 17, 2016, 2:11 p.m. UTC
Hi!

This is a follow-up to the PR70259 that got fixed yesterday.
As the testcase shows, clobbers for empty classes are harmful not just in
the ctors, but also in the dtors, where they can result in stores being
removed before the corresponding dtor has acted upon them.

The ehcleanup1.C part of the patch just reverts the PR34949 adjustment
of the testcase following to addition of clobbers in dtors - it doesn't
actually make the generated code any worse.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk
and 5.x after a while?

2016-03-17  Jakub Jelinek  <jakub@redhat.com>

	PR c++/70272
	* decl.c (begin_destructor_body): Don't insert clobber if
	is_empty_class (current_class_type).

	* g++.dg/opt/flifetime-dse5.C (main): Remove extra semicolon.
	* g++.dg/opt/flifetime-dse6.C: New test.
	* g++.dg/tree-ssa/ehcleanup-1.C: Adjust unreachable count.



	Jakub

Comments

Jason Merrill March 17, 2016, 3:37 p.m. UTC | #1
OK.

Jason
diff mbox

Patch

--- gcc/cp/decl.c.jj	2016-03-17 00:12:07.000000000 +0100
+++ gcc/cp/decl.c	2016-03-17 11:11:04.816068299 +0100
@@ -14354,7 +14354,9 @@  begin_destructor_body (void)
       initialize_vtbl_ptrs (current_class_ptr);
       finish_compound_stmt (compound_stmt);
 
-      if (flag_lifetime_dse)
+      if (flag_lifetime_dse
+	  /* Clobbering an empty base is harmful if it overlays real data.  */
+	  && !is_empty_class (current_class_type))
 	{
 	  /* Insert a cleanup to let the back end know that the object is dead
 	     when we exit the destructor, either normally or via exception.  */
--- gcc/testsuite/g++.dg/opt/flifetime-dse5.C.jj	2016-03-17 00:12:06.000000000 +0100
+++ gcc/testsuite/g++.dg/opt/flifetime-dse5.C	2016-03-17 11:11:28.948734056 +0100
@@ -10,4 +10,4 @@  int main() {
   C c;
   if ( c.a == false )
     __builtin_abort();
-};
+}
--- gcc/testsuite/g++.dg/opt/flifetime-dse6.C.jj	2016-03-17 11:14:41.344069338 +0100
+++ gcc/testsuite/g++.dg/opt/flifetime-dse6.C	2016-03-17 11:14:32.000000000 +0100
@@ -0,0 +1,11 @@ 
+// PR c++/70272
+// { dg-options -O2 }
+// { dg-do run }
+
+struct Empty { };
+struct A { A() : a(true) { } bool a; ~A() { if (!a) __builtin_abort(); } };
+struct B : Empty { B() : Empty() { } ~B() { } };
+struct C : A, B { C() : A(), B() { } ~C() { } };
+int main() {
+  C c;
+}
--- gcc/testsuite/g++.dg/tree-ssa/ehcleanup-1.C.jj	2015-05-29 15:04:33.000000000 +0200
+++ gcc/testsuite/g++.dg/tree-ssa/ehcleanup-1.C	2016-03-17 15:01:01.267373561 +0100
@@ -26,5 +26,5 @@  t (void)
 // { dg-final { scan-tree-dump-times "Empty EH handler" 2 "ehcleanup1" } }
 //
 // And as a result also contained control flow.
-// { dg-final { scan-tree-dump-times "Removing unreachable" 6 "ehcleanup1" } }
+// { dg-final { scan-tree-dump-times "Removing unreachable" 4 "ehcleanup1" } }
 //