From b84f46516bc9e5293d8bc9333b5e8f494e223ff2 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Fri, 26 Aug 2005 19:32:31 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 16 ++++++ gcc/cp/cp-tree.h | 2 +- gcc/cp/init.c | 92 +++++++++++++++++++++---------- gcc/cp/typeck.c | 4 +- gcc/testsuite/ChangeLog | 8 +++ gcc/testsuite/g++.dg/expr/anew1.C | 3 +- gcc/testsuite/g++.dg/expr/anew2.C | 3 +- gcc/testsuite/g++.dg/expr/anew3.C | 3 +- gcc/testsuite/g++.dg/init/new14.C | 11 ++++ 9 files changed, 104 insertions(+), 38 deletions(-) create mode 100644 gcc/testsuite/g++.dg/init/new14.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index db7443b01f8..485cccd22e0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,19 @@ +2005-08-26 Mark Mitchell + + 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 PR c++/20817 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ff9c8bbf0d0..17e074dc99f 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3918,7 +3918,7 @@ extern tree get_type_value (tree); extern tree build_zero_init (tree, tree, bool); extern tree build_offset_ref (tree, tree, bool); 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_delete (tree, tree, special_function_kind, diff --git a/gcc/cp/init.c b/gcc/cp/init.c index a2fcc1ffe60..690e35f8913 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -358,6 +358,7 @@ perform_member_init (tree member, tree init) { /* Initialization of one array from another. */ finish_expr_stmt (build_vec_init (decl, NULL_TREE, TREE_VALUE (init), + /*explicit_default_init_p=*/false, /* from_array=*/1)); } else @@ -1112,6 +1113,7 @@ build_aggr_init (tree exp, tree init, int flags) if (itype && cp_type_quals (itype) != TYPE_UNQUALIFIED) itype = TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype); stmt_expr = build_vec_init (exp, NULL_TREE, init, + /*explicit_default_init_p=*/false, itype && same_type_p (itype, TREE_TYPE (exp))); TREE_READONLY (exp) = was_const; @@ -2055,46 +2057,59 @@ build_new_1 (tree exp) init_expr = build_indirect_ref (data_addr, NULL); - if (init == void_zero_node) - init = build_default_init (full_type, nelts); - else if (init && array_p) - pedwarn ("ISO C++ forbids initialization in array new"); - if (array_p) { + bool explicit_default_init_p = false; + + if (init == void_zero_node) + { + init = NULL_TREE; + explicit_default_init_p = true; + } + else if (init) + pedwarn ("ISO C++ forbids initialization in array new"); + init_expr = build_vec_init (init_expr, cp_build_binary_op (MINUS_EXPR, outer_nelts, integer_one_node), - init, /*from_array=*/0); + init, + explicit_default_init_p, + /*from_array=*/0); /* An array initialization is stable because the initialization of each element is a full-expression, so the temporaries don't leak out. */ stable = true; } - else if (TYPE_NEEDS_CONSTRUCTING (type)) - { - init_expr = build_special_member_call (init_expr, - complete_ctor_identifier, - init, elt_type, - LOOKUP_NORMAL); - stable = stabilize_init (init_expr, &init_preeval_expr); - } else { - /* We are processing something like `new int (10)', which - means allocate an int, and initialize it with 10. */ - - if (TREE_CODE (init) == TREE_LIST) - init = build_x_compound_expr_from_list (init, "new initializer"); + 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, + complete_ctor_identifier, + init, elt_type, + LOOKUP_NORMAL); + stable = stabilize_init (init_expr, &init_preeval_expr); + } else - gcc_assert (TREE_CODE (init) != CONSTRUCTOR - || TREE_TYPE (init) != NULL_TREE); - - init_expr = build_modify_expr (init_expr, INIT_EXPR, init); - stable = stabilize_init (init_expr, &init_preeval_expr); + { + /* We are processing something like `new int (10)', which + means allocate an int, and initialize it with 10. */ + + if (TREE_CODE (init) == TREE_LIST) + init = build_x_compound_expr_from_list (init, + "new initializer"); + else + gcc_assert (TREE_CODE (init) != CONSTRUCTOR + || TREE_TYPE (init) != NULL_TREE); + + init_expr = build_modify_expr (init_expr, INIT_EXPR, init); + stable = stabilize_init (init_expr, &init_preeval_expr); + } } if (init_expr == error_mark_node) @@ -2375,8 +2390,12 @@ get_temp_regvar (tree type, tree init) MAXINDEX is the maximum index of the array (one less than the number of elements). It is only used if TYPE_DOMAIN (TREE_TYPE (BASE)) == NULL_TREE. + 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 (i.e., every element initialized from INIT). FROM_ARRAY is 1 if we should index into INIT in parallel @@ -2385,7 +2404,9 @@ get_temp_regvar (tree type, tree init) but use assignment instead of initialization. */ 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 base2 = NULL_TREE; @@ -2414,6 +2435,9 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array) if (maxindex == NULL_TREE || maxindex == error_mark_node) return error_mark_node; + if (explicit_default_init_p) + gcc_assert (!init); + inner_elt_type = strip_array_types (atype); if (init && (from_array == 2 @@ -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. */ if (from_array - || (TYPE_NEEDS_CONSTRUCTING (type) + || ((TYPE_NEEDS_CONSTRUCTING (type) || explicit_default_init_p) && ! (host_integerp (maxindex, 0) && (num_initialized_elts == tree_low_cst (maxindex, 0) + 1)))) @@ -2553,6 +2577,7 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array) we've already initialized all the elements. */ tree for_stmt; tree elt_init; + tree to; for_stmt = begin_for_stmt (); finish_for_init_stmt (for_stmt); @@ -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), for_stmt); + to = build1 (INDIRECT_REF, type, base); + if (from_array) { - tree to = build1 (INDIRECT_REF, type, base); tree from; if (base2) @@ -2587,11 +2613,17 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array) sorry ("cannot initialize multi-dimensional array with initializer"); 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 - elt_init = build_aggr_init (build1 (INDIRECT_REF, type, base), - init, 0); + elt_init = build_aggr_init (to, init, 0); current_stmt_tree ()->stmts_are_full_exprs_p = 1; finish_expr_stmt (elt_init); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index a052ed168ff..96da3c636f5 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5472,7 +5472,9 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs) from_array = TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE ? 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) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5ad591dd32c..cb31b6aeca1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2005-08-26 Mark Mitchell + + 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 PR middle-end/22439 diff --git a/gcc/testsuite/g++.dg/expr/anew1.C b/gcc/testsuite/g++.dg/expr/anew1.C index 9e0d0ec601f..d7a4288802a 100644 --- a/gcc/testsuite/g++.dg/expr/anew1.C +++ b/gcc/testsuite/g++.dg/expr/anew1.C @@ -1,5 +1,4 @@ -// { dg-do run { xfail *-*-* } } -// XFAILed until PR2123 is fixed +// { dg-do run } // PR 11228: array operator new, with zero-initialization and a variable sized array. // Regression test for PR // Author: Matt Austern diff --git a/gcc/testsuite/g++.dg/expr/anew2.C b/gcc/testsuite/g++.dg/expr/anew2.C index aa11eef149c..fbf2152d4ac 100644 --- a/gcc/testsuite/g++.dg/expr/anew2.C +++ b/gcc/testsuite/g++.dg/expr/anew2.C @@ -1,5 +1,4 @@ -// { dg-do run { xfail *-*-* } } -// XFAILed until PR2123 is fixed +// { dg-do run } // PR 11228: array operator new, with zero-initialization and a variable sized array. // Regression test for PR // Author: Matt Austern diff --git a/gcc/testsuite/g++.dg/expr/anew3.C b/gcc/testsuite/g++.dg/expr/anew3.C index c8ab44183ca..9bb64ea4ea7 100644 --- a/gcc/testsuite/g++.dg/expr/anew3.C +++ b/gcc/testsuite/g++.dg/expr/anew3.C @@ -1,5 +1,4 @@ -// { dg-do run { xfail *-*-* } } -// XFAILed until PR2123 is fixed +// { dg-do run } // PR 11228: array operator new, with zero-initialization and a variable sized array. // Regression test for PR // Author: Matt Austern diff --git a/gcc/testsuite/g++.dg/init/new14.C b/gcc/testsuite/g++.dg/init/new14.C new file mode 100644 index 00000000000..5d13da20e71 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/new14.C @@ -0,0 +1,11 @@ +// PR c++/23491 + +struct X +{ + int m; +}; + +void f(int n) +{ + const X *p = new const X[1] () ; +}