mirror of
https://github.com/cc65/cc65.git
synced 2024-12-28 06:30:16 +00:00
patch from Uz that makes some illegal operations on pointers error out
This commit is contained in:
parent
bdb01212c2
commit
6ab197f364
@ -391,6 +391,12 @@ unsigned SizeOf (const Type* T)
|
||||
case T_VOID:
|
||||
return 0; /* Assume voids have size zero */
|
||||
|
||||
/* Beware: There's a chance that this triggers problems in other parts
|
||||
of the compiler. The solution is to fix the callers, because calling
|
||||
SizeOf() with a function type as argument is bad. */
|
||||
case T_FUNC:
|
||||
return 0; /* Size of function is unknown */
|
||||
|
||||
case T_SCHAR:
|
||||
case T_UCHAR:
|
||||
return SIZEOF_CHAR;
|
||||
@ -404,7 +410,6 @@ unsigned SizeOf (const Type* T)
|
||||
return SIZEOF_INT;
|
||||
|
||||
case T_PTR:
|
||||
case T_FUNC: /* Maybe pointer to function */
|
||||
return SIZEOF_PTR;
|
||||
|
||||
case T_LONG:
|
||||
|
@ -50,6 +50,7 @@
|
||||
/* Generator attributes */
|
||||
#define GEN_NOPUSH 0x01 /* Don't push lhs */
|
||||
#define GEN_COMM 0x02 /* Operator is commutative */
|
||||
#define GEN_NOFUNC 0x04 /* Not allowed for function pointers */
|
||||
|
||||
/* Map a generator function and its attributes to a token */
|
||||
typedef struct {
|
||||
@ -2042,6 +2043,11 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
|
||||
Tok = CurTok.Tok;
|
||||
NextToken ();
|
||||
|
||||
/* If lhs is a function, convert it to pointer to function */
|
||||
if (IsTypeFunc (Expr->Type)) {
|
||||
Expr->Type = PointerTo (Expr->Type);
|
||||
}
|
||||
|
||||
/* Get the lhs on stack */
|
||||
GetCodePos (&Mark1);
|
||||
ltype = TypeOf (Expr->Type);
|
||||
@ -2059,6 +2065,11 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
|
||||
/* Get the right hand side */
|
||||
MarkedExprWithCheck (hienext, &Expr2);
|
||||
|
||||
/* If rhs is a function, convert it to pointer to function */
|
||||
if (IsTypeFunc (Expr2.Type)) {
|
||||
Expr2.Type = PointerTo (Expr2.Type);
|
||||
}
|
||||
|
||||
/* Check for a constant expression */
|
||||
rconst = (ED_IsConstAbs (&Expr2) && ED_CodeRangeIsEmpty (&Expr2));
|
||||
if (!rconst) {
|
||||
@ -2066,6 +2077,22 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
|
||||
LoadExpr (CF_NONE, &Expr2);
|
||||
}
|
||||
|
||||
/* Some operations aren't allowed on function pointers */
|
||||
if ((Gen->Flags & GEN_NOFUNC) != 0) {
|
||||
/* Output only one message even if both sides are wrong */
|
||||
if (IsTypeFuncPtr (Expr->Type)) {
|
||||
Error ("Invalid left operand for relational operator");
|
||||
/* Avoid further errors */
|
||||
ED_MakeConstAbsInt (Expr, 0);
|
||||
ED_MakeConstAbsInt (&Expr2, 0);
|
||||
} else if (IsTypeFuncPtr (Expr2.Type)) {
|
||||
Error ("Invalid right operand for relational operator");
|
||||
/* Avoid further errors */
|
||||
ED_MakeConstAbsInt (Expr, 0);
|
||||
ED_MakeConstAbsInt (&Expr2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure, the types are compatible */
|
||||
if (IsClassInt (Expr->Type)) {
|
||||
if (!IsClassInt (Expr2.Type) && !(IsClassPtr(Expr2.Type) && ED_IsNullPtr(Expr))) {
|
||||
@ -2600,6 +2627,13 @@ static void parsesub (ExprDesc* Expr)
|
||||
int rscale; /* Scale factor for the result */
|
||||
|
||||
|
||||
/* lhs cannot be function or pointer to function */
|
||||
if (IsTypeFunc (Expr->Type) || IsTypeFuncPtr (Expr->Type)) {
|
||||
Error ("Invalid left operand for binary operator `-'");
|
||||
/* Make it pointer to char to avoid further errors */
|
||||
Expr->Type = type_uchar;
|
||||
}
|
||||
|
||||
/* Skip the MINUS token */
|
||||
NextToken ();
|
||||
|
||||
@ -2616,6 +2650,13 @@ static void parsesub (ExprDesc* Expr)
|
||||
/* Parse the right hand side */
|
||||
MarkedExprWithCheck (hie9, &Expr2);
|
||||
|
||||
/* rhs cannot be function or pointer to function */
|
||||
if (IsTypeFunc (Expr2.Type) || IsTypeFuncPtr (Expr2.Type)) {
|
||||
Error ("Invalid right operand for binary operator `-'");
|
||||
/* Make it pointer to char to avoid further errors */
|
||||
Expr2.Type = type_uchar;
|
||||
}
|
||||
|
||||
/* Check for a constant rhs expression */
|
||||
if (ED_IsConstAbs (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)) {
|
||||
|
||||
@ -2775,10 +2816,10 @@ static void hie6 (ExprDesc* Expr)
|
||||
/* Handle greater-than type comparators */
|
||||
{
|
||||
static const GenDesc hie6_ops [] = {
|
||||
{ TOK_LT, GEN_NOPUSH, g_lt },
|
||||
{ TOK_LE, GEN_NOPUSH, g_le },
|
||||
{ TOK_GE, GEN_NOPUSH, g_ge },
|
||||
{ TOK_GT, GEN_NOPUSH, g_gt },
|
||||
{ TOK_LT, GEN_NOPUSH | GEN_NOFUNC, g_lt },
|
||||
{ TOK_LE, GEN_NOPUSH | GEN_NOFUNC, g_le },
|
||||
{ TOK_GE, GEN_NOPUSH | GEN_NOFUNC, g_ge },
|
||||
{ TOK_GT, GEN_NOPUSH | GEN_NOFUNC, g_gt },
|
||||
{ TOK_INVALID, 0, 0 }
|
||||
};
|
||||
hie_compare (hie6_ops, Expr, ShiftExpr);
|
||||
|
38
test/val/cc65150311.c
Normal file
38
test/val/cc65150311.c
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
!!DESCRIPTION!! function pointer bugs
|
||||
!!ORIGIN!! testsuite
|
||||
!!LICENCE!! Public Domain
|
||||
!!AUTHOR!! Greg
|
||||
*/
|
||||
|
||||
/*
|
||||
see: http://www.cc65.org/mailarchive/2015-03/11726.html
|
||||
and: http://www.cc65.org/mailarchive/2015-03/11734.html
|
||||
*/
|
||||
|
||||
static int func(void) {return 0;}
|
||||
static int (*p)(void);
|
||||
static int n;
|
||||
|
||||
int main(void) {
|
||||
|
||||
p = func;
|
||||
n = (p == &func);
|
||||
n = (p == func);
|
||||
|
||||
/* the following are not valid C and should go into seperate tests that MUST fail */
|
||||
/*
|
||||
++p;
|
||||
n = (p > &func);
|
||||
n = (p > func);
|
||||
n = func - func;
|
||||
n = func - &func;
|
||||
n = &func - func;
|
||||
n = &func - &func;
|
||||
n = p - &func;
|
||||
n = p - func;
|
||||
n = &func - p;
|
||||
n = func - p;
|
||||
*/
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user