(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
torture/
pr61346.c
       1  /* { dg-do run } */
       2  
       3  extern void abort (void);
       4  
       5  typedef int int32_t __attribute__ ((mode (SI)));
       6  typedef int int64_t __attribute__ ((mode (DI)));
       7  typedef __SIZE_TYPE__ size_t;
       8  
       9  struct slice
      10  {
      11    unsigned char *data;
      12    int64_t len;
      13    int64_t cap;
      14  };
      15  
      16  void fail (int32_t) __attribute__ ((noinline));
      17  void
      18  fail (int32_t c)
      19  {
      20    if (c != 0)
      21      abort ();
      22  }
      23  
      24  struct decode_rune_ret
      25  {
      26    int32_t r;
      27    int64_t width;
      28  };
      29  
      30  struct decode_rune_ret decode_rune (struct slice) __attribute__ ((noinline));
      31  struct decode_rune_ret
      32  decode_rune (struct slice s)
      33  {
      34    struct decode_rune_ret dr;
      35    dr.r = s.data[0];
      36    dr.width = 1;
      37    return dr;
      38  }
      39  
      40  _Bool is_space (int32_t) __attribute__ ((noinline));
      41  _Bool
      42  is_space (int32_t r)
      43  {
      44    return r == ' ';
      45  }
      46  
      47  struct ret
      48  {
      49    int64_t advance;
      50    struct slice token;
      51  };
      52  
      53  struct ret scanwords (struct slice, _Bool) __attribute__ ((noinline));
      54  
      55  struct ret
      56  scanwords (struct slice data, _Bool ateof)
      57  {
      58    int64_t advance;
      59    struct slice token;
      60    int64_t start = 0;
      61    {
      62      int64_t width;
      63      for (width = 0; start < data.len; start += width)
      64        {
      65  	int32_t r = 0;
      66  	struct slice s;
      67  	if (start > data.cap || start < 0)
      68  	  fail (3);
      69  	s.data = data.data + (size_t) start;
      70  	s.len = data.len - start;
      71  	s.cap = data.cap - start;
      72  	struct decode_rune_ret dr = decode_rune (s);
      73  	r = dr.r;
      74  	width = dr.width;
      75  	if (!is_space (r))
      76  	  break;
      77        }
      78    }
      79    _Bool tmp = ateof;
      80    if (tmp != 0)
      81      goto L1;
      82    else
      83      goto L2;
      84   L1:
      85    tmp = data.len == 0;
      86   L2:
      87    if (tmp != 0)
      88      goto L11;
      89    else
      90      goto L12;
      91   L11:
      92      {
      93        struct ret r;
      94        advance = 0;
      95        token.data = 0;
      96        token.len = 0;
      97        token.cap = 0;
      98        r.advance = advance;
      99        r.token = token;
     100        return r;
     101      }
     102   L12:;
     103    int64_t width;
     104    int64_t i;
     105    for (width = 0, i = start; i < data.len; i += width)
     106      {
     107        int32_t r;
     108        struct slice s;
     109        if (i > data.cap || i < 0)
     110  	fail (3);
     111        s.data = data.data + i;
     112        s.len = data.len - i;
     113        s.cap = data.cap - i;
     114        struct decode_rune_ret dr = decode_rune (s);
     115        r = dr.r;
     116        width = dr.width;
     117        if (is_space (r))
     118  	{
     119  	  if (i < start || i > data.cap || i < 0)
     120  	    fail (3);
     121  	  if (start > data.cap || start < 0)
     122  	    fail (3);
     123  	  struct ret r;
     124  	  advance = i + width;
     125  	  token.data = data.data + (size_t) start;
     126  	  token.len = i - start;
     127  	  token.cap = data.cap - start;
     128  	  r.advance = advance;
     129  	  r.token = token;
     130  	  return r;
     131  	}
     132      }
     133    {
     134      struct ret r;
     135      advance = 0;
     136      token.data = 0;
     137      token.len = 0;
     138      token.cap = 0;
     139      r.advance = advance;
     140      r.token = token;
     141      return r;
     142    }
     143  }
     144  
     145  int
     146  main ()
     147  {
     148    unsigned char buf[1000];
     149    struct slice s;
     150    __builtin_memset (buf, 0, sizeof (buf));
     151    buf[0] = ' ';
     152    buf[1] = 'a';
     153    buf[2] = ' ';
     154    s.data = buf;
     155    s.len = 3;
     156    s.cap = sizeof (buf);
     157    struct ret r;
     158    r = scanwords (s, 1);
     159    if (r.advance != 3 || r.token.data[0] != 'a' || r.token.len != 1)
     160      abort ();
     161    return 0;
     162  }