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  #define assert(expr)						\
      11    ((expr)                                                       \
      12     ? (void)0                                                    \
      13     : (__builtin_printf ("line %i %s: assertion failed: %s\n",	\
      14                          __LINE__, __func__, #expr),		\
      15        __builtin_abort ()))
      16  
      17  int i = 0;
      18  
      19  const char s[] = "1234567";
      20  
      21  char a[32];
      22  
      23  NOIPA void lower_bound_assign_into_empty (void)
      24  {
      25    a[0] = '1';
      26    a[1] = '2';
      27    a[2] = '3';
      28    assert (strlen (a) == 3);
      29  }
      30  
      31  NOIPA void lower_bound_assign_into_longest (void)
      32  {
      33    a[0] = '1';
      34    a[1] = '2';
      35    a[2] = '3';
      36    assert (strlen (a) == 31);
      37  }
      38  
      39  
      40  NOIPA void lower_bound_assign_into_empty_idx_3 (int idx)
      41  {
      42    a[0] = '1';
      43    a[1] = '2';
      44    a[2] = '3';
      45    a[idx] = 'x';
      46    assert (strlen (a) == 4);
      47  }
      48  
      49  NOIPA void lower_bound_assign_into_longest_idx_2 (int idx)
      50  {
      51    a[0] = '1';
      52    a[1] = '2';
      53    a[2] = '3';
      54    a[idx] = '\0';
      55    assert (strlen (a) == 2);
      56  }
      57  
      58  
      59  NOIPA void lower_bound_memcpy_into_empty (void)
      60  {
      61    memcpy (a, "123", 3);
      62    assert (strlen (a) == 3);
      63  }
      64  
      65  NOIPA void lower_bound_memcpy_into_longest (void)
      66  {
      67    memcpy (a, "123", 3);
      68    assert (strlen (a) == 31);
      69  }
      70  
      71  
      72  NOIPA void lower_bound_memcpy_memcpy_into_empty (void)
      73  {
      74    memcpy (a, "123", 3);
      75    memcpy (a + 2, "345", 3);
      76    assert (strlen (a) == 5);
      77  }
      78  
      79  NOIPA void lower_bound_memcpy_memcpy_into_longest (void)
      80  {
      81    memcpy (a, "123", 3);
      82    memcpy (a + 2, "345", 3);
      83    assert (strlen (a) == 31);
      84  }
      85  
      86  
      87  NOIPA void memove_forward_strlen (void)
      88  {
      89    char a[] = "123456";
      90  
      91    memmove (a, a + 1, sizeof a - 1);
      92  
      93    assert (strlen (a) == 5);
      94  }
      95  
      96  NOIPA void memove_backward_into_empty_strlen (void)
      97  {
      98    strcpy (a, "123456");
      99  
     100    memmove (a + 1, a, 6);
     101  
     102    assert (strlen (a) == 7);
     103  }
     104  
     105  NOIPA void memove_backward_into_longest_strlen (void)
     106  {
     107    memcpy (a, "123456", 6);
     108  
     109    memmove (a + 1, a, 6);
     110  
     111    assert (strlen (a) == 31);
     112  }
     113  
     114  NOIPA void memove_strcmp (void)
     115  {
     116    /* Test derived from libstdc++-v3's
     117       20_util/specialized_algorithms/memory_management_tools/1.cc  */
     118  
     119    char a[] = "123456";
     120    char b[] = "000000";
     121  
     122    memmove (b, a, sizeof a);
     123  
     124    assert (strlen (a) == 6);
     125    assert (strlen (b) == 6);
     126    assert (strcmp (a, b) == 0);
     127  }
     128  
     129  
     130  int main (void)
     131  {
     132    memset (a, '\0', sizeof a);
     133    lower_bound_assign_into_empty ();
     134  
     135    memset (a, 'x', sizeof a - 1);
     136    a[sizeof a - 1] = '\0';
     137    lower_bound_assign_into_longest ();
     138  
     139    memset (a, '\0', sizeof a);
     140    lower_bound_assign_into_empty_idx_3 (3);
     141  
     142    memset (a, 'x', sizeof a - 1);
     143    a[sizeof a - 1] = '\0';
     144    lower_bound_assign_into_longest_idx_2 (2);
     145  
     146    memset (a, '\0', sizeof a);
     147    lower_bound_memcpy_into_empty ();
     148  
     149    memset (a, 'x', sizeof a - 1);
     150    a[sizeof a - 1] = '\0';
     151    lower_bound_memcpy_into_longest ();
     152  
     153    memset (a, 'x', sizeof a - 1);
     154    a[sizeof a - 1] = '\0';
     155    lower_bound_memcpy_into_longest ();
     156  
     157    memset (a, '\0', sizeof a);
     158    lower_bound_memcpy_memcpy_into_empty ();
     159  
     160    memset (a, 'x', sizeof a - 1);
     161    a[sizeof a - 1] = '\0';
     162    lower_bound_memcpy_memcpy_into_longest ();
     163  
     164    memove_forward_strlen ();
     165  
     166    memset (a, '\0', sizeof a);
     167    memove_backward_into_empty_strlen ();
     168  
     169    memset (a, 'x', sizeof a - 1);
     170    a[sizeof a - 1] = '\0';
     171    memove_backward_into_longest_strlen ();
     172  
     173    memove_strcmp ();
     174  }