[Bug middle-end/92110] New: too many -Warray-bounds warnings for a loop buffer overflow

msebor at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Tue Oct 15 19:27:00 GMT 2019


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

            Bug ID: 92110
           Summary: too many -Warray-bounds warnings for a loop buffer
                    overflow
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

As mentioned in bug 92016, when GCC unrolls a loop that writes past the end of
a buffer a separate instance of -Warray-bounds is issued for each iteration of
the loop that writes past the end of the destination.  This can be seen in
output for the test case below.  Likewise for -Wstringop-overflow when
-Warray-bounds is disabled.  It would make the diagnostic output much less
cluttered (and less overwhelming) if just a single warning was issued instead
that descried the full extent of the buffer overflow (i.e., its size and offset
from the beginning of the buffer).

$ cat c.c && gcc -S -O2 -Wall -Wextra -fdump-tree-strlen=/dev/stdout
-fdump-tree-optimized=/dev/stdout c.c
static void f (char *p, unsigned n)
{
  while (n--)
    *p++ = 0;
}

void g (void*);

void h (void)
{
  char a[4];
  f (a, 8);
  g (a);
}
c.c: In function ‘h’:
c.c:4:10: warning: array subscript 4 is outside array bounds of ‘char[4]’
[-Warray-bounds]
    4 |     *p++ = 0;
      |     ~~~~~^~~
c.c:11:8: note: while referencing ‘a’
   11 |   char a[4];
      |        ^
c.c:4:10: warning: array subscript 5 is outside array bounds of ‘char[4]’
[-Warray-bounds]
    4 |     *p++ = 0;
      |     ~~~~~^~~
c.c:11:8: note: while referencing ‘a’
   11 |   char a[4];
      |        ^
c.c:4:10: warning: array subscript 6 is outside array bounds of ‘char[4]’
[-Warray-bounds]
    4 |     *p++ = 0;
      |     ~~~~~^~~
c.c:11:8: note: while referencing ‘a’
   11 |   char a[4];
      |        ^
c.c:4:10: warning: array subscript 7 is outside array bounds of ‘char[4]’
[-Warray-bounds]
    4 |     *p++ = 0;
      |     ~~~~~^~~
c.c:11:8: note: while referencing ‘a’
   11 |   char a[4];
      |        ^

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

;; 2 loops found
;;
;; Loop 0
;;  header 0, latch 1
;;  depth 0, outer -1
;;  nodes: 0 1 2
;; 2 succs { 1 }
h ()
{
  char * p;
  unsigned int n;
  char a[4];

  <bb 2> [local count: 118111601]:
  MEM[(char *)&a] = 0;
  MEM[(char *)&a + 1B] = 0;
  MEM[(char *)&a + 2B] = 0;
  MEM[(char *)&a + 3B] = 0;
  MEM[(char *)&a + 4B] = 0;
  MEM[(char *)&a + 5B] = 0;
  MEM[(char *)&a + 6B] = 0;
  MEM[(char *)&a + 7B] = 0;
  g (&a);
  a ={v} {CLOBBER};
  return;

}



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

h ()
{
  char a[4];

  <bb 2> [local count: 118111601]:
  MEM <unsigned long> [(char *)&a] = 0;
  g (&a);
  a ={v} {CLOBBER};
  return;

}



$ gcc -S -O2 -Wall -Wextra -Wno-array-bounds c.c
static void f (char *p, unsigned n)
{
  while (n--)
    *p++ = 0;
}

void g (void*);

void h (void)
{
  char a[4];
  f (a, 8);
  g (a);
}
In function ‘f’,
    inlined from ‘h’ at c.c:12:3:
c.c:4:10: warning: writing 1 byte into a region of size 0
[-Wstringop-overflow=]
    4 |     *p++ = 0;
      |     ~~~~~^~~
c.c: In function ‘h’:
c.c:11:8: note: destination object declared here
   11 |   char a[4];
      |        ^
In function ‘f’,
    inlined from ‘h’ at c.c:12:3:
c.c:4:10: warning: writing 1 byte into a region of size 0
[-Wstringop-overflow=]
    4 |     *p++ = 0;
      |     ~~~~~^~~
c.c: In function ‘h’:
c.c:11:8: note: destination object declared here
   11 |   char a[4];
      |        ^
In function ‘f’,
    inlined from ‘h’ at c.c:12:3:
c.c:4:10: warning: writing 1 byte into a region of size 0
[-Wstringop-overflow=]
    4 |     *p++ = 0;
      |     ~~~~~^~~
c.c: In function ‘h’:
c.c:11:8: note: destination object declared here
   11 |   char a[4];
      |        ^
In function ‘f’,
    inlined from ‘h’ at c.c:12:3:
c.c:4:10: warning: writing 1 byte into a region of size 0
[-Wstringop-overflow=]
    4 |     *p++ = 0;
      |     ~~~~~^~~
c.c: In function ‘h’:
c.c:11:8: note: destination object declared here
   11 |   char a[4];
      |        ^


More information about the Gcc-bugs mailing list