From 66b3f9d97470869c7582221ec4051f67691920bf Mon Sep 17 00:00:00 2001 From: uz Date: Thu, 7 Aug 2008 22:18:12 +0000 Subject: [PATCH] Fixed a bug: It was possible to increment or decrement const qualified objects. git-svn-id: svn://svn.cc65.org/cc65/trunk@3882 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/expr.c | 82 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 73 insertions(+), 9 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index c80c42cf8..a9e0bee54 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -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,11 @@ 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); @@ -1384,9 +1399,56 @@ 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_inc (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1)); } else { - inc (Flags | CF_CONST | CF_FORCECHAR, 1); + 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); + + /* 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_dec (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1)); + } else { + 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; } }