https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79345
Bug ID: 79345 Summary: passing yet-uninitialized member as argument to base class constructor should warn (-Wunitialized) Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: palves at redhat dot com Target Milestone: --- Created attachment 40653 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40653&action=edit test source Using g++ 7.0.1 20170202 (trunk), compiling this code: ============== #include <stdlib.h> struct ui_file {}; ui_file stream_v, stream_q; struct gdb_disassembler { gdb_disassembler (struct ui_file *file) : m_stream (file) {} struct ui_file *m_stream; }; /* Test disassembly of one instruction. */ struct gdb_disassembler_test : public gdb_disassembler { const bool verbose = false; gdb_disassembler_test () : gdb_disassembler (verbose ? &stream_v : &stream_q) // bug here {} void use_stream (); }; void func () { gdb_disassembler_test di; di.use_stream (); } ==== with: g++ -std=gnu++11 uninitialized.cc -c -o uninitialized -O2 does not produce any warning. However, the member initializer here at: gdb_disassembler_test () : gdb_disassembler (verbose ? &stream_v : &stream_q) // bug here {} is passing the yet-uninitialized "gdb_disassembler_test::verbose" to the gdb_disassembler ctor. This is a bug, because even though the "verbose" field has an in-class initializer, base classes are initialized before members of the current class are initialized. The frontend end obviously must know this, so it should be able to detect the bug and warn, regardless of optimization level. (At least, when passing by value. Passing by reference/pointer may have legitimate uses.) (TBC, g++ does not warn at any optimization level.) Looks like a regression. I tried: g++ 7.0.1 20170202 (trunk) g++ 5.3.1 (Fedora 23) g++ 4.8.5 g++ 4.7.4 clang++ 3.7 All but g++ 7 warned at -O2. None warned at -O0. clang++ manages to warn even at -O0. g++ 5.3.1 (-O2): $ g++ -std=gnu++11 -O2 -Wall -Wextra -Wuninitialized gcc-bug.cc -c -o gcc-bug gcc-bug.cc: In function ‘void func()’: gcc-bug.cc:19:25: warning: ‘di.gdb_disassembler_test::verbose’ is used uninitialized in this function [-Wuninitialized] : gdb_disassembler (verbose ? &stream_v : &stream_q) // bug here ^ gcc-bug.cc:28:25: note: ‘di’ was declared here gdb_disassembler_test di; ^ g++ 4.7 (-O2): $ /opt/gcc-4.7/bin/g++ -std=gnu++11 -O2 -Wall -Wextra -Wuninitialized gcc-bug.cc -c -o gcc-bug gcc-bug.cc: In function ‘void func()’: gcc-bug.cc:19:56: warning: ‘di.gdb_disassembler_test::verbose’ is used uninitialized in this function [-Wuninitialized] gcc-bug.cc:28:25: note: ‘di’ was declared here clang++ (-O0): $ clang++ -std=gnu++11 -O0 -Wall -Wextra -Wuninitialized gcc-bug.cc -c -o gcc-bug gcc-bug.cc:19:25: warning: field 'verbose' is uninitialized when used here [-Wuninitialized] : gdb_disassembler (verbose ? &stream_v : &stream_q) // bug here ^ 1 warning generated.