From: Will Wray <wjwray@gmail.com>
To: gcc-patches@gcc.gnu.org
Cc: Will Wray <wjwray@gmail.com>
Subject: [PATCH 1/3] c++: designated init of char array by string constant [PR55227]
Date: Sun, 21 Nov 2021 21:51:12 -0500 [thread overview]
Message-ID: <20211122025114.3167997-2-wjwray@gmail.com> (raw)
In-Reply-To: <20211122025114.3167997-1-wjwray@gmail.com>
Also address "FIXME: this code is duplicated from reshape_init" in
cp_complete_array_type by always calling reshape_init on init-list.
PR c++/55227
gcc/cp/ChangeLog:
* decl.c (reshape_init_r): Only call has_designator_check when
first_initializer_p or for the inner constructor element.
(cp_complete_array_type): Call reshape_init on braced-init-list.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/desig20.C: New test.
---
gcc/cp/decl.c | 42 +++++++++++++------------------
gcc/testsuite/g++.dg/cpp2a/desig20.C | 48 ++++++++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+), 25 deletions(-)
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 2ddf0e4a524..83a2d3bf8f1 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -6824,28 +6824,31 @@ reshape_init_r (tree type, reshape_iter *d, tree first_initializer_p,
if (TREE_CODE (type) == ARRAY_TYPE
&& char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type))))
{
- tree str_init = init;
- tree stripped_str_init = stripped_init;
+ tree arr_init = init;
+ tree stripped_arr_init = stripped_init;
+ reshape_iter stripd = {};
/* Strip one level of braces if and only if they enclose a single
element (as allowed by [dcl.init.string]). */
if (!first_initializer_p
- && TREE_CODE (stripped_str_init) == CONSTRUCTOR
- && CONSTRUCTOR_NELTS (stripped_str_init) == 1)
+ && TREE_CODE (stripped_arr_init) == CONSTRUCTOR
+ && CONSTRUCTOR_NELTS (stripped_arr_init) == 1)
{
- str_init = (*CONSTRUCTOR_ELTS (stripped_str_init))[0].value;
- stripped_str_init = tree_strip_any_location_wrapper (str_init);
+ stripd.cur = CONSTRUCTOR_ELT (stripped_arr_init, 0);
+ arr_init = stripd.cur->value;
+ stripped_arr_init = tree_strip_any_location_wrapper (arr_init);
}
/* If it's a string literal, then it's the initializer for the array
as a whole. Otherwise, continue with normal initialization for
array types (one value per array element). */
- if (TREE_CODE (stripped_str_init) == STRING_CST)
+ if (TREE_CODE (stripped_arr_init) == STRING_CST)
{
- if (has_designator_problem (d, complain))
+ if ((first_initializer_p && has_designator_problem (d, complain))
+ || (stripd.cur && has_designator_problem (&stripd, complain)))
return error_mark_node;
d->cur++;
- return str_init;
+ return arr_init;
}
}
@@ -9545,22 +9548,11 @@ cp_complete_array_type (tree *ptype, tree initial_value, bool do_default)
if (initial_value)
{
/* An array of character type can be initialized from a
- brace-enclosed string constant.
-
- FIXME: this code is duplicated from reshape_init. Probably
- we should just call reshape_init here? */
- if (char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (*ptype)))
- && TREE_CODE (initial_value) == CONSTRUCTOR
- && !vec_safe_is_empty (CONSTRUCTOR_ELTS (initial_value)))
- {
- vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (initial_value);
- tree value = (*v)[0].value;
- STRIP_ANY_LOCATION_WRAPPER (value);
-
- if (TREE_CODE (value) == STRING_CST
- && v->length () == 1)
- initial_value = value;
- }
+ brace-enclosed string constant so call reshape_init to
+ remove the optional braces from a braced string literal. */
+ if (BRACE_ENCLOSED_INITIALIZER_P (initial_value))
+ initial_value = reshape_init (*ptype, initial_value,
+ tf_warning_or_error);
/* If any of the elements are parameter packs, we can't actually
complete this type now because the array size is dependent. */
diff --git a/gcc/testsuite/g++.dg/cpp2a/desig20.C b/gcc/testsuite/g++.dg/cpp2a/desig20.C
new file mode 100644
index 00000000000..daadfa58855
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/desig20.C
@@ -0,0 +1,48 @@
+// PR c++/55227
+// Test designated initializer for char array by string constant
+
+// { dg-options "" }
+
+struct C {char a[2];};
+
+/* Case a, designated, unbraced, string-literal of the exact same size
+ as the initialized char array; valid and accepted before and after. */
+C a = {.a="a"};
+
+/* Cases b,c,d, designated, braced or mimatched-size, string literal,
+ previously rejected; "C99 designator 'a' outside aggregate initializer". */
+C b = {.a=""};
+C c = {.a={""}};
+C d = {.a={"a"}};
+
+/* Case e, designated char array field and braced, designated array element(s)
+ (with GNU [N]= extension) valid and accepted before and after. */
+C e = {.a={[0]='a'}};
+
+/* Cases f,g,h, braced string literal, 'designated' within inner braces;
+ invalid, previously accepted as positional with 'designator' ignored. */
+C f = {{[0]="a"}}; // { dg-error "C99 designator .0. outside aggregate initializer" }
+C g = {{.a="a"}}; // { dg-error "C99 designator .a. outside aggregate initializer" }
+C h = {{.b="a"}}; // { dg-error "C99 designator .b. outside aggregate initializer" }
+
+char a2[][10] = { [0] = { "aaa" } };
+
+struct D { C c; int a[8]; };
+
+D x = { .c {.a={"a"}}, .a={1,2,3,4,5,6,7,8} };
+
+struct A { union { int a; char c[4]; }; };
+
+A non = { .c = "c++" };
+
+template <class T>
+void t()
+{
+ C ca[] = { {.a=""}, {.a={""}}, };
+
+}
+
+void u()
+{
+ return t<void>();
+}
--
2.31.1
next prev parent reply other threads:[~2021-11-22 2:51 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-22 2:51 [PATCH 0/3] P1997 'array-copy' patchset [PR103238] Will Wray
2021-11-22 2:51 ` Will Wray [this message]
2021-11-25 16:05 ` [PATCH 1/3] c++: designated init of char array by string constant [PR55227] Jason Merrill
2021-11-22 2:51 ` [PATCH 2/3] c++: P1997 array-copy extensions: Initialization [PR103238] Will Wray
2021-11-27 22:56 ` Jason Merrill
2021-11-22 2:51 ` [PATCH 3/3] c++: P1997 array-copy extensions: Assignment, return, etc. [PR103238] Will Wray
2021-11-22 20:41 ` Joseph Myers
2021-11-22 21:21 ` will wray
2021-11-29 22:44 ` Jason Merrill
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211122025114.3167997-2-wjwray@gmail.com \
--to=wjwray@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).