revert: re PR c++/40975 (ICE in copy_tree_r on array new)
authorJason Merrill <jason@redhat.com>
Mon, 2 May 2011 22:00:07 +0000 (18:00 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 2 May 2011 22:00:07 +0000 (18:00 -0400)
Revert:
PR c++/40975
* cp-tree.def (VEC_INIT_EXPR): Add third operand.
* cp-tree.h (VEC_INIT_EXPR_NELTS): New.
* cp-gimplify.c (cp_gimplify_expr) [VEC_INIT_EXPR]: Handle it.
* tree.c (build_vec_init_expr): Handle getting pointer/nelts.
(build_vec_init_elt): Don't expect an array type.
(build_array_copy): Adjust.
* init.c (perform_member_init): Adjust.
(build_new_1): Use build_vec_init_expr.

From-SVN: r173274

gcc/cp/ChangeLog
gcc/cp/cp-gimplify.c
gcc/cp/cp-tree.def
gcc/cp/cp-tree.h
gcc/cp/init.c
gcc/cp/method.c
gcc/cp/tree.c

index 127d77a2b3e3b899757b482a8237bcde06e7892b..f36182f226933703104ea8e684e5306ae2c85d57 100644 (file)
@@ -1,5 +1,16 @@
 2011-05-02  Jason Merrill  <jason@redhat.com>
 
+       Revert:
+       PR c++/40975
+       * cp-tree.def (VEC_INIT_EXPR): Add third operand.
+       * cp-tree.h (VEC_INIT_EXPR_NELTS): New.
+       * cp-gimplify.c (cp_gimplify_expr) [VEC_INIT_EXPR]: Handle it.
+       * tree.c (build_vec_init_expr): Handle getting pointer/nelts.
+       (build_vec_init_elt): Don't expect an array type.
+       (build_array_copy): Adjust.
+       * init.c (perform_member_init): Adjust.
+       (build_new_1): Use build_vec_init_expr.
+
        PR c++/48834
        * tree.c (build_vec_init_expr): Set TREE_SIDE_EFFECTS.
        Protect an explicit target.
index dc2e0fb4473f0ea3538e72fb657bdf952599c039..ca62df3e5858c7bd96bcd79e74c5142a3716babf 100644 (file)
@@ -530,12 +530,10 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
       {
        location_t loc = input_location;
        tree init = VEC_INIT_EXPR_INIT (*expr_p);
-       int from_array = (init && TREE_TYPE (init)
-                         && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE);
+       int from_array = (init && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE);
        gcc_assert (EXPR_HAS_LOCATION (*expr_p));
        input_location = EXPR_LOCATION (*expr_p);
-       *expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p),
-                                 VEC_INIT_EXPR_NELTS (*expr_p),
+       *expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p), NULL_TREE,
                                  init, VEC_INIT_EXPR_VALUE_INIT (*expr_p),
                                  from_array,
                                  tf_warning_or_error);
index c9fc9707311de20ac8f2c5eabe01bae755bc75d7..7bd35e0d6b29a5fa2c1fee98d314c90b9ea0dbed 100644 (file)
@@ -83,8 +83,8 @@ DEFTREECODE (AGGR_INIT_EXPR, "aggr_init_expr", tcc_vl_exp, 3)
 
 /* Initialization of an array from another array, expressed at a high level
    so that it works with TARGET_EXPR.  Operand 0 is the target, operand 1
-   is the initializer, operand 2 is the number of elements or NULL_TREE.  */
-DEFTREECODE (VEC_INIT_EXPR, "vec_init_expr", tcc_expression, 3)
+   is the initializer.  */
+DEFTREECODE (VEC_INIT_EXPR, "vec_init_expr", tcc_expression, 2)
 
 /* A throw expression.  operand 0 is the expression, if there was one,
    else it is NULL_TREE.  */
index 40a200802dceba534a2e4fab7418a5450b5c89c8..9bad404f2ed7aaa8b86378a1358772000197eb0f 100644 (file)
@@ -2896,9 +2896,8 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
        (arg) = next_aggr_init_expr_arg (&(iter)))
 
 /* VEC_INIT_EXPR accessors.  */
-#define VEC_INIT_EXPR_SLOT(NODE) TREE_OPERAND (VEC_INIT_EXPR_CHECK (NODE), 0)
-#define VEC_INIT_EXPR_INIT(NODE) TREE_OPERAND (VEC_INIT_EXPR_CHECK (NODE), 1)
-#define VEC_INIT_EXPR_NELTS(NODE) TREE_OPERAND (VEC_INIT_EXPR_CHECK (NODE), 2)
+#define VEC_INIT_EXPR_SLOT(NODE) TREE_OPERAND (NODE, 0)
+#define VEC_INIT_EXPR_INIT(NODE) TREE_OPERAND (NODE, 1)
 
 /* Indicates that a VEC_INIT_EXPR is a potential constant expression.
    Only set when the current function is constexpr.  */
