]> gcc.gnu.org Git - gcc.git/commitdiff
re PR c++/32597 (New operation with empty parameter pack does not value-initialize)
authorDouglas Gregor <doug.gregor@gmail.com>
Fri, 31 Aug 2007 19:18:20 +0000 (19:18 +0000)
committerDoug Gregor <dgregor@gcc.gnu.org>
Fri, 31 Aug 2007 19:18:20 +0000 (19:18 +0000)
2007-08-31 Douglas Gregor <doug.gregor@gmail.com>

PR c++/32597
* init.c (build_default_init): Make extern.
* cp-tree.h (build_default_init): Declare here.
* pt.c (tsubst_expr): When the instantiation of the initializer of
a variable results in an empty list, default-initialize the
variable.
(tsubst_copy_and_build): When the instantiation of the initializer
in a new expression results in an empty initializer list,
default-initialize it.

2007-08-31 Douglas Gregor <doug.gregor@gmail.com>

PR c++/32597
* gcc/testsuite/g++.dg/cpp0x/variadic-new2.C: New.
* gcc/testsuite/g++.dg/cpp0x/variadic-new.C: New.

From-SVN: r128000

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/init.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/variadic-new.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/variadic-new2.C [new file with mode: 0644]

index cc5e063d0e878bd254bcf39573ddfd50b0572b7a..558aa067a432a5ef7694c0c475550a8814c8b530 100644 (file)
@@ -1,3 +1,15 @@
+2007-08-31 Douglas Gregor <doug.gregor@gmail.com>
+
+       PR c++/32597
+       * init.c (build_default_init): Make extern.
+       * cp-tree.h (build_default_init): Declare here.
+       * pt.c (tsubst_expr): When the instantiation of the initializer of
+       a variable results in an empty list, default-initialize the
+       variable.
+       (tsubst_copy_and_build): When the instantiation of the initializer
+       in a new expression results in an empty initializer list,
+       default-initialize it.
+
 2007-08-31  Douglas Gregor  <doug.gregor@gmail.com>
 
        * mangle.c (write_type): Change mangling of rvalue reference from
index e07c0bd40b51704175888700a7e166e15e4a03c2..71f401f247c47c6737f814adcf0adaeb1bdf9885 100644 (file)
@@ -4345,6 +4345,7 @@ extern tree build_zero_init                       (tree, tree, bool);
 extern tree build_offset_ref                   (tree, tree, bool);
 extern tree build_new                          (tree, tree, tree, tree, int);
 extern tree build_vec_init                     (tree, tree, tree, bool, int);
+extern tree build_default_init                  (tree, tree);
 extern tree build_delete                       (tree, tree,
                                                 special_function_kind,
                                                 int, int);
index ce33e42a4cb6f802431f22e0b14fc8c98732a477..b46d687a903efdd6599a832b4eccb47941750b4c 100644 (file)
@@ -51,7 +51,6 @@ static tree initializing_context (tree);
 static void expand_cleanup_for_base (tree, tree);
 static tree get_temp_regvar (tree, tree);
 static tree dfs_initialize_vtbl_ptrs (tree, void *);
-static tree build_default_init (tree, tree);
 static tree build_dtor_call (tree, special_function_kind, int);
 static tree build_field_list (tree, tree, int *);
 static tree build_vtbl_address (tree);
@@ -275,7 +274,7 @@ build_zero_init (tree type, tree nelts, bool static_storage_p)
    returns NULL_TREE; the caller is responsible for arranging for the
    constructors to be called.  */
 
-static tree
+tree
 build_default_init (tree type, tree nelts)
 {
   /* [dcl.init]:
index e1eda243c2d86b3fb87b5ba3263bb6e7319cd765..68716f1ad679f353a2d31f2941334119209096aa 100644 (file)
@@ -9885,7 +9885,23 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
                        init = cp_fname_init (name, &TREE_TYPE (decl));
                      }
                    else
-                     init = RECUR (init);
+                     {
+                       tree t = RECUR (init);
+
+                       if (init && !t)
+                         /* If we had an initializer but it
+                            instantiated to nothing,
+                            value-initialize the object.  This will
+                            only occur when the initializer was a
+                            pack expansion where the parameter packs
+                            used in that expansion were of length
+                            zero.  */
+                         init = build_default_init (TREE_TYPE (decl),
+                                                     NULL_TREE);
+                       else
+                         init = t;
+                     }
+
                    finish_decl (decl, init, NULL_TREE);
                  }
              }
@@ -10489,12 +10505,25 @@ tsubst_copy_and_build (tree t,
       return build_x_arrow (op1);
 
     case NEW_EXPR:
-      return build_new
-       (RECUR (TREE_OPERAND (t, 0)),
-        RECUR (TREE_OPERAND (t, 1)),
-        RECUR (TREE_OPERAND (t, 2)),
-        RECUR (TREE_OPERAND (t, 3)),
-        NEW_EXPR_USE_GLOBAL (t));
+      {
+       tree init = RECUR (TREE_OPERAND (t, 3));
+
+       if (TREE_OPERAND (t, 3) && !init)
+         /* If there was an initializer in the the original tree, but
+            it instantiated to an empty list, then we should pass on
+            VOID_ZERO_NODE to tell build_new that it was an empty
+            initializer () rather than no initializer.  This can only
+            happen when the initializer is a pack expansion whose
+            parameter packs are of length zero.  */
+         init = void_zero_node;
+
+       return build_new
+         (RECUR (TREE_OPERAND (t, 0)),
+          RECUR (TREE_OPERAND (t, 1)),
+          RECUR (TREE_OPERAND (t, 2)),
+          init,
+          NEW_EXPR_USE_GLOBAL (t));
+      }
 
     case DELETE_EXPR:
      return delete_sanity
index ea3bd82291478bb88e88d2b59204a9c39ae2983e..95c522f754388e4631e004a7e2f10a0f4c51dcb2 100644 (file)
@@ -1,3 +1,9 @@
+2007-08-31 Douglas Gregor <doug.gregor@gmail.com>
+
+       PR c++/32597
+       * gcc/testsuite/g++.dg/cpp0x/variadic-new2.C: New.
+       * gcc/testsuite/g++.dg/cpp0x/variadic-new.C: New.
+
 2007-08-31  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/33232
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-new.C b/gcc/testsuite/g++.dg/cpp0x/variadic-new.C
new file mode 100644 (file)
index 0000000..8690527
--- /dev/null
@@ -0,0 +1,19 @@
+// { dg-do "run" }
+// { dg-options "-std=c++0x" }
+// Contributed by Peter Dimov
+// PR c++/32597
+#include <assert.h>
+#include <new>
+
+int k = 5;
+
+template< class... Args > void f( Args... args )
+{
+   new( &k ) int( args... );
+}
+
+int main()
+{
+   f();
+   assert( k == 0 );
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-new2.C b/gcc/testsuite/g++.dg/cpp0x/variadic-new2.C
new file mode 100644 (file)
index 0000000..a40f96e
--- /dev/null
@@ -0,0 +1,24 @@
+// { dg-do "run" }
+// { dg-options "-std=c++0x" }
+// PR c++/32597
+#include <assert.h>
+#include <new>
+
+template< class... Args > void f( Args... args )
+{
+  { 
+    int x = 17;
+    (void)x;
+  }
+
+  {
+    int y(args...);
+    assert(y == 0);
+  }
+
+}
+
+int main()
+{
+   f();
+}
This page took 0.102628 seconds and 5 git commands to generate.