(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Wrestrict-9.c
       1  /* PR tree-optimization/84095 - false-positive -Wrestrict warnings for
       2     strcpy within array
       3     { dg-do compile }
       4     { dg-options "-O2 -Wrestrict -Wno-stringop-overflow -ftrack-macro-expansion=0" } */
       5  
       6  typedef __SIZE_TYPE__ size_t;
       7  
       8  extern void* memcpy (void* restrict, const void* restrict, size_t);
       9  extern char* strcpy (char* restrict, const char* restrict);
      10  
      11  #define T(d, s)   strcpy (d, s)
      12  
      13  struct MemArrays {
      14    char pad[8];
      15    char a2[3][9];
      16    char a3[3][4][9];
      17  } a[2];
      18  
      19  struct NestedMemArrays {
      20    struct MemArrays ma;
      21    struct MemArrays ma1[2];
      22  } nma[2];
      23  
      24  /* Use a variable as the source of a copy to verify that VAR_DECL
      25     is handled correctly when it's the source of GIMPLE assignment.  */
      26  const char *str = "1234567";
      27  
      28  void test_obj_2_dim_const (void)
      29  {
      30    const char *s = strcpy (a[0].a2[0], "1234567");
      31  
      32    T (a[0].a2[1], s);
      33    T (a[0].a2[2], s);
      34  
      35    /* Ideally, the offsets in the warning below would be relative to
      36       the beginning of the accessed array member.  Unfortunately, when
      37       the offset is represented as
      38       MEM_REF (char[9], A, offsetof (struct MemArrays, A[0].A2[0]) + 1)
      39       as it is in this instance it's difficult to determine the member
      40       that is being accessed and tease out from the MEM_REF the offset
      41       as it appears in the source.  As a result, the warning mentions
      42       the offset from the beginning of A instead.  This is suboptimal
      43       and should be fixed, either by printing the correct offsets or
      44       by mentioning the base object that the offset is relative to.  */
      45    T (a[0].a2[0] + 1, s);      /* { dg-warning "accessing 8 bytes at offsets \(1|9\) and \(0|8\) overlaps 7 bytes at offset \(1|9\)." } */
      46    T (a[0].a2[1] + 2, s);
      47    T (a[0].a2[2] + 3, s);
      48  
      49    T (a[1].a2[0], s);
      50    T (a[1].a2[1], s);
      51    T (a[1].a2[2], s);
      52  
      53    T (a[1].a2[0] + 1, s);
      54    T (a[1].a2[1] + 2, s);
      55    T (a[1].a2[2] + 3, s);
      56  }
      57  
      58  void test_obj_nested_2_dim_const (void)
      59  {
      60    const char *s = strcpy (nma[0].ma.a2[0], str);
      61  
      62    T (nma[0].ma.a2[1], s);
      63    T (nma[0].ma.a2[2], s);
      64  
      65    T (nma[0].ma.a2[0] + 1, s);      /* { dg-warning "accessing 8 bytes at offsets 1 and 0 overlaps 7 bytes at offset 1" "bug " { xfail *-*-* } } */
      66    T (nma[0].ma.a2[1] + 2, s);
      67    T (nma[0].ma.a2[2] + 3, s);
      68  
      69    T (nma[1].ma.a2[1], s);
      70    T (nma[1].ma.a2[2], s);
      71  
      72    T (nma[1].ma.a2[0] + 1, s);
      73    T (nma[1].ma.a2[1] + 2, s);
      74    T (nma[1].ma.a2[2] + 3, s);
      75  
      76  
      77    T (nma[0].ma1[0].a2[1], s);
      78    T (nma[0].ma1[0].a2[2], s);
      79  
      80    T (nma[0].ma1[0].a2[0] + 1, s);
      81    T (nma[0].ma1[0].a2[1] + 2, s);
      82    T (nma[0].ma1[0].a2[2] + 3, s);
      83  
      84    T (nma[1].ma1[0].a2[1], s);
      85    T (nma[1].ma1[0].a2[2], s);
      86  
      87    T (nma[1].ma1[0].a2[0] + 1, s);
      88    T (nma[1].ma1[0].a2[1] + 2, s);
      89    T (nma[1].ma1[0].a2[2] + 3, s);
      90  }
      91  
      92  void test_obj_2_dim_var (int i, int j)
      93  {
      94    const char *s = memcpy (a[0].a2[0], "1234567", 8);
      95  
      96    T (a[i].a2[0], s);          /* { dg-bogus "\\\[-Wrestrict]" } */
      97    T (a[i].a2[1], s);
      98    T (a[i].a2[2], s);
      99  
     100    T (a[i].a2[0] + 1, s);
     101    T (a[i].a2[1] + 1, s);
     102    T (a[i].a2[2] + 1, s);
     103  
     104    T (a[0].a2[i], s);          /* { dg-bogus "\\\[-Wrestrict]" } */
     105    T (a[1].a2[i], s);
     106  
     107    T (a[i].a2[0] + j, s);
     108    T (a[i].a2[1] + j, s);
     109    T (a[i].a2[2] + j, s);
     110  
     111    T (a[0].a2[i] + 1, s);
     112    T (a[1].a2[i] + 1, s);
     113  
     114    T (a[0].a2[i] + j, s);
     115    T (a[1].a2[i] + j, s);
     116  
     117    if (i < 0 || 1 < i)
     118      i = 1;
     119  
     120    T (a[i].a2[0], s);
     121    T (a[i].a2[1], s);
     122    T (a[i].a2[2], s);
     123  
     124    T (a[i].a2[0] + 1, s);
     125    T (a[i].a2[1] + 1, s);
     126    T (a[i].a2[2] + 1, s);
     127  
     128    T (a[0].a2[i], s);
     129    T (a[1].a2[i], s);
     130  
     131    T (a[i].a2[0] + j, s);
     132    T (a[i].a2[1] + j, s);
     133    T (a[i].a2[2] + j, s);
     134  
     135    T (a[0].a2[i] + 1, s);
     136    T (a[1].a2[i] + 1, s);
     137  
     138    T (a[0].a2[i] + j, s);
     139    T (a[1].a2[i] + j, s);
     140  }
     141  
     142  void test_obj_nested_2_dim_var (int i, int j)
     143  {
     144    const char *s = strcpy (nma[0].ma.a2[0], "1234567");
     145  
     146    T (nma[i].ma.a2[0], s);     /* { dg-bogus "\\\[-Wrestrict]" } */
     147    T (nma[i].ma.a2[1], s);
     148    T (nma[i].ma.a2[2], s);
     149  
     150    T (nma[i].ma.a2[0] + 1, s);
     151    T (nma[i].ma.a2[1] + 1, s);
     152    T (nma[i].ma.a2[2] + 1, s);
     153  
     154    T (nma[0].ma.a2[i], s);     /* { dg-bogus "\\\[-Wrestrict]" } */
     155    T (nma[1].ma.a2[i], s);
     156  
     157    T (nma[i].ma.a2[0] + j, s);
     158    T (nma[i].ma.a2[1] + j, s);
     159    T (nma[i].ma.a2[2] + j, s);
     160  
     161    T (nma[0].ma.a2[i] + 1, s);
     162    T (nma[1].ma.a2[i] + 1, s);
     163  
     164    T (nma[0].ma.a2[i] + j, s);
     165    T (nma[1].ma.a2[i] + j, s);
     166  }
     167  
     168  void test_ref_2_dim_const (struct MemArrays *p)
     169  {
     170    strcpy (p[0].a2[0], "1234567");
     171    const char *s = p[0].a2[0];
     172  
     173    T (p[0].a2[1], s);
     174    T (p[0].a2[2], s);
     175  
     176    T (p[1].a2[0], s);
     177    T (p[1].a2[1], s);
     178    T (p[1].a2[2], s);
     179  }
     180  
     181  void test_ref_2_dim_var (struct MemArrays *p, int i, int j)
     182  {
     183    strcpy (p[0].a2[0], "1234567");
     184    const char *s = p[0].a2[0];
     185  
     186    T (p[i].a2[0], s);          /* { dg-bogus "\\\[-Wrestrict]" } */
     187    T (p[i].a2[1], s);
     188    T (p[i].a2[2], s);
     189  
     190    T (p[0].a2[i], s);
     191    T (p[1].a2[i], s);
     192  
     193    T (p[i].a2[0] + j, s);
     194    T (p[i].a2[1] + j, s);
     195    T (p[i].a2[2] + j, s);
     196  
     197    T (p[0].a2[i] + j, s);
     198    T (p[1].a2[i] + j, s);
     199  }
     200  
     201  void test_obj_3_dim_var (int i, int j)
     202  {
     203    strcpy (a[0].a3[0][0], "1234567");
     204    const char *s = a[0].a3[0][0];
     205  
     206    T (a[0].a3[0][i], s);
     207    T (a[0].a3[1][i], s);
     208    T (a[0].a3[2][i], s);
     209  
     210    T (a[1].a3[0][i], s);
     211    T (a[1].a3[1][i], s);
     212    T (a[1].a3[2][i], s);
     213  
     214    T (a[0].a3[i][0], s);       /* { dg-bogus "\\\[-Wrestrict\]" } */
     215    T (a[0].a3[i][1], s);
     216    T (a[0].a3[i][2], s);
     217  
     218    T (a[1].a3[i][0], s);
     219    T (a[1].a3[i][1], s);
     220    T (a[1].a3[i][2], s);
     221  
     222    T (a[i].a3[0][0], s);       /* { dg-bogus "\\\[-Wrestrict\]" } */
     223    T (a[i].a3[0][1], s);
     224    T (a[i].a3[0][2], s);
     225  
     226    T (a[i].a3[1][0], s);
     227    T (a[i].a3[1][1], s);
     228    T (a[i].a3[1][2], s);
     229  
     230    T (a[i].a3[2][0], s);
     231    T (a[i].a3[2][1], s);
     232    T (a[i].a3[2][2], s);
     233  
     234  
     235    T (a[0].a3[0][i] + 1, s);
     236    T (a[0].a3[1][i] + 1, s);
     237    T (a[0].a3[2][i] + 1, s);
     238  
     239    T (a[1].a3[0][i] + 1, s);
     240    T (a[1].a3[1][i] + 1, s);
     241    T (a[1].a3[2][i] + 1, s);
     242  
     243  
     244    T (a[0].a3[0][i] + j, s);
     245    T (a[0].a3[1][i] + j, s);
     246    T (a[0].a3[2][i] + j, s);
     247  
     248    T (a[1].a3[0][i] + j, s);
     249    T (a[1].a3[1][i] + j, s);
     250    T (a[1].a3[2][i] + j, s);
     251  
     252    T (a[0].a3[i][0] + j, s);
     253    T (a[0].a3[i][1] + j, s);
     254    T (a[0].a3[i][2] + j, s);
     255  
     256    T (a[1].a3[i][0] + j, s);
     257    T (a[1].a3[i][1] + j, s);
     258    T (a[1].a3[i][2] + j, s);
     259  
     260    T (a[i].a3[0][0] + j, s);
     261    T (a[i].a3[0][1] + j, s);
     262    T (a[i].a3[0][2] + j, s);
     263  
     264    T (a[i].a3[1][0] + j, s);
     265    T (a[i].a3[1][1] + j, s);
     266    T (a[i].a3[1][2] + j, s);
     267  
     268    T (a[i].a3[2][0] + j, s);
     269    T (a[i].a3[2][1] + j, s);
     270    T (a[i].a3[2][2] + j, s);
     271  }
     272  
     273  void test_obj_3_dim_const (struct MemArrays *p)
     274  {
     275    strcpy (p[0].a3[0][0], "1234567");
     276    const char *s = p[0].a3[0][0];
     277  
     278    T (p[0].a3[0][1], s);
     279    T (p[0].a3[0][2], s);
     280    T (p[0].a3[0][3], s);
     281  
     282    T (p[0].a3[0][1] + 1, s);
     283    T (p[0].a3[0][2] + 1, s);
     284    T (p[0].a3[0][3] + 1, s);
     285  
     286    T (p[0].a3[1][0], s);
     287    T (p[0].a3[1][1], s);
     288    T (p[0].a3[1][2], s);
     289    T (p[0].a3[1][3], s);
     290  
     291    T (p[0].a3[1][0] + 1, s);
     292    T (p[0].a3[1][1] + 1, s);
     293    T (p[0].a3[1][2] + 1, s);
     294    T (p[0].a3[1][3] + 1, s);
     295  
     296    T (p[0].a3[2][0], s);
     297    T (p[0].a3[2][1], s);
     298    T (p[0].a3[2][2], s);
     299    T (p[0].a3[2][3], s);
     300  
     301    T (p[1].a3[0][0], s);
     302    T (p[1].a3[0][1], s);
     303    T (p[1].a3[0][2], s);
     304    T (p[1].a3[0][3], s);
     305  
     306    T (p[1].a3[1][0], s);
     307    T (p[1].a3[1][1], s);
     308    T (p[1].a3[1][2], s);
     309    T (p[1].a3[1][3], s);
     310  
     311    T (p[1].a3[2][0], s);
     312    T (p[1].a3[2][1], s);
     313    T (p[1].a3[2][2], s);
     314    T (p[1].a3[2][3], s);
     315  }