(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
strlenopt-64.c
       1  /* PR tree-optimization/90662 - strlen of a string in a vla plus offset
       2     not folded
       3     Verify that strlen of pointers to wide character arrays (emulated
       4     by int16_t) are computed correctly (whether folded or not).
       5     { dg-do run }
       6     { dg-options "-O2 -Wall -Wno-incompatible-pointer-types" } */
       7  
       8  #include "strlenopt.h"
       9  
      10  typedef __INT16_TYPE__ int16_t;
      11  
      12  #define A(expr)                                                 \
      13    ((expr)                                                       \
      14     ? (void)0                                                    \
      15     : (__builtin_printf ("assertion failed on line %i: %s\n",    \
      16                          __LINE__, #expr),                       \
      17        __builtin_abort ()))
      18  
      19  typedef int16_t A5[5];
      20  
      21  A5 a5[5];
      22  A5* p[5] = { &a5[4], &a5[3], &a5[2], &a5[1], &a5[0] };
      23  
      24  __attribute__ ((noclone, noinline, noipa))
      25  void deref_deref (void)
      26  {
      27    strcpy (**p, "12345");
      28    A (strlen (**p) == 5);
      29  }
      30  
      31  __attribute__ ((noclone, noinline, noipa))
      32  void deref_idx_0 (void)
      33  {
      34    strcpy (*p[0], "");
      35    A (strlen (*p[0]) == 0);
      36  }
      37  
      38  __attribute__ ((noclone, noinline, noipa))
      39  void deref_idx_1 (void)
      40  {
      41    strcpy (*p[1], "12");
      42    A (strlen (*p[1]) == 2);
      43    A (strlen (&(*p[1])[1]) == 0);
      44  
      45    A (strlen ((char*)*p[1] + 1) == 1);
      46    A (strlen ((char*)*p[1] + 2) == 0);
      47    A (strlen ((char*)*p[1] + 3) == 0);
      48  
      49    A (strlen ((char*)&(*p[1])[1] + 1) == 0);
      50  
      51    A (strlen (*p[0]) == 0);
      52  }
      53  
      54  __attribute__ ((noclone, noinline, noipa))
      55  void deref_idx_2 (void)
      56  {
      57    strcpy (*p[2], "1234");
      58    A (strlen (*p[2]) == 4);
      59    A (strlen (&(*p[2])[1]) == 2);
      60    A (strlen (&(*p[2])[2]) == 0);
      61  
      62    A (strlen ((char*)*p[2] + 1) == 3);
      63    A (strlen ((char*)*p[2] + 2) == 2);
      64    A (strlen ((char*)*p[2] + 3) == 1);
      65    A (strlen ((char*)*p[2] + 4) == 0);
      66    A (strlen ((char*)*p[2] + 5) == 0);
      67  
      68    A (strlen ((char*)&(*p[2])[1] + 1) == 1);
      69    A (strlen ((char*)&(*p[2])[1] + 2) == 0);
      70  
      71    A (strlen (*p[1]) == 2);
      72    A (strlen (*p[0]) == 0);
      73  }
      74  
      75  __attribute__ ((noclone, noinline, noipa))
      76  void deref_idx_3 (void)
      77  {
      78    strcpy (*p[3], "123456");
      79    A (strlen (*p[3]) == 6);
      80    A (strlen (&(*p[3])[1]) == 4);
      81    A (strlen (&(*p[3])[2]) == 2);
      82    A (strlen (&(*p[3])[3]) == 0);
      83  
      84    A (strlen ((char*)*p[3] + 1) == 5);
      85    A (strlen ((char*)*p[3] + 2) == 4);
      86    A (strlen ((char*)*p[3] + 3) == 3);
      87    A (strlen ((char*)*p[3] + 4) == 2);
      88    A (strlen ((char*)*p[3] + 5) == 1);
      89    A (strlen ((char*)*p[3] + 6) == 0);
      90  
      91    A (strlen (*p[2]) == 4);
      92    A (strlen (*p[1]) == 2);
      93    A (strlen (*p[0]) == 0);
      94  }
      95  
      96  __attribute__ ((noclone, noinline, noipa))
      97  void deref_idx_4 (void)
      98  {
      99    strcpy (*p[4], "12345678");
     100    A (strlen (*p[4]) == 8);
     101    A (strlen (&(*p[4])[1]) == 6);
     102    A (strlen (&(*p[4])[2]) == 4);
     103    A (strlen (&(*p[4])[3]) == 2);
     104    A (strlen (&(*p[4])[4]) == 0);
     105  
     106    A (strlen (*p[3]) == 6);
     107    A (strlen (*p[2]) == 4);
     108    A (strlen (*p[1]) == 2);
     109    A (strlen (*p[0]) == 0);
     110  }
     111  
     112  __attribute__ ((noclone, noinline, noipa))
     113  void deref_idx_4_x (void)
     114  {
     115    strcpy (*p[4], "");
     116    A (strlen (*p[4]) == 0);
     117    A (strlen (*p[3]) == 6);
     118    A (strlen (*p[2]) == 4);
     119    A (strlen (*p[1]) == 2);
     120    A (strlen (*p[0]) == 0);
     121  }
     122  
     123  __attribute__ ((noclone, noinline, noipa))
     124  void deref_idx_3_x (void)
     125  {
     126    strcpy (&(*p[3])[0], "1");
     127    A (strlen (*p[4]) == 0);
     128    A (strlen (*p[3]) == 1);
     129    A (strlen (*p[2]) == 4);
     130    A (strlen (*p[1]) == 2);
     131    A (strlen (*p[0]) == 0);
     132  }
     133  
     134  __attribute__ ((noclone, noinline, noipa))
     135  void deref_idx_2_x (void)
     136  {
     137    strcpy (*p[2], "12");
     138    A (strlen (*p[4]) == 0);
     139    A (strlen (*p[3]) == 1);
     140    A (strlen (*p[2]) == 2);
     141    A (strlen (*p[1]) == 2);
     142    A (strlen (*p[0]) == 0);
     143  }
     144  
     145  __attribute__ ((noclone, noinline, noipa))
     146  void deref_idx_1_x (void)
     147  {
     148    strcpy (*p[1], "123");
     149    A (strlen (*p[4]) == 0);
     150    A (strlen (*p[3]) == 1);
     151    A (strlen (*p[2]) == 2);
     152    A (strlen (*p[1]) == 3);
     153    A (strlen (*p[0]) == 0);
     154  }
     155  
     156  __attribute__ ((noclone, noinline, noipa))
     157  void deref_idx_0_x (void)
     158  {
     159    strcpy (*p[0], "1234");
     160    A (strlen (*p[4]) == 0);
     161    A (strlen (*p[3]) == 1);
     162    A (strlen (*p[2]) == 2);
     163    A (strlen (*p[1]) == 3);
     164    A (strlen (*p[0]) == 4);
     165  }
     166  
     167  int main (void)
     168  {
     169    deref_deref ();
     170  
     171    deref_idx_0 ();
     172    deref_idx_1 ();
     173    deref_idx_2 ();
     174    deref_idx_3 ();
     175    deref_idx_4 ();
     176  
     177    deref_idx_4_x ();
     178    deref_idx_3_x ();
     179    deref_idx_2_x ();
     180    deref_idx_1_x ();
     181    deref_idx_0_x ();
     182  }