diff options
author | Jason Merrill <jason@redhat.com> | 2009-07-12 15:19:03 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2009-07-12 15:19:03 -0400 |
commit | 25357d1ee0ce69a5b1c194e7e1c7b6437c189b01 (patch) | |
tree | 43c0739a8937332d11e29f2a24b12fe31e9a6a6d | |
parent | f345f84ae69406344bbc74ff0c72904e317ad4fe (diff) | |
download | gcc-25357d1ee0ce69a5b1c194e7e1c7b6437c189b01.zip gcc-25357d1ee0ce69a5b1c194e7e1c7b6437c189b01.tar.gz gcc-25357d1ee0ce69a5b1c194e7e1c7b6437c189b01.tar.bz2 |
re PR c++/40689 ([C++0x]: error with initializer list in N2672)
PR c++/40689
* init.c (build_new_1): Handle initializer list as array initializer.
(build_vec_init): Likewise.
* typeck.c (cp_build_modify_expr): Likewise.
* typeck2.c (process_init_constructor_array): Error rather than abort
if too many initializers.
From-SVN: r149533
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/init.c | 39 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 10 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/initlist20.C | 17 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/initlist21.C | 18 |
7 files changed, 93 insertions, 13 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c29e32d..cff424f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2009-07-12 Jason Merrill <jason@redhat.com> + + PR c++/40689 + * init.c (build_new_1): Handle initializer list as array initializer. + (build_vec_init): Likewise. + * typeck.c (cp_build_modify_expr): Likewise. + * typeck2.c (process_init_constructor_array): Error rather than abort + if too many initializers. + 2009-07-10 Jakub Jelinek <jakub@redhat.com> PR c++/40502 diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 68ffe3a..19b2489 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1773,6 +1773,7 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, /* The type of the new-expression. (This type is always a pointer type.) */ tree pointer_type; + tree non_const_pointer_type; tree outer_nelts = NULL_TREE; tree alloc_call, alloc_expr; /* The address returned by the call to "operator new". This node is @@ -2076,9 +2077,15 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, } /* Now use a pointer to the type we've actually allocated. */ - data_addr = fold_convert (pointer_type, data_addr); + + /* But we want to operate on a non-const version to start with, + since we'll be modifying the elements. */ + non_const_pointer_type = build_pointer_type + (cp_build_qualified_type (type, TYPE_QUALS (type) & ~TYPE_QUAL_CONST)); + + data_addr = fold_convert (non_const_pointer_type, data_addr); /* Any further uses of alloc_node will want this type, too. */ - alloc_node = fold_convert (pointer_type, alloc_node); + alloc_node = fold_convert (non_const_pointer_type, alloc_node); /* Now initialize the allocated object. Note that we preevaluate the initialization expression, apart from the actual constructor call or @@ -2098,12 +2105,32 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, if (array_p) { - if (*init) + tree vecinit = NULL_TREE; + if (*init && VEC_length (tree, *init) == 1 + && BRACE_ENCLOSED_INITIALIZER_P (VEC_index (tree, *init, 0)) + && CONSTRUCTOR_IS_DIRECT_INIT (VEC_index (tree, *init, 0))) + { + tree arraytype, domain; + vecinit = VEC_index (tree, *init, 0); + if (TREE_CONSTANT (nelts)) + domain = compute_array_index_type (NULL_TREE, nelts); + else + { + domain = NULL_TREE; + if (CONSTRUCTOR_NELTS (vecinit) > 0) + warning (0, "non-constant array size in new, unable to " + "verify length of initializer-list"); + } + arraytype = build_cplus_array_type (type, domain); + vecinit = digest_init (arraytype, vecinit); + } + else if (*init) { if (complain & tf_error) permerror (input_location, "ISO C++ forbids initialization in array new"); else return error_mark_node; + vecinit = build_tree_list_vec (*init); } init_expr = build_vec_init (data_addr, @@ -2111,7 +2138,7 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, MINUS_EXPR, outer_nelts, integer_one_node, complain), - build_tree_list_vec (*init), + vecinit, explicit_value_init_p, /*from_array=*/0, complain); @@ -2270,7 +2297,7 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, /* A new-expression is never an lvalue. */ gcc_assert (!lvalue_p (rval)); - return rval; + return convert (pointer_type, rval); } /* Generate a representation for a C++ "new" expression. *PLACEMENT @@ -2664,6 +2691,7 @@ build_vec_init (tree base, tree maxindex, tree init, inner_elt_type = strip_array_types (type); if (init + && TREE_CODE (atype) == ARRAY_TYPE && (from_array == 2 ? (!CLASS_TYPE_P (inner_elt_type) || !TYPE_HAS_COMPLEX_ASSIGN_REF (inner_elt_type)) @@ -2679,7 +2707,6 @@ build_vec_init (tree base, tree maxindex, tree init, brace-enclosed initializers. In this case, digest_init and store_constructor will handle the semantics for us. */ - gcc_assert (TREE_CODE (atype) == ARRAY_TYPE); stmt_expr = build2 (INIT_EXPR, atype, base, init); return stmt_expr; } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 871c1d3..6a4802e 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -6202,8 +6202,11 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, { int from_array; - if (!same_or_base_type_p (TYPE_MAIN_VARIANT (lhstype), - TYPE_MAIN_VARIANT (TREE_TYPE (rhs)))) + if (BRACE_ENCLOSED_INITIALIZER_P (rhs)) + rhs = digest_init (lhstype, rhs); + + else if (!same_or_base_type_p (TYPE_MAIN_VARIANT (lhstype), + TYPE_MAIN_VARIANT (TREE_TYPE (rhs)))) { if (complain & tf_error) error ("incompatible types in assignment of %qT to %qT", @@ -6212,7 +6215,8 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, } /* Allow array assignment in compiler-generated code. */ - if (!current_function_decl || !DECL_ARTIFICIAL (current_function_decl)) + else if (!current_function_decl + || !DECL_ARTIFICIAL (current_function_decl)) { /* This routine is used for both initialization and assignment. Make sure the diagnostic message differentiates the context. */ diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index c43fd76..d68383e 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -913,10 +913,9 @@ process_init_constructor_array (tree type, tree init) /* Vectors are like simple fixed-size arrays. */ len = TYPE_VECTOR_SUBPARTS (type); - /* There cannot be more initializers than needed as otherwise - reshape_init would have already rejected the initializer. */ - if (!unbounded) - gcc_assert (VEC_length (constructor_elt, v) <= len); + /* There must not be more initializers than needed. */ + if (!unbounded && VEC_length (constructor_elt, v) > len) + error ("too many initializers for %qT", type); for (i = 0; VEC_iterate (constructor_elt, v, i, ce); ++i) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7df599e..a12a5d2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2009-07-12 Jason Merrill <jason@redhat.com> + + PR c++/40689 + * g++.dg/cpp0x/initlist20.C: New. + * g++.dg/cpp0x/initlist21.C: New. + 2009-07-12 Ira Rosen <irar@il.ibm.com> * gcc.dg/vect/no-scevccp-outer-2.c: Expect to vectorize. diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist20.C b/gcc/testsuite/g++.dg/cpp0x/initlist20.C new file mode 100644 index 0000000..fcdb73f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist20.C @@ -0,0 +1,17 @@ +// PR c++/40689 +// { dg-options "-std=c++0x" } + +class X +{ + public: + X(): data {1,2,3,4,5} {} + private: + const short data[5]; +}; + +int main() +{ + const float * pData = new const float[4] { 1.5, 2.5, 3.5, 4.5 }; + + return 0; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist21.C b/gcc/testsuite/g++.dg/cpp0x/initlist21.C new file mode 100644 index 0000000..9412a08 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist21.C @@ -0,0 +1,18 @@ +// PR c++/40689 +// { dg-options "-std=c++0x" } + +class X +{ + public: + X(): data {1,2} {} // { dg-error "too many initializers" } + private: + const short data[1]; +}; + +int f(int n) +{ + const float * pData = new const float[1] { 1.5, 2.5 }; // { dg-error "too many initializers" } + pData = new const float[n] { 1.5, 2.5 }; // { dg-warning "array size" } + + return 0; +} |