re PR c++/49216 ([C++0x] ICE on compiling new-expression with braced-init-list for...
authorJason Merrill <jason@redhat.com>
Wed, 29 Jun 2011 22:28:15 +0000 (18:28 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 29 Jun 2011 22:28:15 +0000 (18:28 -0400)
PR c++/49216
* init.c (build_new_1): Pass {} down to build_vec_init.
(build_vec_init): Handle it.

From-SVN: r175674

gcc/cp/ChangeLog
gcc/cp/init.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/initlist-value.C
gcc/testsuite/g++.dg/cpp0x/initlist53.C
gcc/testsuite/g++.old-deja/g++.ext/arrnew2.C

index c5751bd1a4150d4a0acb60a1941a29701caa151e..e95e7c8f082128ec4ef22d473aadcab2c265d154 100644 (file)
@@ -1,5 +1,9 @@
 2011-06-29  Jason Merrill  <jason@redhat.com>
 
+       PR c++/49216
+       * init.c (build_new_1): Pass {} down to build_vec_init.
+       (build_vec_init): Handle it.
+
        DR 1207
        PR c++/49003
        * cp-tree.h (struct saved_scope): Add x_current_class_ptr,
index ac2b733d9bf9e93f66441e888d79260d99dc6360..f80c475f7ac2bbbacc9d56921f826a6d4f2598b2 100644 (file)
@@ -2396,24 +2396,31 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
              && BRACE_ENCLOSED_INITIALIZER_P (VEC_index (tree, *init, 0))
              && CONSTRUCTOR_IS_DIRECT_INIT (VEC_index (tree, *init, 0)))
            {
-             tree arraytype, domain;
              vecinit = VEC_index (tree, *init, 0);
-             if (TREE_CONSTANT (nelts))
-               domain = compute_array_index_type (NULL_TREE, nelts, complain);
+             if (CONSTRUCTOR_NELTS (vecinit) == 0)
+               /* List-value-initialization, leave it alone.  */;
              else
                {
-                 domain = NULL_TREE;
-                 if (CONSTRUCTOR_NELTS (vecinit) > 0)
-                   warning (0, "non-constant array size in new, unable to "
-                            "verify length of initializer-list");
+                 tree arraytype, domain;
+                 if (TREE_CONSTANT (nelts))
+                   domain = compute_array_index_type (NULL_TREE, nelts,
+                                                      complain);
+                 else
+                   {
+                     domain = NULL_TREE;
+                     if (CONSTRUCTOR_NELTS (vecinit) > 0)
+                       warning (0, "non-constant array size in new, unable "
+                                "to verify length of initializer-list");
+                   }
+                 arraytype = build_cplus_array_type (type, domain);
+                 vecinit = digest_init (arraytype, vecinit, complain);
                }
-             arraytype = build_cplus_array_type (type, domain);
-             vecinit = digest_init (arraytype, vecinit, complain);
            }
          else if (*init)
             {
               if (complain & tf_error)
-                permerror (input_location, "ISO C++ forbids initialization in array new");
+                permerror (input_location,
+                          "parenthesized initializer in array new");
               else
                 return error_mark_node;
              vecinit = build_tree_list_vec (*init);
@@ -3090,9 +3097,23 @@ build_vec_init (tree base, tree maxindex, tree init,
       try_block = begin_try_block ();
     }
 
+  /* If the initializer is {}, then all elements are initialized from {}.
+     But for non-classes, that's the same as value-initialization.  */
+  if (init && BRACE_ENCLOSED_INITIALIZER_P (init)
+      && CONSTRUCTOR_NELTS (init) == 0)
+    {
+      if (CLASS_TYPE_P (type))
+       /* Leave init alone.  */;
+      else
+       {
+         init = NULL_TREE;
+         explicit_value_init_p = true;
+       }
+    }
+
   /* Maybe pull out constant value when from_array? */
 
-  if (init != NULL_TREE && TREE_CODE (init) == CONSTRUCTOR)
+  else if (init != NULL_TREE && TREE_CODE (init) == CONSTRUCTOR)
     {
       /* Do non-default initialization of non-trivial arrays resulting from
         brace-enclosed initializers.  */
@@ -3210,7 +3231,7 @@ build_vec_init (tree base, tree maxindex, tree init,
      We do need to keep going if we're copying an array.  */
 
   if (from_array
-      || ((type_build_ctor_call (type) || explicit_value_init_p)
+      || ((type_build_ctor_call (type) || init || explicit_value_init_p)
          && ! (host_integerp (maxindex, 0)
                && (num_initialized_elts
                    == tree_low_cst (maxindex, 0) + 1))))
@@ -3276,8 +3297,16 @@ build_vec_init (tree base, tree maxindex, tree init,
        }
       else
        {
-         gcc_assert (type_build_ctor_call (type));
-         elt_init = build_aggr_init (to, init, 0, complain);
+         gcc_assert (type_build_ctor_call (type) || init);
+         if (CLASS_TYPE_P (type))
+           elt_init = build_aggr_init (to, init, 0, complain);
+         else
+           {
+             if (TREE_CODE (init) == TREE_LIST)
+               init = build_x_compound_expr_from_list (init, ELK_INIT,
+                                                       complain);
+             elt_init = build2 (INIT_EXPR, type, to, init);
+           }
        }
 
       if (elt_init == error_mark_node)
index da5b817620da4a5856650fb7d815f435fe866991..7afaafb1f31c34d9be18ee0a8be678f56b33ea42 100644 (file)
@@ -1,5 +1,10 @@
 2011-06-29  Jason Merrill  <jason@redhat.com>
 
+       PR c++/49216
+       * g++.dg/cpp0x/initlist53.C: Use placement new.
+       * g++.dg/cpp0x/initlist-value.C: Use placement new.
+       * g++.old-deja/g++.ext/arrnew2.C: Remove xfail.
+
        PR c++/49003
        * g++.dg/cpp0x/trailing6.C: New.
        * g++.dg/cpp0x/pr45908.C: No error.
index 25a3373c638bc4436c5c8e6151a9144489484c47..215bb90d4df0ffb3a07e2bd1c9020124fb3b7b4e 100644 (file)
@@ -2,6 +2,9 @@
 // { dg-options -std=c++0x }
 // { dg-do run }
 
+void * operator new (__SIZE_TYPE__, void *p) { return p; }
+void * operator new[] (__SIZE_TYPE__, void *p) { return p; }
+
 // Empty base so A isn't an aggregate
 struct B {};
 struct A: B {
@@ -18,8 +21,14 @@ int main()
 {
   A a{};
   C c;
+  int space = 42;
+  A* ap = new (&space) A{};
+  int space1[1] = { 42 };
+  A* a1p = new (space1) A[1]{};
   if (a.i != 0
       || c.i != 0
+      || ap->i != 0
+      || a1p[0].i != 0
       || A{}.i != 0
       || f({}) != 0)
     return 1;
index 750ebbacb96c1ef2688edd9a38bafb941e5b96bc..22633f909559b98d2399a2f12a96c0ffaa68adbb 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <initializer_list>
 extern "C" void abort();
+void * operator new[] (__SIZE_TYPE__, void *p) { return p; }
 
 bool constructed;
 
@@ -14,7 +15,8 @@ struct A
 
 int main() {
   new A[1]{};
-  int *p = new int[1]{};
+  int space[1] = { 42 };
+  int *p = new (space) int[1]{};
   if (p[0] != 0 || !constructed)
     abort();
 }
index 93d15d08d9046cb80ac27ca0c5dec2ef1b3e10a6..c6a967ccc38516e9a81d3b14bb3de317270afc4f 100644 (file)
@@ -1,4 +1,4 @@
-// { dg-do run { xfail *-*-* } }
+// { dg-do run }
 // { dg-options "-w -fpermissive" }
 
 int *foo = new int[1](42); // { dg-bogus "" }