diff options
Diffstat (limited to 'gcc/cp/init.c')
-rw-r--r-- | gcc/cp/init.c | 53 |
1 files changed, 37 insertions, 16 deletions
diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 5eba4c3e18c..1fad79cb247 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1575,27 +1575,34 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain) if (TREE_CODE (type) == ARRAY_TYPE) { - tree itype; + tree itype = init ? TREE_TYPE (init) : NULL_TREE; + int from_array = 0; - /* An array may not be initialized use the parenthesized - initialization form -- unless the initializer is "()". */ - if (init && TREE_CODE (init) == TREE_LIST) + if (VAR_P (exp) && DECL_DECOMPOSITION_P (exp)) + from_array = 1; + else { - if (complain & tf_error) - error ("bad array initializer"); - return error_mark_node; + /* An array may not be initialized use the parenthesized + initialization form -- unless the initializer is "()". */ + if (init && TREE_CODE (init) == TREE_LIST) + { + if (complain & tf_error) + error ("bad array initializer"); + return error_mark_node; + } + /* Must arrange to initialize each element of EXP + from elements of INIT. */ + if (cv_qualified_p (type)) + TREE_TYPE (exp) = cv_unqualified (type); + if (itype && cv_qualified_p (itype)) + TREE_TYPE (init) = cv_unqualified (itype); + from_array = (itype && same_type_p (TREE_TYPE (init), + TREE_TYPE (exp))); } - /* Must arrange to initialize each element of EXP - from elements of INIT. */ - itype = init ? TREE_TYPE (init) : NULL_TREE; - if (cv_qualified_p (type)) - TREE_TYPE (exp) = cv_unqualified (type); - if (itype && cv_qualified_p (itype)) - TREE_TYPE (init) = cv_unqualified (itype); + stmt_expr = build_vec_init (exp, NULL_TREE, init, /*explicit_value_init_p=*/false, - itype && same_type_p (TREE_TYPE (init), - TREE_TYPE (exp)), + from_array, complain); TREE_READONLY (exp) = was_const; TREE_THIS_VOLATILE (exp) = was_volatile; @@ -3891,6 +3898,18 @@ 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. */ @@ -4115,6 +4134,8 @@ build_vec_init (tree base, tree maxindex, tree init, from = build1 (INDIRECT_REF, itype, base2); if (xvalue) from = move (from); + if (direct_init) + from = build_tree_list (NULL_TREE, from); } else from = NULL_TREE; |