Commit 25357d1e by Jason Merrill Committed by Jason Merrill

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
parent f345f84a
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
......
......@@ -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;
}
......
......@@ -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. */
......
......@@ -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)
{
......
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.
......
// 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;
}
// 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;
}
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