Patchwork [C] Quash spurious warnings (PR c/60784)

login
register
mail settings
Submitter Marek Polacek
Date April 13, 2014, 3:03 p.m.
Message ID <20140413150313.GA1200@redhat.com>
Download mbox | patch
Permalink /patch/338757/
State New
Headers show

Comments

Marek Polacek - April 13, 2014, 3:03 p.m.
This PR is about spurious warnings with -Wmissing-field-initializers
that can be seen when using multi-level designated initializers.
The warning should not be output for designated initializers [*],
pop_init_level checks for constructor_designated.  But push_init_level
clears this variable, so we need to set it back if needed.  In other
words, if we have ".a.i", then both "a" and "i" should be marked as
designated.  For "a" we set constructor_designated correctly, but then
when processing "i" we push "a" and thus for "i" it's not set properly.

[*] At least right now.  There's a PR about -Wmissing-field-initializers=2
that should warn even for designated initializers.

Regtested/bootstrapped on x86_64-linux, ok for trunk?

2014-04-13  Marek Polacek  <polacek@redhat.com>

	PR c/60784
	* c-typeck.c (push_init_level): Set constructor_designated to
	p->designated for structures.

	* gcc.dg/pr60784.c: New test.


	Marek
Joseph S. Myers - May 1, 2014, 9:40 p.m.
On Sun, 13 Apr 2014, Marek Polacek wrote:

> This PR is about spurious warnings with -Wmissing-field-initializers
> that can be seen when using multi-level designated initializers.
> The warning should not be output for designated initializers [*],
> pop_init_level checks for constructor_designated.  But push_init_level
> clears this variable, so we need to set it back if needed.  In other
> words, if we have ".a.i", then both "a" and "i" should be marked as
> designated.  For "a" we set constructor_designated correctly, but then
> when processing "i" we push "a" and thus for "i" it's not set properly.
> 
> [*] At least right now.  There's a PR about -Wmissing-field-initializers=2
> that should warn even for designated initializers.
> 
> Regtested/bootstrapped on x86_64-linux, ok for trunk?

OK.

Patch

diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c
index 65aad45..2b6c378 100644
--- gcc/c/c-typeck.c
+++ gcc/c/c-typeck.c
@@ -7266,6 +7266,9 @@  push_init_level (int implicit, struct obstack * braced_init_obstack)
 	  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 gcc/testsuite/gcc.dg/pr60784.c gcc/testsuite/gcc.dg/pr60784.c
index e69de29..82b512f 100644
--- gcc/testsuite/gcc.dg/pr60784.c
+++ gcc/testsuite/gcc.dg/pr60784.c
@@ -0,0 +1,25 @@ 
+/* PR c/60784 */
+/* { dg-do compile } */
+/* { dg-options "-Wextra -std=c99" } */
+
+struct A { int i, j; };
+struct B { struct A a; } b1 = { .a.i = 1, .a.j = 1 };
+struct B b2 = { .a.i = 1 };
+
+struct C { struct { int a, b; }; } c1 = { .a = 4, .b = 2 };
+struct C c2 = { .a = 4, .b = 2 };
+
+struct D { struct A a; };
+struct E { struct D d; };
+struct F { struct E e; } f1 = { .e.d.a.i = 8 };
+struct F f2 = { .e.d.a.i = 8, .e.d.a.j = 3 };
+
+struct G {
+  struct {
+    struct {
+      struct {
+        int a, b, c, d, e, f;
+      };
+    };
+  };
+} g = { .b = 2 };