]> gcc.gnu.org Git - gcc.git/commitdiff
re PR c++/40689 ([C++0x]: error with initializer list in N2672)
authorJason Merrill <jason@redhat.com>
Sun, 12 Jul 2009 19:19:03 +0000 (15:19 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 12 Jul 2009 19:19:03 +0000 (15:19 -0400)
PR c++/40689
* init.c (build_new_1): Handle initializer list as array initializer.
(build_vec_init): Likewise.
* typeck.c (cp_build_modify_expr): Likewise.
* typeck2.c (process_init_constructor_array): Error rather than abort
if too many initializers.

From-SVN: r149533

gcc/cp/ChangeLog
gcc/cp/init.c
gcc/cp/typeck.c
gcc/cp/typeck2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/initlist20.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/initlist21.C [new file with mode: 0644]

index c29e32da3ba61a5171e756e6ba286d190ffac9dd..cff424f55dcc5aa220659ab754b29fb805631edd 100644 (file)
@@ -1,3 +1,12 @@
+2009-07-12  Jason Merrill  <jason@redhat.com>
+
+       PR c++/40689
+       * init.c (build_new_1): Handle initializer list as array initializer.
+       (build_vec_init): Likewise.
+       * typeck.c (cp_build_modify_expr): Likewise.
+       * typeck2.c (process_init_constructor_array): Error rather than abort
+       if too many initializers.
+
 2009-07-10  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/40502
index 68ffe3a3dd02be912bcf4d13485f31c8de47818d..19b24895e55bb3b46d9ac87e2ff1cd4234806aeb 100644 (file)
@@ -1773,6 +1773,7 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
   /* The type of the new-expression.  (This type is always a pointer
      type.)  */
   tree pointer_type;
+  tree non_const_pointer_type;
   tree outer_nelts = NULL_TREE;
   tree alloc_call, alloc_expr;
   /* The address returned by the call to "operator new".  This node is
@@ -2076,9 +2077,15 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
     }
 
   /* Now use a pointer to the type we've actually allocated.  */
-  data_addr = fold_convert (pointer_type, data_addr);
+
+  /* But we want to operate on a non-const version to start with,
+     since we'll be modifying the elements.  */
+  non_const_pointer_type = build_pointer_type
+    (cp_build_qualified_type (type, TYPE_QUALS (type) & ~TYPE_QUAL_CONST));
+
+  data_addr = fold_convert (non_const_pointer_type, data_addr);
   /* Any further uses of alloc_node will want this type, too.  */
-  alloc_node = fold_convert (pointer_type, alloc_node);
+  alloc_node = fold_convert (non_const_pointer_type, alloc_node);
 
   /* Now initialize the allocated object.  Note that we preevaluate the
      initialization expression, apart from the actual constructor call or
@@ -2098,12 +2105,32 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
 
       if (array_p)
        {
-         if (*init)
+         tree vecinit = NULL_TREE;
+         if (*init && VEC_length (tree, *init) == 1
+             && 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);
+             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);
+           }
+         else if (*init)
             {
               if (complain & tf_error)
                 permerror (input_location, "ISO C++ forbids initialization in array new");
               else
                 return error_mark_node;
+             vecinit = build_tree_list_vec (*init);
             }
          init_expr
            = build_vec_init (data_addr,
@@ -2111,7 +2138,7 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
                                                  MINUS_EXPR, outer_nelts,
                                                  integer_one_node,
                                                  complain),
-                             build_tree_list_vec (*init),
+                             vecinit,
                              explicit_value_init_p,
                              /*from_array=*/0,
                               complain);
@@ -2270,7 +2297,7 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
   /* A new-expression is never an lvalue.  */
   gcc_assert (!lvalue_p (rval));
 
-  return rval;
+  return convert (pointer_type, rval);
 }
 
 /* Generate a representation for a C++ "new" expression.  *PLACEMENT
@@ -2664,6 +2691,7 @@ build_vec_init (tree base, tree maxindex, tree init,
 
   inner_elt_type = strip_array_types (type);
   if (init
+      && TREE_CODE (atype) == ARRAY_TYPE
       && (from_array == 2
          ? (!CLASS_TYPE_P (inner_elt_type)
             || !TYPE_HAS_COMPLEX_ASSIGN_REF (inner_elt_type))
@@ -2679,7 +2707,6 @@ build_vec_init (tree base, tree maxindex, tree init,
         brace-enclosed initializers.  In this case, digest_init and
         store_constructor will handle the semantics for us.  */
 
