* src/SDCCglue.c, src/SDCCast.c:
[fw/sdcc] / src / SDCCglue.c
index 7aed6a580456f63c456c665ceb9af7c44a785d5a..be05fca1373580149fb34b4a4a9dc635895ccca1 100644 (file)
@@ -37,7 +37,7 @@
 
 symbol *interrupts[INTNO_MAX+1];
 
-void printIval (symbol *, sym_link *, initList *, struct dbuf_s *);
+void printIval (symbol *, sym_link *, initList *, struct dbuf_s *, bool check);
 set *publics = NULL;            /* public variables */
 set *externs = NULL;            /* Variables that are declared as extern */
 
@@ -276,7 +276,7 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                   ++noAlloc;
                   resolveIvalSym (sym->ival, sym->type);
                   ++noInit;
-                  printIval (sym, sym->type, sym->ival, &tmpBuf);
+                  printIval (sym, sym->type, sym->ival, &tmpBuf, TRUE);
                   --noInit;
                   --noAlloc;
                   dbuf_destroy(&tmpBuf);
@@ -647,6 +647,13 @@ printIvalType (symbol *sym, sym_link * type, initList * ilist, struct dbuf_s * o
     val = constCharVal (0);
   }
 
+  /* check if the literal value is within bounds */
+  if (checkConstantRange (type, val->etype, '=', FALSE) == CCR_OVL &&
+      !options.lessPedantic)
+    {
+      werror (W_LIT_OVERFLOW);
+    }
+
   if (val->type != type) {
     val = valCastLiteral(type, floatFromVal(val));
   }
@@ -696,41 +703,60 @@ void printIvalBitFields(symbol **sym, initList **ilist, struct dbuf_s * oBuf)
   symbol *lsym = *sym;
   initList *lilist = *ilist ;
   unsigned long ival = 0;
-  int size =0;
+  int size = 0;
 
