]> git.sur5r.net Git - cc65/commitdiff
patch from Uz that makes some illegal operations on pointers error out
authormrdudz <mrdudz@users.noreply.github.com>
Fri, 10 Jul 2015 12:27:49 +0000 (14:27 +0200)
committermrdudz <mrdudz@users.noreply.github.com>
Fri, 10 Jul 2015 12:27:49 +0000 (14:27 +0200)
src/cc65/datatype.c
src/cc65/expr.c
test/val/cc65150311.c [new file with mode: 0644]

index 9971a9569e457f76335fae2a846fd5826e6965a4..8c9d6dcb00d6feb81cf12b7b2cc28316d7023c8f 100644 (file)
@@ -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:
index 7563645ff0e9bf6e28da7a8c12bcd6fb049ff06e..b82dff10d0a1f09235295005287a2f39db746449 100644 (file)
@@ -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 (file)
index 0000000..cd644f4
--- /dev/null
@@ -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;
+}