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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Depends on|                            |86318
          Component|c                           |tree-optimization
            Summary|-Warray-bounds falsely      |-Warray-bounds while
                   |claims out-of-bounds access |iterating over an escaped
                   |                            |constant local array
           Keywords|                            |diagnostic,
                   |                            |missed-optimization
             Blocks|                            |56456

--- Comment #2 from Martin Sebor <msebor at gcc dot gnu.org> ---
-Warray-bounds relies on the optimizer to eliminate dead code.  In the test
case, GCC (unnecessarily) assumes that the escaped array may be modified by the
call to c().  This missing optimization (tracked in pr86318) keeps the second
test from being eliminated (see also the test case below).  I note that Clang
optimizes the function to a no-op as expected.

That aside, arrays with zero elements are meant to be used as trailing members
of structures.  Using them anywhere else is a bug waiting to happen.  I would
recommend against using them in any other contexts as they may start getting
diagnosed even more aggressively (e.g., even declaring one that's not last in a
struct might trigger a warning in the future).  I'll keep this open since a
similar warning can be triggered with a non-empty array due to the same
limitation.

A test case for the missing optimization:

$ cat pr95635.c && gcc -O3 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout
pr95635.c
void f (const int*);

void g (void)
{
  const int i = -1;
  f (&i);
  if (i != -1)            // folded to false
    __builtin_abort ();   // eliminated
}

void h (void)
{
  const int a[] = { -1 };
  f (a);
  if (*a != -1)           // not folded
    __builtin_abort ();
}

;; Function g (g, funcdef_no=0, decl_uid=1933, cgraph_uid=1, symbol_order=0)

g ()
{
  const int i;

  <bb 2> [local count: 1073741824]:
  i = -1;
  f (&i);
  i ={v} {CLOBBER};
  return;

}



;; Function h (h, funcdef_no=1, decl_uid=1937, cgraph_uid=2, symbol_order=1)

h ()
{
  const int a[1];
  int _1;

  <bb 2> [local count: 1073741824]:
  a[0] = -1;
  f (&a);
  _1 = a[0];
  if (_1 != -1)
    goto <bb 3>; [0.00%]
  else
    goto <bb 4>; [100.00%]

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

  <bb 4> [local count: 1073741824]:
  a ={v} {CLOBBER};
  return;

}


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56456
[Bug 56456] [meta-bug] bogus/missing -Warray-bounds
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86318
[Bug 86318] const local aggregates can be assumed not to be modified even when
escaped

Reply via email to