small fix
[fw/sdcc] / src / SDCCicode.c
index 02482ec773f07b88bfb9e92d25b27757063fe448..a7439f0c3c8ac57c073f0e953b057195b26577fd 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "common.h"
 #include "newalloc.h"
+#include "math.h"
 
 /*-----------------------------------------------------------------*/
 /* global variables       */
@@ -40,6 +41,7 @@ int scopeLevel;
 
 symbol *returnLabel;           /* function return label */
 symbol *entryLabel;            /* function entry  label */
+
 /*-----------------------------------------------------------------*/
 /* forward definition of some functions */
 operand *geniCodeDivision (operand *, operand *);
@@ -109,9 +111,83 @@ iCodeTable codeTable[] =
   {IFX, "if", picIfx, NULL},
   {INLINEASM, "", picInline, NULL},
   {RECEIVE, "recv", picReceive, NULL},
-  {SEND, "send", picGenericOne, NULL}
+  {SEND, "send", picGenericOne, NULL},
+  {ARRAYINIT, "arrayInit", picGenericOne, NULL},
 };
 
+/*-----------------------------------------------------------------*/
+/* checkConstantRange: check a constant against the type           */
+/*-----------------------------------------------------------------*/
+
+/*   pedantic=0: allmost anything is allowed as long as the absolute
+       value is within the bit range of the type, and -1 is treated as
+       0xf..f for unsigned types (e.g. in assign)
+     pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
+     pedantic>1: "char c=200" is not allowed (evaluates to -56)
+*/
+
+void checkConstantRange(sym_link *ltype, value *val, char *msg, int pedantic) {
+  double max;
+  char message[132]="";
+  int warnings=0;
+  int negative=0;
+  long v;
+
+  max = pow ((double)2.0, (double)bitsForType(ltype));
+
+  if (SPEC_LONG(val->type)) {
+    if (SPEC_USIGN(val->type)) {
+      v=SPEC_CVAL(val->type).v_ulong;
+    } else {
+      v=SPEC_CVAL(val->type).v_long;
+    }
+  } else {
+    if (SPEC_USIGN(val->type)) {
+      v=SPEC_CVAL(val->type).v_uint;
+    } else {
+      v=SPEC_CVAL(val->type).v_int;
+    }
+  }
+
+
+#if 0
+  // this could be a good idea
+  if (options.pedantic)
+    pedantic=2;
+#endif
+
+  if (SPEC_NOUN(ltype)==FLOAT) {
+    // anything will do
+    return;
+  }
+
+  if (!SPEC_USIGN(val->type) && v<0) {
+    negative=1;
+    if (SPEC_USIGN(ltype) && (pedantic>1)) {
+      warnings++;
+    }
+    v=-v;
+  }
+
+  // if very pedantic: "char c=200" is not allowed
+  if (pedantic>1 && !SPEC_USIGN(ltype)) {
+    max = max/2 + negative;
+  }
+
+  if (v >= max) {
+    warnings++;
+  }
+
+  if (warnings) {
+    sprintf (message, "for %s %s in %s", 
+            SPEC_USIGN(ltype) ? "unsigned" : "signed",
+            nounName(ltype), msg);
+    werror (W_CONST_RANGE, message);
+
+    if (pedantic>1)
+      fatalError++;
+  }
+}
 
 /*-----------------------------------------------------------------*/
 /* operandName - returns the name of the operand                   */
@@ -146,12 +222,12 @@ printOperand (operand * op, FILE * file)
     case SYMBOL:
 #define REGA 1
 #ifdef REGA
