(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Wstringop-overflow-11.c
       1  /* PR tree-optimization/89350 - Wrong -Wstringop-overflow warning
       2     on a variable offset from the end of an array
       3     Test exercising -Wstringop-truncation with -Wall.
       4     -Wstringop-truncation is disabled to avoid warnings for strncpy
       5     calls whose bound matches the size of the destination getting
       6     in the way of -Wstringop-overflow.
       7     { dg-do compile }
       8     { dg-options "-O2 -Wall -Wno-stringop-truncation -ftrack-macro-expansion=0" }  */
       9  
      10  #include "range.h"
      11  
      12  extern void* memcpy (void*, const void*, size_t);
      13  extern void* memset (void*, int, size_t);
      14  extern char* strcpy (char*, const char*);
      15  extern char* strncpy (char*, const char*, size_t);
      16  
      17  void sink (void*);
      18  
      19  #define CAT(pfx, line) pfx ## line
      20  #define CONCAT(pfx, line) CAT (pfx, line)
      21  #define UNIQ_NAME(pfx) CONCAT (pfx, __LINE__)
      22  
      23  /* Exercise a call to memset with a distinct destination object each
      24     time to prevent GCC from reusing the destination pointer in later
      25     tests.  */
      26  #define T(off1, off2, n)			\
      27    do {						\
      28      extern char UNIQ_NAME (ga)[7];		\
      29      char *d = UNIQ_NAME (ga) + off1;		\
      30      d += off2;					\
      31      memset (d, 0, n);				\
      32      sink (d);					\
      33    } while (0)
      34  
      35  
      36  /* Exercise calls to memset with a destination pointer pointing to
      37     an array plus constant offset plus variable offset, in that order.  */
      38  
      39  void test_memset_array_cst_range_off (void)
      40  {
      41    T (1, SR (-7, 7), 7);
      42    T (1, SR (-1, 1), 7);
      43    T (1, SR (-1, 1), 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
      44    T (1, SR ( 1, 2), 1);
      45    T (1, SR ( 1, 2), 5);
      46  
      47    T (1, SR ( 0, 1), 6);
      48    T (1, UR ( 1, 2), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
      49  
      50    T (2, SR (-7, 7), 7);
      51    T (2, SR (-2, 7), 7);
      52    T (2, SR (-1, 1), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
      53    T (2, SR (-1, 1), 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
      54    T (2, SR ( 1, 2), 1);
      55    T (2, SR ( 1, 2), 3);
      56    T (2, SR ( 1, 2), 4);
      57    T (2, SR ( 1, 2), 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
      58  
      59    T (2, SR ( 0, 1), 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
      60    T (2, UR ( 1, 2), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
      61    T (7, UR (-7, 0), 7);
      62    T (7, UR (-7, 0), 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
      63    T (7, UR (-3, 2), 3);
      64    T (7, UR (-2, 2), 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
      65  }
      66  
      67  
      68  /* Exercise calls to memset with a destination pointer pointing to
      69     an array plus variable offset plus constant offset.  */
      70  
      71  void test_memset_array_range_cst_off (void)
      72  {
      73    T (SR (-7, 7), 1, 7);
      74    T (SR (-1, 1), 1, 7);
      75    T (SR (-1, 1), 1, 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
      76    T (SR ( 1, 2), 1, 1);
      77    T (SR ( 1, 2), 1, 5);
      78  
      79    T (SR ( 0, 1), 1, 6);
      80    T (UR ( 1, 2), 1, 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
      81  
      82    T (SR (-7, 7), 2, 7);
      83    T (SR (-1, 1), 2, 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
      84    T (SR (-1, 1), 2, 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
      85    T (SR ( 1, 2), 2, 1);
      86    T (SR ( 1, 2), 2, 3);
      87    T (SR ( 1, 2), 2, 4);
      88    T (SR ( 1, 2), 2, 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
      89  
      90    T (SR ( 0, 1), 2, 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
      91  
      92    T (UR ( 1, 2), 2, 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
      93  }
      94  
      95  
      96  void test_memset_array_range_range_off (void)
      97  {
      98    T (UR (0, 1), UR (0, 1), 7);
      99    T (UR (3, 5), UR (2, 7), 1);
     100    T (UR (3, 7), UR (2, 9), 2);
     101    T (UR (3, 9), UR (2, 9), 3);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     102    T (UR (0, 1), UR (1, 2), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     103  }
     104  
     105  
     106  #undef T
     107  #define T(off1, off2, n)			\
     108    do {						\
     109      extern char UNIQ_NAME (ga)[7];		\
     110      char *d = UNIQ_NAME (ga) + off1;		\
     111      d += off2;					\
     112      memcpy (d, s, n);				\
     113      sink (d);					\
     114    } while (0)
     115  
     116  
     117  void test_memcpy_array_cst_range_off (const void *s)
     118  {
     119    T (1, SR (-7, 7), 7);
     120    T (1, SR (-1, 1), 7);
     121    T (1, SR (-1, 1), 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     122    T (1, SR ( 1, 2), 1);
     123    T (1, SR ( 1, 2), 5);
     124  
     125    T (1, SR ( 0, 1), 6);
     126    T (1, UR ( 1, 2), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     127  
     128    T (2, SR (-7, 7), 7);
     129    T (2, SR (-2, 7), 7);
     130    T (2, SR (-1, 1), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     131    T (2, SR (-1, 1), 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     132    T (2, SR ( 1, 2), 1);
     133    T (2, SR ( 1, 2), 3);
     134    T (2, SR ( 1, 2), 4);
     135    T (2, SR ( 1, 2), 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     136  
     137    T (2, SR ( 0, 1), 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
     138    T (2, UR ( 1, 2), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     139    T (7, UR (-7, 0), 7);
     140    T (7, UR (-7, 0), 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     141    T (7, UR (-3, 2), 3);
     142    T (7, UR (-2, 2), 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     143  }
     144  
     145  
     146  void test_memcpy_array_range_cst_off (const void *s)
     147  {
     148    T (SR (-7, 7), 1, 7);
     149    T (SR (-1, 1), 1, 7);
     150    T (SR (-1, 1), 1, 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
     151    T (SR ( 1, 2), 1, 1);
     152    T (SR ( 1, 2), 1, 5);
     153  
     154    T (SR ( 0, 1), 1, 6);
     155    T (UR ( 1, 2), 1, 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     156  
     157    T (SR (-7, 7), 2, 7);
     158    T (SR (-1, 1), 2, 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     159    T (SR (-1, 1), 2, 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     160    T (SR ( 1, 2), 2, 1);
     161    T (SR ( 1, 2), 2, 3);
     162    T (SR ( 1, 2), 2, 4);
     163    T (SR ( 1, 2), 2, 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     164  
     165    T (SR ( 0, 1), 2, 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     166  
     167    T (UR ( 1, 2), 2, 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     168  }
     169  
     170  
     171  void test_memcpy_array_range_range_off (const void *s)
     172  {
     173    T (UR (0, 1), UR (0, 1), 7);
     174    T (UR (3, 5), UR (2, 7), 1);
     175    T (UR (3, 7), UR (2, 9), 2);
     176    T (UR (3, 9), UR (2, 9), 3);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     177    T (UR (0, 1), UR (1, 2), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     178  }
     179  
     180  
     181  #undef T
     182  #define T(off1, off2, n)			\
     183    do {						\
     184      extern char UNIQ_NAME (ga)[7];		\
     185      char *d = UNIQ_NAME (ga) + off1;		\
     186      d += off2;					\
     187      const char str[] = "0123456789";		\
     188      const char *s = str + sizeof str - 1 - n;   \
     189      strcpy (d, s);				\
     190      sink (d);					\
     191    } while (0)
     192  
     193  
     194  void test_strcpy_array_cst_range_off (void)
     195  {
     196    T (1, SR (-7, 7), 6);
     197    T (1, SR (-1, 1), 6);
     198    T (1, SR (-1, 1), 8);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     199    T (1, SR ( 1, 2), 0);
     200    T (1, SR ( 1, 2), 4);
     201  
     202    T (1, SR ( 0, 1), 5);
     203    T (1, UR ( 1, 2), 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     204  
     205    T (2, SR (-7, 7), 6);
     206    T (2, SR (-2, 7), 6);
     207    T (2, SR (-1, 1), 6);      /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     208    T (2, SR (-1, 1), 8);      /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     209    T (2, SR ( 1, 2), 0);
     210    T (2, SR ( 1, 2), 2);
     211    T (2, SR ( 1, 2), 3);
     212    T (2, SR ( 1, 2), 4);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     213  
     214    T (2, SR ( 0, 1), 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
     215    T (2, UR ( 1, 2), 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     216    T (7, UR (-7, 0), 6);
     217    T (7, UR (-7, 0), 8);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     218    T (7, UR (-3, 2), 2);
     219    T (7, UR (-2, 2), 4);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     220  }
     221  
     222  
     223  void test_strcpy_array_range_cst_off (const char *s)
     224  {
     225    T (SR (-7, 7), 1, 6);
     226    T (SR (-1, 1), 1, 6);
     227    T (SR (-1, 1), 1, 8);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
     228    T (SR ( 1, 2), 1, 0);
     229    T (SR ( 1, 2), 1, 1);
     230    T (SR ( 1, 2), 1, 4);
     231  
     232    T (SR ( 0, 1), 1, 5);
     233    T (UR ( 1, 2), 1, 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     234  
     235    T (SR (-7, 7), 2, 6);
     236    T (SR (-1, 1), 2, 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     237    T (SR (-1, 1), 2, 8);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     238    T (SR ( 1, 2), 2, 0);
     239    T (SR ( 1, 2), 2, 1);
     240    T (SR ( 1, 2), 2, 2);
     241    T (SR ( 1, 2), 2, 3);
     242    T (SR ( 1, 2), 2, 4);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     243  
     244    T (SR ( 0, 1), 2, 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     245  
     246    T (UR ( 1, 2), 2, 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     247  }
     248  
     249  
     250  #undef T
     251  #define T(off1, off2, n)			\
     252    do {						\
     253      extern char UNIQ_NAME (ga)[7];		\
     254      char *d = UNIQ_NAME (ga) + off1;		\
     255      d += off2;					\
     256      strncpy (d, s, n);				\
     257      sink (d);					\
     258    } while (0)
     259  
     260  
     261  void test_strncpy_array_cst_range_off (const char *s)
     262  {
     263    T (1, SR (-7, 7), 7);
     264    T (1, SR (-1, 1), 7);
     265    T (1, SR (-1, 1), 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     266    T (1, SR ( 1, 2), 1);
     267    T (1, SR ( 1, 2), 5);
     268  
     269    T (1, SR ( 0, 1), 6);
     270    T (1, UR ( 1, 2), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     271  
     272    T (2, SR ( -7, 7), 7);
     273    T (2, SR ( -1, 1), 7);      /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     274    T (2, SR ( -1, 1), 9);      /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     275    T (2, SR ( 1, 2), 1);
     276    T (2, SR ( 1, 2), 3);
     277    T (2, SR ( 1, 2), 4);
     278    T (2, SR ( 1, 2), 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     279  
     280    T (2, SR ( 0, 1), 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
     281    T (2, UR ( 1, 2), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     282    T (7, UR (-7, 0), 7);
     283    T (7, UR (-7, 0), 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     284    T (7, UR (-3, 2), 3);
     285    T (7, UR (-2, 2), 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     286  }
     287  
     288  
     289  void test_strncpy_array_range_cst_off (const char *s)
     290  {
     291    T (SR (-7, 7), 1, 7);
     292    T (SR (-1, 1), 1, 7);
     293    T (SR (-1, 1), 1, 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
     294    T (SR ( 1, 2), 1, 1);
     295    T (SR ( 1, 2), 1, 5);
     296  
     297    T (SR ( 0, 1), 1, 6);
     298    T (UR ( 1, 2), 1, 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     299  
     300    T (SR (-7, 7), 2, 7);
     301    T (SR (-1, 1), 2, 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     302    T (SR (-1, 1), 2, 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     303    T (SR ( 1, 2), 2, 1);
     304    T (SR ( 1, 2), 2, 3);
     305    T (SR ( 1, 2), 2, 4);
     306    T (SR ( 1, 2), 2, 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     307  
     308    T (SR ( 0, 1), 2, 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     309  
     310    T (UR ( 1, 2), 2, 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     311  }
     312  
     313  
     314  void test_strncpy_array_range_range_off (const char *s)
     315  {
     316    T (UR (0, 1), UR (0, 1), 7);
     317    T (UR (3, 5), UR (2, 7), 1);
     318    T (UR (3, 7), UR (2, 9), 2);
     319    T (UR (3, 9), UR (2, 9), 3);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     320    T (UR (0, 1), UR (1, 2), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     321  }