public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] c: -Wmissing-field-initializers and designated inits [PR82283, PR84685]
@ 2023-02-28 10:09 Alex Coplan
  0 siblings, 0 replies; only message in thread
From: Alex Coplan @ 2023-02-28 10:09 UTC (permalink / raw)
  To: gcc-cvs

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

commit e14c665be5a5b9eb6bb5327828f9f6b10dc47ad4
Author: Marek Polacek <polacek@redhat.com>
Date:   Tue Mar 22 14:37:02 2022 -0400

    c: -Wmissing-field-initializers and designated inits [PR82283, PR84685]
    
    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.)
    
            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.
    
    (cherry picked from commit 4b7d9f8f51bd96d290aac230c71e501fcb6b21a6)

Diff:
---
 gcc/c/c-typeck.c                                   | 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(-)

diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 817b8ac844b..a7181d76a41 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -8565,6 +8565,7 @@ struct initializer_stack
   char top_level;
   char require_constant_value;
   char require_constant_elements;
+  char designated;
   rich_location *missing_brace_richloc;
 };
 
@@ -8591,6 +8592,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;
@@ -8649,6 +8651,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;
@@ -8858,7 +8861,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)
     {
@@ -8883,9 +8888,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",
+};

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

only message in thread, other threads:[~2023-02-28 10:09 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-28 10:09 [gcc(refs/vendors/ARM/heads/morello)] c: -Wmissing-field-initializers and designated inits [PR82283, PR84685] Alex Coplan

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