(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Warray-bounds-29.c
       1  /* PR tree-optimization/83776: missing -Warray-bounds indexing past the end
       2     of a string literal
       3     Test to exercise warnings for computations of otherwise in-bounds indices
       4     into strings that temporarily exceed the bounds of the string.
       5     { dg-do compile }
       6     { dg-options "-O2 -Warray-bounds=2 -ftrack-macro-expansion=0" } */
       7  
       8  #include "range.h"
       9  
      10  #define MAX DIFF_MAX
      11  #define MIN DIFF_MIN
      12  
      13  typedef __WCHAR_TYPE__ wchar_t;
      14  
      15  void sink (int, ...);
      16  
      17  #define T(expr)   sink (0, expr)
      18  
      19  void test_narrow (void)
      20  {
      21    int i = SR (1, 2);
      22  
      23    const char *p0 = "12";
      24    const char *p1 = p0 + i;    /* points at '2' or beyond */
      25    const char *p2 = p1 + i;    /* points at '\0' or beyond */
      26    const char *p3 = p2 + i;    /* points just past the end */
      27    const char *p4 = p3 + i;    /* invalid */
      28  
      29    T (p0[-1]);                 /* { dg-warning "array subscript \(-1|\[0-9\]+) is outside array bounds of .char\\\[3]." } */
      30    T (p0[0]);
      31    T (p0[1]);
      32    T (p0[2]);
      33    T (p0[3]);                  /* { dg-warning "array subscript 3 is outside array bounds of .char\\\[3]." } */
      34  
      35    T (&p0[-1]);                /* { dg-warning "array subscript \(-1|\[0-9\]+) is \(above|below|outside\) array bounds of .char\\\[3]." } */
      36    T (&p0[0]);
      37    T (&p0[1]);
      38    T (&p0[2]);
      39    T (&p0[3]);
      40    T (&p0[4]);                 /* { dg-warning "array subscript 4 is \(above|outside\) array bounds of .char\\\[3]." } */
      41  
      42    T (p1[-3]);                 /* { dg-warning "array subscript \\\[-2, -1] is outside array bounds of .char\\\[3]." } */
      43    T (p1[-2]);
      44    T (p1[-1]);
      45    T (p1[ 0]);
      46    T (p1[ 1]);
      47    T (p1[ 2]);                 /* { dg-warning "array subscript 3 is outside array bounds of .char\\\[3]." } */
      48    T (p1[ 3]);                 /* { dg-warning "array subscript \\\[4, 5] is outside array bounds of .char\\\[3]." } */
      49  
      50    T (&p1[-3]);                /* { dg-warning "array subscript \\\[-2, -1] is outside array bounds of .char\\\[3]." "bug" { xfail *-*-* } } */
      51    T (&p1[-2]);
      52    T (&p1[-1]);
      53    T (&p1[ 0]);
      54    T (&p1[ 1]);
      55    T (&p1[ 2]);
      56    T (&p1[ 3]);                /* { dg-warning "array subscript \\\[4, 6] is outside array bounds of .char\\\[3]." "bug" { xfail *-*-* } } */
      57  
      58    T (p2[-4]);                 /* { dg-warning "subscript \\\[-2, -1\\\] is outside array bounds of .char\\\[3]." } */
      59    T (p2[-3]);
      60    T (p2[-2]);
      61    T (p2[-1]);
      62    T (p2[ 0]);
      63  
      64    /* Even though the lower bound of p3's offsets is in bounds, in order
      65       to subtract 4 from p3 and get a dereferenceable pointer its value
      66       would have to be out-of-bounds.  */
      67    T (p3[-4]);                 /* { dg-warning "array subscript -1 is outside array bounds of .char\\\[3]." } */
      68    T (p3[-3]);
      69    T (p3[-2]);
      70    T (p3[-1]);
      71    T (p3[ 0]);                 /* { dg-warning "array subscript 3 is outside array bounds of .char\\\[3]." } */
      72  
      73    T (p4[-4]);                 /* { dg-warning "intermediate array offset 4 is outside array bounds of .char\\\[3]." } */
      74    T (p4[-3]);                 /* { dg-warning "intermediate array offset 4 is outside array bounds of .char\\\[3]." } */
      75    T (p4[-2]);                 /* { dg-warning "intermediate array offset 4 is outside array bounds of .char\\\[3]." } */
      76  
      77    /* The final subscripts below are invalid.  */
      78    T (p4[-1]);                 /* { dg-warning "array subscript 3 is outside array bounds of .char\\\[3]." } */
      79    T (p4[ 0]);                 /* { dg-warning "array subscript \\\[4, 5] is outside array bounds of .char\\\[3]." } */
      80  }
      81  
      82  
      83  void test_narrow_vflow (void)
      84  {
      85    int i = SR (DIFF_MAX - 2, DIFF_MAX);
      86    int j = SR (1, DIFF_MAX);
      87  
      88    const char *p0 = "123";
      89    const char *p1 = p0 + i;    /* points at '2' or beyond */
      90    const char *p2 = p1 + i;    /* points at '\0' or beyond */
      91    const char *p3 = p2 + i;    /* points just past the end */
      92    const char *p4 = p3 + i;    /* invalid */
      93  }
      94  
      95  
      96  void test_wide (void)
      97  {
      98    int i = SR (1, 2);
      99  
     100    const wchar_t *p0 = L"123";
     101    const wchar_t *p1 = p0 + i;    /* points at L'2' or beyond */
     102    const wchar_t *p2 = p1 + i;    /* points at L'3' or beyond */
     103    const wchar_t *p3 = p2 + i;    /* points at L'\0' or beyond */
     104    const wchar_t *p4 = p3 + i;    /* points just past the end */
     105    const wchar_t *p5 = p4 + i;    /* invalid */
     106  
     107    T (p0[0]);
     108    T (p0[1]);
     109    T (p0[2]);
     110    T (p0[3]);
     111    T (p0[4]);                  /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */
     112  
     113    T (p1[-1]);
     114    T (p1[ 0]);
     115    T (p1[ 1]);
     116    T (p1[ 2]);
     117    T (p1[ 3]);                  /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */
     118  
     119    T (&p1[-1]);
     120    T (&p1[ 0]);
     121    T (&p1[ 1]);
     122    T (&p1[ 2]);
     123    T (&p1[ 3]);
     124    T (&p1[ 4]);                 /* { dg-warning "array subscript \\\[5, 6] is outside array bounds of .\[a-z \]+\\\[4]." "bug" { xfail *-*-* } } */
     125  
     126    T (p2[-5]);                 /* { dg-warning "array subscript \\\[-3, -1] is outside array bounds of .\[a-z \]+\\\[4]." } */
     127    T (p2[-4]);
     128    T (p2[-3]);
     129    T (p2[-2]);
     130    T (p2[-1]);
     131    T (p2[ 0]);
     132  
     133    /* Even though the lower bound of p3's offsets is in bounds, in order
     134       to subtract 5 from p3 and get a dereferenceable pointer its value
     135       would have to be out-of-bounds.  */
     136    T (p3[-5]);                 /* { dg-warning "array subscript \\\[-2, -1\\\] is outside array bounds of .\[a-z \]+\\\[4]." } */
     137    T (p3[-4]);
     138    T (p3[-3]);
     139    T (p3[-2]);
     140    T (p3[-1]);
     141    T (p3[ 0]);
     142    T (p3[ 1]);                 /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */
     143  
     144    T (p4[-5]);                 /* { dg-warning "array subscript -1 is outside array bounds of .\[a-z \]+\\\[4]." } */
     145    T (p4[-4]);
     146    T (p4[-3]);
     147    T (p4[-2]);
     148    T (p4[-1]);
     149    T (p4[ 0]);                 /* { dg-warning "array subscript 4 is outside array bounds of .\[a-z \]+\\\[4]." } */
     150  }