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.
This commit is contained in:
parent
774ab2edcb
commit
4b7d9f8f51
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 }
|
||||
};
|
|
@ -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" } */
|
|
@ -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;
|
||||
}
|
|
@ -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" } */
|
||||
};
|
|
@ -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",
|
||||
};
|
Loading…
Reference in New Issue