fixed a regression bug, although it doesn't fix the regression
[fw/sdcc] / src / SDCCicode.c
index 3731ecb730d7e8fecdb8df2d78a154edf9a1e01a..62b3a119b11e94d8141a84a725a0f57bac9940f2 100644 (file)
@@ -40,6 +40,13 @@ int scopeLevel;
 
 symbol *returnLabel;           /* function return label */
 symbol *entryLabel;            /* function entry  label */
+
+#if defined(__BORLANDC__) || defined(_MSC_VER)
+#define LONG_LONG __int64
+#else
+#define LONG_LONG long long
+#endif
+
 /*-----------------------------------------------------------------*/
 /* forward definition of some functions */
 operand *geniCodeDivision (operand *, operand *);
@@ -48,6 +55,7 @@ operand *geniCodeArray (operand *, operand *,int);
 operand *geniCodeArray2Ptr (operand *);
 operand *geniCodeRValue (operand *, bool);
 operand *geniCodeDerefPtr (operand *,int);
+int isLvaluereq(int lvl);
 
 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
 /* forward definition of ic print functions */
@@ -108,9 +116,73 @@ 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) {
+  LONG_LONG max = (LONG_LONG) 1 << bitsForType(ltype);
+  char message[132]="";
+  int warnings=0;
+  int negative=0;
+  long v;
+
+  if (SPEC_LONG(val->type)) {
+    v=SPEC_CVAL(val->type).v_long;
+  } 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                   */
@@ -145,12 +217,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, "{");
@@ -434,7 +506,7 @@ newOperand ()
 {
   operand *op;
 
-  op = Safe_calloc (1, sizeof (operand));
+  op = Safe_alloc ( sizeof (operand));
 
   op->key = 0;
   return op;
@@ -448,7 +520,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;
@@ -472,6 +544,10 @@ newiCodeCondition (operand * condition,
 {
   iCode *ic;
 
+  if (IS_VOID(OP_SYMBOL(condition)->type)) {
+    werror(E_VOID_VALUE_USED);
+  }
+
   ic = newiCode (IFX, NULL, NULL);
   IC_COND (ic) = condition;
   IC_TRUE (ic) = trueLabel;
@@ -538,7 +614,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;
 }
 
@@ -556,7 +632,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;
 }
 
@@ -609,6 +685,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));
@@ -838,11 +918,15 @@ operand *
 operandOperation (operand * left, operand * right,
                  int op, sym_link * type)
 {
+  sym_link *let , *ret=NULL;
   operand *retval = (operand *) 0;
-
+  
   assert (isOperandLiteral (left));
-  if (right)
+  let = getSpec(operandType(left));
+  if (right) {
     assert (isOperandLiteral (right));
+    ret = getSpec(operandType(left));
+  }
 
   switch (op)
     {
@@ -874,22 +958,34 @@ operandOperation (operand * left, operand * right,
                                                   operandLitValue (right)));
       break;
     case '%':
-      if ((unsigned long) operandLitValue (right) == 0)
-       {
+      if ((unsigned long) operandLitValue (right) == 0) {
          werror (E_DIVIDE_BY_ZERO);
          retval = right;
-       }
-      else
-       retval = operandFromLit ((unsigned long) operandLitValue (left) %
-                                (unsigned long) operandLitValue (right));
+      }
+      else 
+       retval = operandFromLit ((SPEC_USIGN(let) ? 
+                                 (unsigned long) operandLitValue (left) :
+                                 (long) operandLitValue (left)) %
+                                (SPEC_USIGN(ret) ? 
+                                 (unsigned long) operandLitValue (right) :
+                                 (long) operandLitValue (right)));
+
       break;
     case LEFT_OP:
-      retval = operandFromLit ((unsigned long) operandLitValue (left) <<
-                              (unsigned long) operandLitValue (right));
+      retval = operandFromLit ((SPEC_USIGN(let) ? 
+                                 (unsigned long) operandLitValue (left) :
+                                 (long) operandLitValue (left)) <<
+                                (SPEC_USIGN(ret) ? 
+                                 (unsigned long) operandLitValue (right) :
+                                 (long) operandLitValue (right)));
       break;
     case RIGHT_OP:
-      retval = operandFromLit ((unsigned long) operandLitValue (left) >>
-                              (unsigned long) operandLitValue (right));
+      retval = operandFromLit ((SPEC_USIGN(let) ? 
+                                 (unsigned long) operandLitValue (left) :
+                                 (long) operandLitValue (left)) >>
+                                (SPEC_USIGN(ret) ? 
+                                 (unsigned long) operandLitValue (right) :
+                                 (long) operandLitValue (right)));
       break;
     case EQ_OP:
       retval = operandFromLit (operandLitValue (left) ==
@@ -916,16 +1012,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) &&
@@ -937,7 +1033,7 @@ operandOperation (operand * left, operand * right,
       break;
     case RRC:
       {
-       long i = operandLitValue (left);
+       long i = (long) operandLitValue (left);
 
        retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
                                 (i << 1));
@@ -945,7 +1041,7 @@ operandOperation (operand * left, operand * right,
       break;
     case RLC:
       {
-       long i = operandLitValue (left);
+       long i = (long) operandLitValue (left);
 
        retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
                                 (i >> 1));
@@ -1004,7 +1100,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;
     }
@@ -1012,9 +1108,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)
 {
@@ -1048,6 +1144,7 @@ isiCodeEqual (iCode * left, iCode * right)
          if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
            return 0;
        }
+      
       return 1;
     }
   return 0;
