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

            Bug ID: 82588
           Summary: missing -Warray-bounds on a excessively large index
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

GCC fails to issue a -Warray-bounds warning for indices so large that they
cannot be valid even for the largest objects.

In function f0() below, GCC recognizes that the signed distance between the
beginning of the array and the end pointer cannot be positive and transforms
the function into an unconditional call to abort, but it doesn't issue any sort
of a diagnostic.  -Warray-bounds would seem to be appropriate here.  Likewise
in function f1().

Similarly in function f2(), the size of the member array cannot be half the
address space because it would leave no room for the remaining members of the
same struct.  So again, -Warray-bounds could be issued for this pathological
case.  The comment in check_array_ref that reads "Can not check flexible
arrays." indicates the absence of checking for flexible array members is
intentional, but it can be tightened up to detect these boundary conditions.

$ cat a.c && gcc -O2 -S -Wall -Warray-bounds -fdump-tree-optimized=/dev/stdout
a.c 
struct A { int n; char a[]; };

void f0 (void)
{
  extern int a[];

  int *e = a + __SIZE_MAX__ / sizeof (int) + 1;   // missing warning

  if (e - a <= 0)
    __builtin_abort ();
}

int f1 (void)
{
  extern int a[];

  return a[__SIZE_MAX__ / sizeof (int) + 1];   // missing -Warray-bounds
}

int f2 (struct A *a)
{
  return a->a[__SIZE_MAX__ / 2];   // missing -Warray-bounds
}

;; Function f0 (f0, funcdef_no=0, decl_uid=1834, cgraph_uid=0, symbol_order=0)
(unlikely executed)

f0 ()
{
  <bb 2> [100.00%] [count: 0]:
  __builtin_abort ();

}



;; Function f1 (f1, funcdef_no=1, decl_uid=1840, cgraph_uid=1, symbol_order=1)

f1 ()
{
  int _2;

  <bb 2> [100.00%] [count: INV]:
  _2 = a[4611686018427387904];
  return _2;

}



;; Function f2 (f2, funcdef_no=2, decl_uid=1845, cgraph_uid=2, symbol_order=2)

f2 (struct A * a)
{
  char _1;
  int _4;

  <bb 2> [100.00%] [count: INV]:
  _1 = a_3(D)->a[9223372036854775807];
  _4 = (int) _1;
  return _4;

}

Reply via email to