Bug fix: INC/DEC evaluated argument twice(!)

This commit is contained in:
ceriel 1992-01-31 13:44:57 +00:00
parent f3e5c3032f
commit 81ec28ccb9

View file

@ -474,6 +474,23 @@ addu(sz)
C_adu((arith)sz);
}
static int
complex_lhs(nd)
register t_node *nd;
{
switch(nd->nd_class) {
case Value:
case Name:
case Set:
case Def:
return 0;
case Select:
return complex_lhs(nd->nd_NEXT);
default:
return 1;
}
}
CodeStd(nd)
t_node *nd;
{
@ -545,10 +562,19 @@ CodeStd(nd)
case S_DEC:
case S_INC: {
register arith size;
int compl = complex_lhs(left);
arith tmp = 0;
size = left->nd_type->tp_size;
if ((int) size < (int) word_size) size = word_size;
CodePExpr(left);
if (compl) {
tmp = NewPtr();
CodeDAddress(left, 1);
STL(tmp, pointer_size);
LOL(tmp, pointer_size);
C_loi(left->nd_type->tp_size);
}
else CodePExpr(left);
CodeCoercion(left->nd_type, tp);
if (arg) {
CodePExpr(arg->nd_LEFT);
@ -570,7 +596,12 @@ CodeStd(nd)
RangeCheck(left->nd_type, tp->tp_fund == T_INTEGER ?
int_type : card_type);
}
CodeDStore(left);
if (compl) {
LOL(tmp, pointer_size);
C_sti(left->nd_type->tp_size);
FreePtr(tmp);
}
else CodeDStore(left);
break;
}
@ -579,8 +610,18 @@ CodeStd(nd)
break;
case S_INCL:
case S_EXCL:
CodePExpr(left);
case S_EXCL: {
int compl = complex_lhs(left);
arith tmp = 0;
if (compl) {
tmp = NewPtr();
CodeDAddress(left, 1);
STL(tmp, pointer_size);
LOL(tmp, pointer_size);
C_loi(left->nd_type->tp_size);
}
else CodePExpr(left);
CodePExpr(arg->nd_LEFT);
C_loc(tp->set_low);
C_sbi(word_size);
@ -592,8 +633,14 @@ CodeStd(nd)
C_com(tp->tp_size);
C_and(tp->tp_size);
}
CodeDStore(left);
if (compl) {
LOL(tmp, pointer_size);
C_sti(left->nd_type->tp_size);
FreePtr(tmp);
}
else CodeDStore(left);
break;
}
default:
crash("(CodeStd)");