(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
strlenopt-81.c
       1  /* PR tree-optimization/91996 - fold non-constant strlen relational expressions
       2     { dg-do run }
       3     { dg-options "-O2 -Wall -Wno-unused-local-typedefs" } */
       4  
       5  typedef __SIZE_TYPE__ size_t;
       6  
       7  #define NOIPA   __attribute__ ((noipa))
       8  
       9  #define CONCAT(a, b) a ## b
      10  #define CAT(a, b)    CONCAT (a, b)
      11  
      12  /* Used in tests where EXPR is expected to be folded to false.  */
      13  #define ELIM(expr)							\
      14    if (expr) {								\
      15      extern void								\
      16        CAT (CAT (test_on_line_, __LINE__), _not_eliminated)(void);	\
      17      CAT (CAT (test_on_line_, __LINE__), _not_eliminated)();		\
      18    } typedef void dummy_type
      19  
      20  
      21  /* Set the alignment for targets that depend on it in order to
      22     optimize away the ELIM calls.  See pr92128.  */
      23  __attribute__ ((aligned(4))) char a[32], b[32];
      24  
      25  void init (void)
      26  {
      27    __builtin_strncpy (a, "abcdefgh", sizeof a);
      28    __builtin_strncpy (b, "0123456789", sizeof b);
      29  }
      30  
      31  NOIPA void fail (const char *func)
      32  {
      33    __builtin_printf ("failure in %s\n", func);
      34    __builtin_abort ();
      35  }
      36  
      37  NOIPA void test_global_cpy_4 (void)
      38  {
      39    size_t blen = __builtin_strlen (b);
      40    if (blen < 9) return;
      41  
      42    char *d = a;
      43    __builtin_memcpy (d, b, 4);
      44  
      45    size_t dlen = __builtin_strlen (d);
      46    if (dlen != 8)   // cannot be eliminated
      47      fail ("test_global");
      48  }
      49  
      50  
      51  NOIPA void test_global_cpy_10 (void)
      52  {
      53    size_t blen = __builtin_strlen (b);
      54    if (blen < 9) return;
      55  
      56    char *d = a;
      57    __builtin_memcpy (d, b, 10);
      58  
      59    size_t dlen = __builtin_strlen (d);
      60    if (dlen != 10)   // cannot be eliminated
      61      fail ("test_global_cpy_10");
      62  }
      63  
      64  NOIPA void test_global_cpy_11 (void)
      65  {
      66    size_t blen = __builtin_strlen (b);
      67    if (blen < 9) return;
      68  
      69    char *d = a;
      70    __builtin_memcpy (d, b, 11);
      71  
      72    size_t dlen = __builtin_strlen (d);
      73    if (dlen != 10)   // cannot be eliminated
      74      fail ("test_global_cpy_11");
      75  }
      76  
      77  NOIPA void test_global_cpy_20 (void)
      78  {
      79    size_t blen = __builtin_strlen (b);
      80    if (blen < 9) return;
      81  
      82    char *d = a;
      83    __builtin_memcpy (d, b, 20);
      84  
      85    size_t dlen = __builtin_strlen (d);
      86    if (dlen != 10)   // cannot be eliminated
      87      fail ("test_global_cpy_20");
      88  }
      89  
      90  NOIPA void test_local_cpy_4 (void)
      91  {
      92    size_t blen = __builtin_strlen (b);
      93    if (blen < 9) return;
      94  
      95  /* Set the alignment for targets that depend on it in order to
      96     optimize away the ELIM calls.  See pr92128.  */
      97    __attribute__ ((aligned(4))) char a[10] = "abcdefgh";
      98    char *d = a;
      99    __builtin_memcpy (d, b, 4);
     100  
     101    size_t dlen = __builtin_strlen (d);
     102    ELIM (dlen != 8);
     103  }
     104  
     105  NOIPA void test_local_cpy_10 (void)
     106  {
     107    size_t blen = __builtin_strlen (b);
     108    if (blen < 9) return;
     109  
     110    char a[32] = "abcdefgh";
     111    char *d = a;
     112    __builtin_memcpy (d, b, 10);
     113  
     114    /* B can be longer than 9 and A can initially be longer than 10
     115       so the test below cannot be eliminated.  */
     116    size_t dlen = __builtin_strlen (d);
     117    if (dlen != 10)
     118      fail ("test_local_cpy_10");
     119  }
     120  
     121  NOIPA void test_local_cpy_11 (void)
     122  {
     123    size_t blen = __builtin_strlen (b);
     124    if (blen < 9) return;
     125  
     126    char a[32] = "abcdefgh";
     127    char *d = a;
     128    __builtin_memcpy (d, b, 11);
     129  
     130    size_t dlen = __builtin_strlen (d);
     131    if (dlen != 10)
     132      fail ("test_global_cpy_20");
     133  }
     134  
     135  NOIPA void test_local_cpy_20 (void)
     136  {
     137    size_t blen = __builtin_strlen (b);
     138    if (blen < 9) return;
     139  
     140    char a[32] = "abcdefgh";
     141    char *d = a;
     142    __builtin_memcpy (d, b, 20);
     143  
     144    size_t dlen = __builtin_strlen (d);
     145    if (dlen != 10)
     146      fail ("test_global_cpy_20");
     147  }
     148  
     149  NOIPA void test_global_length_eq (void)
     150  {
     151    size_t blen = __builtin_strlen (b);
     152    if (blen != 10) return;
     153  
     154    size_t alen = __builtin_strlen (a);
     155    if (alen != 8) return;
     156  
     157    char *d = a;
     158    __builtin_memcpy (d, b, 4);
     159  
     160    size_t dlen = __builtin_strlen (d);
     161    ELIM (dlen != 8);
     162  }
     163  
     164  
     165  NOIPA void test_global_length_gt (void)
     166  {
     167    size_t blen = __builtin_strlen (b);
     168    if (blen < 9) return;
     169  
     170    size_t alen = __builtin_strlen (a);
     171    if (alen < 8) return;
     172  
     173    char *d = a;
     174    __builtin_memcpy (d, b, 4);
     175  
     176    size_t dlen = __builtin_strlen (d);
     177    ELIM (dlen < 8);
     178  }
     179  
     180  #define TEST(name) do { init (); test_ ## name (); } while (0)
     181  
     182  int main (void)
     183  {
     184    TEST (local_cpy_4);
     185    TEST (local_cpy_10);
     186    TEST (local_cpy_11);
     187    TEST (local_cpy_20);
     188  
     189    TEST (global_cpy_4);
     190    TEST (global_cpy_10);
     191    TEST (global_cpy_11);
     192    TEST (global_cpy_20);
     193    TEST (global_length_eq);
     194    TEST (global_length_gt);
     195  }