(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
strlenopt-6.c
       1  /* { dg-do run } */
       2  /* { dg-options "-O2 -fdump-tree-strlen" } */
       3  
       4  #include "strlenopt.h"
       5  
       6  __attribute__((noinline, noclone)) char *
       7  foo (char *x)
       8  {
       9  #ifdef PR50262_FIXED
      10    /* Once PTA is fixed, we'll need just one strlen here,
      11       without the memcpy.  */
      12    char *p = x;
      13    char *q = malloc (strlen (p) + 64);
      14  #else
      15    /* This is here just because PTA can't figure that
      16       *q = '\0' store below can't change p's length.
      17       In this case we have one strlen and one memcpy here.  */
      18    char b[64];
      19    char *q = malloc (strlen (x) + 64);
      20    char *p = strcpy (b, x);
      21  #endif
      22    char *r;
      23    if (q == NULL) return NULL;
      24    /* This store can be optimized away once strcat is
      25       replaced with memcpy.  */
      26    *q = '\0';
      27    /* These two strcat calls can be optimized into memcpy calls.  */
      28    strcat (q, p);
      29    strcat (q, "/");
      30    /* The strchr can be optimized away, as we know the current
      31       string length as well as end pointer.  */
      32    r = strchr (q, '\0');
      33    /* This store can go, as it is overwriting '\0' with the same
      34       character.  */
      35    *r = '\0';
      36    /* And this strcat can be again optimized into memcpy call.  */
      37    strcat (q, "abcde");
      38    return q;
      39  }
      40  
      41  __attribute__((noinline, noclone)) char *
      42  bar (char *p)
      43  {
      44    char buf[26];
      45    char *r;
      46    if (strlen (p) + 9 > 26)
      47      return NULL;
      48    *buf = '\0';
      49    strcat (buf, p);
      50    strcat (buf, "/");
      51    r = strchr (buf, '\0');
      52    *r = '\0';
      53    strcat (buf, "abcde");
      54    return strdup (buf);
      55  }
      56  
      57  int
      58  main ()
      59  {
      60    char *volatile p = "string1";
      61    char *volatile r = "string2";
      62    char *q = foo (p);
      63    if (q != NULL)
      64      {
      65        if (strcmp (q, "string1/abcde"))
      66  	abort ();
      67        memset (q, '\0', 14);
      68        free (q);
      69      }
      70    q = bar (p);
      71    if (q != NULL)
      72      {
      73        if (strcmp (q, "string1/abcde"))
      74  	abort ();
      75        free (q);
      76      }
      77    return 0;
      78  }
      79  
      80  /* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
      81  /* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen1" } } */
      82  /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
      83  /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
      84  /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
      85  /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */