https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79658
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Resolution|--- |FIXED CC| |msebor at gcc dot gnu.org Status|NEW |RESOLVED --- Comment #10 from Martin Sebor <msebor at gcc dot gnu.org> --- Many test cases here... For the test case in comment #0, GCC 11 still diagnoses only the second function. The first was never diagnosed because the variable is optimized out. That should be expected. When the variable is used it is diagnosed. $ gcc -O2 -S -Wall pr79658-c0.C pr79658-c0.C: In function ‘void bar()’: pr79658-c0.C:31:15: warning: ‘f’ is used uninitialized [-Wuninitialized] 31 | f = (flag) (f | FLAG1); // warning here | ^ pr79658-c0.C:29:8: note: ‘f’ was declared here 29 | flag f; | ^ For the test case in comment #4, with -O, GCC 11 diagnoses all but the first function. The first function isn't diagnosed because the conditionals are folded away and all the warning sees is an unconditional call to bar(). Without optimization, the member functions aren't inlined and so the warning doesn't see the uninitialized reads. That's mostly unavoidable. The warning does have logic to trigger when an uninitialized object is passed to a const-qualified reference (or pointer) but not if the object is passed to a non-const argument by reference prior to that. $ gcc -O2 -S -Wall pr79658-c4.C pr79658-c4.C: In function ‘void foo_1(int)’: pr79658-c4.C:40:10: warning: ‘*(unsigned int*)((char*)&f1 + offsetof(eflags, enum_flags<flag>::m_enum_value))’ may be used uninitialized [-Wmaybe-uninitialized] 40 | eflags f1; | ^~ pr79658-c4.C: In function ‘void foo_2(int)’: pr79658-c4.C:52:10: warning: ‘*(unsigned int*)((char*)&f2 + offsetof(eflags, enum_flags<flag>::m_enum_value))’ may be used uninitialized [-Wmaybe-uninitialized] 52 | eflags f2; | ^~ pr79658-c4.C: In function ‘void foo_3(int)’: pr79658-c4.C:64:10: warning: ‘*(unsigned int*)((char*)&f3 + offsetof(eflags, enum_flags<flag>::m_enum_value))’ may be used uninitialized [-Wmaybe-uninitialized] 64 | eflags f3; | ^~ Finally, for the test case in comment #7, GCC 11 (and prior, including 9, since r264078) diagnoses all four functions: $ gcc -O2 -S -Wall pr79658.c pr79658.c: In function ‘foo_0’: pr79658.c:13:21: warning: ‘f0.value’ is used uninitialized [-Wuninitialized] 13 | struct enum_flags f0; // doesn't warn | ^~ pr79658.c: In function ‘foo_1’: pr79658.c:3:81: warning: ‘f1.value’ may be used uninitialized [-Wmaybe-uninitialized] 3 | oid set_flag (struct enum_flags *f, int e) { f->value = f->value | e; } | ~~~~~~~~~^~~ pr79658.c:25:21: note: ‘f1.value’ was declared here 25 | struct enum_flags f1; // warns | ^~ pr79658.c: In function ‘foo_2’: pr79658.c:3:81: warning: ‘f1.value’ may be used uninitialized [-Wmaybe-uninitialized] 3 | oid set_flag (struct enum_flags *f, int e) { f->value = f->value | e; } | ~~~~~~~~~^~~ pr79658.c:25:21: note: ‘f1.value’ was declared here 25 | struct enum_flags f1; // warns | ^~ pr79658.c: In function ‘foo_3’: pr79658.c:3:81: warning: ‘f3.value’ may be used uninitialized [-Wmaybe-uninitialized] 3 | oid set_flag (struct enum_flags *f, int e) { f->value = f->value | e; } | ~~~~~~~~~^~~ pr79658.c:49:21: note: ‘f3.value’ was declared here 49 | struct enum_flags f3; // warns | ^~ With that, I'm going to resolve this as fixed (for the last test case).