]> git.sur5r.net Git - cc65/commitdiff
Merge branch 'pointer' of https://github.com/mrdudz/cc65 into mrdudz-pointer
authorOliver Schmidt <ol.sc@web.de>
Wed, 15 Jul 2015 10:04:06 +0000 (12:04 +0200)
committerOliver Schmidt <ol.sc@web.de>
Wed, 15 Jul 2015 10:24:09 +0000 (12:24 +0200)
1  2 
src/cc65/expr.c

diff --combined src/cc65/expr.c
index 7563645ff0e9bf6e28da7a8c12bcd6fb049ff06e,b82dff10d0a1f09235295005287a2f39db746449..64fc17e3f2833018b1c1b9d12a340bb0f956986b
@@@ -50,6 -50,7 +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 +2043,11 @@@ static void hie_compare (const GenDesc
          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);
          /* 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) {
              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 +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 ();
  
      /* 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,11 -2816,11 +2816,11 @@@ 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_INVALID,  0,              0       }
+         { 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       }
++        { TOK_INVALID,  0,                           0       }
      };
      hie_compare (hie6_ops, Expr, ShiftExpr);
  }