diff mbox

C++ PATCH for c++/70259 (-flifetime-dse vs. empty bases)

Message ID 56E9AA2D.8000901@redhat.com
State New
Headers show

Commit Message

Jason Merrill March 16, 2016, 6:47 p.m. UTC
The constructor for an empty class can't do the -flifetime-dse clobber 
because when the class is used as a base it might be assigned the same 
offset as a real base, so the clobber would mess with real data.

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

Comments

Jakub Jelinek March 16, 2016, 10:50 p.m. UTC | #1
On Wed, Mar 16, 2016 at 02:47:09PM -0400, Jason Merrill wrote:
> The constructor for an empty class can't do the -flifetime-dse clobber
> because when the class is used as a base it might be assigned the same
> offset as a real base, so the clobber would mess with real data.

Isn't this needed also for the begin_destructor_body case?
I mean can't it clobber prematurely something that shouldn't be clobbered
yet?

> commit e1a5f038350d1881153d8f65359bd883f7452237
> Author: Jason Merrill <jason@redhat.com>
> Date:   Wed Mar 16 13:46:32 2016 -0400
> 
>     	PR c++/70259
>     	* decl.c (start_preparsed_function): Don't clobber an empty base.

	Jakub
diff mbox

Patch

commit e1a5f038350d1881153d8f65359bd883f7452237
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Mar 16 13:46:32 2016 -0400

    	PR c++/70259
    	* decl.c (start_preparsed_function): Don't clobber an empty base.

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 4ee4ccc..e783163 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -14125,6 +14125,8 @@  start_preparsed_function (tree decl1, tree attrs, int flags)
       && (flag_lifetime_dse > 1)
       && DECL_CONSTRUCTOR_P (decl1)
       && !DECL_CLONED_FUNCTION_P (decl1)
+      /* Clobbering an empty base is harmful if it overlays real data.  */
+      && !is_empty_class (current_class_type)
       /* We can't clobber safely for an implicitly-defined default constructor
 	 because part of the initialization might happen before we enter the
 	 constructor, via AGGR_INIT_ZERO_FIRST (c++/68006).  */
diff --git a/gcc/testsuite/g++.dg/opt/flifetime-dse5.C b/gcc/testsuite/g++.dg/opt/flifetime-dse5.C
new file mode 100644
index 0000000..2c49021
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/flifetime-dse5.C
@@ -0,0 +1,13 @@ 
+// PR c++/70259
+// { dg-options -O2 }
+// { dg-do run }
+
+struct Empty { };
+struct A { A() : a(true) { } bool a; };
+struct B : Empty { B() : Empty() { } };
+struct C : A, B { C() : A(), B() { } };
+int main() {
+  C c;
+  if ( c.a == false )
+    __builtin_abort();
+};