From b73a47045560ac7b2b808736383e8b5f8a97f55a Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 2 May 2011 18:00:07 -0400 Subject: [PATCH] revert: re PR c++/40975 (ICE in copy_tree_r on array new) 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 | 11 +++++ gcc/cp/cp-gimplify.c | 6 +-- gcc/cp/cp-tree.def | 4 +- gcc/cp/cp-tree.h | 8 ++-- gcc/cp/init.c | 23 +++++----- gcc/cp/method.c | 10 +---- gcc/cp/tree.c | 99 +++++++++++--------------------------------- 7 files changed, 56 insertions(+), 105 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 127d77a2b3e..f36182f2269 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,16 @@ 2011-05-02 Jason Merrill + 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. diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index dc2e0fb4473..ca62df3e585 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -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); diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index c9fc9707311..7bd35e0d6b2 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -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. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 40a200802dc..9bad404f2ed 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index d8b19c7491e..50dbcc932fe 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -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 diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 8b1b4dcf40c..6b268067cc0 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -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; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index fff3fbf28a2..dfd11ad9dc4 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -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 -- 2.30.2