Bug fix: INC/DEC evaluated argument twice(!)
authorceriel <none@none>
Fri, 31 Jan 1992 13:44:57 +0000 (13:44 +0000)
committerceriel <none@none>
Fri, 31 Jan 1992 13:44:57 +0000 (13:44 +0000)
lang/m2/comp/code.c

index ab12389..656dca1 100644 (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)");