OSDN Git Service

* expr.c (expand_expr) <case COND_EXPR>: Never modify exp in place.
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 6 Dec 2002 07:07:57 +0000 (07:07 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 6 Dec 2002 07:07:57 +0000 (07:07 +0000)
* gcc.c-torture/execute/20021204-1.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@59881 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 2ee0382..9cd5598 100644 (file)
@@ -1,3 +1,7 @@
+2002-12-06  Jakub Jelinek  <jakub@redhat.com>
+
+       * expr.c (expand_expr) <case COND_EXPR>: Never modify exp in place.
+
 2002-12-05  John David Anglin  <dave@hiauly1.hia.nrc.ca>
 
        * pa32-linux.h (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL): Move define.
index 8851343..144bc00 100644 (file)
@@ -8618,6 +8618,7 @@ expand_expr (exp, target, tmode, modifier)
            && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == '<')
          {
            rtx result;
+           tree cond;
            optab boptab = (TREE_CODE (binary_op) == PLUS_EXPR
                            ? (TYPE_TRAP_SIGNED (TREE_TYPE (binary_op))
                               ? addv_optab : add_optab)
@@ -8627,20 +8628,14 @@ expand_expr (exp, target, tmode, modifier)
                            : TREE_CODE (binary_op) == BIT_IOR_EXPR ? ior_optab
                            : xor_optab);
 
-           /* If we had X ? A : A + 1, do this as A + (X == 0).
-
-              We have to invert the truth value here and then put it
-              back later if do_store_flag fails.  We cannot simply copy
-              TREE_OPERAND (exp, 0) to another variable and modify that
-              because invert_truthvalue can modify the tree pointed to
-              by its argument.  */
+           /* If we had X ? A : A + 1, do this as A + (X == 0).  */
            if (singleton == TREE_OPERAND (exp, 1))
-             TREE_OPERAND (exp, 0)
-               = invert_truthvalue (TREE_OPERAND (exp, 0));
+             cond = invert_truthvalue (TREE_OPERAND (exp, 0));
+           else
+             cond = TREE_OPERAND (exp, 0);
 
-           result = do_store_flag (TREE_OPERAND (exp, 0),
-                                   (safe_from_p (temp, singleton, 1)
-                                    ? temp : NULL_RTX),
+           result = do_store_flag (cond, (safe_from_p (temp, singleton, 1)
+                                          ? temp : NULL_RTX),
                                    mode, BRANCH_COST <= 1);
 
            if (result != 0 && ! integer_onep (TREE_OPERAND (binary_op, 1)))
@@ -8658,9 +8653,6 @@ expand_expr (exp, target, tmode, modifier)
                return expand_binop (mode, boptab, op1, result, temp,
                                     unsignedp, OPTAB_LIB_WIDEN);
              }
-           else if (singleton == TREE_OPERAND (exp, 1))
-             TREE_OPERAND (exp, 0)
-               = invert_truthvalue (TREE_OPERAND (exp, 0));
          }
 
        do_pending_stack_adjust ();
index c8181d4..7ced2af 100644 (file)
@@ -1,3 +1,7 @@
+2002-12-06  Jakub Jelinek  <jakub@redhat.com>
+
+       * gcc.c-torture/execute/20021204-1.c: New test.
+
 2002-12-04  Geoffrey Keating  <geoffk@apple.com>
 
        * gcc.dg/ppc-fmadd-1.c: New file.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20021204-1.c b/gcc/testsuite/gcc.c-torture/execute/20021204-1.c
new file mode 100644 (file)
index 0000000..e92c408
--- /dev/null
@@ -0,0 +1,25 @@
+/* This test was miscompiled when using sibling call optimization,
+   because X ? Y : Y - 1 optimization changed X into !X in place
+   and haven't reverted it if do_store_flag was successful, so
+   when expanding the expression the second time it was
+   !X ? Y : Y - 1.  */
+
+extern void abort (void);
+extern void exit (int);
+
+void foo (int x)
+{
+  if (x != 1)
+    abort ();
+}
+
+int z;
+
+int main (int argc, char **argv)
+{
+  char *a = "test";
+  char *b = a + 2;
+
+  foo (z > 0 ? b - a : b - a - 1);
+  exit (0);
+}