diff options
author | Jason Merrill <jason@redhat.com> | 2017-01-19 09:37:51 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2017-01-19 09:37:51 -0500 |
commit | 0655c6d5561026bf5b3749d69cc3f30ea09ff66e (patch) | |
tree | c4542bd3a072177016e813d586013c4b67e40f3a | |
parent | 332429c807f56de7948885368277723a7a5ac0ac (diff) | |
download | gcc-0655c6d5561026bf5b3749d69cc3f30ea09ff66e.zip gcc-0655c6d5561026bf5b3749d69cc3f30ea09ff66e.tar.gz gcc-0655c6d5561026bf5b3749d69cc3f30ea09ff66e.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/init.c | 51 | ||||
-rw-r--r-- | gcc/cp/parser.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/decomp6.C | 36 |
4 files changed, 76 insertions, 23 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f8377e2..5b8eb7c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 8f68c88..15388b1 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -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. */ diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 6d3b877..29dcfea 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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) { diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp6.C b/gcc/testsuite/g++.dg/cpp1z/decomp6.C index ed6fce4..7a8a239 100644 --- a/gcc/testsuite/g++.dg/cpp1z/decomp6.C +++ b/gcc/testsuite/g++.dg/cpp1z/decomp6.C @@ -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 (); } |