-      gcc_assert (TREE_CODE (atype) == ARRAY_TYPE);
       stmt_expr = build2 (INIT_EXPR, atype, base, init);
       return stmt_expr;
     }
index 871c1d36319dbe684efc1c3ca07b8d827073984c..6a4802e3375d5d44d6084e7d1dbbb0e5f4b49784 100644 (file)
@@ -6202,8 +6202,11 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
     {
       int from_array;
 
-      if (!same_or_base_type_p (TYPE_MAIN_VARIANT (lhstype),
-                               TYPE_MAIN_VARIANT (TREE_TYPE (rhs))))
+      if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
+       rhs = digest_init (lhstype, rhs);
+
+      else if (!same_or_base_type_p (TYPE_MAIN_VARIANT (lhstype),
+                                    TYPE_MAIN_VARIANT (TREE_TYPE (rhs))))
        {
          if (complain & tf_error)
            error ("incompatible types in assignment of %qT to %qT",
@@ -6212,7 +6215,8 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
        }
 
       /* Allow array assignment in compiler-generated code.  */
-      if (!current_function_decl || !DECL_ARTIFICIAL (current_function_decl))
+      else if (!current_function_decl
+              || !DECL_ARTIFICIAL (current_function_decl))
        {
           /* This routine is used for both initialization and assignment.
              Make sure the diagnostic message differentiates the context.  */
index c43fd763dc07ca4df70aa1b6d345d4cd70a25d9e..d68383e380a34a20e84e51da31f86e44595d07f1 100644 (file)
@@ -913,10 +913,9 @@ process_init_constructor_array (tree type, tree init)
     /* Vectors are like simple fixed-size arrays.  */
     len = TYPE_VECTOR_SUBPARTS (type);
 
-  /* There cannot be more initializers than needed as otherwise
-     reshape_init would have already rejected the initializer.  */
-  if (!unbounded)
-    gcc_assert (VEC_length (constructor_elt, v) <= len);
+  /* There must not be more initializers than needed.  */
+  if (!unbounded && VEC_length (constructor_elt, v)  > len)
+    error ("too many initializers for %qT", type);
 
   for (i = 0; VEC_iterate (constructor_elt, v, i, ce); ++i)
     {
index 7df599ed587287c49bf3957f6d30a9e5e0f2639a..a12a5d206985a9a0aea187183ff33c097fd0213f 100644 (file)
@@ -1,3 +1,9 @@
+2009-07-12  Jason Merrill  <jason@redhat.com>
+
+       PR c++/40689
+       * g++.dg/cpp0x/initlist20.C: New.
+       * g++.dg/cpp0x/initlist21.C: New.
+
 2009-07-12  Ira Rosen  <irar@il.ibm.com>
 
        * gcc.dg/vect/no-scevccp-outer-2.c: Expect to vectorize.
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist20.C b/gcc/testsuite/g++.dg/cpp0x/initlist20.C
new file mode 100644 (file)
index 0000000..fcdb73f
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/40689
+// { dg-options "-std=c++0x" }
+
+class X
+{
+ public:
+  X(): data {1,2,3,4,5} {}
+ private:
+  const short data[5];
+};
+
+int main()
+{
+  const float * pData = new const float[4] { 1.5, 2.5, 3.5, 4.5 };
+
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist21.C b/gcc/testsuite/g++.dg/cpp0x/initlist21.C
new file mode 100644 (file)
index 0000000..9412a08
--- /dev/null
@@ -0,0 +1,18 @@
+// PR c++/40689
+// { dg-options "-std=c++0x" }
+
+class X
+{
+ public:
+  X(): data {1,2} {} // { dg-error "too many initializers" }
+ private:
+  const short data[1];
+};
+
+int f(int n)
+{
+  const float * pData = new const float[1] { 1.5, 2.5 }; // { dg-error "too many initializers" }
+  pData = new const float[n] { 1.5, 2.5 }; // { dg-warning "array size" }
+
+  return 0;
+}
This page took 0.078134 seconds and 5 git commands to generate.