Prior to this change clang didn't emit missing-field-initializers
warning for designated initializers. The comments say that it is done to
match gcc behavior. However, gcc behaves so only for C. For C++ warnings
are emitted.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Thank you for working on this! The changes should come with a release note.
I think the diagnostic is triggered a bit to aggressively in the case where there is an invalid initializer for a field -- we'll claim there is no initializer in that case, but that effectively duplicates the diagnostics without adding anything actionable for the user to do (once they fix the initialization, both diagnostics go away). Can we silence the diagnostic in these cases?
clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp | ||
---|---|---|
64 | This second warning seems wrong, there is an initializer for a, it's just not a valid one. | |
72–79 | This warning is quite wrong, there's a whole pile of initializers for x. :-) | |
228 | I also think this one is wrong. |
Add a release note, apply feedback:
- Do not report invalid initializers as missing
- Fix wrong warning if record has bitfields
Thank you for working on this! The changes should come with a release note.
Thanks for feedback, I added a release note.
Can we silence the diagnostic in these cases?
And this is done.
Tangentially related: Now that we have this InitializedFields set, would it be easy to add a warning for double-initialization of fields (that would also trigger in C)?
Isn't a warning like this already in place - https://godbolt.org/z/E1dGsY3ze ? Or you meant something else?
Yes, thanks. Someone else was asking for this feature a while back but looks like they didn't notice it already exists.
The failure is unrelated, since the patch doesn't touch modules and I've seen the test failing for other patches as well.
is there any way to suppress this for a specific field? (I believe) I'm seeing user code where a field is intentionally not being initialized
Hmmm, so they're wanting to rely on the implicit initialization (http://eel.is/c++draft/dcl.init#aggr-5)? It seems a bit odd to pass -Wmissing-field-initializers and then rely on implicit initialization of fields, so some more details might be helpful.
ah I thought this was in -Wall but it's not
the struct is
struct Foo { const void* buffer; uint32_t capacity; uint32_t reserved; };
where reserved isn't explicitly initialized. that seems like reasonable code, but I suppose we can just explicitly initialize reserved here
Thank you for sharing the use case, that's actually a rather interesting one! Leaving the identifier reserved off the field would trigger a -Wmissing-declarations diagnostic (which is on by default). You can leave the field named and use an in-class initializer for it and that should silence the diagnostic. But I kind of wonder if we want to special case fields named reserved or similar (wReserved, reserved2, etc)?
Note that there's an ongoing discussion on the GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96868 whether -Wmissing-field-initializers should apply to both C and C++ or just C.
FWIW, if this is the specific piece of code that led me to this conversation, that declaration is in a header which at least in theory is supposed to remain compatible with C. It's inside extern "C" { ... } even. We can't add explicit initialize reserved and keep the definition C comaptible.
Thank you for posting this! I'm with @jwakely on this: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96868#c3 -- the warning is for people who want to be told they've not explicitly specified all of the initializers, it is not for telling you "this hasn't been initialized". I think the desire makes as much sense in C++ as it does in C, but this is more of a style warning than a correctness warning.
Ouch, yeah, that does make it a challenge. But why is -Wmissing-field-initializers enabled in the first place for the code? It seems like there are fields you *don't* want explicit initialization for, so perhaps the answer is to disable the diagnostic for those types?
It's an unfortunate configuration. We saw this in Chrome where some projects were manually setting -Wmissing-field-initializers, but when building for Fuchsia, some Fuchsia system headers had this code. We can just suppress this for all Fuchsia builds, I think that's fine.
This change has introduced a false positive for anonymous union members:
struct A { int m; union { int n = 0; }; }; A a = A{.m = 0};
now produces a false positive warning saying that the anonymous union member in A is uninitialized.
Thanks! I've created https://github.com/llvm/llvm-project/issues/70444 and will figure something to fix this asap.
This second warning seems wrong, there is an initializer for a, it's just not a valid one.