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++/79658] [-Wuninitialized] referencing uninitialized field of POD struct should warn


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

--- Comment #7 from Pedro Alves <palves at redhat dot com> ---
Today I remembered to try reducing the v3 reproducer by converting to C instead
of C++.

The resulting warnings are not exactly the same, but they're very similar.  The
fact that we still only get warnings for foo_1 and foo_3 is preserved.
All the foo_* functions are identical except for the literal being compared to.
 Somehow comparing against 0, 1, 3, or FLAG1 behaves differently.  Comparing
against 1 doesn't warn, but against FLAG1 (which is 1)
does.  Quite mystifying.

============================================
struct enum_flags { int value; };

static inline void set_flag (struct enum_flags *f, int e) { f->value = f->value
| e; }
static inline int get_flag (struct enum_flags *f) { return f->value; }

enum flag { FLAG1 = 1, };

extern void bar ();

void
foo_0 (int param)
{
  struct enum_flags f0; // doesn't warn

  if (param)
    set_flag (&f0, FLAG1);

  if (get_flag (&f0) != 0) // doesn't warn
    bar ();
}

void
foo_1 (int param)
{
  struct enum_flags f1; // warns

  if (param)
    set_flag (&f1, FLAG1);

  if (get_flag (&f1) != FLAG1) // warns
    bar ();
}

void
foo_2 (int param)
{
  struct enum_flags f2; // doesn't warn

  if (param)
    set_flag (&f2, FLAG1);

  if (get_flag (&f2) != 1)
    bar ();
}

void
foo_3 (int param)
{
  struct enum_flags f3; // warns

  if (param)
    set_flag (&f3, FLAG1);

  if (get_flag (&f3) != 3)
    bar ();
}
============================================

Results in:

============================================
$ /opt/gcc/bin/gcc enum_flags4.c -o enum_flags -O2 -Wall -Werror
-Wuninitialized -c
enum_flags4.c: In function ‘foo_1’:
enum_flags4.c:3:81: error: ‘f1.value’ may be used uninitialized in this
function [-Werror=maybe-uninitialized]
 static inline void set_flag (struct enum_flags *f, int e) { f->value =
f->value | e; }
                                                                       
~~~~~~~~~^~~
enum_flags4.c:25:21: note: ‘f1.value’ was declared here
   struct enum_flags f1; // warns
                     ^~
enum_flags4.c: In function ‘foo_3’:
enum_flags4.c:3:81: error: ‘f3.value’ may be used uninitialized in this
function [-Werror=maybe-uninitialized]
 static inline void set_flag (struct enum_flags *f, int e) { f->value =
f->value | e; }
                                                                       
~~~~~~~~~^~~
enum_flags4.c:49:21: note: ‘f3.value’ was declared here
   struct enum_flags f3; // warns
                     ^~
cc1: all warnings being treated as errors
============================================

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