diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/decl.c | 12 | ||||
-rw-r--r-- | gcc/cp/init.c | 54 |
2 files changed, 34 insertions, 32 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index ca1c8a4..ce97d19 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6599,7 +6599,17 @@ reshape_init (tree type, tree init, tsubst_flags_t complain) /* Brace elision is not performed for a CONSTRUCTOR representing parenthesized aggregate initialization. */ if (CONSTRUCTOR_IS_PAREN_INIT (init)) - return init; + { + tree elt = (*v)[0].value; + /* If we're initializing a char array from a string-literal that is + enclosed in braces, unwrap it here. */ + if (TREE_CODE (type) == ARRAY_TYPE + && vec_safe_length (v) == 1 + && char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type))) + && TREE_CODE (tree_strip_any_location_wrapper (elt)) == STRING_CST) + return elt; + return init; + } /* Handle [dcl.init.list] direct-list-initialization from single element of enumeration with a fixed underlying type. */ diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 3268ae4..e84e985 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -3596,15 +3596,6 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, vecinit = digest_init (arraytype, vecinit, complain); } } - /* This handles code like new char[]{"foo"}. */ - else if (len == 1 - && char_type_p (TYPE_MAIN_VARIANT (type)) - && TREE_CODE (tree_strip_any_location_wrapper ((**init)[0])) - == STRING_CST) - { - vecinit = (**init)[0]; - STRIP_ANY_LOCATION_WRAPPER (vecinit); - } else if (*init) { if (complain & tf_error) @@ -3944,9 +3935,8 @@ build_new (location_t loc, vec<tree, va_gc> **placement, tree type, } /* P1009: Array size deduction in new-expressions. */ - if (TREE_CODE (type) == ARRAY_TYPE - && !TYPE_DOMAIN (type) - && *init) + const bool array_p = TREE_CODE (type) == ARRAY_TYPE; + if (*init && (array_p || (nelts && cxx_dialect >= cxx20))) { /* This means we have 'new T[]()'. */ if ((*init)->is_empty ()) @@ -3959,27 +3949,29 @@ build_new (location_t loc, vec<tree, va_gc> **placement, tree type, /* The C++20 'new T[](e_0, ..., e_k)' case allowed by P0960. */ if (!DIRECT_LIST_INIT_P (elt) && cxx_dialect >= cxx20) { - /* Handle new char[]("foo"). */ - if (vec_safe_length (*init) == 1 - && char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type))) - && TREE_CODE (tree_strip_any_location_wrapper (elt)) - == STRING_CST) - /* Leave it alone: the string should not be wrapped in {}. */; - else - { - tree ctor = build_constructor_from_vec (init_list_type_node, *init); - CONSTRUCTOR_IS_DIRECT_INIT (ctor) = true; - CONSTRUCTOR_IS_PAREN_INIT (ctor) = true; - elt = ctor; - /* We've squashed all the vector elements into the first one; - truncate the rest. */ - (*init)->truncate (1); - } + tree ctor = build_constructor_from_vec (init_list_type_node, *init); + CONSTRUCTOR_IS_DIRECT_INIT (ctor) = true; + CONSTRUCTOR_IS_PAREN_INIT (ctor) = true; + elt = ctor; + /* We've squashed all the vector elements into the first one; + truncate the rest. */ + (*init)->truncate (1); } /* Otherwise we should have 'new T[]{e_0, ..., e_k}'. */ - if (BRACE_ENCLOSED_INITIALIZER_P (elt)) - elt = reshape_init (type, elt, complain); - cp_complete_array_type (&type, elt, /*do_default*/false); + if (array_p && !TYPE_DOMAIN (type)) + { + /* We need to reshape before deducing the bounds to handle code like + + struct S { int x, y; }; + new S[]{1, 2, 3, 4}; + + which should deduce S[2]. But don't change ELT itself: we want to + pass a list-initializer to build_new_1, even for STRING_CSTs. */ + tree e = elt; + if (BRACE_ENCLOSED_INITIALIZER_P (e)) + e = reshape_init (type, e, complain); + cp_complete_array_type (&type, e, /*do_default*/false); + } } /* The type allocated must be complete. If the new-type-id was |