That C parser bug
Charles M. Hannum
root@ihack.net
Fri Oct 30 15:11:00 GMT 1998
So, looking at store_expr() some more, I think the following is
actually a `correct' fix. All it does is swap two blocks of code, so
that the test for a postincrement in the lhs is earlier. With this
change, my test cases all generate correct code.
(I put `correct' in quotes because it seems to me that the entire
method of handling postincrement is kind of hokey, but I'll save that
for another day.)
Index: expr.c
===================================================================
RCS file: /cvsroot/src/gnu/dist/gcc/expr.c,v
retrieving revision 1.1.1.2
diff -c -2 -r1.1.1.2 expr.c
*** expr.c 1998/08/16 17:37:14 1.1.1.2
--- expr.c 1998/10/30 23:09:47
***************
*** 3327,3349 ****
return want_value ? target : NULL_RTX;
}
- else if (want_value && GET_CODE (target) == MEM && ! MEM_VOLATILE_P (target)
- && GET_MODE (target) != BLKmode)
- /* If target is in memory and caller wants value in a register instead,
- arrange that. Pass TARGET as target for expand_expr so that,
- if EXP is another assignment, WANT_VALUE will be nonzero for it.
- We know expand_expr will not use the target in that case.
- Don't do this if TARGET is volatile because we are supposed
- to write it and then read it. */
- {
- temp = expand_expr (exp, cse_not_expected ? NULL_RTX : target,
- GET_MODE (target), 0);
- if (GET_MODE (temp) != BLKmode && GET_MODE (temp) != VOIDmode)
- temp = copy_to_reg (temp);
- dont_return_target = 1;
- }
else if (queued_subexp_p (target))
/* If target contains a postincrement, let's not risk
using it as the place to generate the rhs. */
{
if (GET_MODE (target) != BLKmode && GET_MODE (target) != VOIDmode)
{
--- 3327,3334 ----
***************
*** 3360,3363 ****
--- 3345,3363 ----
if (! MEM_VOLATILE_P (target) && want_value)
dont_return_target = 1;
+ }
+ else if (want_value && GET_CODE (target) == MEM && ! MEM_VOLATILE_P (target)
+ && GET_MODE (target) != BLKmode)
+ /* If target is in memory and caller wants value in a register instead,
+ arrange that. Pass TARGET as target for expand_expr so that,
+ if EXP is another assignment, WANT_VALUE will be nonzero for it.
+ We know expand_expr will not use the target in that case.
+ Don't do this if TARGET is volatile because we are supposed
+ to write it and then read it. */
+ {
+ temp = expand_expr (exp, cse_not_expected ? NULL_RTX : target,
+ GET_MODE (target), 0);
+ if (GET_MODE (temp) != BLKmode && GET_MODE (temp) != VOIDmode)
+ temp = copy_to_reg (temp);
+ dont_return_target = 1;
}
else if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
More information about the Gcc-bugs
mailing list