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

Submitted by Marek Polacek on April 13, 2014, 3:03 p.m.

Details

Message ID 20140413150313.GA1200@redhat.com
State New
Headers show

Commit Message

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

Comments

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 hide | download patch | download mbox

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 };