From 61f6c84f21a542b10c4d915751f1fc4ec3d0f1ff Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 6 Dec 2002 08:07:57 +0100 Subject: [PATCH] expr.c (expand_expr): Never modify exp in place. * expr.c (expand_expr) : Never modify exp in place. * gcc.c-torture/execute/20021204-1.c: New test. From-SVN: r59881 --- gcc/ChangeLog | 4 +++ gcc/expr.c | 22 ++++++---------- gcc/testsuite/ChangeLog | 4 +++ .../gcc.c-torture/execute/20021204-1.c | 25 +++++++++++++++++++ 4 files changed, 40 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/20021204-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2ee03820237..9cd559875de 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2002-12-06 Jakub Jelinek + + * expr.c (expand_expr) : Never modify exp in place. + 2002-12-05 John David Anglin * pa32-linux.h (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL): Move define. diff --git a/gcc/expr.c b/gcc/expr.c index 8851343299a..144bc008b55 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -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 (); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c8181d41233..7ced2afb62a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2002-12-06 Jakub Jelinek + + * gcc.c-torture/execute/20021204-1.c: New test. + 2002-12-04 Geoffrey Keating * 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 index 00000000000..e92c408a7b5 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20021204-1.c @@ -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); +} -- 2.30.2