aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2025-03-11 23:08:38 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2025-03-11 23:08:38 +0100
commitafb46540d3921e96c4cd7ba8fa2c8b0901759455 (patch)
tree2ebd0b2dae2dc0d4bdf4778322c2d91e7e0edd58 /gcc
parent799ed87bcf6b5bede87311717adac5fb88fd7722 (diff)
downloadgcc-afb46540d3921e96c4cd7ba8fa2c8b0901759455.zip
gcc-afb46540d3921e96c4cd7ba8fa2c8b0901759455.tar.gz
gcc-afb46540d3921e96c4cd7ba8fa2c8b0901759455.tar.bz2
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 <jakub@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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c/c-typeck.cc6
-rw-r--r--gcc/testsuite/gcc.dg/Wunterminated-string-initialization-2.c120
2 files changed, 125 insertions, 1 deletions
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index bc51cc2..11fa98d 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 0000000..73186a7
--- /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\\\)" } */
+};