This addresses post-commit review feedback from someone who discovered
that we diagnosed code like the following:
```
struct S {
int len;
const char fam[];
} s;
```
despite it being invalid to initialize the flexible array member.
Note, this applies to flexible array members and zero-sized arrays at
the end of a structure (an old-style flexible array member), but it does
not apply to one-sized arrays at the end of a structure because those do
occupy storage that can be initialized.
A default-initialized union with a const member is generally reasonable
in C and isn't necessarily incompatible with C++, so we now silence the
diagnostic in that case. However, we do still diagnose a const-
qualified, default-initialized union as that is incompatible with C++.
This drops the "and is incompatible with C++" phrasing from the
diagnostic unless -Wc++-compat is explicitly passed. This makes the
diagnostic less confusing when it is on by default rather than enabled
because of C++ compatibility concerns
This adds a new diagnostic to warn about redeclaration of a tentative
definition in C. This is incompatible with C++, so the new diagnostic
group is under -Wc++-compat.
Post-commit review feedback on
https://github.com/llvm/llvm-project/pull/137166 raised a concern from
the Linux kernel about wanting to silence the new diagnostic when the
uninitialized object is a const member of a structure. These members can
be initialized later if the containing object is non-const, such as
through a call to memset, for example.
This splits the diagnostic groups into:
```
-Wc++-compat
-Wdefault-const-init
-Wdefault-const-init-field
-Wdefault-const-init-var
-Wdefault-const-init-unsafe
-Wdefault-const-init-field-unsafe
-Wdefault-const-init-var-unsafe
```
---------
Co-authored-by: Mariya Podchishchaeva <mariya.podchishchaeva@intel.com>
Unlike C++, C allows the definition of an uninitialized `const` object.
If the object has static or thread storage duration, it is still
zero-initialized, otherwise, the object is left uninitialized. In either
case, the code is not compatible with C++.
This adds a new diagnostic group, `-Wdefault-const-init-unsafe`, which
is on by default and diagnoses any definition of a `const` object which
remains uninitialized.
It also adds another new diagnostic group, `-Wdefault-const-init` (which
also enabled the `unsafe` variant) that diagnoses any definition of a
`const` object (including ones which are zero-initialized). This
diagnostic is off by default.
Finally, it adds `-Wdefault-const-init` to `-Wc++-compat`. GCC diagnoses
these situations under this flag.
Fixes#19297