public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-6825] c++: designated init of char array by string constant [PR55227]
@ 2022-01-23 22:27 Jason Merrill
  0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2022-01-23 22:27 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:2da90ad39bf8fa9ee287e040d1f4411cb7a2e7ed

commit r12-6825-g2da90ad39bf8fa9ee287e040d1f4411cb7a2e7ed
Author: Will Wray <wjwray@gmail.com>
Date:   Fri Jan 14 19:28:53 2022 -0500

    c++: designated init of char array by string constant [PR55227]
    
    There are two underlying bugs in the designated initialization of char array
    fields by string literals that cause:
    
    (1) Rejection of valid cases with:
      (a) brace-enclosed string literal initializer (of any valid size), or
      (b) unbraced string literal shorter than the target char array field.
    
    (2) Acceptance of invalid cases with designators appearing within the braces
        of a braced string literal, in which case the bogus 'designator' was
        being entirely ignored and the string literal treated as a positional
        initializer.
    
    The fixes above allow to address a FIXME in cp_complete_array_type:
    
      /* FIXME: this code is duplicated from reshape_init.
         Probably we should just call reshape_init here?  */
    
    I believe that this was obstructed by the designator bugs (see comment here
    https://patchwork.ozlabs.org/project/gcc/list/?series=199783)
    
            PR c++/55227
    
    gcc/cp/ChangeLog:
    
            * decl.cc (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/desig21.C: New test.

Diff:
---
 gcc/cp/decl.cc                       | 28 ++++++++-------------
 gcc/testsuite/g++.dg/cpp2a/desig21.C | 48 ++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+), 18 deletions(-)

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index c5d4f2f5369..22d3dd1e2ad 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -6817,6 +6817,7 @@ reshape_init_r (tree type, reshape_iter *d, tree first_initializer_p,
     {
       tree str_init = init;
       tree stripped_str_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]).  */
@@ -6824,7 +6825,8 @@ reshape_init_r (tree type, reshape_iter *d, tree first_initializer_p,
 	  && TREE_CODE (stripped_str_init) == CONSTRUCTOR
 	  && CONSTRUCTOR_NELTS (stripped_str_init) == 1)
 	{
-	  str_init = (*CONSTRUCTOR_ELTS (stripped_str_init))[0].value;
+	  stripd.cur = CONSTRUCTOR_ELT (stripped_str_init, 0);
+	  str_init = stripd.cur->value;
 	  stripped_str_init = tree_strip_any_location_wrapper (str_init);
 	}
 
@@ -6833,7 +6835,8 @@ reshape_init_r (tree type, reshape_iter *d, tree first_initializer_p,
 	 array types (one value per array element).  */
       if (TREE_CODE (stripped_str_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;
@@ -9555,22 +9558,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/desig21.C b/gcc/testsuite/g++.dg/cpp2a/desig21.C
new file mode 100644
index 00000000000..daadfa58855
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/desig21.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>();
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-01-23 22:27 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-23 22:27 [gcc r12-6825] c++: designated init of char array by string constant [PR55227] Jason Merrill

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).