Skip to content

No -Wc++-compat warning on uninitialized const field in struct #19297

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
chengniansun opened this issue Feb 21, 2014 · 5 comments · Fixed by #137166
Closed

No -Wc++-compat warning on uninitialized const field in struct #19297

chengniansun opened this issue Feb 21, 2014 · 5 comments · Fixed by #137166
Labels
bugzilla Issues migrated from bugzilla clang:diagnostics New/improved warning or error message in Clang, but not in clang-tidy or static analyzer

Comments

@chengniansun
Copy link

Bugzilla Link 18923
Version trunk
OS Windows NT
CC @chengniansun

Extended Description

At trunk 201801. I am not sure whether clang support the warning flag -Wc++-compat. Currently it does not warn on the uninitialized field in a struct.

$: cat s.c
struct S{const int i;};
void f() {struct S s;}
$: clang-trunk -Wc++-compat -c s.c
$: clang++ -c s.c
clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated
s.c:1:8: error: implicit default constructor for 'S' must explicitly initialize the const member 'i'
struct S{const int i;};
^
s.c:1:20: note: declared here
struct S{const int i;};
^
s.c:2:20: note: implicit default constructor for 'S' first required here
void f() {struct S s;}
^
1 error generated.
$:
$: gcc-trunk -Wc++-compat -c s.c
s.c: In function ‘f’:
s.c:2:20: warning: uninitialized const member in ‘struct S’ is invalid in C++ [-Wc++-compat]
void f() {struct S s;}
^
s.c:1:20: note: ‘i’ should be initialized
struct S{const int i;};
^

@chengniansun
Copy link
Author

This also happens to global const variable.

$: cat s.c
const int a;
$: gcc-trunk -Wc++-compat -c s.c
s.c:1:11: warning: uninitialized const ¡®a¡¯ is invalid in C++ [-Wc++-compat]
const int a;
^
$: clang-trunk -Wc++-compat -c s.c
$: clang-trunk -v
clang version 3.8.0 (trunk 246843)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/i686-linux-gnu/4.9
Found candidate GCC installation: /usr/bin/../lib/gcc/i686-linux-gnu/4.9.2
Found candidate GCC installation: /usr/bin/../lib/gcc/i686-linux-gnu/5.1.0
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8.4
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9.2
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/5.1.0
Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/4.9
Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/4.9.2
Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/5.1.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8.4
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9.2
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.1.0
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Candidate multilib: x32;@MX32
Selected multilib: .;@m64
$:

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 9, 2021
@Quuxplusone Quuxplusone added clang:diagnostics New/improved warning or error message in Clang, but not in clang-tidy or static analyzer and removed clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jan 17, 2022
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this issue May 6, 2025
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 llvm#19297
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this issue May 6, 2025
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 llvm#19297
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this issue May 6, 2025
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 llvm#19297
Ankur-0429 pushed a commit to Ankur-0429/llvm-project that referenced this issue May 9, 2025
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 llvm#19297
@pm215
Copy link

pm215 commented May 19, 2025

The changes to fix this bug seem to have introduced a spurious warning when the uninitialized const object is a C flexible array. In this case there is nothing to initialize:

https://godbolt.org/z/xPYa3E7vx

struct debug_entry {
    int lineno;
    const char name[];
};

int main(void) {
    struct debug_entry ent;
}

(and the C99 spec specifically says it would be an error to try to initialize the flexible-array member), but clang head-of-trunk now complains:

<source>:7:24: warning: default initialization of an object of type 'struct debug_entry' with const member leaves the object uninitialized [-Wdefault-const-init-field-unsafe]
    7 |     struct debug_entry ent;
      |                        ^
<source>:3:16: note: member 'name' declared 'const' here
    3 |     const char name[];
      |                ^

GCC trunk doesn't complain about this, and nor does clang 20.1.0.

(Noticed originally because this provokes a warning for QEMU: https://gitlab.com/qemu-project/qemu/-/issues/2970 . The repro above is a cut down version of that.)

@AaronBallman
Copy link
Collaborator

AaronBallman commented May 19, 2025

I think the warning should maybe be silenced in the case of a FAM, though stack allocating an object with a FAM is already pretty tenuous ground. But I also think the warning should be silenced in FAM-like constructs, such as const char buf[0]; The questionable one is const char buf[1]; which is FAM-like but still has some amount of space that could be initialized. I think that one should probably still be diagnosed? CC @kees @bwendling as folks who often care about flexible array members.

#140578 is the PR for updating this.

@pm215
Copy link

pm215 commented May 19, 2025

Agreed that stack-allocating the object with a FAM is a bit odd (slightly surprising the compiler doesn't warn about that, but perhaps it's too widespread a practice to complain about?). In this case the actual QEMU code is writing data structures out to a file, so it fills in the stack-allocated debug_entry, fwrite()s that to the file, and then separately fwrite()s the string that corresponds to the name[] field. That lets it avoid dynamically re-allocating the memory every time round the loop.

https://gitlab.com/qemu-project/qemu/-/blob/757a34115e7491744a63dfc3d291fd1de5297ee2/tcg/perf.c#L244 is the actual usage if you're interested.

In this case we could simply define the struct without the FAM on the end, since we never actually use that member. However, the reason we have it is that the debug_entry struct is the same definition as the kernel's one in tools/perf/util/jitdump.h.

The definition of struct jr_code_debug_info (again, borrowed from jitdump.h) as ending with a FAM whose entries are structs ending with a FAM is also a construct I'm surprised the compiler doesn't complain about :-)

@AaronBallman
Copy link
Collaborator

Thanks for the explanation, that's good to know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla clang:diagnostics New/improved warning or error message in Clang, but not in clang-tidy or static analyzer
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants