re PR c++/68006 ([C++14] Incorrect aggregate initialization from empty initializer...
authorJason Merrill <jason@redhat.com>
Sun, 18 Oct 2015 18:02:10 +0000 (14:02 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 18 Oct 2015 18:02:10 +0000 (14:02 -0400)
PR c++/68006

* decl.c (implicit_default_ctor_p): New.
(start_preparsed_function): Don't clobber on entry to one.

From-SVN: r228949

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

index 6664cf939d4cbccb689eeacc6baaface9cded926..93ffc73fcc822d9a17227995ff6d769cb2b2e00f 100644 (file)
@@ -1,3 +1,9 @@
+2015-10-17  Jason Merrill  <jason@redhat.com>
+
+       PR c++/68006
+       * decl.c (implicit_default_ctor_p): New.
+       (start_preparsed_function): Don't clobber on entry to one.
+
 2015-10-16  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/67926
index 8eb9cc2e27fd8bd60e1d48886913832f8191a90f..8036fb78b432a30689a47cb67c513b32b6ae36e6 100644 (file)
@@ -13630,6 +13630,16 @@ check_function_type (tree decl, tree current_function_parms)
     abstract_virtuals_error (decl, TREE_TYPE (fntype));
 }
 
+/* True iff FN is an implicitly-defined default constructor.  */
+
+static bool
+implicit_default_ctor_p (tree fn)
+{
+  return (DECL_CONSTRUCTOR_P (fn)
+         && !user_provided_p (fn)
+         && sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (fn)));
+}
+
 /* Create the FUNCTION_DECL for a function definition.
    DECLSPECS and DECLARATOR are the parts of the declaration;
    they describe the function's name and the type it returns,
@@ -14036,7 +14046,11 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
   store_parm_decls (current_function_parms);
 
   if (!processing_template_decl
-      && flag_lifetime_dse && DECL_CONSTRUCTOR_P (decl1))
+      && flag_lifetime_dse && DECL_CONSTRUCTOR_P (decl1)
+      /* We can't clobber safely for an implicitly-defined default constructor
+        because part of the initialization might happen before we enter the
+        consructor, via AGGR_INIT_ZERO_FIRST (c++/68006).  */
+      && !implicit_default_ctor_p (decl1))
     {
       /* Insert a clobber to let the back end know that the object storage
         is dead when we enter the constructor.  */
diff --git a/gcc/testsuite/g++.dg/opt/flifetime-dse3.C b/gcc/testsuite/g++.dg/opt/flifetime-dse3.C
new file mode 100644 (file)
index 0000000..7a03acc
--- /dev/null
@@ -0,0 +1,22 @@
+// PR c++/68006
+// { dg-do run { target c++11 } }
+// { dg-options -O2 }
+
+inline void* operator new(__SIZE_TYPE__, void* ptr)
+{
+  return ptr;
+}
+
+struct X { int x; int y; int z = 42; };
+
+void test_bar(void* p)
+{
+  new(p) X{};   // Bad.
+}
+
+int main()
+{
+  int ar[3] = { 1,2,3 };
+  test_bar (ar);
+  return (ar[0] != 0 || ar[1] != 0 || ar[2] != 42);
+}