]> git.sur5r.net Git - cc65/commitdiff
Fixed several more problems like the one in Assignment() some time ago: An
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 8 Sep 2009 20:29:12 +0000 (20:29 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 8 Sep 2009 20:29:12 +0000 (20:29 +0000)
expression that yields a constant value may have side effects, and the
expression code must not be removed in this case.

git-svn-id: svn://svn.cc65.org/cc65/trunk@4138 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/expr.c
src/cc65/stdfunc.c

index 211b1b6d4303d44089de6d600792abf556e9a90b..9eed43aea4bc05f10829f1ee47ac6700dbe88374 100644 (file)
@@ -828,7 +828,7 @@ static void ArrayRef (ExprDesc* Expr)
     }
 
     /* TOS now contains ptr to array elements. Get the subscript. */
-    ExprWithCheck (hie0, &Subscript);
+    MarkedExprWithCheck (hie0, &Subscript);
 
     /* Check the types of array and subscript. We can either have a
      * pointer/array to the left, in which case the subscript must be of an
@@ -870,7 +870,7 @@ static void ArrayRef (ExprDesc* Expr)
     }
 
     /* Check if the subscript is constant absolute value */
-    if (ED_IsConstAbs (&Subscript)) {
+    if (ED_IsConstAbs (&Subscript) && ED_CodeRangeIsEmpty (&Subscript)) {
 
                /* The array subscript is a numeric constant. If we had pushed the
          * array base address onto the stack before, we can remove this value,
@@ -1896,7 +1896,14 @@ static void hie_compare (const GenDesc* Ops,    /* List of generators */
        }
 
        /* Get the right hand side */
-       rconst = (evalexpr (CF_NONE, hienext, &Expr2) == 0);
+        MarkedExprWithCheck (hienext, &Expr2);
+
+        /* Check for a constant expression */
+        rconst = (ED_IsConstAbs (&Expr2) && ED_CodeRangeIsEmpty (&Expr2));
+        if (!rconst) {
+            /* Not constant, load into the primary */
+            LoadExpr (CF_NONE, &Expr2);
+        }
 
        /* Make sure, the types are compatible */
        if (IsClassInt (Expr->Type)) {
@@ -2064,21 +2071,21 @@ static void parseadd (ExprDesc* Expr)
 
            /* Both expressions are constants. Check for pointer arithmetic */
                    if (IsClassPtr (lhst) && IsClassInt (rhst)) {
-                       /* Left is pointer, right is int, must scale rhs */
+                       /* Left is pointer, right is int, must scale rhs */
                        Expr->IVal += Expr2.IVal * CheckedPSizeOf (lhst);
-               /* Result type is a pointer */
+               /* Result type is a pointer */
            } else if (IsClassInt (lhst) && IsClassPtr (rhst)) {
-               /* Left is int, right is pointer, must scale lhs */
+               /* Left is int, right is pointer, must scale lhs */
                        Expr->IVal = Expr->IVal * CheckedPSizeOf (rhst) + Expr2.IVal;
-               /* Result type is a pointer */
-               Expr->Type = Expr2.Type;
+               /* Result type is a pointer */
+               Expr->Type = Expr2.Type;
                    } else if (IsClassInt (lhst) && IsClassInt (rhst)) {
-               /* Integer addition */
-               Expr->IVal += Expr2.IVal;
-               typeadjust (Expr, &Expr2, 1);
+               /* Integer addition */
+               Expr->IVal += Expr2.IVal;
+               typeadjust (Expr, &Expr2, 1);
            } else {
                        /* OOPS */
-               Error ("Invalid operands for binary operator `+'");
+               Error ("Invalid operands for binary operator `+'");
            }
 
                } else {
@@ -2176,7 +2183,10 @@ static void parseadd (ExprDesc* Expr)
        g_push (TypeOf (Expr->Type), 0);        /* --> stack */
 
        /* Evaluate the rhs */
-               if (evalexpr (CF_NONE, hie9, &Expr2) == 0) {
+        MarkedExprWithCheck (hie9, &Expr2);
+
+        /* Check for a constant rhs expression */
+        if (ED_IsConstAbs (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)) {
 
                    /* Right hand side is a constant. Get the rhs type */
            rhst = Expr2.Type;
@@ -2210,6 +2220,9 @@ static void parseadd (ExprDesc* Expr)
 
        } else {
 
+            /* Not constant, load into the primary */
+            LoadExpr (CF_NONE, &Expr2);
+
            /* lhs and rhs are not constant. Get the rhs type. */
            rhst = Expr2.Type;
 
@@ -2289,7 +2302,10 @@ static void parsesub (ExprDesc* Expr)
     g_push (TypeOf (lhst), 0); /* --> stack */
 
     /* Parse the right hand side */
-    if (evalexpr (CF_NONE, hie9, &Expr2) == 0) {
+    MarkedExprWithCheck (hie9, &Expr2);
+
+    /* Check for a constant rhs expression */
+    if (ED_IsConstAbs (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)) {
 
        /* The right hand side is constant. Get the rhs type. */
                rhst = Expr2.Type;
@@ -2361,38 +2377,41 @@ static void parsesub (ExprDesc* Expr)
            /* Do the subtraction */
            g_dec (flags | CF_CONST, Expr2.IVal);
 
-           /* If this was a pointer subtraction, we must scale the result */
-           if (rscale != 1) {
-               g_scale (flags, -rscale);
-           }
+           /* If this was a pointer subtraction, we must scale the result */
+           if (rscale != 1) {
+               g_scale (flags, -rscale);
+           }
 
-           /* Result is a rvalue in the primary register */
-           ED_MakeRValExpr (Expr);
-           ED_MarkAsUntested (Expr);
+           /* Result is a rvalue in the primary register */
+           ED_MakeRValExpr (Expr);
+           ED_MarkAsUntested (Expr);
 
-       }
+       }
 
     } else {
 
-       /* Right hand side is not constant. Get the rhs type. */
-       rhst = Expr2.Type;
+        /* Not constant, load into the primary */
+        LoadExpr (CF_NONE, &Expr2);
+
+       /* Right hand side is not constant. Get the rhs type. */
+       rhst = Expr2.Type;
 
                /* Check for pointer arithmetic */
-       if (IsClassPtr (lhst) && IsClassInt (rhst)) {
+       if (IsClassPtr (lhst) && IsClassInt (rhst)) {
            /* Left is pointer, right is int, must scale rhs */
-           g_scale (CF_INT, CheckedPSizeOf (lhst));
-           /* Operate on pointers, result type is a pointer */
-           flags = CF_PTR;
-       } else if (IsClassPtr (lhst) && IsClassPtr (rhst)) {
-           /* Left is pointer, right is pointer, must scale result */
-           if (TypeCmp (Indirect (lhst), Indirect (rhst)) < TC_QUAL_DIFF) {
-               Error ("Incompatible pointer types");
-           } else {
-               rscale = CheckedPSizeOf (lhst);
-           }
-           /* Operate on pointers, result type is an integer */
-           flags = CF_PTR;
-           Expr->Type = type_int;
+           g_scale (CF_INT, CheckedPSizeOf (lhst));
+           /* Operate on pointers, result type is a pointer */
+           flags = CF_PTR;
+       } else if (IsClassPtr (lhst) && IsClassPtr (rhst)) {
+           /* Left is pointer, right is pointer, must scale result */
+           if (TypeCmp (Indirect (lhst), Indirect (rhst)) < TC_QUAL_DIFF) {
+               Error ("Incompatible pointer types");
+           } else {
+               rscale = CheckedPSizeOf (lhst);
+           }
+           /* Operate on pointers, result type is an integer */
+           flags = CF_PTR;
+           Expr->Type = type_int;
        } else if (IsClassInt (lhst) && IsClassInt (rhst)) {
            /* Integer subtraction. If the left hand side descriptor says that
             * the lhs is const, we have to remove this mark, since this is no
@@ -2868,7 +2887,10 @@ static void opeq (const GenDesc* Gen, ExprDesc* Expr)
     g_push (flags, 0);
 
     /* Evaluate the rhs */
-    if (evalexpr (CF_NONE, hie1, &Expr2) == 0) {
+    MarkedExprWithCheck (hie1, &Expr2);
+
+    /* Check for a constant expression */
+    if (ED_IsConstAbs (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)) {
        /* The resulting value is a constant. If the generator has the NOPUSH
         * flag set, don't push the lhs.
         */
@@ -2904,7 +2926,9 @@ static void opeq (const GenDesc* Gen, ExprDesc* Expr)
                    Gen->Func (flags | CF_CONST, Expr2.IVal);
        }
     } else {
-       /* rhs is not constant and already in the primary register */
+
+       /* rhs is not constant. Load into the primary */
+        LoadExpr (CF_NONE, &Expr2);
                if (MustScale) {
            /* lhs is a pointer, scale rhs */
                    g_scale (TypeOf (Expr2.Type), CheckedSizeOf (Expr->Type+1));
index b41210f4461d3e50687960f1366b3a759a0d37d7..4f48c4fc4d3c5626397f23790c1f3ced7227c318 100644 (file)
@@ -154,7 +154,7 @@ static void ParseArg (ArgDesc* Arg, Type* Type)
     GetCodePos (&Arg->Start);
 
     /* Read the expression we're going to pass to the function */
-    ExprWithCheck (hie1, &Arg->Expr);
+    MarkedExprWithCheck (hie1, &Arg->Expr);
 
     /* Remember the actual argument type */
     Arg->Type = Arg->Expr.Type;
@@ -165,7 +165,7 @@ static void ParseArg (ArgDesc* Arg, Type* Type)
     /* If the value is a constant, set the flag, otherwise load it into the
      * primary register.
      */
-    if (ED_IsConstAbsInt (&Arg->Expr)) {
+    if (ED_IsConstAbsInt (&Arg->Expr) && ED_CodeRangeIsEmpty (&Arg->Expr)) {
         /* Remember that we have a constant value */
         Arg->Flags |= CF_CONST;
     } else {