(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
strlenopt-89.c
       1  /* PR tree-optimization/92226 - live nul char store to array eliminated
       2     { dg-do compile }
       3     { dg-options "-O2 -fdump-tree-strlen" } */
       4  
       5  #include "strlenopt.h"
       6  
       7  #define NOIPA __attribute__ ((noipa))
       8  
       9  /* Verify that the nul store  into the destination is only eliminated
      10     when overwrites the existing terminating nul added by the strcpy call.
      11     Also verify that the second strlen call is eliminated in all cases.  */
      12  #define T(SIZE, IDX)							\
      13    NOIPA void test_ ## SIZE ## _store_nul_ ## IDX (const char *s)	\
      14    {									\
      15      extern char a ## SIZE[SIZE];					\
      16      char *d = a ## SIZE;						\
      17      size_t len = SIZE - 1;						\
      18      size_t idx = IDX;							\
      19      if (strlen (s) == len)						\
      20        {									\
      21  	strcpy (d, s);							\
      22  	d[idx] = 0;							\
      23  	if (strlen (d) != idx)						\
      24  	  abort ();							\
      25        }									\
      26    } typedef void dummy_type
      27  
      28  
      29  T (1, 0);   // expect nul store to be eliminated
      30  
      31  T (2, 0);   // nul store must be retained
      32  T (2, 1);   // expect nul store to be eliminated
      33  
      34  // Same as above but for larger arrays.
      35  T (3, 0);
      36  T (3, 1);
      37  T (3, 2);
      38  
      39  T (4, 0);
      40  T (4, 1);
      41  T (4, 2);
      42  T (4, 3);
      43  
      44  T (5, 0);
      45  T (5, 1);
      46  T (5, 2);
      47  T (5, 3);
      48  T (5, 4);
      49  
      50  T (6, 0);
      51  T (6, 1);
      52  T (6, 2);
      53  T (6, 3);
      54  T (6, 4);
      55  T (6, 5);
      56  
      57  T (7, 0);
      58  T (7, 1);
      59  T (7, 2);
      60  T (7, 3);
      61  T (7, 4);
      62  T (7, 5);
      63  T (7, 6);
      64  
      65  T (8, 0);
      66  T (8, 1);
      67  T (8, 2);
      68  T (8, 3);
      69  T (8, 4);
      70  T (8, 5);
      71  T (8, 6);
      72  T (8, 7);
      73  
      74  /* Verify that each function makes just one call to strlen to compute
      75     the length of its argument (and not also to compute the length of
      76     the copy):
      77    { dg-final { scan-tree-dump-times "strlen \\(s_" 36 "strlen1" } }
      78    { dg-final { scan-tree-dump-not "strlen \\(\\&a" "strlen1" } }
      79  
      80    Verify that nul stores into the last array element have been eliminated
      81    (they are preceded by a strcpy storing into all the elements of the array:
      82    { dg-final { scan-tree-dump-not "a1\\\] = 0;" "strlen1" } }
      83    { dg-final { scan-tree-dump-not "a2 \\\+ 1B\\\] = 0;" "strlen1" } }
      84    { dg-final { scan-tree-dump-not "a3 \\\+ 2B\\\] = 0;" "strlen1" } }
      85    { dg-final { scan-tree-dump-not "a4 \\\+ 3B\\\] = 0;" "strlen1" } }
      86    { dg-final { scan-tree-dump-not "a5 \\\+ 4B\\\] = 0;" "strlen1" } }
      87    { dg-final { scan-tree-dump-not "a6 \\\+ 5B\\\] = 0;" "strlen1" } }
      88    { dg-final { scan-tree-dump-not "a7 \\\+ 6B\\\] = 0;" "strlen1" } }
      89    { dg-final { scan-tree-dump-not "a8 \\\+ 7B\\\] = 0;" "strlen1" } } */