re PR rtl-optimization/13400 (Compiled code crashes storing to read-only location)
authorRoger Sayle <roger@eyesopen.com>
Tue, 16 Dec 2003 02:22:59 +0000 (02:22 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Tue, 16 Dec 2003 02:22:59 +0000 (02:22 +0000)
PR middle-end/13400
* ifcvt.c (noce_process_if_block): Disable unconditional write
optimizations if we could introduce a store to trapping memory
that wasn't present previously.

* gcc.c-torture/execute/20031215-1.c: New test case.

From-SVN: r74663

gcc/ChangeLog
gcc/ifcvt.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20031215-1.c [new file with mode: 0644]

index cc3def4ec09f5ac502d3f90077260629a102e4c3..950083c271226e721b21c6bc1b3ac2a44c8363c1 100644 (file)
@@ -1,3 +1,10 @@
+2003-12-15  Roger Sayle  <roger@eyesopen.com>
+
+       PR middle-end/13400
+       * ifcvt.c (noce_process_if_block): Disable unconditional write
+       optimizations if we could introduce a store to trapping memory
+       that wasn't present previously.
+
 2003-12-15  Kazu Hirata  <kazu@cs.umass.edu>
 
        * system.h (DEFAULT_CALLER_SAVES): Poison.
index 4a13ba2a45b9b701ab29e093f8926670ced49503..8aba0d50efc9afe9abd2cb732cc504b529de63cf 100644 (file)
@@ -1965,6 +1965,25 @@ noce_process_if_block (struct ce_if_block * ce_info)
       goto success;
     }
 
+  /* Disallow the "if (...) x = a;" form (with an implicit "else x = x;")
+     for most optimizations if writing to x may trap, i.e. its a memory
+     other than a static var or a stack slot.  */
+  if (! set_b
+      && GET_CODE (orig_x) == MEM
+      && ! MEM_NOTRAP_P (orig_x)
+      && rtx_addr_can_trap_p (XEXP (orig_x, 0)))
+    {
+      if (HAVE_conditional_move)
+       {
+         if (noce_try_cmove (&if_info))
+           goto success;
+         if (! HAVE_conditional_execution
+             && noce_try_cmove_arith (&if_info))
+           goto success;
+       }
+      return FALSE;
+    }
+
   if (noce_try_move (&if_info))
     goto success;
   if (noce_try_store_flag (&if_info))
index 8862f109ff203d50a46d0bbf361da37b3ede24af..96c0ee8a93ecc3f1fbea7c46a80be2e9b212bcbe 100644 (file)
@@ -1,3 +1,8 @@
+2003-12-15  Roger Sayle  <roger@eyesopen.com>
+
+       PR middle-end/13400
+       * gcc.c-torture/execute/20031215-1.c: New test case.
+
 2003-12-15  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/13269
diff --git a/gcc/testsuite/gcc.c-torture/execute/20031215-1.c b/gcc/testsuite/gcc.c-torture/execute/20031215-1.c
new file mode 100644 (file)
index 0000000..d62177b
--- /dev/null
@@ -0,0 +1,38 @@
+/* PR middle-end/13400 */
+/* The following test used to fail at run-time with a write to read-only
+   memory, caused by if-conversion converting a conditional write into an
+   unconditional write.  */
+
+typedef struct {int c, l; char ch[3];} pstr;
+const pstr ao = {2, 2, "OK"};
+const pstr * const a = &ao;
+
+void test1(void)
+{
+    if (a->ch[a->l]) {
+        ((char *)a->ch)[a->l] = 0;
+    }
+}
+
+void test2(void)
+{
+    if (a->ch[a->l]) {
+        ((char *)a->ch)[a->l] = -1;
+    }
+}
+
+void test3(void)
+{
+    if (a->ch[a->l]) {
+        ((char *)a->ch)[a->l] = 1;
+    }
+}
+
+int main(void)
+{
+    test1();
+    test2();
+    test3();
+    return 0;
+}
+