@@ -5025,7 +5024,6 @@ extern tree get_copy_ctor                 (tree);
 extern tree get_copy_assign                    (tree);
 extern tree get_default_ctor                   (tree);
 extern tree get_dtor                           (tree);
-extern tree get_dtor_sfinae                    (tree, tsubst_flags_t);
 extern tree locate_ctor                                (tree);
 
 /* In optimize.c */
@@ -5422,7 +5420,7 @@ extern tree get_target_expr_sfinae                (tree, tsubst_flags_t);
 extern tree build_cplus_array_type             (tree, tree);
 extern tree build_array_of_n_type              (tree, int);
 extern tree build_array_copy                   (tree);
-extern tree build_vec_init_expr                        (tree, tree, tree, tsubst_flags_t);
+extern tree build_vec_init_expr                        (tree, tree);
 extern void diagnose_non_constexpr_vec_init    (tree);
 extern tree hash_tree_cons                     (tree, tree, tree);
 extern tree hash_tree_chain                    (tree, tree);
index d8b19c7491ee2580a923cbd6260ecb2b5ccf36d9..50dbcc932fe497f5986fa270249f162e18d0da0b 100644 (file)
@@ -506,8 +506,7 @@ perform_member_init (tree member, tree init)
       /* mem() means value-initialization.  */
       if (TREE_CODE (type) == ARRAY_TYPE)
        {
-         init = build_vec_init_expr (type, init, NULL_TREE,
-                                     tf_warning_or_error);
+         init = build_vec_init_expr (type, init);
          init = build2 (INIT_EXPR, type, decl, init);
          finish_expr_stmt (init);
        }
@@ -544,8 +543,7 @@ perform_member_init (tree member, tree init)
              || same_type_ignoring_top_level_qualifiers_p (type,
                                                            TREE_TYPE (init)))
            {
-             init = build_vec_init_expr (type, init, NULL_TREE,
-                                         tf_warning_or_error);
+             init = build_vec_init_expr (type, init);
              init = build2 (INIT_EXPR, type, decl, init);
              finish_expr_stmt (init);
            }
@@ -2388,14 +2386,15 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
              vecinit = build_tree_list_vec (*init);
             }
          init_expr
-           = build_vec_init_expr (data_addr,
-                                  (explicit_value_init_p
-                                   ? void_type_node: vecinit),
-                                  cp_build_binary_op (input_location,
-                                                      MINUS_EXPR, outer_nelts,
-                                                      integer_one_node,
-                                                      complain),
-                                  complain);
+           = build_vec_init (data_addr,
+                             cp_build_binary_op (input_location,
+                                                 MINUS_EXPR, outer_nelts,
+                                                 integer_one_node,
+                                                 complain),
+                             vecinit,
+                             explicit_value_init_p,
+                             /*from_array=*/0,
+                              complain);
 
          /* An array initialization is stable because the initialization
             of each element is a full-expression, so the temporaries don't
index 8b1b4dcf40c24b59c75603f55e03af01fe62b51b..6b268067cc028ea0c00e04cd85b21efdf452f555 100644 (file)
@@ -842,17 +842,11 @@ locate_fn_flags (tree type, tree name, tree argtype, int flags,
 
 /* Locate the dtor of TYPE.  */
 
