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

            Bug ID: 77291
           Summary: False positive for -Warray-bounds
           Product: gcc
           Version: 6.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: abbeyj+gcc at gmail dot com
  Target Milestone: ---

Created attachment 39473
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=39473&action=edit
Test case

Testcase:

struct Rec {
  unsigned char data[1];  // actually variable length
};

union U {
  unsigned char buf[42];
  struct Rec rec;
};

int Load()
{
  union U u;
  return u.rec.data[1];
}

======

When compiled with either of
$ gcc -c -O2 -Warray-bounds array_bounds.c
or
$ g++ -c -O2 -Warray-bounds array_bounds.cpp

produces

array_bounds.c: In function ‘Load’:
array_bounds.c:13:20: warning: array subscript is above array bounds
[-Warray-bounds]
   return u.rec.data[1];
          ~~~~~~~~~~^~~


There's an exception for accessing beyond the end of an array if that array is
the last member in a struct.  In that case it is assumed the user is using the
so-called "struct hack".  So, for instance, this doesn't warn:

int F(struct Rec *r) {
  return r->data[1];
}

But the warning *is* issued if the variable is allocated as an auto stack
variable since then the compiler knows the exact size allocated.  So this
example does warn:

int G() {
  struct Rec r;
  return r.data[1];
}

I'm assuming that the compiler is treating the test case more like this last
example since u.rec is on the stack.  But I believe the warning is incorrect
since the union should provide enough space.  Would it be possible to disable
this warning if the struct is on the stack but is also part of a union?  I
guess you could even try to figure out from the union how much space is
available and what the largest allowable index is but that seems like a lot of
effort to spend on what is going to be a rare case.

Please ignore the reading of uninitialized data in the testcase.  This can be
remedied by initializing before reading but the initialization must be done in
a separate translation unit.  If it is done in this translation unit the
optimizer causes the warning to disappear.  To keep the testcase to one file, I
left the initialization out.

Reply via email to