https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79658

            Bug ID: 79658
           Summary: [-Wuninitialized] referencing uninitialized field of
                    POD struct should warn
           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: ---

In this code:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template <typename E>
struct enum_flags
{
  enum_flags &operator|= (E e)
  {
    m_enum_value = (E) (m_enum_value | e); // uses uninitialized m_enum_value
    return *this;
  }

  E m_enum_value;
};

enum flag
  {
    FLAG1 = 1
  };

void
foo ()
{
  enum_flags<flag> ef;

  ef |= FLAG1; // missing warning here
}

void
bar ()
{
  flag f;

  f = (flag) (f | FLAG1);  // warning here
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I expect to get a warning on the "missing warning here" line,
because inside operator|= there's a reference to the uninitialized
m_enum_value field.

However, compiling the code below using GCC 7.0.1 20170221 (current trunk),
with "-O2 -Wall -Wextra -Wuninitialized" does not catch that bug.

I tried adding __attribute__((__always_inline__)) to the operator|= method,
to try to help gcc see through the method, but it makes no difference.

Note there's no user-defined ctor here.

The equivalent code using raw enums directly like in the "bar" function, does
warn on the "warning here" line.

Enabling optimization does NOT help.

Here's current G++ output with g++ 7.0.1 20170221 (experimental):

 $ /opt/gcc/bin/g++ enum_flags.cc -o enum_flags -g3 -O2 -c -Wall -Wextra
-Wuninitialized
 enum_flags.cc: In function ‘void bar()’:
 enum_flags.cc:31:17: warning: ‘f’ is used uninitialized in this function
[-Wuninitialized]
    f = (flag) (f | FLAG1);
               ~~~^~~~~~~~

Reply via email to