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

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Blocks|                            |56456
            Summary|[10/11 Regression] array    |[10/11 Regression] spurious
                   |subscript i is outside      |-Warray-bounds for a zero
                   |array bounds of ‘int[0]’    |length array member of
                   |since                       |union since
                   |r10-4300-g49fb45c81f4ac068  |r10-4300-g49fb45c81f4ac068
          Component|tree-optimization           |middle-end

--- Comment #4 from Martin Sebor <msebor at gcc dot gnu.org> ---
When the array is a member of a declared object of a struct type (e in the
small test case in comment #0) it has no elements and attempting to access any
of them is invalid.

In the original translation unit the array is a member of an object of a union
type: union intelvf_msg.  The object, msg, is defined in function
intelvf_mbox_set_mtu(), and the array is used to alias other members. 
Presumably GCC supports this sort of aliasing as long as it's done through the
union type (as mentioned in -fstrict-aliasing), so the warning could be relaxed
not to trigger for them.

Here's a test case that more closely corresponds to the translation unit,
reproduces the warning, and shows that GCC doesn't make assumptions about the
two arrays being distinct:

$ cat pr94940_c4.c && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout
pr94940_c4.c
struct S { int a[2]; };

union U {
  struct S s;
  int a[0];
};

static void f (union U *p, int i, int j)
{
  int t = p->s.a[j];
  p->a[i] = 0;
  if (t == p->s.a[j])     // not eleminated
    __builtin_abort ();
}

void sink (void*);

void g (int i, int j)
{
  union U u = { .s = { { 1, 2 } } };
  f (&u, i, j);
  sink (&u);
}

pr94940_c4.c: In function ‘g’:
pr94940_c4.c:11:7: warning: array subscript i is outside array bounds of
‘int[0]’ [-Warray-bounds]
   11 |   p->a[i] = 0;
      |   ~~~~^~~
pr94940_c4.c:5:7: note: while referencing ‘a’
    5 |   int a[0];
      |       ^
pr94940_c4.c:20:11: note: defined here ‘u’
   20 |   union U u = { .s = { { 1, 2 } } };
      |           ^

;; Function g (g, funcdef_no=1, decl_uid=1944, cgraph_uid=2, symbol_order=1)

g (int i, int j)
{
  int t;
  union U u;
  int _10;

  <bb 2> [local count: 1073741824]:
  MEM[(union U *)&u] = 8589934593;
  t_9 = u.s.a[j_5(D)];
  u.a[i_4(D)] = 0;
  _10 = u.s.a[j_5(D)];
  if (t_9 == _10)
    goto <bb 3>; [0.00%]
  else
    goto <bb 4>; [100.00%]

  <bb 3> [count: 0]:
  __builtin_abort ();

  <bb 4> [local count: 1073741824]:
  sink (&u);
  u ={v} {CLOBBER};
  return;

}


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56456
[Bug 56456] [meta-bug] bogus/missing -Warray-bounds

Reply via email to