(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
strlenopt-62.c
       1  /* PR tree-optimization/90662 - strlen of a string in a vla plus offset
       2     not folded
       3     { dg-do compile }
       4     { dg-require-effective-target alloca }
       5     { dg-options "-O2 -Wall -fdump-tree-gimple -fdump-tree-optimized" } */
       6  
       7  #include "strlenopt.h"
       8  
       9  typedef __INT16_TYPE__   int16_t;
      10  typedef __INT32_TYPE__   int32_t;
      11  
      12  #define CONCAT(x, y) x ## y
      13  #define CAT(x, y) CONCAT (x, y)
      14  #define FAILNAME(name, counter) \
      15    CAT (CAT (CAT (call_ ## name ##_on_line_, __LINE__), _), counter)
      16  
      17  #define FAIL(name, counter) do {			\
      18      extern void FAILNAME (name, counter) (void);	\
      19      FAILNAME (name, counter)();				\
      20    } while (0)
      21  
      22  /* Macro to emit a call to funcation named
      23       call_in_true_branch_not_eliminated_on_line_NNN()
      24     for each call that's expected to be eliminated.  The dg-final
      25     scan-tree-dump-time directive at the bottom of the test verifies
      26     that no such call appears in output.  */
      27  #define ELIM(expr) \
      28    if (!(expr)) FAIL (in_true_branch_not_eliminated, __COUNTER__); else (void)0
      29  
      30  #define ARGS(...) __VA_ARGS__
      31  
      32  void sink (void*, ...);
      33  
      34  
      35  #define T(Type, expect, init, p)			\
      36    do {							\
      37      Type vla[n];					\
      38      char *ptr = strcpy ((char*)vla, init);		\
      39      ELIM (expect == strlen (p));			\
      40      sink (ptr);						\
      41    } while (0)
      42  
      43  void test_char_vla_local (int n)
      44  {
      45    T (char, 0, "", vla);
      46    T (char, 0, "\0", vla);
      47    T (char, 1, "1", vla);
      48    T (char, 2, "12", vla);
      49    T (char, 3, "123", vla);
      50  
      51    T (char, 2, "123", vla + 1);
      52    T (char, 1, "123", &vla[2]);
      53    T (char, 0, "123", &vla[1] + 2);
      54  
      55    T (char, 2, "123", &vla[2] - 1);
      56    T (char, 3, "123", &vla[1] - 1);
      57  
      58    T (char, 0, "", ptr);
      59    T (char, 0, "\0", ptr);
      60    T (char, 1, "1", ptr);
      61    T (char, 2, "12", ptr);
      62    T (char, 3, "123", ptr);
      63  
      64    T (char, 2, "123", ptr + 1);
      65    T (char, 1, "123", &ptr[2]);
      66    T (char, 0, "123", &ptr[1] + 2);
      67  }
      68  
      69  void test_int16_vla_local (int n)
      70  {
      71    T (int16_t, 0, "", (char*)vla);
      72    T (int16_t, 0, "\0", (char*)vla);
      73    T (int16_t, 1, "1", (char*)vla);
      74    T (int16_t, 2, "12", (char*)vla);
      75    T (int16_t, 3, "123", (char*)vla);
      76  
      77    T (int16_t, 2, "1234", (char*)(vla + 1));
      78    T (int16_t, 2, "123456", (char*)&vla[2]);
      79    T (int16_t, 1, "123456", (char*)&vla[2] + 1);
      80    T (int16_t, 0, "123456", (char*)&vla[2] + 2);
      81    T (int16_t, 0, "123456", (char*)(&vla[1] + 2));
      82  
      83    T (int16_t, 3, "123456", (char*)&vla[2] - 1);
      84    T (int16_t, 4, "123456", (char*)&vla[2] - 2);
      85  
      86    T (int16_t, 0, "", ptr);
      87    T (int16_t, 0, "\0", ptr);
      88    T (int16_t, 1, "1", ptr);
      89    T (int16_t, 2, "12", ptr);
      90    T (int16_t, 3, "123", ptr);
      91  
      92    T (int16_t, 2, "123", ptr + 1);
      93    T (int16_t, 1, "123", &ptr[2]);
      94    T (int16_t, 0, "123", &ptr[1] + 2);
      95  }
      96  
      97  void test_int_vla_local (int n)
      98  {
      99    T (int16_t, 0, "", (char*)vla);
     100    T (int16_t, 0, "\0", (char*)vla);
     101    T (int16_t, 1, "1", (char*)vla);
     102    T (int16_t, 2, "12", (char*)vla);
     103    T (int16_t, 3, "123", (char*)vla);
     104  
     105    T (int16_t, 2, "1234", (char*)(vla + 1));
     106    T (int16_t, 2, "123456", (char*)&vla[2]);
     107    T (int16_t, 1, "123456", (char*)&vla[2] + 1);
     108    T (int16_t, 0, "123456", (char*)&vla[2] + 2);
     109    T (int16_t, 0, "123456", (char*)(&vla[1] + 2));
     110  
     111    T (int, 0, "", ptr);
     112    T (int, 0, "\0", ptr);
     113    T (int, 1, "1", ptr);
     114    T (int, 2, "12", ptr);
     115    T (int, 3, "123", ptr);
     116  
     117    T (int, 2, "123", ptr + 1);
     118    T (int, 1, "123", &ptr[2]);
     119    T (int, 0, "123", &ptr[1] + 2);
     120  }
     121  
     122  
     123  #undef T
     124  #define T(Type, expect, parr, init, p)			\
     125    do {							\
     126      Type (*parray)[] = *ppa++;				\
     127      char *ptr = strcpy ((char*)parr, init);		\
     128      (void)&ptr;						\
     129      ELIM (expect == strlen (p));			\
     130    } while (0)
     131  
     132  /* Have the function take a pointer to pointers to arrays so that each
     133     test case can use its own pointer to avoid interference between.  */
     134  
     135  void test_char_array_ptr (char (**ppa)[])
     136  {
     137    T (char, 0, *parray, "", *parray);
     138    T (char, 0, *parray, "", &(*parray)[0]);
     139  
     140    T (char, 1, *parray, "1", &(*parray)[0]);
     141    T (char, 0, *parray, "1", &(*parray)[1]);
     142  
     143    T (char, 2, *parray, "12", &(*parray)[0]);
     144    T (char, 1, *parray, "12", &(*parray)[1]);
     145    T (char, 0, *parray, "12", &(*parray)[2]);
     146  
     147    T (char, 3, *parray, "123", &(*parray)[0]);
     148    T (char, 2, *parray, "123", &(*parray)[1]);
     149    T (char, 1, *parray, "123", &(*parray)[2]);
     150    T (char, 0, *parray, "123", &(*parray)[3]);
     151  
     152    T (char, 3, *parray, "123", ptr);
     153    T (char, 2, *parray, "123", &ptr[1]);
     154    T (char, 1, *parray, "123", &ptr[2]);
     155    T (char, 0, *parray, "123", &ptr[3]);
     156  }
     157  
     158  void test_int16_array_ptr (int16_t (**ppa)[])
     159  {
     160    T (int16_t, 0, *parray, "", (char*)*parray);
     161    T (int16_t, 0, *parray, "", (char*)&(*parray)[0]);
     162  
     163    T (int16_t, 1, *parray, "1", (char*)&(*parray)[0]);
     164    T (int16_t, 0, *parray, "12", (char*)&(*parray)[1]);
     165  
     166    T (int16_t, 2, *parray, "12", (char*)&(*parray)[0]);
     167    T (int16_t, 1, *parray, "12", (char*)&(*parray)[0] + 1);
     168    T (int16_t, 2, *parray, "1234", (char*)&(*parray)[1]);
     169    T (int16_t, 1, *parray, "1234", (char*)&(*parray)[1] + 1);
     170    T (int16_t, 0, *parray, "1234", (char*)&(*parray)[2]);
     171  
     172    T (int16_t, 6, *parray, "123456", (char*)&(*parray)[0]);
     173    T (int16_t, 5, *parray, "123456", (char*)&(*parray)[0] + 1);
     174    T (int16_t, 0, *parray, "123456", (char*)&(*parray)[0] + 6);
     175    T (int16_t, 4, *parray, "123456", (char*)&(*parray)[1]);
     176    T (int16_t, 3, *parray, "123456", (char*)&(*parray)[1] + 1);
     177    T (int16_t, 0, *parray, "123456", (char*)&(*parray)[1] + 4);
     178    T (int16_t, 2, *parray, "123456", (char*)&(*parray)[2]);
     179    T (int16_t, 1, *parray, "123456", (char*)&(*parray)[2] + 1);
     180    T (int16_t, 0, *parray, "123456", (char*)&(*parray)[2] + 2);
     181    T (int16_t, 0, *parray, "123456", (char*)&(*parray)[3]);
     182  
     183    T (int16_t, 3, *parray, "123", (char*)ptr);
     184    T (int16_t, 2, *parray, "123", (char*)&ptr[1]);
     185    T (int16_t, 1, *parray, "123", (char*)&ptr[2]);
     186    T (int16_t, 0, *parray, "123", (char*)&ptr[3]);
     187  }
     188  
     189  /* { dg-final { scan-tree-dump-times "strlen" 0 "optimized" } }
     190     { dg-final { scan-tree-dump-times "not_eliminated" 0 "optimized" } } */