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

            Bug ID: 92939
           Summary: missing -Wstringop-overflow on negative index from the
                    end of array
           Product: gcc
           Version: 10.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: ---

Even with -Wno-array-bounds the out-of-bounds stores in the first assignment to
p[1] below and in the last assignment to p[-2] should be diagnosed by
-Wstringop-overflow.  But only the first is because the implementation of the
warning (the compute_objsize function) isn't prepared to handle negative
offsets.

$ cat b.c && gcc -O2 -S -Wall -Wno-array-bounds b.c
void sink (void*);

void f (int n, int i)
{
  if (n < 2 || 3 < n) n = 2;
  if (i < 1 || 2 < i) i = 1;

  char a[3], *p = a + n;

               //     N=2              N=3
               // I=1     I=2      I=1     I=2
  p[1] = 0;    // a[3]    a[3]     a[4]    a[4]    << warns
  p[0] = 0;    // a[2]    a[2]     a[3]    a[3]    << should not warn
  p[-1] = 0;   // a[1]    a[1]     a[2]    a[2]    << must not warn
  p -= i;
  p[0]  = 0;   // a[1]    a[0]     a[2]    a[1]    << must not warn
  p[-1] = 0;   // a[0]    a[-1]    a[1]    a[0]    << should not warn
  p[-2] = 0;   // a[-1]   a[-2]    a[0]    a[-1]   << should not warn
  p -= i;
  p[0] = 0;    // a[0]    a[-1]    a[1]    a[0]    << should not warn
  p[-1] = 0;   // a[-1]   a[-2]    a[0]    a[-1]   << should not warn
  p[-2] = 0;   // a[-2]   a[-3]    a[-1]   a[-2]   << should warn

  sink (p);
}

b.c: In function ‘f’:
b.c:12:8: warning: writing 1 byte into a region of size 0
[-Wstringop-overflow=]
   12 |   p[1] = 0;    // a[3]    a[3]     a[4]    a[4]    << warns
      |   ~~~~~^~~
b.c:8:8: note: at offset 0 to object ‘a’ with size 3 declared here
    8 |   char a[3], *p = a + n;
      |        ^


Without -Wno-array-bounds GCC correctly diagnoses the out-of-bounds access:

b.c: In function ‘f’:
b.c:12:4: warning: array subscript [3, 4] is outside array bounds of ‘char[3]’
[-Warray-bounds]
   12 |   p[1] = 0;    // a[3]    a[3]     a[4]    a[4]    << warns
      |   ~^~~
b.c:8:8: note: while referencing ‘a’
    8 |   char a[3], *p = a + n;
      |        ^
b.c:22:4: warning: array subscript [-4, -1] is outside array bounds of
‘char[3]’ [-Warray-bounds]
   22 |   p[-2] = 0;   // a[-2]   a[-3]    a[-1]   a[-2]   << should warn
      |   ~^~~~
b.c:8:8: note: while referencing ‘a’
    8 |   char a[3], *p = a + n;
      |        ^

Reply via email to