From 6ab197f364571f370604bb10b68e54dc5ecdd208 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Fri, 10 Jul 2015 14:27:49 +0200 Subject: [PATCH 1/2] patch from Uz that makes some illegal operations on pointers error out --- src/cc65/datatype.c | 7 ++++++- src/cc65/expr.c | 49 +++++++++++++++++++++++++++++++++++++++---- test/val/cc65150311.c | 38 +++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 5 deletions(-) create mode 100644 test/val/cc65150311.c diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index 9971a9569..8c9d6dcb0 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -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: diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 7563645ff..b82dff10d 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -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); diff --git a/test/val/cc65150311.c b/test/val/cc65150311.c new file mode 100644 index 000000000..cd644f491 --- /dev/null +++ b/test/val/cc65150311.c @@ -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; +} From 12a3e6841c258faa66c269007f92529e742e23e0 Mon Sep 17 00:00:00 2001 From: mrdudz Date: Fri, 10 Jul 2015 18:38:54 +0200 Subject: [PATCH 2/2] tests for illegal pointer operations that must always fail --- test/err/cc65150311-1.c | 26 ++++++++++++++++++++++++++ test/err/cc65150311-10.c | 26 ++++++++++++++++++++++++++ test/err/cc65150311-11.c | 26 ++++++++++++++++++++++++++ test/err/cc65150311-2.c | 26 ++++++++++++++++++++++++++ test/err/cc65150311-3.c | 26 ++++++++++++++++++++++++++ test/err/cc65150311-4.c | 26 ++++++++++++++++++++++++++ test/err/cc65150311-5.c | 26 ++++++++++++++++++++++++++ test/err/cc65150311-6.c | 26 ++++++++++++++++++++++++++ test/err/cc65150311-7.c | 26 ++++++++++++++++++++++++++ test/err/cc65150311-8.c | 26 ++++++++++++++++++++++++++ test/err/cc65150311-9.c | 26 ++++++++++++++++++++++++++ 11 files changed, 286 insertions(+) create mode 100644 test/err/cc65150311-1.c create mode 100644 test/err/cc65150311-10.c create mode 100644 test/err/cc65150311-11.c create mode 100644 test/err/cc65150311-2.c create mode 100644 test/err/cc65150311-3.c create mode 100644 test/err/cc65150311-4.c create mode 100644 test/err/cc65150311-5.c create mode 100644 test/err/cc65150311-6.c create mode 100644 test/err/cc65150311-7.c create mode 100644 test/err/cc65150311-8.c create mode 100644 test/err/cc65150311-9.c diff --git a/test/err/cc65150311-1.c b/test/err/cc65150311-1.c new file mode 100644 index 000000000..c4a836e39 --- /dev/null +++ b/test/err/cc65150311-1.c @@ -0,0 +1,26 @@ +/* + !!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); + + ++p; /* invalid C */ + + return 0; +} diff --git a/test/err/cc65150311-10.c b/test/err/cc65150311-10.c new file mode 100644 index 000000000..14e14d4fd --- /dev/null +++ b/test/err/cc65150311-10.c @@ -0,0 +1,26 @@ +/* + !!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); + + n = &func - p; /* invalid C */ + + return 0; +} diff --git a/test/err/cc65150311-11.c b/test/err/cc65150311-11.c new file mode 100644 index 000000000..ffc8c9a02 --- /dev/null +++ b/test/err/cc65150311-11.c @@ -0,0 +1,26 @@ +/* + !!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); + + n = func - p; /* invalid C */ + + return 0; +} diff --git a/test/err/cc65150311-2.c b/test/err/cc65150311-2.c new file mode 100644 index 000000000..34c862ad8 --- /dev/null +++ b/test/err/cc65150311-2.c @@ -0,0 +1,26 @@ +/* + !!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); + + n = (p > &func); /* invalid C */ + + return 0; +} diff --git a/test/err/cc65150311-3.c b/test/err/cc65150311-3.c new file mode 100644 index 000000000..2bf8267a5 --- /dev/null +++ b/test/err/cc65150311-3.c @@ -0,0 +1,26 @@ +/* + !!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); + + n = (p > func); /* invalid C */ + + return 0; +} diff --git a/test/err/cc65150311-4.c b/test/err/cc65150311-4.c new file mode 100644 index 000000000..0a7f44ec0 --- /dev/null +++ b/test/err/cc65150311-4.c @@ -0,0 +1,26 @@ +/* + !!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); + + n = func - func; /* invalid C */ + + return 0; +} diff --git a/test/err/cc65150311-5.c b/test/err/cc65150311-5.c new file mode 100644 index 000000000..41229ad67 --- /dev/null +++ b/test/err/cc65150311-5.c @@ -0,0 +1,26 @@ +/* + !!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); + + n = func - &func; /* invalid C */ + + return 0; +} diff --git a/test/err/cc65150311-6.c b/test/err/cc65150311-6.c new file mode 100644 index 000000000..a08ab11d3 --- /dev/null +++ b/test/err/cc65150311-6.c @@ -0,0 +1,26 @@ +/* + !!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); + + n = &func - func; /* invalid C */ + + return 0; +} diff --git a/test/err/cc65150311-7.c b/test/err/cc65150311-7.c new file mode 100644 index 000000000..71e6368f7 --- /dev/null +++ b/test/err/cc65150311-7.c @@ -0,0 +1,26 @@ +/* + !!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); + + n = &func - &func; /* invalid C */ + + return 0; +} diff --git a/test/err/cc65150311-8.c b/test/err/cc65150311-8.c new file mode 100644 index 000000000..d18dc0b2d --- /dev/null +++ b/test/err/cc65150311-8.c @@ -0,0 +1,26 @@ +/* + !!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); + + n = p - &func; /* invalid C */ + + return 0; +} diff --git a/test/err/cc65150311-9.c b/test/err/cc65150311-9.c new file mode 100644 index 000000000..8cf805b07 --- /dev/null +++ b/test/err/cc65150311-9.c @@ -0,0 +1,26 @@ +/* + !!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); + + n = p - func; /* invalid C */ + + return 0; +}