(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
strlenopt-46.c
       1  /* PR tree-optimization/86204 - wrong strlen result after prior strnlen
       2     { dg-do run }
       3     { dg-options "-O2 -Wall -fdump-tree-optimized" } */
       4  
       5  #include "strlenopt.h"
       6  
       7  #define NOIPA   __attribute__ ((noipa))
       8  
       9  char a[] = "12345";
      10  
      11  NOIPA void f0 (void)
      12  {
      13    unsigned n0 = strnlen (a, 0);
      14    unsigned n1 = strlen (a);
      15  
      16    if (n0 != 0 || n1 != 5)
      17      abort ();
      18  }
      19  
      20  NOIPA void f1 (void)
      21  {
      22    unsigned n0 = strnlen (a, 1);
      23    unsigned n1 = strlen (a);
      24  
      25    if (n0 != 1 || n1 != 5)
      26      abort ();
      27  }
      28  
      29  NOIPA void f2 (void)
      30  {
      31    unsigned n0 = strnlen (a, 2);
      32    unsigned n1 = strlen (a);
      33  
      34    if (n0 != 2 || n1 != 5)
      35      abort ();
      36  }
      37  
      38  NOIPA void f3 (void)
      39  {
      40    unsigned n0 = strnlen (a, 3);
      41    unsigned n1 = strlen (a);
      42  
      43    if (n0 != 3 || n1 != 5)
      44      abort ();
      45  }
      46  
      47  NOIPA void f4 (void)
      48  {
      49    unsigned n0 = strnlen (a, 4);
      50    unsigned n1 = strlen (a);
      51  
      52    if (n0 != 4 || n1 != 5)
      53      abort ();
      54  }
      55  
      56  NOIPA void f5 (void)
      57  {
      58    unsigned n0 = strnlen (a, 5);
      59    unsigned n1 = strlen (a);
      60  
      61    if (n0 != 5 || n1 != 5)
      62      abort ();
      63  }
      64  
      65  NOIPA void f6 (void)
      66  {
      67    unsigned n0 = strnlen (a, 6);
      68    unsigned n1 = strlen (a);
      69  
      70    if (n0 != 5 || n1 != 5)
      71      abort ();
      72  }
      73  
      74  NOIPA void fx (unsigned n)
      75  {
      76    unsigned n0 = strnlen (a, n);
      77    unsigned n1 = strlen (a);
      78  
      79    unsigned min = n < 5 ? n : 5;
      80    if (n0 != min || n1 != 5)
      81      abort ();
      82  }
      83  
      84  NOIPA void g2 (void)
      85  {
      86    strcpy (a, "123");
      87    unsigned n0 = strnlen (a, 2);
      88    unsigned n1 = strlen (a);
      89  
      90    if (n0 != 2 || n1 != 3)
      91      abort ();
      92  }
      93  
      94  NOIPA void g7 (void)
      95  {
      96    strcpy (a, "123");
      97    unsigned n0 = strnlen (a, 7);
      98    unsigned n1 = strlen (a);
      99  
     100    if (n0 != 3 || n1 != 3)
     101      abort ();
     102  }
     103  
     104  NOIPA void gx (unsigned n)
     105  {
     106    strcpy (a, "123");
     107    unsigned n0 = strnlen (a, n);
     108    unsigned n1 = strlen (a);
     109  
     110    unsigned min = n < 3 ? n : 3;
     111    if (n0 != min || n1 != 3)
     112      abort ();
     113  }
     114  
     115  int main (void)
     116  {
     117    f0 ();
     118    f1 ();
     119    f2 ();
     120    f3 ();
     121    f4 ();
     122    f5 ();
     123    f6 ();
     124    fx (2);
     125    fx (7);
     126  
     127    g2 ();
     128    g7 ();
     129    gx (2);
     130    gx (7);
     131  }
     132  
     133  
     134  /* For targets like Solaris 10 that don't define strnlen().  */
     135  
     136  NOIPA size_t
     137  strnlen (const char *s, size_t n)
     138  {
     139    size_t len = 0;
     140    while (*s++ && n--)
     141      ++len;
     142    return len;
     143  }
     144  
     145  /* Verify that at least some of the 11 calls to strnlen have been
     146     folded (this number of folded calls may need to be adjusted up
     147     if the strnlen optimization improves, but it should not go down.
     148    { dg-final { scan-tree-dump-times "= strnlen" 7 "optimized" } } */