OSDN Git Service

PR c++/8564
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 17 Jan 2003 03:43:52 +0000 (03:43 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 17 Jan 2003 03:43:52 +0000 (03:43 +0000)
        * init.c (build_vec_init): Re-add maxindex parm.
        (perform_member_init, build_aggr_init): Pass it.
        (build_new_1): Pass it. Use an incomplete array type for full_type.
        * typeck.c (build_modify_expr): Pass it.
        * cp-tree.h: Adjust.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@61422 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/init.c
gcc/cp/typeck.c
gcc/testsuite/g++.dg/init/new3.C [new file with mode: 0644]

index 54d66be..d50b3d6 100644 (file)
@@ -1,3 +1,12 @@
+2003-01-16  Jason Merrill  <jason@redhat.com>
+
+       PR c++/8564
+       * init.c (build_vec_init): Re-add maxindex parm.
+       (perform_member_init, build_aggr_init): Pass it.
+       (build_new_1): Pass it. Use an incomplete array type for full_type.
+       * typeck.c (build_modify_expr): Pass it.
+       * cp-tree.h: Adjust.
+
 2003-01-16  Jeffrey D. Oldham  <oldham@codesourcery.com>
 
        * cp-tree.h (tsubst_copy_and_build): New declaration.
index 9d06763..4b29211 100644 (file)
@@ -3957,7 +3957,7 @@ extern tree build_member_call                     (tree, tree, tree);
 extern tree build_offset_ref                   (tree, tree);
 extern tree resolve_offset_ref                 (tree);
 extern tree build_new                          (tree, tree, tree, int);
-extern tree build_vec_init                     (tree, tree, int);
+extern tree build_vec_init                     (tree, tree, tree, int);
 extern tree build_x_delete                     (tree, int, tree);
 extern tree build_delete                       (tree, tree, special_function_kind, int, int);
 extern void push_base_cleanups                 (void);
index 964ee1e..c822516 100644 (file)
@@ -353,7 +353,8 @@ perform_member_init (tree member, tree init)
          && TREE_CODE (TREE_TYPE (TREE_VALUE (init))) == ARRAY_TYPE)
        {
          /* Initialization of one array from another.  */
-         finish_expr_stmt (build_vec_init (decl, TREE_VALUE (init), 1));
+         finish_expr_stmt (build_vec_init (decl, NULL_TREE, TREE_VALUE (init),
+                                           /* from_array=*/1));
        }
       else
        finish_expr_stmt (build_aggr_init (decl, init, 0));
@@ -1115,7 +1116,7 @@ build_aggr_init (exp, init, flags)
        TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
       if (itype && cp_type_quals (itype) != TYPE_UNQUALIFIED)
        TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);
-      stmt_expr = build_vec_init (exp, init,
+      stmt_expr = build_vec_init (exp, NULL_TREE, init,
                                  init && same_type_p (TREE_TYPE (init),
                                                       TREE_TYPE (exp)));
       TREE_READONLY (exp) = was_const;
@@ -2155,6 +2156,7 @@ build_new_1 (exp)
   tree placement, init;
   tree type, true_type, size, rval, t;
   tree full_type;
+  tree outer_nelts = NULL_TREE;
   tree nelts = NULL_TREE;
   tree alloc_call, alloc_expr, alloc_node;
   tree alloc_fn;
@@ -2184,12 +2186,11 @@ build_new_1 (exp)
   if (TREE_CODE (type) == ARRAY_REF)
     {
       has_array = 1;
-      nelts = TREE_OPERAND (type, 1);
+      nelts = outer_nelts = TREE_OPERAND (type, 1);
       type = TREE_OPERAND (type, 0);
 
-      full_type = cp_build_binary_op (MINUS_EXPR, nelts, integer_one_node);
-      full_type = build_index_type (full_type);
-      full_type = build_cplus_array_type (type, full_type);
+      /* Use an incomplete array type to avoid VLA headaches.  */
+      full_type = build_cplus_array_type (type, NULL_TREE);
     }
   else
     full_type = type;
@@ -2379,7 +2380,11 @@ build_new_1 (exp)
        pedwarn ("ISO C++ forbids initialization in array new");
 
       if (has_array)
-       init_expr = build_vec_init (init_expr, init, 0);
+       init_expr
+         = build_vec_init (init_expr,
+                           cp_build_binary_op (MINUS_EXPR, outer_nelts,
+                                               integer_one_node),
+                           init, /*from_array=*/0);
       else if (TYPE_NEEDS_CONSTRUCTING (type))
        init_expr = build_special_member_call (init_expr, 
                                               complete_ctor_identifier,
@@ -2710,6 +2715,9 @@ get_temp_regvar (type, init)
    initialization of a vector of aggregate types.
 
    BASE is a reference to the vector, of ARRAY_TYPE.
+   MAXINDEX is the maximum index of the array (one less than the
+     number of elements).  It is only used if
+     TYPE_DOMAIN (TREE_TYPE (BASE)) == NULL_TREE.
    INIT is the (possibly NULL) initializer.
 
    FROM_ARRAY is 0 if we should init everything with INIT
@@ -2720,8 +2728,8 @@ get_temp_regvar (type, init)
    but use assignment instead of initialization.  */
 
 tree
-build_vec_init (base, init, from_array)
-     tree base, init;
+build_vec_init (base, maxindex, init, from_array)
+     tree base, init, maxindex;
      int from_array;
 {
   tree rval;
@@ -2741,9 +2749,11 @@ build_vec_init (base, init, from_array)
   tree try_block = NULL_TREE;
   tree try_body = NULL_TREE;
   int num_initialized_elts = 0;
-  tree maxindex = array_type_nelts (TREE_TYPE (base));
 
-  if (maxindex == error_mark_node)
+  if (TYPE_DOMAIN (atype))
+    maxindex = array_type_nelts (atype);
+
+  if (maxindex == NULL_TREE || maxindex == error_mark_node)
     return error_mark_node;
 
   if (init
@@ -2934,7 +2944,7 @@ build_vec_init (base, init, from_array)
            sorry
              ("cannot initialize multi-dimensional array with initializer");
          elt_init = build_vec_init (build1 (INDIRECT_REF, type, base),
-                                    0, 0);
+                                    0, 0, 0);
        }
       else
        elt_init = build_aggr_init (build1 (INDIRECT_REF, type, base), 
index 2c896d4..57d95ad 100644 (file)
@@ -5380,7 +5380,7 @@ build_modify_expr (lhs, modifycode, rhs)
 
       from_array = TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE
                   ? 1 + (modifycode != INIT_EXPR): 0;
-      return build_vec_init (lhs, newrhs, from_array);
+      return build_vec_init (lhs, NULL_TREE, newrhs, from_array);
     }
 
   if (modifycode == INIT_EXPR)
diff --git a/gcc/testsuite/g++.dg/init/new3.C b/gcc/testsuite/g++.dg/init/new3.C
new file mode 100644 (file)
index 0000000..d0eab73
--- /dev/null
@@ -0,0 +1,8 @@
+// Test that new-expressions at file scope work properly.
+
+struct A { static char* p; };
+
+int i = 1;
+char* A::p = new char[i];
+
+void foo() {}