-      fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d}",                /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}"  , */
+      fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d}",          /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}"  , */
               (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
               op->key,
               OP_LIVEFROM (op), OP_LIVETO (op),
               OP_SYMBOL (op)->stack,
-              op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat
+              op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc
        );
       {
        fprintf (file, "{");
@@ -435,7 +511,7 @@ newOperand ()
 {
   operand *op;
 
-  op = Safe_calloc (1, sizeof (operand));
+  op = Safe_alloc ( sizeof (operand));
 
   op->key = 0;
   return op;
@@ -449,7 +525,7 @@ newiCode (int op, operand * left, operand * right)
 {
   iCode *ic;
 
-  ic = Safe_calloc (1, sizeof (iCode));
+  ic = Safe_alloc ( sizeof (iCode));
 
   ic->lineno = lineno;
   ic->filename = filename;
@@ -473,6 +549,10 @@ newiCodeCondition (operand * condition,
 {
   iCode *ic;
 
+  if (IS_VOID(operandType(condition))) {
+    werror(E_VOID_VALUE_USED);
+  }
+
   ic = newiCode (IFX, NULL, NULL);
   IC_COND (ic) = condition;
   IC_TRUE (ic) = trueLabel;
@@ -539,7 +619,7 @@ newiTempLabel (char *s)
   itmplbl->isitmp = 1;
   itmplbl->islbl = 1;
   itmplbl->key = labelKey++;
-  addSym (LabelTab, itmplbl, itmplbl->name, 0, 0);
+  addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
   return itmplbl;
 }
 
@@ -557,7 +637,7 @@ newiTempPreheaderLabel ()
   itmplbl->isitmp = 1;
   itmplbl->islbl = 1;
   itmplbl->key = labelKey++;
-  addSym (LabelTab, itmplbl, itmplbl->name, 0, 0);
+  addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
   return itmplbl;
 }
 
@@ -610,6 +690,10 @@ copyiCode (iCode * ic)
       IC_INLINE (nic) = IC_INLINE (ic);
       break;
 
+    case ARRAYINIT:
+      IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
+      break;
+
     default:
       IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
       IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
@@ -893,20 +977,20 @@ operandOperation (operand * left, operand * right,
 
       break;
     case LEFT_OP:
-      retval = operandFromLit (((SPEC_USIGN(let) ? 
+      retval = operandFromLit ((SPEC_USIGN(let) ? 
                                  (unsigned long) operandLitValue (left) :
                                  (long) operandLitValue (left)) <<
                                 (SPEC_USIGN(ret) ? 
                                  (unsigned long) operandLitValue (right) :
-                                 (long) operandLitValue (right))));
+                                 (long) operandLitValue (right)));
       break;
     case RIGHT_OP:
-      retval = operandFromLit (((SPEC_USIGN(let) ? 
+      retval = operandFromLit ((SPEC_USIGN(let) ? 
                                  (unsigned long) operandLitValue (left) :
                                  (long) operandLitValue (left)) >>
                                 (SPEC_USIGN(ret) ? 
                                  (unsigned long) operandLitValue (right) :
-                                 (long) operandLitValue (right))));
+                                 (long) operandLitValue (right)));
       break;
     case EQ_OP:
       retval = operandFromLit (operandLitValue (left) ==
@@ -933,16 +1017,16 @@ operandOperation (operand * left, operand * right,
                               operandLitValue (right));
       break;
     case BITWISEAND:
-      retval = operandFromLit ((unsigned long) operandLitValue (left) &
-                              (unsigned long) operandLitValue (right));
+      retval = operandFromLit ((long)operandLitValue(left) & 
+                              (long)operandLitValue(right));
       break;
     case '|':
-      retval = operandFromLit ((unsigned long) operandLitValue (left) |
-                              (unsigned long) operandLitValue (right));
+      retval = operandFromLit ((long)operandLitValue (left) |
+                              (long)operandLitValue (right));
       break;
     case '^':
-      retval = operandFromLit ((unsigned long) operandLitValue (left) ^
-                              (unsigned long) operandLitValue (right));
+      retval = operandFromLit ((long)operandLitValue (left) ^
+                              (long)operandLitValue (right));
       break;
     case AND_OP:
       retval = operandFromLit (operandLitValue (left) &&
@@ -1021,7 +1105,7 @@ isOperandEqual (operand * left, operand * right)
       return (floatFromVal (left->operand.valOperand) ==
              floatFromVal (right->operand.valOperand));
     case TYPE:
-      if (checkType (left->operand.typeOperand,
+      if (compareType (left->operand.typeOperand,
                     right->operand.typeOperand) == 1)
        return 1;
     }
@@ -1029,9 +1113,9 @@ isOperandEqual (operand * left, operand * right)
   return 0;
 }
 
-/*-----------------------------------------------------------------*/
-/* isiCodeEqual - comapres two iCodes are returns true if yes      */
-/*-----------------------------------------------------------------*/
+/*-------------------------------------------------------------------*/
+/* isiCodeEqual - compares two iCodes are equal, returns true if yes */
+/*-------------------------------------------------------------------*/
 int 
 isiCodeEqual (iCode * left, iCode * right)
 {
@@ -1065,6 +1149,7 @@ isiCodeEqual (iCode * left, iCode * right)
          if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
            return 0;
        }
+      
       return 1;
     }
   return 0;
@@ -1089,7 +1174,6 @@ newiTempFromOp (operand * op)
   nop->isvolatile = op->isvolatile;
   nop->isGlobal = op->isGlobal;
   nop->isLiteral = op->isLiteral;
-  nop->noSpilLoc = op->noSpilLoc;
   nop->usesDefs = op->usesDefs;
   nop->isParm = op->isParm;
   return nop;
@@ -1112,7 +1196,6 @@ operandFromOperand (operand * op)
   nop->isvolatile = op->isvolatile;
   nop->isGlobal = op->isGlobal;
   nop->isLiteral = op->isLiteral;
-  nop->noSpilLoc = op->noSpilLoc;
   nop->usesDefs = op->usesDefs;
   nop->isParm = op->isParm;
 
@@ -1182,7 +1265,9 @@ operandFromSymbol (symbol * sym)
   /* under the following conditions create a
      register equivalent for a local symbol */
   if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
-      (IN_FARSPACE (SPEC_OCLS (sym->etype)) && (!TARGET_IS_DS390)) &&
+      (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
+      /* (!TARGET_IS_DS390)) && */
+      (!(options.model == MODEL_FLAT24)) ) &&
       options.stackAuto == 0)
     ok = 0;
 
@@ -1467,7 +1552,9 @@ geniCodeRValue (operand * op, bool force)
 
   if (IS_SPEC (type) &&
       IS_TRUE_SYMOP (op) &&
-      (!IN_FARSPACE (SPEC_OCLS (etype)) || TARGET_IS_DS390))
+      (!IN_FARSPACE (SPEC_OCLS (etype)) ||
+      /* TARGET_IS_DS390)) */
+      (options.model == MODEL_FLAT24) ))
     {
       op = operandFromOperand (op);
       op->isaddr = 0;
@@ -1504,6 +1591,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit)
   sym_link *optype;
   sym_link *opetype = getSpec (optype = operandType (op));
   sym_link *restype;
+  int errors=0;
 
   /* one of them has size zero then error */
   if (IS_VOID (optype))
@@ -1513,7 +1601,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit)
     }
 
   /* if the operand is already the desired type then do nothing */
-  if (checkType (type, optype) == 1)
+  if (compareType (type, optype) == 1)
     return op;
 
   /* if this is a literal then just change the type & return */
@@ -1521,20 +1609,69 @@ geniCodeCast (sym_link * type, operand * op, bool implicit)
     return operandFromValue (valCastLiteral (type,
                                             operandLitValue (op)));
 
-  /* if casting to some pointer type &&
-     the destination is not a generic pointer
-     then give a warning : (only for implicit casts) */
-  if (IS_PTR (optype) && implicit &&
-      (DCL_TYPE (optype) != DCL_TYPE (type)) &&
-      !IS_GENPTR (type))
-    {
-      werror (E_INCOMPAT_CAST);
-      werror (E_CONTINUE, "from type '");
-      printTypeChain (optype, stderr);
-      fprintf (stderr, "' to type '");
-      printTypeChain (type, stderr);
-      fprintf (stderr, "'\n");
+  /* if casting to/from pointers, do some checking */
+  if (IS_PTR(type)) { // to a pointer
+    if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
+      if (IS_INTEGRAL(optype)) { 
+       // maybe this is NULL, than it's ok.
+       if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
+         if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
+           // no way to set the storage
+           if (IS_LITERAL(optype)) {
+             werror(E_LITERAL_GENERIC);
+             errors++;
+           } else {
+             werror(E_NONPTR2_GENPTR);
+             errors++;
+           }
+         } else if (implicit) {
+           werror(W_INTEGRAL2PTR_NOCAST);
+           errors++;
+         }
+       }
+      }        else { 
+       // shouldn't do that with float, array or structure unless to void
+       if (!IS_VOID(getSpec(type)) && 
+           !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
+         werror(E_INCOMPAT_TYPES);
+         errors++;
+       }
+      }
+    } else { // from a pointer to a pointer
+      if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
+       // if not a pointer to a function
+       if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
+         if (implicit) { // if not to generic, they have to match 
+           if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
+             werror(E_INCOMPAT_PTYPES);
+             errors++;
+           }
+         }
+       }
+      }
     }
