* [PATCH] c: -Wmissing-field-initializers and designated inits [PR82283, PR84685]
@ 2022-03-22 20:11 Marek Polacek
2022-03-22 20:35 ` Joseph Myers
0 siblings, 1 reply; 2+ messages in thread
From: Marek Polacek @ 2022-03-22 20:11 UTC (permalink / raw)
To: Joseph Myers, GCC Patches
This patch fixes two kinds of wrong -Wmissing-field-initializers
warnings. Our docs say that this warning "does not warn about designated
initializers", but we give a warning for
1) the array case:
struct S {
struct N {
int a;
int b;
} c[1];
} d = {
.c[0].a = 1,
.c[0].b = 1, // missing initializer for field 'b' of 'struct N'
};
we warn because push_init_level, when constructing an array, clears
constructor_designated (which the warning relies on), and we forget
that we were in a designated initializer context. Fixed by the
push_init_level hunk; and
2) the compound literal case:
struct T {
int a;
int *b;
int c;
};
struct T t = { .b = (int[]){1} }; // missing initializer for field 'c' of 'struct T'
where set_designator properly sets constructor_designated to 1, but the
compound literal causes us to create a whole new initializer_stack in
start_init, which clears constructor_designated. Then, after we've parsed
the compound literal, finish_init flushes the initializer_stack entry,
but doesn't restore constructor_designated, so we forget we were in
a designated initializer context, which causes the bogus warning. (The
designated flag is also tracked in constructor_stack, but in this case,
we didn't perform push_init_level between set_designator and start_init
so it wasn't saved anywhere.)
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? Maybe 11 too.
PR c/82283
PR c/84685
gcc/c/ChangeLog:
* c-typeck.cc (struct initializer_stack): Add 'designated' member.
(start_init): Set it.
(finish_init): Restore constructor_designated.
(push_init_level): Set constructor_designated to the value of
constructor_designated in the upper constructor_stack.
gcc/testsuite/ChangeLog:
* gcc.dg/Wmissing-field-initializers-1.c: New test.
* gcc.dg/Wmissing-field-initializers-2.c: New test.
* gcc.dg/Wmissing-field-initializers-3.c: New test.
* gcc.dg/Wmissing-field-initializers-4.c: New test.
* gcc.dg/Wmissing-field-initializers-5.c: New test.
---
gcc/c/c-typeck.cc | 10 +++--
.../gcc.dg/Wmissing-field-initializers-1.c | 22 ++++++++++
.../gcc.dg/Wmissing-field-initializers-2.c | 11 +++++
.../gcc.dg/Wmissing-field-initializers-3.c | 24 +++++++++++
.../gcc.dg/Wmissing-field-initializers-4.c | 43 +++++++++++++++++++
.../gcc.dg/Wmissing-field-initializers-5.c | 22 ++++++++++
6 files changed, 128 insertions(+), 4 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/Wmissing-field-initializers-1.c
create mode 100644 gcc/testsuite/gcc.dg/Wmissing-field-initializers-2.c
create mode 100644 gcc/testsuite/gcc.dg/Wmissing-field-initializers-3.c
create mode 100644 gcc/testsuite/gcc.dg/Wmissing-field-initializers-4.c
create mode 100644 gcc/testsuite/gcc.dg/Wmissing-field-initializers-5.c
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index c0812de84b4..6c4af5e4cde 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -8438,6 +8438,7 @@ struct initializer_stack
char top_level;
char require_constant_value;
char require_constant_elements;
+ char designated;
rich_location *missing_brace_richloc;
};
@@ -8464,6 +8465,7 @@ start_init (tree decl, tree asmspec_tree ATTRIBUTE_UNUSED, int top_level,
p->top_level = constructor_top_level;
p->next = initializer_stack;
p->missing_brace_richloc = richloc;
+ p->designated = constructor_designated;
initializer_stack = p;
constructor_decl = decl;
@@ -8522,6 +8524,7 @@ finish_init (void)
require_constant_value = p->require_constant_value;
require_constant_elements = p->require_constant_elements;
constructor_stack = p->constructor_stack;
+ constructor_designated = p->designated;
constructor_range_stack = p->constructor_range_stack;
constructor_elements = p->elements;
spelling = p->spelling;
@@ -8731,7 +8734,9 @@ push_init_level (location_t loc, int implicit,
constructor_depth = SPELLING_DEPTH ();
constructor_elements = NULL;
constructor_incremental = 1;
- constructor_designated = 0;
+ /* If the upper initializer is designated, then mark this as
+ designated too to prevent bogus warnings. */
+ constructor_designated = p->designated;
constructor_pending_elts = 0;
if (!implicit)
{
@@ -8756,9 +8761,6 @@ push_init_level (location_t loc, int implicit,
push_member_name (constructor_fields);
constructor_depth++;
}
- /* If upper initializer is designated, then mark this as
- designated too to prevent bogus warnings. */
- constructor_designated = p->designated;
}
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
{
diff --git a/gcc/testsuite/gcc.dg/Wmissing-field-initializers-1.c b/gcc/testsuite/gcc.dg/Wmissing-field-initializers-1.c
new file mode 100644
index 00000000000..fbcca44db5f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wmissing-field-initializers-1.c
@@ -0,0 +1,22 @@
+/* PR c/82283 */
+/* { dg-do compile } */
+/* { dg-options "-Wmissing-field-initializers" } */
+
+struct A {
+ int *a;
+ int b;
+};
+
+struct B {
+ struct A a;
+};
+
+struct B data1 = {
+ .a.a = &(int){ 0 },
+ .a.b = 13 /* { dg-bogus "missing initializer" } */
+};
+
+struct B data2 = {
+ .a.b = 0,
+ .a.a = & (int) { 0 }
+};
diff --git a/gcc/testsuite/gcc.dg/Wmissing-field-initializers-2.c b/gcc/testsuite/gcc.dg/Wmissing-field-initializers-2.c
new file mode 100644
index 00000000000..cb42968a490
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wmissing-field-initializers-2.c
@@ -0,0 +1,11 @@
+/* PR c/84685 */
+/* { dg-do compile } */
+/* { dg-options "-Wmissing-field-initializers" } */
+
+struct T {
+ int a;
+ int *b;
+ int c;
+};
+
+struct T t = { .b = (int[]){1} }; /* { dg-bogus "missing initializer" } */
diff --git a/gcc/testsuite/gcc.dg/Wmissing-field-initializers-3.c b/gcc/testsuite/gcc.dg/Wmissing-field-initializers-3.c
new file mode 100644
index 00000000000..5512d97d12f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wmissing-field-initializers-3.c
@@ -0,0 +1,24 @@
+/* PR c/84685 */
+/* { dg-do compile } */
+/* { dg-options "-Wmissing-field-initializers" } */
+
+struct T
+{
+ int a;
+ int *b;
+ int c;
+ int d;
+ int *e;
+ int f;
+ int g;
+ int h;
+};
+
+struct T foo(int bar);
+
+struct T foo(int bar)
+{
+ struct T t = { .b = (int[]){ 1 }, .e = (int[]){ 2 } }; /* { dg-bogus "missing initializer" } */
+ t.c = bar;
+ return t;
+}
diff --git a/gcc/testsuite/gcc.dg/Wmissing-field-initializers-4.c b/gcc/testsuite/gcc.dg/Wmissing-field-initializers-4.c
new file mode 100644
index 00000000000..57e4e4d3372
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wmissing-field-initializers-4.c
@@ -0,0 +1,43 @@
+/* PR c/82283 */
+/* { dg-do compile } */
+/* { dg-options "-Wmissing-field-initializers" } */
+
+struct a {
+ int b;
+};
+
+struct c {
+ struct a d;
+ int e;
+};
+
+void f (struct c *);
+
+void
+g (void)
+{
+ struct c h = {.d = (struct a){0}}; /* { dg-bogus "missing initializer" } */
+ f(&h);
+}
+
+struct {
+ struct {
+ int a;
+ int b;
+ } c[1];
+} d = {
+ .c[0].a = 1,
+ .c[0].b = 1, /* { dg-bogus "missing initializer" } */
+};
+
+struct test_t {
+ int value1;
+ int value2;
+};
+
+struct test_t test[] = {
+ [0].value1 = 1,
+ [0].value2 = 2, /* { dg-bogus "missing initializer" } */
+ [1].value1 = 10,
+ [1].value2 = 20 /* { dg-bogus "missing initializer" } */
+};
diff --git a/gcc/testsuite/gcc.dg/Wmissing-field-initializers-5.c b/gcc/testsuite/gcc.dg/Wmissing-field-initializers-5.c
new file mode 100644
index 00000000000..7cf5df17764
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wmissing-field-initializers-5.c
@@ -0,0 +1,22 @@
+/* PR c/82283 */
+/* { dg-do compile } */
+/* { dg-options "-Wmissing-field-initializers" } */
+
+struct foo {
+ const char *a1;
+ const char * const *a2;
+ void *a3;
+ void *a4;
+};
+
+const char *aux[] = { "y", 0 };
+
+struct foo a = {
+ .a1 = "x",
+ .a2 = (const char * const []){ "y", 0 },
+}; /* { dg-bogus "missing initializer" } */
+
+struct foo b = {
+ .a2 = (const char * const []){ "y", 0 },
+ .a1 = "x",
+};
base-commit: b6e33907ebe89361f8ddfb7481534cbf4a97f213
--
2.35.1
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] c: -Wmissing-field-initializers and designated inits [PR82283, PR84685]
2022-03-22 20:11 [PATCH] c: -Wmissing-field-initializers and designated inits [PR82283, PR84685] Marek Polacek
@ 2022-03-22 20:35 ` Joseph Myers
0 siblings, 0 replies; 2+ messages in thread
From: Joseph Myers @ 2022-03-22 20:35 UTC (permalink / raw)
To: Marek Polacek; +Cc: GCC Patches
On Tue, 22 Mar 2022, Marek Polacek via Gcc-patches wrote:
> PR c/82283
> PR c/84685
>
> gcc/c/ChangeLog:
>
> * c-typeck.cc (struct initializer_stack): Add 'designated' member.
> (start_init): Set it.
> (finish_init): Restore constructor_designated.
> (push_init_level): Set constructor_designated to the value of
> constructor_designated in the upper constructor_stack.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.dg/Wmissing-field-initializers-1.c: New test.
> * gcc.dg/Wmissing-field-initializers-2.c: New test.
> * gcc.dg/Wmissing-field-initializers-3.c: New test.
> * gcc.dg/Wmissing-field-initializers-4.c: New test.
> * gcc.dg/Wmissing-field-initializers-5.c: New test.
OK.
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2022-03-22 20:35 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-22 20:11 [PATCH] c: -Wmissing-field-initializers and designated inits [PR82283, PR84685] Marek Polacek
2022-03-22 20:35 ` Joseph Myers
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).