This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/79345] New: passing yet-uninitialized member as argument to base class constructor should warn (-Wunitialized)


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.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]