+  } else { // to a non pointer
+    if (IS_PTR(optype)) { // from a pointer
+      if (implicit) { // sneaky
+       if (IS_INTEGRAL(type)) {
+         werror(W_PTR2INTEGRAL_NOCAST);
+         errors++;
+       } else { // shouldn't do that with float, array or structure
+         werror(E_INCOMPAT_TYPES);
+         errors++;
+       }
+      }
+    }
+  }
+  if (errors) {
+    /* fprintf (stderr, "%s%s %d: ", op->operand.symOperand->name,
+       implicit?"(implicit)":"", errors); */
+    fprintf (stderr, "from type '");
+    printTypeChain (optype, stderr);
+    fprintf (stderr, "' to type '");
+    printTypeChain (type, stderr);
+    fprintf (stderr, "'\n");
+  }
 
   /* if they are the same size create an assignment */
   if (getSize (type) == getSize (optype) &&
@@ -1632,7 +1769,7 @@ geniCodeMultiply (operand * left, operand * right,int resultIsInt)
      if port has 1 byte muldiv */
   if (p2 && !IS_FLOAT (letype) &&
       !((resultIsInt) && (getSize (resType) != getSize (ltype)) && 
-       (port->muldiv.native_below == 1)))
+       (port->support.muldiv == 1)))
     {
       if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
        {
@@ -2021,10 +2158,10 @@ geniCodePostInc (operand * op)
     }
 
   rOp = newiTempOperand (rvtype, 0);
-  rOp->noSpilLoc = 1;
+  OP_SYMBOL(rOp)->noSpilLoc = 1;
 
   if (IS_ITEMP (rv))
-    rv->noSpilLoc = 1;
+    OP_SYMBOL(rv)->noSpilLoc = 1;
 
   geniCodeAssign (rOp, rv, 0);
 
@@ -2096,15 +2233,15 @@ geniCodePostDec (operand * op)
   /* if this is not an address we have trouble */
   if (!op->isaddr)
     {
-      werror (E_LVALUE_REQUIRED, "++");
+      werror (E_LVALUE_REQUIRED, "--");
       return op;
     }
 
   rOp = newiTempOperand (rvtype, 0);
-  rOp->noSpilLoc = 1;
+  OP_SYMBOL(rOp)->noSpilLoc = 1;
 
   if (IS_ITEMP (rv))
-    rv->noSpilLoc = 1;
+    OP_SYMBOL(rv)->noSpilLoc = 1;
 
   geniCodeAssign (rOp, rv, 0);
 
@@ -2140,7 +2277,7 @@ geniCodePreDec (operand * op)
 
   if (!op->isaddr)
     {
-      werror (E_LVALUE_REQUIRED, "++");
+      werror (E_LVALUE_REQUIRED, "--");
       return op;
     }
 
@@ -2370,12 +2507,6 @@ geniCodeRightShift (operand * left, operand * right)
   return IC_RESULT (ic);
 }
 
