Commit 0655c6d5 by Jason Merrill Committed by Jason Merrill

PR c++/79130 - decomposition and direct-initialization

	* init.c (build_aggr_init): Communicate direct-initialization to
	build_vec_init.
	(build_vec_init): Check for array copy sooner.
	* parser.c (cp_parser_decomposition_declaration): Remove call to
	build_x_compound_expr_from_list.

From-SVN: r244635
parent 332429c8
2017-01-19 Jason Merrill <jason@redhat.com>
PR c++/79130 - decomposition and direct-initialization
* init.c (build_aggr_init): Communicate direct-initialization to
build_vec_init.
(build_vec_init): Check for array copy sooner.
* parser.c (cp_parser_decomposition_declaration): Remove call to
build_x_compound_expr_from_list.
2017-01-18 Jason Merrill <jason@redhat.com> 2017-01-18 Jason Merrill <jason@redhat.com>
PR c++/68666 - member variable template-id PR c++/68666 - member variable template-id
......
...@@ -1574,20 +1574,24 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain) ...@@ -1574,20 +1574,24 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
TREE_READONLY (exp) = 0; TREE_READONLY (exp) = 0;
TREE_THIS_VOLATILE (exp) = 0; TREE_THIS_VOLATILE (exp) = 0;
if (init && init != void_type_node
&& TREE_CODE (init) != TREE_LIST
&& !(TREE_CODE (init) == TARGET_EXPR
&& TARGET_EXPR_DIRECT_INIT_P (init))
&& !DIRECT_LIST_INIT_P (init))
flags |= LOOKUP_ONLYCONVERTING;
if (TREE_CODE (type) == ARRAY_TYPE) if (TREE_CODE (type) == ARRAY_TYPE)
{ {
tree itype = init ? TREE_TYPE (init) : NULL_TREE; tree itype = init ? TREE_TYPE (init) : NULL_TREE;
int from_array = 0; int from_array = 0;
if (VAR_P (exp) && DECL_DECOMPOSITION_P (exp)) if (VAR_P (exp) && DECL_DECOMPOSITION_P (exp))
from_array = 1; {
from_array = 1;
if (init && DECL_P (init)
&& !(flags & LOOKUP_ONLYCONVERTING))
{
/* Wrap the initializer in a CONSTRUCTOR so that build_vec_init
recognizes it as direct-initialization. */
init = build_constructor_single (init_list_type_node,
NULL_TREE, init);
CONSTRUCTOR_IS_DIRECT_INIT (init) = true;
}
}
else else
{ {
/* An array may not be initialized use the parenthesized /* An array may not be initialized use the parenthesized
...@@ -1621,6 +1625,13 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain) ...@@ -1621,6 +1625,13 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
return stmt_expr; return stmt_expr;
} }
if (init && init != void_type_node
&& TREE_CODE (init) != TREE_LIST
&& !(TREE_CODE (init) == TARGET_EXPR
&& TARGET_EXPR_DIRECT_INIT_P (init))
&& !DIRECT_LIST_INIT_P (init))
flags |= LOOKUP_ONLYCONVERTING;
if ((VAR_P (exp) || TREE_CODE (exp) == PARM_DECL) if ((VAR_P (exp) || TREE_CODE (exp) == PARM_DECL)
&& !lookup_attribute ("warn_unused", TYPE_ATTRIBUTES (type))) && !lookup_attribute ("warn_unused", TYPE_ATTRIBUTES (type)))
/* Just know that we've seen something for this node. */ /* Just know that we've seen something for this node. */
...@@ -3825,6 +3836,18 @@ build_vec_init (tree base, tree maxindex, tree init, ...@@ -3825,6 +3836,18 @@ build_vec_init (tree base, tree maxindex, tree init,
&& from_array != 2) && from_array != 2)
init = TARGET_EXPR_INITIAL (init); init = TARGET_EXPR_INITIAL (init);
bool direct_init = false;
if (from_array && init && BRACE_ENCLOSED_INITIALIZER_P (init)
&& CONSTRUCTOR_NELTS (init) == 1)
{
tree elt = CONSTRUCTOR_ELT (init, 0)->value;
if (TREE_CODE (TREE_TYPE (elt)) == ARRAY_TYPE)
{
direct_init = DIRECT_LIST_INIT_P (init);
init = elt;
}
}
/* If we have a braced-init-list, make sure that the array /* If we have a braced-init-list, make sure that the array
is big enough for all the initializers. */ is big enough for all the initializers. */
bool length_check = (init && TREE_CODE (init) == CONSTRUCTOR bool length_check = (init && TREE_CODE (init) == CONSTRUCTOR
...@@ -3905,18 +3928,6 @@ build_vec_init (tree base, tree maxindex, tree init, ...@@ -3905,18 +3928,6 @@ build_vec_init (tree base, tree maxindex, tree init,
base = get_temp_regvar (ptype, rval); base = get_temp_regvar (ptype, rval);
iterator = get_temp_regvar (ptrdiff_type_node, maxindex); iterator = get_temp_regvar (ptrdiff_type_node, maxindex);
bool direct_init = false;
if (from_array && init && BRACE_ENCLOSED_INITIALIZER_P (init)
&& CONSTRUCTOR_NELTS (init) == 1)
{
tree elt = CONSTRUCTOR_ELT (init, 0)->value;
if (TREE_CODE (TREE_TYPE (elt)) == ARRAY_TYPE)
{
direct_init = DIRECT_LIST_INIT_P (init);
init = elt;
}
}
/* If initializing one array from another, initialize element by /* If initializing one array from another, initialize element by
element. We rely upon the below calls to do the argument element. We rely upon the below calls to do the argument
checking. Evaluate the initializer before entering the try block. */ checking. Evaluate the initializer before entering the try block. */
......
...@@ -13026,9 +13026,6 @@ cp_parser_decomposition_declaration (cp_parser *parser, ...@@ -13026,9 +13026,6 @@ cp_parser_decomposition_declaration (cp_parser *parser,
*init_loc = cp_lexer_peek_token (parser->lexer)->location; *init_loc = cp_lexer_peek_token (parser->lexer)->location;
tree initializer = cp_parser_initializer (parser, &is_direct_init, tree initializer = cp_parser_initializer (parser, &is_direct_init,
&non_constant_p); &non_constant_p);
if (TREE_CODE (initializer) == TREE_LIST)
initializer = build_x_compound_expr_from_list (initializer, ELK_INIT,
tf_warning_or_error);
if (decl != error_mark_node) if (decl != error_mark_node)
{ {
...@@ -89,4 +89,40 @@ main () ...@@ -89,4 +89,40 @@ main ()
} }
if (ccnt != 12 || dcnt != 24 || cccnt != 6 || tccnt != 6) if (ccnt != 12 || dcnt != 24 || cccnt != 6 || tccnt != 6)
__builtin_abort (); __builtin_abort ();
{
A a[6];
if (ccnt != 18 || dcnt != 24 || cccnt != 6 || tccnt != 6)
__builtin_abort ();
{
auto [b,c,d,e,f,g] ( a ); // { dg-warning "decomposition declaration only available with" "" { target c++14_down } }
if (ccnt != 18 || dcnt != 24 || cccnt != 12 || tccnt != 6)
__builtin_abort ();
b.a++;
c.a += 2;
f.a += 3;
if (b.a != 7 || c.a != 8 || d.a != 6 || e.a != 6 || f.a != 9 || g.a != 6)
__builtin_abort ();
if (&b == &a[0] || &c == &a[1] || &d == &a[2] || &e == &a[3] || &f == &a[4] || &g == &a[5])
__builtin_abort ();
{
auto&[ h, i, j, k, l, m ] (a); // { dg-warning "decomposition declaration only available with" "" { target c++14_down } }
if (ccnt != 18 || dcnt != 24 || cccnt != 12 || tccnt != 6)
__builtin_abort ();
j.a += 4;
k.a += 5;
m.a += 6;
if (a[0].a != 6 || a[1].a != 6 || a[2].a != 10 || a[3].a != 11 || a[4].a != 6 || a[5].a != 12)
__builtin_abort ();
if (&h != &a[0] || &i != &a[1] || &j != &a[2] || &k != &a[3] || &l != &a[4] || &m != &a[5])
__builtin_abort ();
}
if (ccnt != 18 || dcnt != 24 || cccnt != 12 || tccnt != 6)
__builtin_abort ();
}
if (ccnt != 18 || dcnt != 30 || cccnt != 12 || tccnt != 6)
__builtin_abort ();
}
if (ccnt != 18 || dcnt != 36 || cccnt != 12 || tccnt != 6)
__builtin_abort ();
} }
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