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
This commit is contained in:
parent
92a4690ac3
commit
66b3f9d974
1 changed files with 73 additions and 9 deletions
|
@ -1233,6 +1233,11 @@ static void PreInc (ExprDesc* Expr)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We cannot modify const values */
|
||||||
|
if (IsQualConst (Expr->Type)) {
|
||||||
|
Error ("Increment of read-only variable");
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the data type */
|
/* Get the data type */
|
||||||
Flags = TypeOf (Expr->Type) | CF_FORCECHAR | CF_CONST;
|
Flags = TypeOf (Expr->Type) | CF_FORCECHAR | CF_CONST;
|
||||||
|
|
||||||
|
@ -1304,6 +1309,11 @@ static void PreDec (ExprDesc* Expr)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We cannot modify const values */
|
||||||
|
if (IsQualConst (Expr->Type)) {
|
||||||
|
Error ("Decrement of read-only variable");
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the data type */
|
/* Get the data type */
|
||||||
Flags = TypeOf (Expr->Type) | CF_FORCECHAR | CF_CONST;
|
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))
|
static void PostInc (ExprDesc* Expr)
|
||||||
/* Handle i-- and i++ */
|
/* Handle the postincrement operator */
|
||||||
{
|
{
|
||||||
unsigned Flags;
|
unsigned Flags;
|
||||||
|
|
||||||
|
@ -1372,6 +1382,11 @@ static void PostIncDec (ExprDesc* Expr, void (*inc) (unsigned, unsigned long))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We cannot modify const values */
|
||||||
|
if (IsQualConst (Expr->Type)) {
|
||||||
|
Error ("Increment of read-only variable");
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the data type */
|
/* Get the data type */
|
||||||
Flags = TypeOf (Expr->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 we have a pointer expression, increment by the size of the type */
|
||||||
if (IsTypePtr (Expr->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 {
|
} 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 */
|
/* Store the result back */
|
||||||
|
@ -1505,6 +1567,7 @@ void hie10 (ExprDesc* Expr)
|
||||||
} else {
|
} else {
|
||||||
Error ("Illegal indirection");
|
Error ("Illegal indirection");
|
||||||
}
|
}
|
||||||
|
/* The * operator yields an lvalue */
|
||||||
ED_MakeLVal (Expr);
|
ED_MakeLVal (Expr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1519,6 +1582,7 @@ void hie10 (ExprDesc* Expr)
|
||||||
Error ("Illegal address");
|
Error ("Illegal address");
|
||||||
} else {
|
} else {
|
||||||
Expr->Type = PointerTo (Expr->Type);
|
Expr->Type = PointerTo (Expr->Type);
|
||||||
|
/* The & operator yields an rvalue */
|
||||||
ED_MakeRVal (Expr);
|
ED_MakeRVal (Expr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1555,10 +1619,10 @@ void hie10 (ExprDesc* Expr)
|
||||||
hie11 (Expr);
|
hie11 (Expr);
|
||||||
|
|
||||||
/* Handle post increment */
|
/* Handle post increment */
|
||||||
if (CurTok.Tok == TOK_INC) {
|
switch (CurTok.Tok) {
|
||||||
PostIncDec (Expr, g_inc);
|
case TOK_INC: PostInc (Expr); break;
|
||||||
} else if (CurTok.Tok == TOK_DEC) {
|
case TOK_DEC: PostDec (Expr); break;
|
||||||
PostIncDec (Expr, g_dec);
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue