https://gcc.gnu.org/g:afb46540d3921e96c4cd7ba8fa2c8b0901759455

commit r15-7976-gafb46540d3921e96c4cd7ba8fa2c8b0901759455
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Tue Mar 11 23:08:38 2025 +0100

    c: Don't emit -Wunterminated-string-initialization warning for 
multi-dimensional nonstring array initializers [PR117178]
    
    My/Kees' earlier patches adjusted -Wunterminated-string-initialization
    warning so that it doesn't warn about initializers of nonstring decls
    and that nonstring attribute is allowed on multi-dimensional arrays.
    Unfortunately as this testcase shows, we still warn about initializers
    of multi-dimensional array nonstring decls.
    
    The problem is that in that case field passed to output_init_element
    is actually INTEGER_CST, index into the array.
    For RECORD_OR_UNION_TYPE_P (constructor_type) field is a FIELD_DECL
    which we want to use, but otherwise (in arrays) IMHO we want to use
    constructor_fields (which is the innermost FIELD_DECL whose part
    is being initialized), or - if that is NULL - constructor_decl, the
    whole decl being initialized with multi-dimensional array type.
    
    2025-03-11  Jakub Jelinek  <ja...@redhat.com>
    
            PR c/117178
            * c-typeck.cc (output_init_element): Pass field to digest_init
            only for record/union types, otherwise pass constructor_fields
            if non-NULL and constructor_decl if constructor_fields is NULL.
    
            * gcc.dg/Wunterminated-string-initialization-2.c: New test.

Diff:
---
 gcc/c/c-typeck.cc                                  |   6 +-
 .../gcc.dg/Wunterminated-string-initialization-2.c | 120 +++++++++++++++++++++
 2 files changed, 125 insertions(+), 1 deletion(-)

diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index bc51cc2693bf..11fa98d86ee8 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -11419,7 +11419,11 @@ output_init_element (location_t loc, tree value, tree 
origtype,
   if (!require_constexpr_value
       || !npc
       || TREE_CODE (constructor_type) != POINTER_TYPE)
-    new_value = digest_init (loc, field, type, new_value, origtype, npc,
+    new_value = digest_init (loc,
+                            RECORD_OR_UNION_TYPE_P (constructor_type)
+                            ? field : constructor_fields
+                            ? constructor_fields : constructor_decl,
+                            type, new_value, origtype, npc,
                             int_const_expr, arith_const_expr, strict_string,
                             require_constant_value, require_constexpr_value);
   if (new_value == error_mark_node)
diff --git a/gcc/testsuite/gcc.dg/Wunterminated-string-initialization-2.c 
b/gcc/testsuite/gcc.dg/Wunterminated-string-initialization-2.c
new file mode 100644
index 000000000000..73186a74decf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wunterminated-string-initialization-2.c
@@ -0,0 +1,120 @@
+/* PR c/117178 */
+/* { dg-do compile } */
+/* { dg-options "-Wunterminated-string-initialization" } */
+
+const char a[][4] __attribute__((nonstring)) = {
+  "ABCD",
+  "EFGH",
+  "IJK",
+  "LMNO"
+};
+const char b[][2][2] __attribute__((nonstring)) = {
+  { "PQ",
+    "R" },
+  { "S",
+    "TU" }
+};
+struct S { int c; char d[3][5] __attribute__((nonstring)); int e; } f = {
+  0,
+  { "abcde",
+    "defg",
+    "hijkl" },
+  1
+};
+struct T { int g; char h[3][2][2] __attribute__((nonstring)); int i; } j = {
+  0,
+  { { "m",
+      "no" },
+    { "pq",
+      "r" },
+    { "s",
+      "tu" } },
+  1
+};
+const char k[][4] = {
+  "ABCD",      /* { dg-warning "initializer-string for array of 'char' 
truncates NUL terminator but destination lacks 'nonstring' attribute \\\(5 
chars into 4 available\\\)" } */
+  "EFGH",      /* { dg-warning "initializer-string for array of 'char' 
truncates NUL terminator but destination lacks 'nonstring' attribute \\\(5 
chars into 4 available\\\)" } */
+  "IJK",
+  "LMNO"       /* { dg-warning "initializer-string for array of 'char' 
truncates NUL terminator but destination lacks 'nonstring' attribute \\\(5 
chars into 4 available\\\)" } */
+};
+const char l[][2][2] = {
+  { "PQ",      /* { dg-warning "initializer-string for array of 'char' 
truncates NUL terminator but destination lacks 'nonstring' attribute \\\(3 
chars into 2 available\\\)" } */
+    "R" },
+  { "S",
+    "TU" }     /* { dg-warning "initializer-string for array of 'char' 
truncates NUL terminator but destination lacks 'nonstring' attribute \\\(3 
chars into 2 available\\\)" } */
+};
+struct U { int m; char n[3][5]; int o; } p = {
+  0,
+  { "abcde",   /* { dg-warning "initializer-string for array of 'char' 
truncates NUL terminator but destination lacks 'nonstring' attribute \\\(6 
chars into 5 available\\\)" } */
+    "defg",
+    "hijkl" }, /* { dg-warning "initializer-string for array of 'char' 
truncates NUL terminator but destination lacks 'nonstring' attribute \\\(6 
chars into 5 available\\\)" } */
+  1
+};
+struct V { int q; char r[3][2][2]; int s; } t = {
+  0,
+  { { "m",
+      "no" },  /* { dg-warning "initializer-string for array of 'char' 
truncates NUL terminator but destination lacks 'nonstring' attribute \\\(3 
chars into 2 available\\\)" } */
+    { "pq",    /* { dg-warning "initializer-string for array of 'char' 
truncates NUL terminator but destination lacks 'nonstring' attribute \\\(3 
chars into 2 available\\\)" } */
+      "r" },
+    { "s",
+      "tu" } },        /* { dg-warning "initializer-string for array of 'char' 
truncates NUL terminator but destination lacks 'nonstring' attribute \\\(3 
chars into 2 available\\\)" } */
+  1
+};
+const char u[][4] __attribute__((nonstring)) = {
+  [3] = "ABCD",
+  [1] = "EFGH",
+  "IJK",
+  [0] = "LMNO"
+};
+const char v[][2][2] __attribute__((nonstring)) = {
+  [1][1] = "PQ",
+  [0][1] = "R",
+  [0][0] = "S",
+  [1][0] = "TU"
+};
+struct S w = {
+  0,
+  { [2] = "abcde",
+    [0] = "defg",
+    [1] = "hijkl" },
+  1
+};
+struct T x = {
+  .i = 0,
+  .h = { [2][1] = "m",
+        [1][1] = "no",
+        [0][0] = "pq" },
+  .h[1][0] = "r",
+  .h[2][0] = "s",
+  .g = 1,
+  .h[0][1] = "tu"
+};
+const char y[][4] = {
+  [3] = "ABCD",        /* { dg-warning "initializer-string for array of 'char' 
truncates NUL terminator but destination lacks 'nonstring' attribute \\\(5 
chars into 4 available\\\)" } */
+  [1] = "EFGH",        /* { dg-warning "initializer-string for array of 'char' 
truncates NUL terminator but destination lacks 'nonstring' attribute \\\(5 
chars into 4 available\\\)" } */
+  "IJK",
+  [0] = "LMNO" /* { dg-warning "initializer-string for array of 'char' 
truncates NUL terminator but destination lacks 'nonstring' attribute \\\(5 
chars into 4 available\\\)" } */
+};
+const char z[][2][2] = {
+  [1][1] = "PQ",       /* { dg-warning "initializer-string for array of 'char' 
truncates NUL terminator but destination lacks 'nonstring' attribute \\\(3 
chars into 2 available\\\)" } */
+  [0][1] = "R",
+  [0][0] = "S",
+  [1][0] = "TU"                /* { dg-warning "initializer-string for array 
of 'char' truncates NUL terminator but destination lacks 'nonstring' attribute 
\\\(3 chars into 2 available\\\)" } */
+};
+struct U aa = {
+  0,
+  { [2] = "abcde",     /* { dg-warning "initializer-string for array of 'char' 
truncates NUL terminator but destination lacks 'nonstring' attribute \\\(6 
chars into 5 available\\\)" } */
+    [0] = "defg",
+    [1] = "hijkl" },   /* { dg-warning "initializer-string for array of 'char' 
truncates NUL terminator but destination lacks 'nonstring' attribute \\\(6 
chars into 5 available\\\)" } */
+  1
+};
+struct V ab = {
+  .s = 0,
+  .r = { [2][1] = "m",
+        [1][1] = "no", /* { dg-warning "initializer-string for array of 'char' 
truncates NUL terminator but destination lacks 'nonstring' attribute \\\(3 
chars into 2 available\\\)" } */
+        [0][0] = "pq" }, /* { dg-warning "initializer-string for array of 
'char' truncates NUL terminator but destination lacks 'nonstring' attribute 
\\\(3 chars into 2 available\\\)" } */
+  .r[1][0] = "r",
+  .r[2][0] = "s",
+  .q = 1,
+  .r[0][1] = "tu"      /* { dg-warning "initializer-string for array of 'char' 
truncates NUL terminator but destination lacks 'nonstring' attribute \\\(3 
chars into 2 available\\\)" } */
+};

Reply via email to