re PR middle-end/26300 (ICE in trunc_int_for_mode)
authorJakub Jelinek <jakub@redhat.com>
Wed, 15 Feb 2006 20:41:03 +0000 (21:41 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 15 Feb 2006 20:41:03 +0000 (21:41 +0100)
PR middle-end/26300
* combine.c (make_extraction): Bail out if ORIG_POS is negative.

* gcc.c-torture/compile/20060215-1.c: New test.

From-SVN: r111116

gcc/ChangeLog
gcc/combine.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/20060215-1.c [new file with mode: 0644]

index 3be2c3f5a8f6d68b810f26a83678e69d251656d2..9b388d6cf2b093a01a1e236250cada86b202673b 100644 (file)
@@ -1,5 +1,8 @@
 2006-02-15  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/26300
+       * combine.c (make_extraction): Bail out if ORIG_POS is negative.
+
        * tree.h (struct tree_omp_clause): Use OMP_CLAUSE_CODE rather
        than TREE_CODE as index into omp_clause_num_ops array.
 
index d4ea6897c81df3660a7c4d561cf67dd175fffa3b..96ebd208a825730ae623a5acc1e7d167a46bd652 100644 (file)
@@ -6249,6 +6249,9 @@ make_extraction (enum machine_mode mode, rtx inner, HOST_WIDE_INT pos,
              || orig_pos + len > GET_MODE_BITSIZE (wanted_inner_mode)))
        return 0;
 
+      if (orig_pos < 0)
+       return 0;
+
       inner = force_to_mode (inner, wanted_inner_mode,
                             pos_rtx
                             || len + orig_pos >= HOST_BITS_PER_WIDE_INT
index d2319a10fbf51c0c5dcb59934f56b7c80ff200ec..d22edd340f29bc8e0876bd7a8b34a6e1dc91531c 100644 (file)
@@ -1,3 +1,8 @@
+2006-02-15  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/26300
+       * gcc.c-torture/compile/20060215-1.c: New test.
+
 2006-02-14  Roger Sayle  <roger@eyesopen.com>
 
        PR middle-end/23670
diff --git a/gcc/testsuite/gcc.c-torture/compile/20060215-1.c b/gcc/testsuite/gcc.c-torture/compile/20060215-1.c
new file mode 100644 (file)
index 0000000..7979561
--- /dev/null
@@ -0,0 +1,42 @@
+/* PR middle-end/26300 */
+
+struct S
+{
+  char c;
+  struct S *d;
+  struct S *e;
+};
+extern struct S *u, *v;
+extern void fn1 (struct S *) __attribute__ ((noreturn));
+void fn2 (struct S *);
+
+static inline struct S *
+fn3 (struct S *x)
+{
+  if (x->c != 6)
+    fn1 (0);
+  return (struct S *) x;
+}
+
+static inline int
+fn4 (struct S *x)
+{
+  if (x != u)
+    return 3;
+  fn2 (x);
+  return 0;
+}
+
+int
+test (struct S *x)
+{
+  struct S *r;
+  int m = 0;
+
+  for (r = x; r != v; r = (fn3 (r)->d))
+    if (r->c != 6)
+      fn1 (x);
+    else
+      m |= 1 << (fn4 (fn3 (r)->e) - 1);
+  return m;
+}