-#if defined(__BORLANDC__) || defined(_MSC_VER)
-#define LONG_LONG __int64
-#else
-#define LONG_LONG long long
-#endif
-
 /*-----------------------------------------------------------------*/
 /* geniCodeLogic- logic code                                       */
 /*-----------------------------------------------------------------*/
@@ -2389,13 +2520,10 @@ geniCodeLogic (operand * left, operand * right, int op)
 
   /* left is integral type and right is literal then
      check if the literal value is within bounds */
-  if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype))
+  if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
     {
-      int nbits = bitsForType (ltype);
-      long v = (long) operandLitValue (right);
-
-      if (v > ((LONG_LONG) 1 << nbits) && v > 0)
-       werror (W_CONST_RANGE, " compare operation ");
+      checkConstantRange(ltype, 
+                        OP_VALUE(right), "compare operation", 1);
     }
 
   ctype = usualBinaryConversions (&left, &right);
@@ -2487,11 +2615,8 @@ geniCodeAssign (operand * left, operand * right, int nosupdate)
      check if the literal value is within bounds */
   if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
     {
-      int nbits = bitsForType (ltype);
-      long v = (long) operandLitValue (right);
-
-      if (v > ((LONG_LONG) 1 << nbits) && v > 0)
-       werror (W_CONST_RANGE, " = operation");
+      checkConstantRange(ltype, 
+                        OP_VALUE(right), "= operation", 0);
     }
 
   /* if the left & right type don't exactly match */
@@ -2501,12 +2626,12 @@ geniCodeAssign (operand * left, operand * right, int nosupdate)
 
   /* first check the type for pointer assignement */
   if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
-      checkType (ltype, rtype) < 0)
+      compareType (ltype, rtype) < 0)
     {
-      if (checkType (ltype->next, rtype) < 0)
+      if (compareType (ltype->next, rtype) < 0)
        right = geniCodeCast (ltype->next, right, TRUE);
     }
-  else if (checkType (ltype, rtype) < 0)
+  else if (compareType (ltype, rtype) < 0)
     right = geniCodeCast (ltype, right, TRUE);
 
   /* if left is a true symbol & ! volatile
@@ -2654,6 +2779,12 @@ geniCodeCall (operand * left, ast * parms,int lvl)
   sym_link *type, *etype;
   int stack = 0;
 
+  if (!IS_FUNC(OP_SYMBOL(left)->type) && 
+      !IS_CODEPTR(OP_SYMBOL(left)->type)) {
+    werror (E_FUNCTION_EXPECTED);
+    return NULL;
+  }
+
   /* take care of parameters with side-effecting
      function calls in them, this is required to take care
      of overlaying function parameters */
