aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2014-06-02 08:07:23 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2014-06-02 08:07:23 +0000
commit2ba0071e3da6e8f12e6e323e16de707211071e85 (patch)
tree2e1b68caf42e11c8fae3edd72e70df000b8289ba /gcc
parent31815ed772cda8e1962c5335158f0525039ae4ca (diff)
downloadgcc-2ba0071e3da6e8f12e6e323e16de707211071e85.zip
gcc-2ba0071e3da6e8f12e6e323e16de707211071e85.tar.gz
gcc-2ba0071e3da6e8f12e6e323e16de707211071e85.tar.bz2
re PR tree-optimization/61346 (VRP chooses bad bounds for variable)
2014-06-02 Richard Biener <rguenther@suse.de> PR tree-optimization/61346 * gcc.dg/torture/pr61346.c: New testcase. From-SVN: r211128
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr61346.c162
2 files changed, 167 insertions, 0 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 960b60f..617a197 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2014-06-02 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/61346
+ * gcc.dg/torture/pr61346.c: New testcase.
+
2014-06-01 Uros Bizjak <ubizjak@gmail.com>
* gcc.target/i386/sibcall-2.c: Xfail dg-final scan-assembler-not,
diff --git a/gcc/testsuite/gcc.dg/torture/pr61346.c b/gcc/testsuite/gcc.dg/torture/pr61346.c
new file mode 100644
index 0000000..e27b9ca
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr61346.c
@@ -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;
+}