expr.c (expand_expr): Never modify exp in place.
* expr.c (expand_expr) <case COND_EXPR>: Never modify exp in place. * gcc.c-torture/execute/20021204-1.c: New test. From-SVN: r59881
This commit is contained in:
parent
bf97847b37
commit
61f6c84f21
@ -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.
|
||||
|
22
gcc/expr.c
22
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 ();
|
||||
|
@ -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.
|
||||
|
25
gcc/testsuite/gcc.c-torture/execute/20021204-1.c
Normal file
25
gcc/testsuite/gcc.c-torture/execute/20021204-1.c
Normal file
@ -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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user