@@ -2706,7 +2837,8 @@ geniCodeReceive (value * args)
 
              if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
                  options.stackAuto == 0 &&
-                 !TARGET_IS_DS390)
+                 /* !TARGET_IS_DS390) */
+                 (!(options.model == MODEL_FLAT24)) )
                {
                }
              else
@@ -3009,6 +3141,27 @@ geniCodeInline (ast * tree)
   ADDTOCHAIN (ic);
 }
 
+/*-----------------------------------------------------------------*/
+/* geniCodeArrayInit - intermediate code for array initializer     */
+/*-----------------------------------------------------------------*/
+static void 
+geniCodeArrayInit (ast * tree, operand *array)
+{
+  iCode *ic;
+
+  if (!getenv("TRY_THE_NEW_INITIALIZER")) {
+    ic = newiCode (ARRAYINIT, array, NULL);
+    IC_ARRAYILIST (ic) = tree->values.constlist;
+  } else {
+    operand *left=newOperand(), *right=newOperand();
+    left->type=right->type=SYMBOL;
+    OP_SYMBOL(left)=AST_SYMBOL(tree->left);
+    OP_SYMBOL(right)=AST_SYMBOL(tree->right);
+    ic = newiCode (ARRAYINIT, left, right);
+  }
+  ADDTOCHAIN (ic);
+}
+
 /*-----------------------------------------------------------------*/
 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some      */
 /* particular case. Ie : assigning or dereferencing array or ptr   */
@@ -3026,7 +3179,7 @@ lvalItem;
 /*-----------------------------------------------------------------*/
 void addLvaluereq(int lvl)
 {
-  lvalItem * lpItem = (lvalItem *)Safe_calloc (1, sizeof (lvalItem));
+  lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
   lpItem->req=1;
   lpItem->lvl=lvl;
   addSetHead(&lvaluereqSet,lpItem);
@@ -3039,7 +3192,7 @@ void delLvaluereq()
 {
   lvalItem * lpItem;
   lpItem = getSet(&lvaluereqSet);
-  if(lpItem) free(lpItem);
+  if(lpItem) Safe_free(lpItem);
 }
 /*-----------------------------------------------------------------*/
 /* clearLvaluereq - clear lvalreq flag                            */
@@ -3158,8 +3311,9 @@ ast2iCode (ast * tree,int lvl)
 
     case '[':                  /* array operation */
       {
-       sym_link *ltype = operandType (left);
-       left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
+       //sym_link *ltype = operandType (left);
+       //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
+       left = geniCodeRValue (left, FALSE);
        right = geniCodeRValue (right, TRUE);
       }
 
@@ -3286,7 +3440,7 @@ ast2iCode (ast * tree,int lvl)
        sym_link *rtype = operandType (right);
        sym_link *ltype = operandType (left);
        if (IS_PTR (rtype) && IS_ITEMP (right)
-           && right->isaddr && checkType (rtype->next, ltype) == 1)
+           && right->isaddr && compareType (rtype->next, ltype) == 1)
          right = geniCodeRValue (right, TRUE);
        else
          right = geniCodeRValue (right, FALSE);
@@ -3318,7 +3472,7 @@ ast2iCode (ast * tree,int lvl)
        sym_link *rtype = operandType (right);
        sym_link *ltype = operandType (left);
        if (IS_PTR (rtype) && IS_ITEMP (right)
-           && right->isaddr && checkType (rtype->next, ltype) == 1)
+           && right->isaddr && compareType (rtype->next, ltype) == 1)
          right = geniCodeRValue (right, TRUE);
        else
          right = geniCodeRValue (right, FALSE);
@@ -3334,7 +3488,7 @@ ast2iCode (ast * tree,int lvl)
        sym_link *rtype = operandType (right);
        sym_link *ltype = operandType (left);
        if (IS_PTR (rtype) && IS_ITEMP (right)
-           && right->isaddr && checkType (rtype->next, ltype) == 1)
+           && right->isaddr && compareType (rtype->next, ltype) == 1)
          {
            right = geniCodeRValue (right, TRUE);
          }
@@ -3417,6 +3571,10 @@ ast2iCode (ast * tree,int lvl)
     case INLINEASM:
       geniCodeInline (tree);
       return NULL;
+       
+    case ARRAYINIT:
+       geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
+       return NULL;
     }
 
   return NULL;