Commit b73a4704 by Jason Merrill Committed by Jason Merrill

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
parent 3533b943
2011-05-02 Jason Merrill <jason@redhat.com> 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 PR c++/48834
* tree.c (build_vec_init_expr): Set TREE_SIDE_EFFECTS. * tree.c (build_vec_init_expr): Set TREE_SIDE_EFFECTS.
Protect an explicit target. Protect an explicit target.
......
...@@ -530,12 +530,10 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) ...@@ -530,12 +530,10 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{ {
location_t loc = input_location; location_t loc = input_location;
tree init = VEC_INIT_EXPR_INIT (*expr_p); tree init = VEC_INIT_EXPR_INIT (*expr_p);
int from_array = (init && TREE_TYPE (init) int from_array = (init && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE);
&& TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE);
gcc_assert (EXPR_HAS_LOCATION (*expr_p)); gcc_assert (EXPR_HAS_LOCATION (*expr_p));
input_location = EXPR_LOCATION (*expr_p); input_location = EXPR_LOCATION (*expr_p);
*expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p), *expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p), NULL_TREE,
VEC_INIT_EXPR_NELTS (*expr_p),
init, VEC_INIT_EXPR_VALUE_INIT (*expr_p), init, VEC_INIT_EXPR_VALUE_INIT (*expr_p),
from_array, from_array,
tf_warning_or_error); tf_warning_or_error);
......
...@@ -83,8 +83,8 @@ DEFTREECODE (AGGR_INIT_EXPR, "aggr_init_expr", tcc_vl_exp, 3) ...@@ -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 /* 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 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. */ is the initializer. */
DEFTREECODE (VEC_INIT_EXPR, "vec_init_expr", tcc_expression, 3) DEFTREECODE (VEC_INIT_EXPR, "vec_init_expr", tcc_expression, 2)
/* A throw expression. operand 0 is the expression, if there was one, /* A throw expression. operand 0 is the expression, if there was one,
else it is NULL_TREE. */ else it is NULL_TREE. */
......
...@@ -2896,9 +2896,8 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) ...@@ -2896,9 +2896,8 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
(arg) = next_aggr_init_expr_arg (&(iter))) (arg) = next_aggr_init_expr_arg (&(iter)))
/* VEC_INIT_EXPR accessors. */ /* VEC_INIT_EXPR accessors. */
#define VEC_INIT_EXPR_SLOT(NODE) TREE_OPERAND (VEC_INIT_EXPR_CHECK (NODE), 0) #define VEC_INIT_EXPR_SLOT(NODE) TREE_OPERAND (NODE, 0)
#define VEC_INIT_EXPR_INIT(NODE) TREE_OPERAND (VEC_INIT_EXPR_CHECK (NODE), 1) #define VEC_INIT_EXPR_INIT(NODE) TREE_OPERAND (NODE, 1)
#define VEC_INIT_EXPR_NELTS(NODE) TREE_OPERAND (VEC_INIT_EXPR_CHECK (NODE), 2)
/* Indicates that a VEC_INIT_EXPR is a potential constant expression. /* Indicates that a VEC_INIT_EXPR is a potential constant expression.
Only set when the current function is constexpr. */ Only set when the current function is constexpr. */
...@@ -5025,7 +5024,6 @@ extern tree get_copy_ctor (tree); ...@@ -5025,7 +5024,6 @@ extern tree get_copy_ctor (tree);
extern tree get_copy_assign (tree); extern tree get_copy_assign (tree);
extern tree get_default_ctor (tree); extern tree get_default_ctor (tree);
extern tree get_dtor (tree); extern tree get_dtor (tree);
extern tree get_dtor_sfinae (tree, tsubst_flags_t);
extern tree locate_ctor (tree); extern tree locate_ctor (tree);
/* In optimize.c */ /* In optimize.c */
...@@ -5422,7 +5420,7 @@ extern tree get_target_expr_sfinae (tree, tsubst_flags_t); ...@@ -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_cplus_array_type (tree, tree);
extern tree build_array_of_n_type (tree, int); extern tree build_array_of_n_type (tree, int);
extern tree build_array_copy (tree); 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 void diagnose_non_constexpr_vec_init (tree);
extern tree hash_tree_cons (tree, tree, tree); extern tree hash_tree_cons (tree, tree, tree);
extern tree hash_tree_chain (tree, tree); extern tree hash_tree_chain (tree, tree);
......
...@@ -506,8 +506,7 @@ perform_member_init (tree member, tree init) ...@@ -506,8 +506,7 @@ perform_member_init (tree member, tree init)
/* mem() means value-initialization. */ /* mem() means value-initialization. */
if (TREE_CODE (type) == ARRAY_TYPE) if (TREE_CODE (type) == ARRAY_TYPE)
{ {
init = build_vec_init_expr (type, init, NULL_TREE, init = build_vec_init_expr (type, init);
tf_warning_or_error);
init = build2 (INIT_EXPR, type, decl, init); init = build2 (INIT_EXPR, type, decl, init);
finish_expr_stmt (init); finish_expr_stmt (init);
} }
...@@ -544,8 +543,7 @@ perform_member_init (tree member, tree init) ...@@ -544,8 +543,7 @@ perform_member_init (tree member, tree init)
|| same_type_ignoring_top_level_qualifiers_p (type, || same_type_ignoring_top_level_qualifiers_p (type,
TREE_TYPE (init))) TREE_TYPE (init)))
{ {
init = build_vec_init_expr (type, init, NULL_TREE, init = build_vec_init_expr (type, init);
tf_warning_or_error);
init = build2 (INIT_EXPR, type, decl, init); init = build2 (INIT_EXPR, type, decl, init);
finish_expr_stmt (init); finish_expr_stmt (init);
} }
...@@ -2388,14 +2386,15 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, ...@@ -2388,14 +2386,15 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
vecinit = build_tree_list_vec (*init); vecinit = build_tree_list_vec (*init);
} }
init_expr init_expr
= build_vec_init_expr (data_addr, = build_vec_init (data_addr,
(explicit_value_init_p cp_build_binary_op (input_location,
? void_type_node: vecinit), MINUS_EXPR, outer_nelts,
cp_build_binary_op (input_location, integer_one_node,
MINUS_EXPR, outer_nelts, complain),
integer_one_node, vecinit,
complain), explicit_value_init_p,
complain); /*from_array=*/0,
complain);
/* An array initialization is stable because the initialization /* An array initialization is stable because the initialization
of each element is a full-expression, so the temporaries don't of each element is a full-expression, so the temporaries don't
......
...@@ -843,16 +843,10 @@ locate_fn_flags (tree type, tree name, tree argtype, int flags, ...@@ -843,16 +843,10 @@ locate_fn_flags (tree type, tree name, tree argtype, int flags,
/* Locate the dtor of TYPE. */ /* Locate the dtor of TYPE. */
tree 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) 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) if (fn == error_mark_node)
return NULL_TREE; return NULL_TREE;
return fn; return fn;
......
...@@ -475,80 +475,45 @@ build_cplus_new (tree type, tree init, tsubst_flags_t complain) ...@@ -475,80 +475,45 @@ build_cplus_new (tree type, tree init, tsubst_flags_t complain)
another array to copy. */ another array to copy. */
static tree 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; 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. */ /* No interesting initialization to do. */
return integer_zero_node; return integer_zero_node;
else if (init == void_type_node) else if (init == void_type_node)
return build_value_init (inner_type, tf_warning_or_error); return build_value_init (inner_type, tf_warning_or_error);
if (init == NULL_TREE) gcc_assert (init == NULL_TREE
argvec = make_tree_vector (); || (same_type_ignoring_top_level_qualifiers_p
else if (TREE_CODE (init) == TREE_LIST) (type, TREE_TYPE (init))));
/* Array init extension, i.e. g++.robertl/eb58.C. */
argvec = make_tree_vector_from_list (init); argvec = make_tree_vector ();
else if (same_type_ignoring_top_level_qualifiers_p if (init)
(inner_type, strip_array_types (TREE_TYPE (init))))
{ {
/* Array copy or list-initialization. */
tree dummy = build_dummy_object (inner_type); tree dummy = build_dummy_object (inner_type);
if (!real_lvalue_p (init)) if (!real_lvalue_p (init))
dummy = move (dummy); dummy = move (dummy);
argvec = make_tree_vector_single (dummy); VEC_quick_push (tree, argvec, dummy);
} }
else return build_special_member_call (NULL_TREE, complete_ctor_identifier,
gcc_unreachable ();
init = build_special_member_call (NULL_TREE, complete_ctor_identifier,
&argvec, inner_type, LOOKUP_NORMAL, &argvec, inner_type, LOOKUP_NORMAL,
complain); tf_warning_or_error);
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;
} }
/* Return a TARGET_EXPR which expresses the initialization of an array. If /* Return a TARGET_EXPR which expresses the initialization of an array to
TARGET is an array type, the initialization is of an array to be named be named later, either default-initialization or copy-initialization
later, and the initialization will be wrapped in a TARGET_EXPR. If from another array of the same type. */
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. */
tree tree
build_vec_init_expr (tree target, tree init, tree nelts, build_vec_init_expr (tree type, tree init)
tsubst_flags_t complain)
{ {
tree slot, type; tree slot;
bool value_init = false; bool value_init = false;
tree elt_init; tree elt_init = build_vec_init_elt (type, 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);
}
if (init == void_type_node) if (init == void_type_node)
{ {
...@@ -556,14 +521,8 @@ build_vec_init_expr (tree target, tree init, tree nelts, ...@@ -556,14 +521,8 @@ build_vec_init_expr (tree target, tree init, tree nelts,
init = NULL_TREE; init = NULL_TREE;
} }
real_nelts = nelts ? nelts : array_type_nelts_total (type); slot = build_local_temp (type);
if (integer_zerop (real_nelts)) init = build2 (VEC_INIT_EXPR, type, slot, init);
/* 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);
TREE_SIDE_EFFECTS (init) = true; TREE_SIDE_EFFECTS (init) = true;
SET_EXPR_LOCATION (init, input_location); SET_EXPR_LOCATION (init, input_location);
...@@ -572,15 +531,8 @@ build_vec_init_expr (tree target, tree init, tree nelts, ...@@ -572,15 +531,8 @@ build_vec_init_expr (tree target, tree init, tree nelts,
VEC_INIT_EXPR_IS_CONSTEXPR (init) = true; VEC_INIT_EXPR_IS_CONSTEXPR (init) = true;
VEC_INIT_EXPR_VALUE_INIT (init) = value_init; VEC_INIT_EXPR_VALUE_INIT (init) = value_init;
if (slot == target) init = build_target_expr (slot, init, complain);
/* If we specified what array we're initializing, make sure TARGET_EXPR_IMPLICIT_P (init) = 1;
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;
}
return init; return init;
} }
...@@ -598,15 +550,14 @@ diagnose_non_constexpr_vec_init (tree expr) ...@@ -598,15 +550,14 @@ diagnose_non_constexpr_vec_init (tree expr)
else else
init = VEC_INIT_EXPR_INIT (expr); 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); require_potential_constant_expression (elt_init);
} }
tree tree
build_array_copy (tree init) build_array_copy (tree init)
{ {
return build_vec_init_expr (TREE_TYPE (init), init, NULL_TREE, return build_vec_init_expr (TREE_TYPE (init), init);
tf_warning_or_error);
} }
/* Build a TARGET_EXPR using INIT to initialize a new temporary of the /* Build a TARGET_EXPR using INIT to initialize a new temporary of the
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment