[Bug c/82283] Wrong warning with -Wmissing-field-initializers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283 Marek Polacek changed: What|Removed |Added Resolution|--- |FIXED Status|ASSIGNED|RESOLVED --- Comment #18 from Marek Polacek --- Fixed.
[Bug c/82283] Wrong warning with -Wmissing-field-initializers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283 --- Comment #17 from CVS Commits --- The releases/gcc-11 branch has been updated by Marek Polacek : https://gcc.gnu.org/g:0fa9022aa30b9c4dde965a0406943c8c0af5eb54 commit r11-9715-g0fa9022aa30b9c4dde965a0406943c8c0af5eb54 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.c (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)
[Bug c/82283] Wrong warning with -Wmissing-field-initializers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283 --- Comment #16 from Yann Droneaud --- (In reply to Marek Polacek from comment #13) > I have a patch which fixes all the testcases here. I've checked my test cases using godbolt gcc trunk, and, yeah, thanks a lot !
[Bug c/82283] Wrong warning with -Wmissing-field-initializers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283 --- Comment #15 from Marek Polacek --- Patch seems safe to backport to 11.
[Bug c/82283] Wrong warning with -Wmissing-field-initializers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283 --- Comment #14 from CVS Commits --- The trunk branch has been updated by Marek Polacek : https://gcc.gnu.org/g:4b7d9f8f51bd96d290aac230c71e501fcb6b21a6 commit r12-7772-g4b7d9f8f51bd96d290aac230c71e501fcb6b21a6 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.
[Bug c/82283] Wrong warning with -Wmissing-field-initializers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283 Marek Polacek changed: What|Removed |Added Assignee|unassigned at gcc dot gnu.org |mpolacek at gcc dot gnu.org Status|NEW |ASSIGNED --- Comment #13 from Marek Polacek --- I have a patch which fixes all the testcases here.
[Bug c/82283] Wrong warning with -Wmissing-field-initializers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283 rsandifo at gcc dot gnu.org changed: What|Removed |Added CC||rsandifo at gcc dot gnu.org --- Comment #12 from rsandifo at gcc dot gnu.org --- Here's another example, from Alexey Neyman [https://gcc.gnu.org/pipermail/gcc-help/2022-February/141197.html]: struct foo { const char *a1; const char * const *a2; void *a3; void *a4; }; const char *aux[] = { "y", 0 }; struct foo a = { .a1 = "x", #if defined(CASE1) .a2 = (const char * const []){ "y", 0 }, #elif defined(CASE2) .a2 = aux, #elif defined(CASE3) .a2 = 0, #elif defined(CASE4) /* .a2 not initialized */ #elif defined(CASE5) .a2 = (const char * const []){ "y", 0 }, .a3 = 0, #endif }; struct foo b = { .a2 = (const char * const []){ "y", 0 }, .a1 = "x", }; Only CASE1 of a warns; the others are (correctly) accepted without warnings.
[Bug c/82283] Wrong warning with -Wmissing-field-initializers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283 --- Comment #11 from Jonathan Wakely --- (In reply to Robert Dumitru from comment #10) > I think https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99081 is also relating > to this. A similar issue, but I think the code for parsing these initializes in C and C++ is completely separate. I've added it to the "See Also" field anyway.
[Bug c/82283] Wrong warning with -Wmissing-field-initializers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283 Robert Dumitru changed: What|Removed |Added CC||robert.dumitru@cyberthorstu ||dios.com --- Comment #10 from Robert Dumitru --- We are experiencing the same issue: The warning: missing initializer for field ... [-Wmissing-field-initializers] is being thrown incorrectly. The following code is correct, however [-Wmissing-field-initializers] are shown. struct test_t{ int value1; int value2; }; struct test_t test[] = { [0].value1 = 1, [0].value2 = 2, [1].value1 = 10, [1].value2 = 20 }; int main(){ return 0; } warning: missing initializer for field 'value2' of 'struct test_t' [-Wmissing-field-initializers] [0].value2 = 2, warning: missing initializer for field 'value2' of 'struct test_t' [-Wmissing-field-initializers] [1].value2 = 20 The initialization is correct: _test: .long 1 .long 2 .long 10 .long 20 This bug was discovered first on version 8.3 but it can be reproduced on version 10.2 as well. Please note you need the -Wextra flag in order to reproduce this. I think https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99081 is also relating to this.
[Bug c/82283] Wrong warning with -Wmissing-field-initializers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283 Martin Liška changed: What|Removed |Added CC||marxin at gcc dot gnu.org, ||mpolacek at gcc dot gnu.org --- Comment #9 from Martin Liška --- @Marek: Would it be possible to fix these issues in C FE?
[Bug c/82283] Wrong warning with -Wmissing-field-initializers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283 --- Comment #8 from Yann Droneaud --- See also this stack overflow question https://stackoverflow.com/questions/49081541/compound-literal-and-designated-initializer-warning-from-gcc-but-not-clang
[Bug c/82283] Wrong warning with -Wmissing-field-initializers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283 --- Comment #7 from Yann Droneaud --- See also bug #84685 which is a very likely duplicate of this one.
[Bug c/82283] Wrong warning with -Wmissing-field-initializers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283 --- Comment #6 from Yann Droneaud --- Found this one on stack overflow[1], and I find it a bit embarrassing: struct { struct { int a; int b; } c[1]; } d = { .c[0].a = 1, .c[0].b = 1, }; Results in the following warning: :7:8: error: missing initializer for field 'b' of 'struct ' [-Werror=missing-field-initializers] 7 |.c[0].b = 1, |^ :4:9: note: 'b' declared here 4 | int b; | ^ cc1: all warnings being treated as errors Compiler returned: 1 See https://godbolt.org/z/zGqM7C GCC emits a warning about a field missing an initializer despite being obviously explicitly initialized. If the present but missing initialization is removed: struct { struct { int a; int b; } c[1]; } d = { .c[0].a = 1, }; GCC complains, incorrectly, about a missing initializer, as described in previous comments: :8:1: error: missing initializer for field 'b' of 'struct ' [-Werror=missing-field-initializers] 8 | }; | ^ :4:9: note: 'b' declared here 4 | int b; | ^ cc1: all warnings being treated as errors Compiler returned: 1 See https://godbolt.org/z/8NRwo5 [1] https://stackoverflow.com/questions/22194935/wmissing-field-initializer-when-using-designated-initializers
[Bug c/82283] Wrong warning with -Wmissing-field-initializers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283 --- Comment #5 from Yann Droneaud --- For a full combo, here's the almost original code that trigger the two errors above with GLibc < 2.28, only one with newer Glibc. #define _GNU_SOURCE 1 #include #include #include int test(int fd) { static const char message[] = "Hello world"; struct sockaddr_in addr = { .sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK), .sin_port = htons(12345), }; struct iovec vec = { .iov_base = (void *)message, .iov_len = sizeof(message), }; struct mmsghdr mmsghdr = { .msg_hdr = (struct msghdr) { .msg_name = , .msg_namelen = sizeof(addr), .msg_iov = , .msg_iovlen = 1, }, }; return sendmmsg(fd, , 1, 0); } see https://godbolt.org/z/pwXyzE
[Bug c/82283] Wrong warning with -Wmissing-field-initializers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283 --- Comment #4 from Yann Droneaud --- Also with the ({}) GCC extension: struct a { int b; int c; }; void d(struct a *); void e(void) { struct a f = { .b = ({ int g = 0; g; }) }; d(); } It produces the warning: : In function 'e': :10:17: error: missing initializer for field 'c' of 'struct a' [-Werror=missing-field-initializers] 10 | })}; | ^ :3:7: note: 'c' declared here 3 | int c; | ^ cc1: all warnings being treated as errors Compiler returned: 1 See https://godbolt.org/z/VJAuv4 (Note: this example and the one above were reduced by c-reduce https://embed.cs.utah.edu/creduce/ )
[Bug c/82283] Wrong warning with -Wmissing-field-initializers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283 Yann Droneaud changed: What|Removed |Added CC||yann at droneaud dot fr --- Comment #3 from Yann Droneaud --- I'm experiencing the same issue in multiple cases, even with latest GCC trunk (10.x). I believe the following code is C99 conformant, but still trigger an unexpected warning: 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}}; f(); } It produces the following warning: : In function 'g': :10:30: error: missing initializer for field 'e' of 'struct c' [-Weror=missing-field-initializers] 10 | struct c h = {.d = (struct a){0}}; | ^ :6:7: note: 'e' declared here 6 | int e; | ^ cc1: all warnings being treated as errors Compiler returned: 1 See https://godbolt.org/z/vQLYRX
[Bug c/82283] Wrong warning with -Wmissing-field-initializers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283 Eric Gallager changed: What|Removed |Added CC||dmalcolm at gcc dot gnu.org, ||dodji at gcc dot gnu.org --- Comment #2 from Eric Gallager --- cc-ing diagnostics maintainers
[Bug c/82283] Wrong warning with -Wmissing-field-initializers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283 Eric Gallager changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2017-09-29 CC||egallager at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #1 from Eric Gallager --- Confirmed that I get the same warning for data1 but not for data2.