@@ -1072,7 +1169,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;
@@ -1095,7 +1191,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;
 
@@ -1165,7 +1260,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;
 
@@ -1277,7 +1374,7 @@ operandFromLink (sym_link * type)
 /* operandFromLit - makes an operand from a literal value          */
 /*-----------------------------------------------------------------*/
 operand *
-operandFromLit (float i)
+operandFromLit (double i)
 {
   return operandFromValue (valueFromLit (i));
 }
@@ -1390,7 +1487,7 @@ usualUnaryConversions (operand * op)
 {
   if (IS_INTEGRAL (operandType (op)))
     {
-      if (getSize (operandType (op)) < INTSIZE)
+      if (getSize (operandType (op)) < (unsigned int) INTSIZE)
        {
          /* Widen to int. */
          return geniCodeCast (INTTYPE, op, TRUE);
@@ -1450,7 +1547,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;
@@ -1487,6 +1586,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))
@@ -1496,7 +1596,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 */
@@ -1504,20 +1604,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) &&
@@ -1606,7 +1755,6 @@ geniCodeMultiply (operand * left, operand * right,int resultIsInt)
   if (resultIsInt)
     {
       SPEC_NOUN(getSpec(resType))=V_INT;
-      SPEC_SHORT(getSpec(resType))=0;
     }
 
   /* if the right is a literal & power of 2 */
@@ -1616,7 +1764,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)))
        {
@@ -1661,8 +1809,9 @@ geniCodeDivision (operand * left, operand * right)
   if (IS_LITERAL (retype) &&
       !IS_FLOAT (letype) &&
       (p2 = powof2 ((unsigned long)
-                   floatFromVal (right->operand.valOperand))))
-    ic = newiCode (RIGHT_OP, left, operandFromLit (p2));       /* right shift */
+                   floatFromVal (right->operand.valOperand)))) {
+    ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
+  }
   else
     {
       ic = newiCode ('/', left, right);                /* normal division */
@@ -2004,10 +2153,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);
 
@@ -2079,15 +2228,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);
 
@@ -2123,7 +2272,7 @@ geniCodePreDec (operand * op)
 
   if (!op->isaddr)
     {
-      werror (E_LVALUE_REQUIRED, "++");
+      werror (E_LVALUE_REQUIRED, "--");
       return op;
     }
 
@@ -2353,12 +2502,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                                       */
 /*-----------------------------------------------------------------*/
@@ -2372,13 +2515,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 = 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);
@@ -2470,11 +2610,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 = 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 */
@@ -2484,12 +2621,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
@@ -2637,6 +2774,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 */
@@ -2689,7 +2832,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
@@ -2992,6 +3136,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   */
@@ -3009,7 +3174,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);
@@ -3022,7 +3187,7 @@ void delLvaluereq()
 {
   lvalItem * lpItem;
   lpItem = getSet(&lvaluereqSet);
-  if(lpItem) free(lpItem);
+  if(lpItem) Safe_free(lpItem);
 }
 /*-----------------------------------------------------------------*/
 /* clearLvaluereq - clear lvalreq flag                            */
@@ -3141,8 +3306,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);
       }
 
@@ -3269,7 +3435,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);
@@ -3301,7 +3467,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);
@@ -3317,7 +3483,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);
          }
@@ -3400,6 +3566,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;