Committed. Richard.
2014-06-02 Richard Biener <rguent...@suse.de> PR tree-optimization/61346 * gcc.dg/torture/pr61346.c: New testcase. Index: gcc/testsuite/gcc.dg/torture/pr61346.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr61346.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/pr61346.c (working copy) @@ -0,0 +1,162 @@ +/* { dg-do run } */ + +extern void abort (void); + +typedef int int32_t __attribute__ ((mode (SI))); +typedef int int64_t __attribute__ ((mode (DI))); +typedef __SIZE_TYPE__ size_t; + +struct slice +{ + unsigned char *data; + int64_t len; + int64_t cap; +}; + +void fail (int32_t) __attribute__ ((noinline)); +void +fail (int32_t c) +{ + if (c != 0) + abort (); +} + +struct decode_rune_ret +{ + int32_t r; + int64_t width; +}; + +struct decode_rune_ret decode_rune (struct slice) __attribute__ ((noinline)); +struct decode_rune_ret +decode_rune (struct slice s) +{ + struct decode_rune_ret dr; + dr.r = s.data[0]; + dr.width = 1; + return dr; +} + +_Bool is_space (int32_t) __attribute__ ((noinline)); +_Bool +is_space (int32_t r) +{ + return r == ' '; +} + +struct ret +{ + int64_t advance; + struct slice token; +}; + +struct ret scanwords (struct slice, _Bool) __attribute__ ((noinline)); + +struct ret +scanwords (struct slice data, _Bool ateof) +{ + int64_t advance; + struct slice token; + int64_t start = 0; + { + int64_t width; + for (width = 0; start < data.len; start += width) + { + int32_t r = 0; + struct slice s; + if (start > data.cap || start < 0) + fail (3); + s.data = data.data + (size_t) start; + s.len = data.len - start; + s.cap = data.cap - start; + struct decode_rune_ret dr = decode_rune (s); + r = dr.r; + width = dr.width; + if (!is_space (r)) + break; + } + } + _Bool tmp = ateof; + if (tmp != 0) + goto L1; + else + goto L2; + L1: + tmp = data.len == 0; + L2: + if (tmp != 0) + goto L11; + else + goto L12; + L11: + { + struct ret r; + advance = 0; + token.data = 0; + token.len = 0; + token.cap = 0; + r.advance = advance; + r.token = token; + return r; + } + L12:; + int64_t width; + int64_t i; + for (width = 0, i = start; i < data.len; i += width) + { + int32_t r; + struct slice s; + if (i > data.cap || i < 0) + fail (3); + s.data = data.data + i; + s.len = data.len - i; + s.cap = data.cap - i; + struct decode_rune_ret dr = decode_rune (s); + r = dr.r; + width = dr.width; + if (is_space (r)) + { + if (i < start || i > data.cap || i < 0) + fail (3); + if (start > data.cap || start < 0) + fail (3); + struct ret r; + advance = i + width; + token.data = data.data + (size_t) start; + token.len = i - start; + token.cap = data.cap - start; + r.advance = advance; + r.token = token; + return r; + } + } + { + struct ret r; + advance = 0; + token.data = 0; + token.len = 0; + token.cap = 0; + r.advance = advance; + r.token = token; + return r; + } +} + +int +main () +{ + unsigned char buf[1000]; + struct slice s; + __builtin_memset (buf, 0, sizeof (buf)); + buf[0] = ' '; + buf[1] = 'a'; + buf[2] = ' '; + s.data = buf; + s.len = 3; + s.cap = sizeof (buf); + struct ret r; + r = scanwords (s, 1); + if (r.advance != 3 || r.token.data[0] != 'a' || r.token.len != 1) + abort (); + return 0; +}