]> git.sur5r.net Git - cc65/commitdiff
Fixed a bug: It was possible to increment or decrement const qualified
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 7 Aug 2008 22:18:12 +0000 (22:18 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 7 Aug 2008 22:18:12 +0000 (22:18 +0000)
objects.

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

src/cc65/expr.c

index c80c42cf89b4eaa79b68327a6b27a1fa5ddca675..a9e0bee545c52c39d1f51e8b73c17c07b1cb2e16 100644 (file)
@@ -1167,7 +1167,7 @@ void Store (ExprDesc* Expr, const Type* StoreType)
 
     /* Prepare the code generator flags */
     Flags = TypeOf (StoreType);
-                   
+
     /* Do the store depending on the location */
     switch (ED_GetLoc (Expr)) {
 
@@ -1233,6 +1233,11 @@ static void PreInc (ExprDesc* Expr)
        return;
     }
 
+    /* We cannot modify const values */
+    if (IsQualConst (Expr->Type)) {
+        Error ("Increment of read-only variable");
+    }
+
     /* Get the data type */
     Flags = TypeOf (Expr->Type) | CF_FORCECHAR | CF_CONST;
 
@@ -1304,6 +1309,11 @@ static void PreDec (ExprDesc* Expr)
        return;
     }
 
+    /* We cannot modify const values */
+    if (IsQualConst (Expr->Type)) {
+        Error ("Decrement of read-only variable");
+    }
+
     /* Get the data type */
     Flags = TypeOf (Expr->Type) | CF_FORCECHAR | CF_CONST;
 
@@ -1359,8 +1369,8 @@ static void PreDec (ExprDesc* Expr)
 
 
 
-static void PostIncDec (ExprDesc* Expr, void (*inc) (unsigned, unsigned long))
-/* Handle i-- and i++ */
+static void PostInc (ExprDesc* Expr)
+/* Handle the postincrement operator */
 {
     unsigned Flags;
 
@@ -1372,6 +1382,58 @@ static void PostIncDec (ExprDesc* Expr, void (*inc) (unsigned, unsigned long))
                return;
     }
 
+    /* We cannot modify const values */
+    if (IsQualConst (Expr->Type)) {
+        Error ("Increment of read-only variable");
+    }
+
+    /* Get the data type */
+    Flags = TypeOf (Expr->Type);
+
+    /* Push the address if needed */
+    PushAddr (Expr);
+
+    /* Fetch the value and save it (since it's the result of the expression) */
+    LoadExpr (CF_NONE, Expr);
+    g_save (Flags | CF_FORCECHAR);
+
+    /* If we have a pointer expression, increment by the size of the type */
+    if (IsTypePtr (Expr->Type)) {
+       g_inc (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1));
+    } else {
+       g_inc (Flags | CF_CONST | CF_FORCECHAR, 1);
+    }
+
+    /* Store the result back */
+    Store (Expr, 0);
+
+    /* Restore the original value in the primary register */
+    g_restore (Flags | CF_FORCECHAR);
+
+    /* The result is always an expression, no reference */
+    ED_MakeRValExpr (Expr);
+}
+
+
+
+static void PostDec (ExprDesc* Expr)
+/* Handle the postdecrement operator */
+{
+    unsigned Flags;
+
+    NextToken ();
+
+    /* The expression to increment must be an lvalue */
+    if (!ED_IsLVal (Expr)) {
+       Error ("Invalid lvalue");
+               return;
+    }
+
+    /* We cannot modify const values */
+    if (IsQualConst (Expr->Type)) {
+        Error ("Decrement of read-only variable");
+    }
+
     /* Get the data type */
     Flags = TypeOf (Expr->Type);
 
@@ -1384,9 +1446,9 @@ static void PostIncDec (ExprDesc* Expr, void (*inc) (unsigned, unsigned long))
 
     /* If we have a pointer expression, increment by the size of the type */
     if (IsTypePtr (Expr->Type)) {
-       inc (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1));
+       g_dec (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1));
     } else {
-       inc (Flags | CF_CONST | CF_FORCECHAR, 1);
+       g_dec (Flags | CF_CONST | CF_FORCECHAR, 1);
     }
 
     /* Store the result back */
@@ -1505,6 +1567,7 @@ void hie10 (ExprDesc* Expr)
                 } else {
                     Error ("Illegal indirection");
                 }
+                /* The * operator yields an lvalue */
                 ED_MakeLVal (Expr);
             }
             break;
@@ -1519,6 +1582,7 @@ void hie10 (ExprDesc* Expr)
                 Error ("Illegal address");
            } else {
                 Expr->Type = PointerTo (Expr->Type);
+                /* The & operator yields an rvalue */
                 ED_MakeRVal (Expr);
            }
            break;
@@ -1555,10 +1619,10 @@ void hie10 (ExprDesc* Expr)
                 hie11 (Expr);
 
                 /* Handle post increment */
-                if (CurTok.Tok == TOK_INC) {
-                    PostIncDec (Expr, g_inc);
-                } else if (CurTok.Tok == TOK_DEC) {
-                    PostIncDec (Expr, g_dec);
+                switch (CurTok.Tok) {
+                    case TOK_INC:   PostInc (Expr); break;
+                    case TOK_DEC:   PostDec (Expr); break;
+                    default:                        break;
                 }
 
             }