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
This commit is contained in:
Jason Merrill 2017-01-19 09:37:51 -05:00 committed by Jason Merrill
parent 332429c807
commit 0655c6d556
4 changed files with 76 additions and 23 deletions

View File

@ -1,3 +1,12 @@
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>
PR c++/68666 - member variable template-id

View File

@ -1574,20 +1574,24 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
TREE_READONLY (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)
{
tree itype = init ? TREE_TYPE (init) : NULL_TREE;
int from_array = 0;
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
{
/* 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)
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)
&& !lookup_attribute ("warn_unused", TYPE_ATTRIBUTES (type)))
/* Just know that we've seen something for this node. */
@ -3825,6 +3836,18 @@ build_vec_init (tree base, tree maxindex, tree init,
&& from_array != 2)
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
is big enough for all the initializers. */
bool length_check = (init && TREE_CODE (init) == CONSTRUCTOR
@ -3905,18 +3928,6 @@ build_vec_init (tree base, tree maxindex, tree init,
base = get_temp_regvar (ptype, rval);
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
element. We rely upon the below calls to do the argument
checking. Evaluate the initializer before entering the try block. */

View File

@ -13026,9 +13026,6 @@ cp_parser_decomposition_declaration (cp_parser *parser,
*init_loc = cp_lexer_peek_token (parser->lexer)->location;
tree initializer = cp_parser_initializer (parser, &is_direct_init,
&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)
{

View File

@ -89,4 +89,40 @@ main ()
}
if (ccnt != 12 || dcnt != 24 || cccnt != 6 || tccnt != 6)
__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 ();
}