Bug 80454 - -Wmissing-braces wrongly warns about universal zero initializer {0}
Summary: -Wmissing-braces wrongly warns about universal zero initializer {0}
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 6.3.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2017-04-18 16:14 UTC by Vincent Lefèvre
Modified: 2024-04-18 01:12 UTC (History)
11 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2021-09-29 00:00:00


Attachments
proposed patch (1.87 KB, patch)
2023-10-27 21:58 UTC, Barnabás Pőcze
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Vincent Lefèvre 2017-04-18 16:14:54 UTC
Consider:

typedef union { char c; int i; } union_t;

struct { struct { int a; long b; } x; int y; } t = { { 0 }, 1 };

struct { struct { union_t a; long b; } x; int y; } u = { { 0 }, 1 };

As expected, I do not get a warning for the first initialization. But with Debian's GCC 6.3.0 20170415 (and previous versions GCC 4.9 and 5), I get a warning for the second one:

tst.c:5:56: warning: missing braces around initializer [-Wmissing-braces]
 struct { struct { union_t a; long b; } x; int y; } u = { { 0 }, 1 };
                                                        ^
tst.c:5:56: note: (near initialization for ‘u’)

(pthread_rwlock_t from <pthread.h> is such a union type on my machine, so that there's the same problem with this.)

It seems that not everything was fixed in PR 53119.
Comment 1 Eric Gallager 2017-08-01 11:27:50 UTC
Confirmed, and the placement of the fixit hint looks weird, too:

$ /usr/local/bin/gcc -c -Wmissing-braces 80454.c
80454.c:5:56: warning: missing braces around initializer [-Wmissing-braces]
 struct { struct { union_t a; long b; } x; int y; } u = { { 0 }, 1 };
                                                        ^
                                                            { }
$
Comment 2 Marek Polacek 2017-08-28 09:41:50 UTC
Is this really a bug?

In the second case we have a union in two nested structs, in the first case just two nested structs.  clang also warns:

w.c:3:60: warning: suggest braces around initialization of subobject [-Wmissing-braces]
struct { struct { union_t a; long b; } x; int y; } u = { { 0 }, 1 };
                                                           ^
                                                           {}

But yes, the fix-it hints looks strange.
Comment 3 Alexander Monakov 2017-08-28 10:48:05 UTC
The bug is that universal zero initializers are warned about when they are inside of some other initializer, even though we correctly stopped doing that when they appear on their own. In the following example GCC shouldn't warn for the initialization of s2, like it already doesn't for s1 (Clang warns for both, but that's probably a bug in Clang).

struct S1 {
    struct S1i {
        int i;
    } s1i;
    int i;
};

#define S1_INIT {0}

struct S1 s1 = S1_INIT;

struct S2 {
    struct S1 s1;
    int i;
} s2 = {S1_INIT, 0};
Comment 4 Eric Gallager 2019-08-15 04:22:58 UTC
cc-ing diagnostics maintainers
Comment 5 Andrew Pinski 2021-09-30 01:56:55 UTC
clang no longer warns with their C front-end.
Comment 6 Marek Polacek 2023-09-19 16:37:04 UTC
To fix this, we have to somehow propagate the flag constructor_zeroinit up in pop_init_level.
Comment 7 Barnabás Pőcze 2023-10-27 21:58:03 UTC
Created attachment 56319 [details]
proposed patch

I would like to see this fixed, so I have tried something, see the attached patch. It's a bit of a hack at the moment, and I am not sure it fixes everything (it improves the status quo in any case), any thoughts?