1  /* PR tree-optimization/91294 - strlen result of a conditional with
       2     an offset
       3     { dg-do run }
       4     { dg-options "-O2 -Wall" } */
       5  
       6  #include "strlenopt.h"
       7  
       8  #define NOIPA __attribute__ ((noclone, noinline, noipa))
       9  
      10  int i = 0;
      11  
      12  const char s[] = "1234567";
      13  
      14  char a[32];
      15  
      16  /* Exercise a memcpy overwriting a destination string of known length
      17     with a source argument involving a conditional expression with strings
      18     of unqual lengths, with the selected one being the longer of the two
      19     and resulting in no change to the length of the overwritten destination
      20     string.  */
      21  NOIPA void test_memcpy_same_length ()
      22  {
      23    memcpy (a, "123456789a", 11);
      24    memcpy (a + 6, i ? "78\0" : "789\0", 4);
      25    if (strlen (a) != 9)
      26      abort ();
      27  }
      28  
      29  /* Same as above but with strcpy/strcat.  */
      30  
      31  NOIPA void test_strcpy_strcat_same_length ()
      32  {
      33    strcpy (a, "12345678");
      34    strcat (a, "9a");
      35    memcpy (a + 6, i ? "78\0" : "789\0", 4);
      36    if (strlen (a) != 9)
      37      abort ();
      38  }
      39  
      40  /* Same as above but using a memcpy of a power-of-two size that gets
      41     (on some targets) transformed into a single MEM_REF assignment.  */
      42  
      43  NOIPA void test_assign_same_length ()
      44  {
      45    memcpy (a, s, 8);
      46    memcpy (a + 5, i ? "67\0" : "678\0", 4);
      47    if (strlen (a) != 8)
      48      abort ();
      49  }
      50  
      51  /* Same as above but resulting in increasing the length of the destination
      52     string.  */
      53  
      54  NOIPA void test_memcpy_lengthen ()
      55  {
      56    memcpy (a, "123456789a", 11);
      57    memcpy (a + 8, i ? "9a\0" : "9ab\0", 4);
      58    if (strlen (a) != 11)
      59      abort ();
      60  }
      61  
      62  NOIPA void test_strcpy_strcat_lengthen ()
      63  {
      64    strcpy (a, "12345678");
      65    strcat (a, "9a");
      66    memcpy (a + 8, i ? "9a\0" : "9ab\0", 4);
      67    if (strlen (a) != 11)
      68      abort ();
      69  }
      70  
      71  NOIPA void test_assign_lengthen ()
      72  {
      73    memcpy (a, s, 8);
      74    memcpy (a + 6, i ? "78\0" : "789\0", 4);
      75    if (strlen (a) != 9)
      76      abort ();
      77  }
      78  
      79  NOIPA void test_memcpy_shorten ()
      80  {
      81    memcpy (a, "123456789a", 11);
      82    memcpy (a + 6, i ? "789\0" : "78\0", 4);
      83    if (strlen (a) != 8)
      84      abort ();
      85  }
      86  
      87  NOIPA void test_strcpy_strcat_shorten ()
      88  {
      89    strcpy (a, "12345678");
      90    strcat (a, "9a");
      91    memcpy (a + 6, i ? "789\0" : "78\0", 4);
      92    if (strlen (a) != 8)
      93      abort ();
      94  }
      95  
      96  NOIPA void test_assign_shorten ()
      97  {
      98    memcpy (a, s, 8);
      99    memcpy (a + 6, i ? "789\0" : "78\0", 4);
     100    if (strlen (a) != 8)
     101      abort ();
     102  }
     103  
     104  
     105  int main (void)
     106  {
     107    test_memcpy_same_length ();
     108    test_strcpy_strcat_same_length ();
     109    test_assign_same_length ();
     110  
     111    test_memcpy_lengthen ();
     112    test_strcpy_strcat_lengthen ();
     113    test_assign_lengthen ();
     114  
     115    test_memcpy_shorten ();
     116    test_strcpy_strcat_shorten ();
     117    test_assign_shorten ();
     118  }