-tree
-get_dtor_sfinae (tree type, tsubst_flags_t complain)
-{
-  return locate_fn_flags (type, complete_dtor_identifier, NULL_TREE,
-                         LOOKUP_NORMAL, complain);
-}
-
 tree
 get_dtor (tree type)
 {
-  tree fn = get_dtor_sfinae (type, tf_warning_or_error);
+  tree fn = locate_fn_flags (type, complete_dtor_identifier, NULL_TREE,
+                            LOOKUP_NORMAL, tf_warning_or_error);
   if (fn == error_mark_node)
     return NULL_TREE;
   return fn;
index fff3fbf28a2327ec816c5bac65e748e9202e2747..dfd11ad9dc49120bc9f54faed804944b65d253a8 100644 (file)
@@ -475,80 +475,45 @@ build_cplus_new (tree type, tree init, tsubst_flags_t complain)
    another array to copy.  */
 
 static tree
-build_vec_init_elt (tree type, tree init, tsubst_flags_t complain)
+build_vec_init_elt (tree type, tree init)
 {
-  tree inner_type = strip_array_types (TREE_TYPE (type));
+  tree inner_type = strip_array_types (type);
   VEC(tree,gc) *argvec;
 
-  if (!CLASS_TYPE_P (inner_type))
+  if (integer_zerop (array_type_nelts_total (type))
+      || !CLASS_TYPE_P (inner_type))
     /* No interesting initialization to do.  */
     return integer_zero_node;
   else if (init == void_type_node)
     return build_value_init (inner_type, tf_warning_or_error);
 
-  if (init == NULL_TREE)
-    argvec = make_tree_vector ();
-  else if (TREE_CODE (init) == TREE_LIST)
-    /* Array init extension, i.e. g++.robertl/eb58.C. */
-    argvec = make_tree_vector_from_list (init);
-  else if (same_type_ignoring_top_level_qualifiers_p
-          (inner_type, strip_array_types (TREE_TYPE (init))))
+  gcc_assert (init == NULL_TREE
+             || (same_type_ignoring_top_level_qualifiers_p
+                 (type, TREE_TYPE (init))));
+
+  argvec = make_tree_vector ();
+  if (init)
     {
-      /* Array copy or list-initialization.  */
       tree dummy = build_dummy_object (inner_type);
       if (!real_lvalue_p (init))
        dummy = move (dummy);
-      argvec = make_tree_vector_single (dummy);
+      VEC_quick_push (tree, argvec, dummy);
     }
-  else
-    gcc_unreachable ();
-  init = build_special_member_call (NULL_TREE, complete_ctor_identifier,
+  return build_special_member_call (NULL_TREE, complete_ctor_identifier,
                                    &argvec, inner_type, LOOKUP_NORMAL,
-                                   complain);
-  release_tree_vector (argvec);
-
-  /* For array new, also mark the destructor as used.  */
-  if (TREE_CODE (type) == POINTER_TYPE
-      && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (inner_type))
-    {
-      tree dtor = get_dtor_sfinae (inner_type, complain);
-      if (dtor == error_mark_node)
-       return error_mark_node;
-      else if (dtor)
-       mark_used (dtor);
-    }
-  return init;
+                                   tf_warning_or_error);
 }
 
-/* Return a TARGET_EXPR which expresses the initialization of an array.  If
-   TARGET is an array type, the initialization is of an array to be named
-   later, and the initialization will be wrapped in a TARGET_EXPR.  If
-   TARGET is an expression, it is the array to be initialized.  INIT is the
-   initializer, or void_type_node for value-initialization.  If TARGET is
-   an expression, NELTS is the number of elements to initialize. */
+/* Return a TARGET_EXPR which expresses the initialization of an array to
+   be named later, either default-initialization or copy-initialization
+   from another array of the same type.  */
 
 tree
-build_vec_init_expr (tree target, tree init, tree nelts,
-                    tsubst_flags_t complain)
+build_vec_init_expr (tree type, tree init)
 {
-  tree slot, type;
+  tree slot;
   bool value_init = false;
-  tree elt_init;
-  tree real_nelts;
-
-  if (TYPE_P (target))
-    {
-      gcc_assert (TREE_CODE (target) == ARRAY_TYPE && nelts == NULL_TREE);
-      type = target;
-      slot = build_local_temp (type);
-    }
-  else
-    {
-      gcc_assert (EXPR_P (target));
-      slot = target;
-      type = TREE_TYPE (slot);
-      gcc_assert (TREE_CODE (type) == POINTER_TYPE && nelts != NULL_TREE);
-    }
+  tree elt_init = build_vec_init_elt (type, init);
 
   if (init == void_type_node)
     {
@@ -556,14 +521,8 @@ build_vec_init_expr (tree target, tree init, tree nelts,
       init = NULL_TREE;
     }
 
-  real_nelts = nelts ? nelts : array_type_nelts_total (type);
-  if (integer_zerop (real_nelts))
-    /* No elements to initialize.  */
-    elt_init = integer_zero_node;
-  else
-    elt_init = build_vec_init_elt (type, init, complain);
-
-  init = build3 (VEC_INIT_EXPR, type, slot, init, nelts);
+  slot = build_local_temp (type);
+  init = build2 (VEC_INIT_EXPR, type, slot, init);
   TREE_SIDE_EFFECTS (init) = true;
   SET_EXPR_LOCATION (init, input_location);
 
@@ -572,15 +531,8 @@ build_vec_init_expr (tree target, tree init, tree nelts,
     VEC_INIT_EXPR_IS_CONSTEXPR (init) = true;
   VEC_INIT_EXPR_VALUE_INIT (init) = value_init;
 
-  if (slot == target)
-    /* If we specified what array we're initializing, make sure
-       we don't override that in cp_gimplify_init_expr.  */
-    init = cp_build_compound_expr (init, slot, complain);
-  else
-    {
-      init = build_target_expr (slot, init, complain);
-      TARGET_EXPR_IMPLICIT_P (init) = 1;
-    }
+  init = build_target_expr (slot, init, complain);
+  TARGET_EXPR_IMPLICIT_P (init) = 1;
 
   return init;
 }
@@ -598,15 +550,14 @@ diagnose_non_constexpr_vec_init (tree expr)
   else
     init = VEC_INIT_EXPR_INIT (expr);
 
-  elt_init = build_vec_init_elt (type, init, tf_warning_or_error);
+  elt_init = build_vec_init_elt (type, init);
   require_potential_constant_expression (elt_init);
 }
 
 tree
 build_array_copy (tree init)
 {
-  return build_vec_init_expr (TREE_TYPE (init), init, NULL_TREE,
-                             tf_warning_or_error);
+  return build_vec_init_expr (TREE_TYPE (init), init);
 }
 
 /* Build a TARGET_EXPR using INIT to initialize a new temporary of the