Patch to expand_expr:MINUS_EXPR
Jason Merrill
jason@cygnus.com
Mon Oct 4 01:38:00 GMT 1999
When we would reach this point for subtracting some constant from a pointer
value, we would try to negate the constant in the POINTER_TYPE, which fails
because POINTER_TYPEs are unsigned. So then we would take the signed_type
of that, and assume it would work. But of course it doesn't, since the
signed_type of a POINTER_TYPE is the same, unsigned, POINTER_TYPE. So we
would end up with a very large unsigned value. Expanding this to RTX often
fixed the problem, as RTX has no concept of signed/unsigned, and so the
value would magically become signed again, but that doesn't work when
cross-compiling from a 32-bit host to a 64-bit target.
I don't actually understand why we're trying to do the negation here at
all, since expand_binop seems perfectly capable of doing it for us without
the semantic pitfalls, but I assume there's some reason.
1999-10-04 Jason Merrill <jason@yorick.cygnus.com>
* expr.c (expand_expr, case MINUS_EXPR): If negation fails, just
punt.
Index: expr.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/expr.c,v
retrieving revision 1.174
diff -c -p -r1.174 expr.c
*** expr.c 1999/09/23 11:34:48 1.174
--- expr.c 1999/10/04 08:30:33
*************** expand_expr (exp, target, tmode, modifie
*** 7128,7148 ****
tree negated = fold (build1 (NEGATE_EXPR, type,
TREE_OPERAND (exp, 1)));
- /* Deal with the case where we can't negate the constant
- in TYPE. */
if (TREE_UNSIGNED (type) || TREE_OVERFLOW (negated))
! {
! tree newtype = signed_type (type);
! tree newop0 = convert (newtype, TREE_OPERAND (exp, 0));
! tree newop1 = convert (newtype, TREE_OPERAND (exp, 1));
! tree newneg = fold (build1 (NEGATE_EXPR, newtype, newop1));
!
! if (! TREE_OVERFLOW (newneg))
! return expand_expr (convert (type,
! build (PLUS_EXPR, newtype,
! newop0, newneg)),
! target, tmode, ro_modifier);
! }
else
{
exp = build (PLUS_EXPR, type, TREE_OPERAND (exp, 0), negated);
--- 7128,7138 ----
tree negated = fold (build1 (NEGATE_EXPR, type,
TREE_OPERAND (exp, 1)));
if (TREE_UNSIGNED (type) || TREE_OVERFLOW (negated))
! /* If we can't negate the constant in TYPE, leave it alone and
! expand_binop will negate it for us. We used to try to do it
! here in the signed version of TYPE, but that doesn't work
! on POINTER_TYPEs. */;
else
{
exp = build (PLUS_EXPR, type, TREE_OPERAND (exp, 0), negated);
More information about the Gcc-patches
mailing list