summaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2022-03-22 14:37:02 -0400
committerMarek Polacek <polacek@redhat.com>2022-03-22 16:40:40 -0400
commit4b7d9f8f51bd96d290aac230c71e501fcb6b21a6 (patch)
tree26583f7173616f5b0545172c3b209370f989c4de /gcc/c
parent774ab2edcb5f3a24ed3a5cffd1143bd49a69f1ee (diff)
downloadgcc-4b7d9f8f51bd96d290aac230c71e501fcb6b21a6.tar.gz
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.
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/c-typeck.cc10
1 files changed, 6 insertions, 4 deletions
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)
{