From 81de459ec7ccf46c3e5a776b0c13f01e989d9593 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Sat, 5 Sep 2020 20:50:32 -0400 Subject: c++: Further tweaks for new-expression and paren-init [PR77841] This patch corrects our handling of array new-expression with ()-init: new int[4](1, 2, 3, 4); should work even with the explicit array bound, and new char[3]("so_sad"); should cause an error, but we weren't giving any. Fixed by handling array new-expressions with ()-init in the same spot where we deduce the array bound in array new-expression. I'm now always passing STRING_CSTs to build_new_1 wrapped in { } which allowed me to remove the special handling of STRING_CSTs in build_new_1. And since the DIRECT_LIST_INIT_P block in build_new_1 calls digest_init, we report errors about too short arrays. reshape_init now does the {"foo"} -> "foo" transformation even for CONSTRUCTOR_IS_PAREN_INIT, so no need to do it in build_new. I took a stab at cp_complete_array_type's "FIXME: this code is duplicated from reshape_init", but calling reshape_init there, I ran into issues with has_designator_problem: when we reshape an already reshaped CONSTRUCTOR again, d.cur.index has been filled, so we think that we have a user-provided designator (though there was no designator in the source code), and report an error. gcc/cp/ChangeLog: PR c++/77841 * decl.c (reshape_init): If we're initializing a char array from a string-literal that is enclosed in braces, unwrap it. * init.c (build_new_1): Don't handle string-initializers here. (build_new): Handle new-expression with paren-init when the array bound is known. Always pass string constants to build_new_1 enclosed in braces. Don't handle string-initializers in any special way. gcc/testsuite/ChangeLog: PR c++/77841 * g++.old-deja/g++.ext/arrnew2.C: Expect the error only in C++17 and less. * g++.old-deja/g++.robertl/eb58.C: Adjust dg-error. * g++.old-deja/g++.robertl/eb63.C: Expect the error only in C++17 and less. * g++.dg/cpp2a/new-array5.C: New test. * g++.dg/cpp2a/paren-init36.C: New test. * g++.dg/cpp2a/paren-init37.C: New test. * g++.dg/pr84729.C: Adjust dg-error. --- gcc/cp/decl.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'gcc/cp/decl.c') 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. */ -- cgit v1.1