+  do
+    {
+      unsigned long i;
+      val = list2val (lilist);
+      if (size)
+        {
+          if (SPEC_BLEN (lsym->etype) > 8)
+            {
+              size += ((SPEC_BLEN (lsym->etype) / 8) +
+                       (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
+            }
+        }
+      else
+        {
+          size = ((SPEC_BLEN (lsym->etype) / 8) +
+                  (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
+        }
 
-  do {
-    unsigned long i;
-    val = list2val(lilist);
-    if (size) {
-      if (SPEC_BLEN(lsym->etype) > 8) {
-        size += ((SPEC_BLEN (lsym->etype) / 8) +
-                 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
-      }
-    } else {
-      size = ((SPEC_BLEN (lsym->etype) / 8) +
-              (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
-    }
-    i = ulFromVal(val);
-    i <<= SPEC_BSTR (lsym->etype);
-    ival |= i;
-    if (! ( lsym->next &&
-          (IS_BITFIELD(lsym->next->type)) &&
-          (SPEC_BSTR(lsym->next->etype)))) break;
-    lsym = lsym->next;
-    lilist = lilist ? lilist->next : NULL;
-  } while (1);
-  switch (size) {
+      /* check if the literal value is within bounds */
+      if (val &&
+        checkConstantRange (lsym->etype, val->etype, '=', FALSE) == CCR_OVL &&
+        !options.lessPedantic)
+        {
+          werror (W_LIT_OVERFLOW);
+        }
+
+      i = ulFromVal (val);
+      i &= (1 << SPEC_BLEN (lsym->etype)) - 1;
+      i <<= SPEC_BSTR (lsym->etype);
+      ival |= i;
+      if (!(lsym->next &&
+        (IS_BITFIELD (lsym->next->type)) &&
+        (SPEC_BSTR (lsym->next->etype))))
+        break;
+      lsym = lsym->next;
+      lilist = lilist ? lilist->next : NULL;
+    }
+  while (1);
+
+  switch (size)
+  {
   case 1:
-    dbuf_tprintf (oBuf, "\t!db !constbyte\n",ival);
+    dbuf_tprintf (oBuf, "\t!db !constbyte\n", ival);
     break;
 
   case 2:
-    dbuf_tprintf (oBuf, "\t!dw !constword\n",ival);
+    dbuf_tprintf (oBuf, "\t!dw !constword\n", ival);
     break;
+
   case 4:
     dbuf_tprintf (oBuf, "\t!dw  !constword,!constword\n",
-             (ival >> 16) & 0xffff, (ival & 0xffff));
+      (ival >> 16) & 0xffff, (ival & 0xffff));
     break;
   }
   *sym = lsym;
@@ -759,14 +785,14 @@ printIvalStruct (symbol * sym, sym_link * type,
   }
 
   if (SPEC_STRUCT (type)->type == UNION) {
-    printIval (sym, sflds->type, iloop, oBuf);
+    printIval (sym, sflds->type, iloop, oBuf, TRUE);
     iloop = iloop ? iloop->next : NULL;
   } else {
     for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
       if (IS_BITFIELD(sflds->type)) {
         printIvalBitFields(&sflds, &iloop, oBuf);
       } else {
-        printIval (sym, sflds->type, iloop, oBuf);
+        printIval (sym, sflds->type, iloop, oBuf, TRUE);
       }
     }
   }
@@ -780,7 +806,7 @@ printIvalStruct (symbol * sym, sym_link * type,
 /* printIvalChar - generates initital value for character array    */
 /*-----------------------------------------------------------------*/
 int
-printIvalChar (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, char *s)
+printIvalChar (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, char *s, bool check)
 {
   value *val;
   unsigned int size = DCL_ELEM (type);
@@ -802,6 +828,9 @@ printIvalChar (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s *
                 DCL_ELEM (type) = size;
             }
 
+          if (check && DCL_ELEM (val->type) > size)
+            werror (W_EXCESS_INITIALIZERS, "array of chars", sym->name, sym->lineDef);
+
           printChar (oBuf, SPEC_CVAL (val->etype).v_char, size);
 
           return 1;
@@ -819,7 +848,7 @@ printIvalChar (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s *
 /*-----------------------------------------------------------------*/
 void
 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
-                struct dbuf_s * oBuf)
+                struct dbuf_s * oBuf, bool check)
 {
   value *val;
   initList *iloop;
@@ -841,7 +870,7 @@ printIvalArray (symbol * sym, sym_link * type, initList * ilist,
       }
       if (printIvalChar (sym, type,
                          (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
-                         oBuf, SPEC_CVAL (sym->etype).v_char))
+                         oBuf, SPEC_CVAL (sym->etype).v_char, check))
         return;
     }
     /* not the special case             */
@@ -855,7 +884,7 @@ printIvalArray (symbol * sym, sym_link * type, initList * ilist,
         werrorfl (sym->fileDef, sym->lineDef, W_EXCESS_INITIALIZERS, "array", sym->name);
         break;
       }
-      printIval (sym, type->next, iloop, oBuf);
+      printIval (sym, type->next, iloop, oBuf, TRUE);
     }
   }
 
@@ -1156,7 +1185,7 @@ printIvalPtr (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * o
 /* printIval - generates code for initial value                    */
 /*-----------------------------------------------------------------*/
 void
-printIval (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf)
+printIval (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf, bool check)
 {
   sym_link *itype;
 
@@ -1170,7 +1199,7 @@ printIval (symbol * sym, sym_link * type, initList * ilist, struct dbuf_s * oBuf
   /* if this is an array   */
   if (IS_ARRAY (type))
     {
-      printIvalArray (sym, type, ilist, oBuf);
+      printIvalArray (sym, type, ilist, oBuf, check);
       return;
     }
 
@@ -1244,21 +1273,23 @@ emitStaticSeg (memmap * map, struct dbuf_s * oBuf)
         }
 
       /* print extra debug info if required */
-      if (options.debug) {
-
-        if (!sym->level)
-          {                     /* global */
-            if (IS_STATIC (sym->etype))
-              dbuf_printf (oBuf, "F%s$", moduleName);        /* scope is file */
-            else
-              dbuf_printf (oBuf, "G$");      /* scope is global */
-          }
-        else
-          /* symbol is local */
-          dbuf_printf (oBuf, "L%s$",
-                   (sym->localof ? sym->localof->name : "-null-"));
-        dbuf_printf (oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
-      }
+      if (options.debug)
+        {
+          if (!sym->level)
+            {                     /* global */
+              if (IS_STATIC (sym->etype))
+                dbuf_printf (oBuf, "F%s$", moduleName);        /* scope is file */
+              else
+                dbuf_printf (oBuf, "G$");      /* scope is global */
+            }
+          else
+            {
+              /* symbol is local */
+              dbuf_printf (oBuf, "L%s$",
+                           (sym->localof ? sym->localof->name : "-null-"));
+            }
+          dbuf_printf (oBuf, "%s$%d$%d", sym->name, sym->level, sym->block);
+        }
 
       /* if it has an absolute address and no initializer */
       if (SPEC_ABSA (sym->etype) && !sym->ival)
@@ -1285,7 +1316,7 @@ emitStaticSeg (memmap * map, struct dbuf_s * oBuf)
               dbuf_printf (oBuf, "%s:\n", sym->rname);
               ++noAlloc;
               resolveIvalSym (sym->ival, sym->type);
-              printIval (sym, sym->type, sym->ival, oBuf);
+              printIval (sym, sym->type, sym->ival, oBuf, map != xinit);
               --noAlloc;
               /* if sym is a simple string and sym->ival is a string,
                  WE don't need it anymore */