Commit b84f4651 by Mark Mitchell Committed by Mark Mitchell

re PR c++/23491 (new declarator with constant expression gives "error: invalid…

re PR c++/23491 (new declarator with constant expression gives "error: invalid use of array with unspecified bounds")

	PR c++/23491
	* cp-tree.h (build_vec_init): Adjust prototype.
	* init.c (perform_member_init): Adjust call to build_vec_init.
	(build_aggr_init): Likewise.
	(build_new_1): Do not call build_default_init for array types.
	(build_vec_init): Add explicit_default_init_p parameter.  Perform
	default initialization of vector elements when set.
	* typeck.c (build_modify_expr): Adjust call to build_vec_init.

	PR c++/23491
	* g++.dg/init/new14.C: New test.
	* g++.dg/expr/anew1.C: Do not XFAIL.
	* g++.dg/expr/anew2.C: Likewise.
	* g++.dg/expr/anew3.C: Likewise.

From-SVN: r103530
parent d6cde480
2005-08-26 Mark Mitchell <mark@codesourcery.com>
PR c++/23491
* cp-tree.h (build_vec_init): Adjust prototype.
* init.c (perform_member_init): Adjust call to build_vec_init.
(build_aggr_init): Likewise.
(build_new_1): Do not call build_default_init for array types.
(build_vec_init): Add explicit_default_init_p parameter. Perform
default initialization of vector elements when set.
* typeck.c (build_modify_expr): Adjust call to build_vec_init.
PR c++/19004
* pt.c (uses_template_parms): Handle IDENTIFIER_NODE.
(type_dependent_expression_p): Allow BASELINKs whose associated
functions are simply a FUNCTION_DECL.
2005-08-25 Nathan Sidwell <nathan@codesourcery.com> 2005-08-25 Nathan Sidwell <nathan@codesourcery.com>
PR c++/20817 PR c++/20817
......
...@@ -3918,7 +3918,7 @@ extern tree get_type_value (tree); ...@@ -3918,7 +3918,7 @@ extern tree get_type_value (tree);
extern tree build_zero_init (tree, tree, bool); extern tree build_zero_init (tree, tree, bool);
extern tree build_offset_ref (tree, tree, bool); extern tree build_offset_ref (tree, tree, bool);
extern tree build_new (tree, tree, tree, tree, int); extern tree build_new (tree, tree, tree, tree, int);
extern tree build_vec_init (tree, tree, tree, int); extern tree build_vec_init (tree, tree, tree, bool, int);
extern tree build_x_delete (tree, int, tree); extern tree build_x_delete (tree, int, tree);
extern tree build_delete (tree, tree, extern tree build_delete (tree, tree,
special_function_kind, special_function_kind,
......
...@@ -358,6 +358,7 @@ perform_member_init (tree member, tree init) ...@@ -358,6 +358,7 @@ perform_member_init (tree member, tree init)
{ {
/* Initialization of one array from another. */ /* Initialization of one array from another. */
finish_expr_stmt (build_vec_init (decl, NULL_TREE, TREE_VALUE (init), finish_expr_stmt (build_vec_init (decl, NULL_TREE, TREE_VALUE (init),
/*explicit_default_init_p=*/false,
/* from_array=*/1)); /* from_array=*/1));
} }
else else
...@@ -1112,6 +1113,7 @@ build_aggr_init (tree exp, tree init, int flags) ...@@ -1112,6 +1113,7 @@ build_aggr_init (tree exp, tree init, int flags)
if (itype && cp_type_quals (itype) != TYPE_UNQUALIFIED) if (itype && cp_type_quals (itype) != TYPE_UNQUALIFIED)
itype = TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype); itype = TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);
stmt_expr = build_vec_init (exp, NULL_TREE, init, stmt_expr = build_vec_init (exp, NULL_TREE, init,
/*explicit_default_init_p=*/false,
itype && same_type_p (itype, itype && same_type_p (itype,
TREE_TYPE (exp))); TREE_TYPE (exp)));
TREE_READONLY (exp) = was_const; TREE_READONLY (exp) = was_const;
...@@ -2055,25 +2057,37 @@ build_new_1 (tree exp) ...@@ -2055,25 +2057,37 @@ build_new_1 (tree exp)
init_expr = build_indirect_ref (data_addr, NULL); init_expr = build_indirect_ref (data_addr, NULL);
if (array_p)
{
bool explicit_default_init_p = false;
if (init == void_zero_node) if (init == void_zero_node)
init = build_default_init (full_type, nelts); {
else if (init && array_p) init = NULL_TREE;
explicit_default_init_p = true;
}
else if (init)
pedwarn ("ISO C++ forbids initialization in array new"); pedwarn ("ISO C++ forbids initialization in array new");
if (array_p)
{
init_expr init_expr
= build_vec_init (init_expr, = build_vec_init (init_expr,
cp_build_binary_op (MINUS_EXPR, outer_nelts, cp_build_binary_op (MINUS_EXPR, outer_nelts,
integer_one_node), integer_one_node),
init, /*from_array=*/0); init,
explicit_default_init_p,
/*from_array=*/0);
/* 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
leak out. */ leak out. */
stable = true; stable = true;
} }
else if (TYPE_NEEDS_CONSTRUCTING (type)) else
{
if (init == void_zero_node)
init = build_default_init (full_type, nelts);
if (TYPE_NEEDS_CONSTRUCTING (type))
{ {
init_expr = build_special_member_call (init_expr, init_expr = build_special_member_call (init_expr,
complete_ctor_identifier, complete_ctor_identifier,
...@@ -2087,8 +2101,8 @@ build_new_1 (tree exp) ...@@ -2087,8 +2101,8 @@ build_new_1 (tree exp)
means allocate an int, and initialize it with 10. */ means allocate an int, and initialize it with 10. */
if (TREE_CODE (init) == TREE_LIST) if (TREE_CODE (init) == TREE_LIST)
init = build_x_compound_expr_from_list (init, "new initializer"); init = build_x_compound_expr_from_list (init,
"new initializer");
else else
gcc_assert (TREE_CODE (init) != CONSTRUCTOR gcc_assert (TREE_CODE (init) != CONSTRUCTOR
|| TREE_TYPE (init) != NULL_TREE); || TREE_TYPE (init) != NULL_TREE);
...@@ -2096,6 +2110,7 @@ build_new_1 (tree exp) ...@@ -2096,6 +2110,7 @@ build_new_1 (tree exp)
init_expr = build_modify_expr (init_expr, INIT_EXPR, init); init_expr = build_modify_expr (init_expr, INIT_EXPR, init);
stable = stabilize_init (init_expr, &init_preeval_expr); stable = stabilize_init (init_expr, &init_preeval_expr);
} }
}
if (init_expr == error_mark_node) if (init_expr == error_mark_node)
return error_mark_node; return error_mark_node;
...@@ -2375,8 +2390,12 @@ get_temp_regvar (tree type, tree init) ...@@ -2375,8 +2390,12 @@ get_temp_regvar (tree type, tree init)
MAXINDEX is the maximum index of the array (one less than the MAXINDEX is the maximum index of the array (one less than the
number of elements). It is only used if number of elements). It is only used if
TYPE_DOMAIN (TREE_TYPE (BASE)) == NULL_TREE. TYPE_DOMAIN (TREE_TYPE (BASE)) == NULL_TREE.
INIT is the (possibly NULL) initializer. INIT is the (possibly NULL) initializer.
If EXPLICIT_DEFAULT_INIT_P is true, then INIT must be NULL. All
elements in the array are default-initialized.
FROM_ARRAY is 0 if we should init everything with INIT FROM_ARRAY is 0 if we should init everything with INIT
(i.e., every element initialized from INIT). (i.e., every element initialized from INIT).
FROM_ARRAY is 1 if we should index into INIT in parallel FROM_ARRAY is 1 if we should index into INIT in parallel
...@@ -2385,7 +2404,9 @@ get_temp_regvar (tree type, tree init) ...@@ -2385,7 +2404,9 @@ get_temp_regvar (tree type, tree init)
but use assignment instead of initialization. */ but use assignment instead of initialization. */
tree tree
build_vec_init (tree base, tree maxindex, tree init, int from_array) build_vec_init (tree base, tree maxindex, tree init,
bool explicit_default_init_p,
int from_array)
{ {
tree rval; tree rval;
tree base2 = NULL_TREE; tree base2 = NULL_TREE;
...@@ -2414,6 +2435,9 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array) ...@@ -2414,6 +2435,9 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array)
if (maxindex == NULL_TREE || maxindex == error_mark_node) if (maxindex == NULL_TREE || maxindex == error_mark_node)
return error_mark_node; return error_mark_node;
if (explicit_default_init_p)
gcc_assert (!init);
inner_elt_type = strip_array_types (atype); inner_elt_type = strip_array_types (atype);
if (init if (init
&& (from_array == 2 && (from_array == 2
...@@ -2544,7 +2568,7 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array) ...@@ -2544,7 +2568,7 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array)
We do need to keep going if we're copying an array. */ We do need to keep going if we're copying an array. */
if (from_array if (from_array
|| (TYPE_NEEDS_CONSTRUCTING (type) || ((TYPE_NEEDS_CONSTRUCTING (type) || explicit_default_init_p)
&& ! (host_integerp (maxindex, 0) && ! (host_integerp (maxindex, 0)
&& (num_initialized_elts && (num_initialized_elts
== tree_low_cst (maxindex, 0) + 1)))) == tree_low_cst (maxindex, 0) + 1))))
...@@ -2553,6 +2577,7 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array) ...@@ -2553,6 +2577,7 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array)
we've already initialized all the elements. */ we've already initialized all the elements. */
tree for_stmt; tree for_stmt;
tree elt_init; tree elt_init;
tree to;
for_stmt = begin_for_stmt (); for_stmt = begin_for_stmt ();
finish_for_init_stmt (for_stmt); finish_for_init_stmt (for_stmt);
...@@ -2562,9 +2587,10 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array) ...@@ -2562,9 +2587,10 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array)
finish_for_expr (build_unary_op (PREDECREMENT_EXPR, iterator, 0), finish_for_expr (build_unary_op (PREDECREMENT_EXPR, iterator, 0),
for_stmt); for_stmt);
to = build1 (INDIRECT_REF, type, base);
if (from_array) if (from_array)
{ {
tree to = build1 (INDIRECT_REF, type, base);
tree from; tree from;
if (base2) if (base2)
...@@ -2587,11 +2613,17 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array) ...@@ -2587,11 +2613,17 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array)
sorry sorry
("cannot initialize multi-dimensional array with initializer"); ("cannot initialize multi-dimensional array with initializer");
elt_init = build_vec_init (build1 (INDIRECT_REF, type, base), elt_init = build_vec_init (build1 (INDIRECT_REF, type, base),
0, 0, 0); 0, 0,
/*explicit_default_init_p=*/false,
0);
} }
else if (!TYPE_NEEDS_CONSTRUCTING (type))
elt_init = (build_modify_expr
(to, INIT_EXPR,
build_zero_init (type, size_one_node,
/*static_storage_p=*/false)));
else else
elt_init = build_aggr_init (build1 (INDIRECT_REF, type, base), elt_init = build_aggr_init (to, init, 0);
init, 0);
current_stmt_tree ()->stmts_are_full_exprs_p = 1; current_stmt_tree ()->stmts_are_full_exprs_p = 1;
finish_expr_stmt (elt_init); finish_expr_stmt (elt_init);
......
...@@ -5472,7 +5472,9 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs) ...@@ -5472,7 +5472,9 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
from_array = TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE from_array = TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE
? 1 + (modifycode != INIT_EXPR): 0; ? 1 + (modifycode != INIT_EXPR): 0;
return build_vec_init (lhs, NULL_TREE, newrhs, from_array); return build_vec_init (lhs, NULL_TREE, newrhs,
/*explicit_default_init_p=*/false,
from_array);
} }
if (modifycode == INIT_EXPR) if (modifycode == INIT_EXPR)
......
2005-08-26 Mark Mitchell <mark@codesourcery.com>
PR c++/23491
* g++.dg/init/new14.C: New test.
* g++.dg/expr/anew1.C: Do not XFAIL.
* g++.dg/expr/anew2.C: Likewise.
* g++.dg/expr/anew3.C: Likewise.
2005-08-26 Andrew Pinski <pinskia@physics.uc.edu> 2005-08-26 Andrew Pinski <pinskia@physics.uc.edu>
PR middle-end/22439 PR middle-end/22439
......
// { dg-do run { xfail *-*-* } } // { dg-do run }
// XFAILed until PR2123 is fixed
// PR 11228: array operator new, with zero-initialization and a variable sized array. // PR 11228: array operator new, with zero-initialization and a variable sized array.
// Regression test for PR // Regression test for PR
// Author: Matt Austern <austern@apple.com> // Author: Matt Austern <austern@apple.com>
......
// { dg-do run { xfail *-*-* } } // { dg-do run }
// XFAILed until PR2123 is fixed
// PR 11228: array operator new, with zero-initialization and a variable sized array. // PR 11228: array operator new, with zero-initialization and a variable sized array.
// Regression test for PR // Regression test for PR
// Author: Matt Austern <austern@apple.com> // Author: Matt Austern <austern@apple.com>
......
// { dg-do run { xfail *-*-* } } // { dg-do run }
// XFAILed until PR2123 is fixed
// PR 11228: array operator new, with zero-initialization and a variable sized array. // PR 11228: array operator new, with zero-initialization and a variable sized array.
// Regression test for PR // Regression test for PR
// Author: Matt Austern <austern@apple.com> // Author: Matt Austern <austern@apple.com>
......
// PR c++/23491
struct X
{
int m;
};
void f(int n)
{
const X *p = new const X[1] () ;
}
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