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
This commit is contained in:
Jason Merrill 2011-05-02 18:00:07 -04:00 committed by Jason Merrill
parent 3533b943d1
commit b73a470455
7 changed files with 56 additions and 105 deletions

View 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.

View 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);

View 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. */

View 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);

View 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

View 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;

View 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