diff options
author | Jakub Jelinek <jakub@redhat.com> | 2025-03-11 23:08:38 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2025-03-11 23:08:38 +0100 |
commit | afb46540d3921e96c4cd7ba8fa2c8b0901759455 (patch) | |
tree | 2ebd0b2dae2dc0d4bdf4778322c2d91e7e0edd58 | |
parent | 799ed87bcf6b5bede87311717adac5fb88fd7722 (diff) | |
download | gcc-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.
-rw-r--r-- | gcc/c/c-typeck.cc | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/Wunterminated-string-initialization-2.c | 120 |
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\\\)" } */ +}; |