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