From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7810) id 113263858408; Tue, 28 Feb 2023 10:09:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 113263858408 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1677578952; bh=/B3R4Gw2AWTfVGAZHaWMetioZ5tfqnp079okjrqkDdI=; h=From:To:Subject:Date:From; b=wWajUVEP27iI2KnCowcG+QqrsgEbzNbnUAxVWbrUsnppHl68+ZVSYyZ5HGFHgCQoN WnLxKG+J+6puzMCdLJ14hPmOKUON4E18abFkG9Se0ag0JuLpNmqmp+wLbS3Ry5mF6U hZXTUS3SaMxfTwyax8Bo3nq5ZcNCYsBeFnQZfq34= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Alex Coplan To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/vendors/ARM/heads/morello)] c: -Wmissing-field-initializers and designated inits [PR82283, PR84685] X-Act-Checkin: gcc X-Git-Author: Marek Polacek X-Git-Refname: refs/vendors/ARM/heads/morello X-Git-Oldrev: ea9d6de2ca1ae1d6931e5e8f55d1bc431920b057 X-Git-Newrev: e14c665be5a5b9eb6bb5327828f9f6b10dc47ad4 Message-Id: <20230228100912.113263858408@sourceware.org> Date: Tue, 28 Feb 2023 10:09:12 +0000 (GMT) List-Id: https://gcc.gnu.org/g:e14c665be5a5b9eb6bb5327828f9f6b10dc47ad4 commit e14c665be5a5b9eb6bb5327828f9f6b10dc47ad4 Author: Marek Polacek 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", +};