(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Warray-bounds-81.c
       1  /* PR tree-optimization/101397 - spurious warning writing to the result
       2     of stpcpy minus 1
       3     Verify warnings for indexing into a pointer returned from stpncpy.
       4     The call stpncpy(S1, S2, N) returns the address of the copy of
       5     the first NUL is it exists or &S1[N] otherwise.
       6     { dg-do compile }
       7     { dg-options "-O2 -Wall -Wno-stringop-truncation" } */
       8  
       9  typedef __SIZE_TYPE__ size_t;
      10  
      11  void* calloc (size_t, size_t);
      12  char* stpncpy (char*, const char*, size_t);
      13  
      14  void sink (int, ...);
      15  
      16  extern char ax[], a3[3], a5[5], a7[7], a9[9], *s;
      17  
      18  volatile int x;
      19  
      20  /* Verify warnings for indexing into the result of stpncpy with a source
      21     pointing to an array of unknown bound.  */
      22  
      23  void test_stpncpy_from_ptr (int i, int n)
      24  {
      25    {
      26      // P is in [ax, ax + 5].
      27      char *p = stpncpy (ax, s, 5);
      28      x = p[-6];                          // { dg-warning "\\\[-Warray-bounds" }
      29      sink (p[-5], p[-1], p[0], p[9]);
      30    }
      31  
      32    {
      33      // P is in [a5, a5 + 3].
      34      char *p = stpncpy (a5, s, 3);
      35      x = p[-4];                          // { dg-warning "\\\[-Warray-bounds" }
      36      sink (p[-3], p[-2], p[-1], p[0]);
      37      sink (p[ 1], p[ 2], p[ 3], p[4]);
      38      x = p[ 5];                          // { dg-warning "\\\[-Warray-bounds" }
      39    }
      40  
      41    {
      42      // P is in [ax, ax + 4].
      43      char *p = stpncpy (a5, s, 4);
      44      x = p[-5];                          // { dg-warning "\\\[-Warray-bounds" }
      45      sink (p[-4], p[-3], p[-2], p[-1], p[0]);
      46      sink (p[ 1], p[ 2], p[ 3], p[4]);
      47      x = p[ 5];                          // { dg-warning "\\\[-Warray-bounds" }
      48    }
      49  
      50    {
      51      // P is in [ax, ax + 5].
      52      char *p = stpncpy (a5, s, n);
      53      x = p[-6];                          // { dg-warning "\\\[-Warray-bounds" }
      54      sink (p[-5], p[-4], p[-3], p[-2], p[-1], p[0]);
      55      sink (p[ 1], p[ 2], p[ 3], p[4]);
      56      x = p[ 5];                          // { dg-warning "\\\[-Warray-bounds" }
      57    }
      58  
      59    {
      60      // P is in [ax, ax + 4].
      61      char *p = stpncpy (a5, s, 4);
      62  
      63      if (i > -1) i = -1;
      64      x = p[i];
      65  
      66      if (i > -2) i = -2;
      67      x = p[i];
      68  
      69      if (i > -3) i = -3;
      70      x = p[i];
      71  
      72      if (i > -4) i = -4;
      73      x = p[i];
      74  
      75      if (i > -5) i = -5;
      76      x = p[i];                           // { dg-warning "\\\[-Warray-bounds" }
      77    }
      78  }
      79  
      80  /* Verify warnings for indexing into the result of stpncpy with a source
      81     an array of size 5.  */
      82  
      83  void test_stpncpy_from_a5 (int i, int n, int n3_9)
      84  {
      85    {
      86      // The returned pointer is in [ax, ax + 3].
      87      char *p = stpncpy (ax, a5, 3);
      88      x = p[-4];                          // { dg-warning "\\\[-Warray-bounds" }
      89      sink (p[-3], p[-2], p[-1], p[0], p[1], p[99]);
      90    }
      91  
      92    {
      93      // The returned pointer is in [ax, ax + 5].
      94      char *p = stpncpy (ax, a5, 5);
      95      x = p[-6];                          // { dg-warning "\\\[-Warray-bounds" }
      96      x = p[-5];
      97      x = p[-1];
      98      x = p[ 0];
      99      x = p[ 9];
     100    }
     101  
     102    {
     103      //The returned pointer is in [ax, ax + 5] even though n is not known.
     104      char *p = stpncpy (ax, a5, n);
     105      x = p[-6];                          // { dg-warning "\\\[-Warray-bounds" }
     106      sink (p[-5], p[-4], p[-2], p[-1], p[0]);
     107      sink (p[1], p[2], p[3], p[4], p[9], p[99]);
     108    }
     109  
     110  
     111    {
     112      // The returned pointer is in [a3, a3 + 3].
     113      char *p = stpncpy (a3, a5, 3);
     114      x = p[-4];                          // { dg-warning "\\\[-Warray-bounds" }
     115      sink (p[-3], p[-2], p[-1], p[0]);
     116      sink (p[ 1], p[ 2]);
     117      x = p[ 3];                          // { dg-warning "\\\[-Warray-bounds" }
     118    }
     119  
     120    {
     121      // The returned pointer is in [a3, a3 + 3].
     122      char *p = stpncpy (a3, a5, n);
     123      x = p[-4];                          // { dg-warning "\\\[-Warray-bounds" }
     124      sink (p[-3], p[-2], p[-1], p[0]);
     125      sink (p[ 1], p[ 2]);
     126      x = p[ 3];                          // { dg-warning "\\\[-Warray-bounds" }
     127    }
     128  
     129    {
     130      if (n3_9 < 3 || 9 < n3_9)
     131        n3_9 = 3;
     132  
     133      // The returned pointer is in [a3, a3 + 3].
     134      char *p = stpncpy (a3, a5, n3_9);
     135      x = p[-4];                          // { dg-warning "\\\[-Warray-bounds" }
     136      sink (p[-3], p[-2], p[-1], p[0]);
     137      sink (p[ 1], p[ 2]);
     138      x = p[ 3];                          // { dg-warning "\\\[-Warray-bounds" }
     139    }
     140  
     141    {
     142      char *p = stpncpy (a3, a5, 3);
     143  
     144      if (i > -1) i = -1;
     145      x = p[i];
     146  
     147      if (i > -2) i = -2;
     148      x = p[i];
     149  
     150      if (i > -3) i = -3;
     151      x = p[i];
     152  
     153      if (i > -4) i = -4;
     154      x = p[i];                           // { dg-warning "\\\[-Warray-bounds" }
     155    }
     156  }
     157  
     158  
     159  /* Verify warnings for indexing into the result of stpncpy with a source
     160     an array of size 7.  */
     161  
     162  void test_stpncpy_from_a7 (int i, int n, int n3_9)
     163  {
     164    {
     165      // The returned pointer is ax + 5.
     166      char *p = stpncpy (ax, a7, 5);
     167      x = p[-6];                          // { dg-warning "\\\[-Warray-bounds" }
     168      x = p[-5];
     169      x = p[-1];
     170      x = p[ 0];
     171      x = p[ 9];
     172    }
     173  
     174    {
     175      //The returned pointer is in [ax, ax + 7] even though n is not known.
     176      char *p = stpncpy (ax, a7, n);
     177      x = p[-8];                          // { dg-warning "\\\[-Warray-bounds" }
     178      sink (p[-7], p[-6], p[-5], p[-4], p[-3], p[-2], p[-1], p[0]);
     179      sink (p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9]);
     180    }
     181  
     182  
     183    {
     184      // The returned pointer is in [a5, a5 + 3].
     185      char *p = stpncpy (a5, a7, 3);
     186      x = p[-4];                          // { dg-warning "\\\[-Warray-bounds" }
     187      sink (p[-3], p[-2], p[-1], p[0]);
     188      sink (p[1], p[2], p[3], p[4]);
     189      x = p[ 5];                          // { dg-warning "\\\[-Warray-bounds" }
     190    }
     191  
     192    {
     193      // The returned pointer is a5 + 4.
     194      char *p = stpncpy (a5, a7, 4);
     195      x = p[-5];                          // { dg-warning "\\\[-Warray-bounds" }
     196      sink (p[-4], p[-3], p[-2], p[-1], p[0]);
     197      sink (p[1], p[2], p[3], p[4]);
     198      x = p[ 5];                          // { dg-warning "\\\[-Warray-bounds" }
     199    }
     200  
     201    {
     202      // The returned pointer is in [a5, a5 + 5].
     203      char *p = stpncpy (a5, a7, n);
     204      x = p[-6];                          // { dg-warning "\\\[-Warray-bounds" }
     205      sink (p[-5], p[-4], p[-3], p[-2], p[-1], p[0]);
     206      sink (p[1], p[2], p[3], p[4]);
     207      x = p[ 5];                          // { dg-warning "\\\[-Warray-bounds" }
     208    }
     209  
     210    {
     211      if (n3_9 < 3 || 9 < n3_9)
     212        n3_9 = 3;
     213  
     214      // The returned pointer is in [a5, a5 + 5].
     215      char *p = stpncpy (a5, a7, n3_9);
     216      x = p[-6];                          // { dg-warning "\\\[-Warray-bounds" }
     217      sink (p[-5], p[-4], p[-3], p[-2], p[-1], p[0]);
     218      sink (p[1], p[2], p[3], p[4]);
     219      x = p[ 5];                          // { dg-warning "\\\[-Warray-bounds" }
     220    }
     221  
     222    {
     223      char *p = stpncpy (a5, a7, 4);
     224  
     225      if (i > -1) i = -1;
     226      x = p[i];
     227  
     228      if (i > -2) i = -2;
     229      x = p[i];
     230  
     231      if (i > -3) i = -3;
     232      x = p[i];
     233  
     234      if (i > -4) i = -4;
     235      x = p[i];
     236  
     237      if (i > -5) i = -5;
     238      x = p[i];                           // { dg-warning "\\\[-Warray-bounds" }
     239    }
     240  }
     241  
     242  
     243  void test_stpncpy_from_a5_to_allocated (int i, int n, int n5_7, int n3_9)
     244  {
     245    if (n5_7 < 5 || 7 < n5_7)
     246      n5_7 = 5;
     247  
     248    {
     249      char *d = calloc (n5_7, 1);
     250      char *p = stpncpy (d, s, n);
     251      x = p[-8];                          // { dg-warning "\\\[-Warray-bounds" }
     252      sink (p[-7], p[-6], p[-5], p[-4], p[-3], p[-2], p[-1], p[0]);
     253      sink (p[1], p[2], p[3], p[4], p[5], p[6]);
     254      x = p[7];                           // { dg-warning "\\\[-Warray-bounds" }
     255    }
     256  
     257    {
     258      char *d = calloc (n5_7, 1);
     259      char *p = stpncpy (d, a3, n);
     260      x = p[-4];                          // { dg-warning "\\\[-Warray-bounds" }
     261      sink (p[-3], p[-2], p[-1], p[0]);
     262      sink (p[1], p[2], p[3], p[4], p[5], p[6]);
     263      x = p[7];                           // { dg-warning "\\\[-Warray-bounds" }
     264    }
     265  
     266    {
     267      char *d = calloc (n5_7, 1);
     268      char *p = stpncpy (d, a5, n);
     269      x = p[-6];                          // { dg-warning "\\\[-Warray-bounds" }
     270      sink (p[-5], p[-4], p[-3], p[-2], p[-1], p[0]);
     271      sink (p[1], p[2], p[3], p[4], p[5], p[6]);
     272      x = p[7];                           // { dg-warning "\\\[-Warray-bounds" }
     273    }
     274  
     275    {
     276      char *d = calloc (n5_7, 1);
     277      char *p = stpncpy (d, a9, n);
     278      x = p[-8];                          // { dg-warning "\\\[-Warray-bounds" }
     279      sink (p[-7], p[-6], p[-5], p[-3], p[-4], p[-2], p[-1], p[0]);
     280      sink (p[1], p[2], p[3], p[4], p[5], p[6]);
     281      x = p[7];                           // { dg-warning "\\\[-Warray-bounds" }
     282    }
     283  
     284    {
     285      char *d = calloc (n5_7, 1);
     286      char *p = stpncpy (d, a3, n3_9);
     287      x = p[-4];                          // { dg-warning "\\\[-Warray-bounds" }
     288      sink (p[-3], p[-2], p[-1], p[0]);
     289      sink (p[1], p[2], p[3], p[4], p[5], p[6]);
     290      x = p[7];                           // { dg-warning "\\\[-Warray-bounds" }
     291    }
     292  
     293    {
     294      char *d = calloc (n5_7, 1);
     295      char *p = stpncpy (d, a9, n3_9);
     296      x = p[-8];                          // { dg-warning "\\\[-Warray-bounds" }
     297      sink (p[-7], p[-6], p[-5], p[-4], p[-4], p[-2], p[-1], p[0]);
     298      sink (p[1], p[2], p[3], p[4], p[5], p[6]);
     299      x = p[7];                           // { dg-warning "\\\[-Warray-bounds" }
     300    }
     301  
     302  }