I was too fast: this breaks regression test bug-221220.c
[fw/sdcc] / src / SDCCsymt.c
index 3ea2843fcbb3b92dea7bf4033e65bd8f6a8b6e85..de557529207f98479ff68e0c354fcb6fd4efa817 100644 (file)
@@ -43,7 +43,7 @@ char *nounName(sym_link *sl) {
     {
     case V_INT: {
       if (SPEC_LONG(sl)) return "long";
-      if (sl->select.s._short) return "short";
+      if (SPEC_SHORT(sl)) return "short";
       return "int";
     }
     case V_FLOAT: return "float";
@@ -328,6 +328,20 @@ newStruct (char *tag)
   return s;
 }
   
+/*------------------------------------------------------------------*/
+/* copyStruct - copies a structdef including the fields-list        */
+/*------------------------------------------------------------------*/
+static structdef *
+copyStruct (structdef *src)
+{
+  structdef *dest;
+
+  dest = newStruct ("");
+  memcpy (dest, src, sizeof (structdef));
+  dest->fields = copySymbolChain (src->fields);
+  return dest;
+}
+  
 /*------------------------------------------------------------------*/
 /* sclsFromPtr - Return the storage class a pointer points into.    */
 /*               S_FIXED is returned for generic pointers or other  */
@@ -545,7 +559,7 @@ void checkTypeSanity(sym_link *etype, char *name) {
        SPEC_NOUN(etype)==V_FIXED16X16 ||
        SPEC_NOUN(etype)==V_DOUBLE || 
        SPEC_NOUN(etype)==V_VOID) &&
-      (etype->select.s._short || SPEC_LONG(etype))) {
+      (SPEC_SHORT(etype) || SPEC_LONG(etype))) {
     // long or short for char float double or void
     werror (E_LONG_OR_SHORT_INVALID, noun, name);
   }
@@ -553,15 +567,15 @@ void checkTypeSanity(sym_link *etype, char *name) {
        SPEC_NOUN(etype)==V_FIXED16X16 ||
        SPEC_NOUN(etype)==V_DOUBLE || 
        SPEC_NOUN(etype)==V_VOID) && 
-      (etype->select.s._signed || SPEC_USIGN(etype))) {
+      (etype->select.s.b_signed || SPEC_USIGN(etype))) {
     // signed or unsigned for float double or void
     werror (E_SIGNED_OR_UNSIGNED_INVALID, noun, name);
   }
 
   // special case for "short"
-  if (etype->select.s._short) {
+  if (SPEC_SHORT(etype)) {
     SPEC_NOUN(etype) = options.shortis8bits ? V_CHAR : V_INT;
-    etype->select.s._short = 0;
+    SPEC_SHORT(etype) = 0;
   }
 
   /* if no noun e.g. 
@@ -575,15 +589,15 @@ void checkTypeSanity(sym_link *etype, char *name) {
   /* a "plain" int bitfield is unsigned */
   if (SPEC_NOUN(etype)==V_BIT ||
       SPEC_NOUN(etype)==V_SBIT) {
-    if (!etype->select.s._signed)
+    if (!etype->select.s.b_signed)
       SPEC_USIGN(etype) = 1;
   }
 
-  if (etype->select.s._signed && SPEC_USIGN(etype)) {
+  if (etype->select.s.b_signed && SPEC_USIGN(etype)) {
     // signed AND unsigned 
     werror (E_SIGNED_AND_UNSIGNED_INVALID, noun, name);
   }
-  if (etype->select.s._short && SPEC_LONG(etype)) {
+  if (SPEC_SHORT(etype) && SPEC_LONG(etype)) {
     // short AND long
     werror (E_LONG_AND_SHORT_INVALID, noun, name);
   }
@@ -645,9 +659,9 @@ mergeSpec (sym_link * dest, sym_link * src, char *name)
   // but there are more important thing right now
 
   SPEC_LONG (dest) |= SPEC_LONG (src);
-  dest->select.s._short|=src->select.s._short;
+  SPEC_SHORT(dest) |= SPEC_SHORT(src);
   SPEC_USIGN (dest) |= SPEC_USIGN (src);
-  dest->select.s._signed|=src->select.s._signed;
+  dest->select.s.b_signed|=src->select.s.b_signed;
   SPEC_STAT (dest) |= SPEC_STAT (src);
   SPEC_EXTR (dest) |= SPEC_EXTR (src);
   SPEC_CONST(dest) |= SPEC_CONST (src);
@@ -781,6 +795,20 @@ newIntLink ()
   return p;
 }
 
+/*------------------------------------------------------------------*/
+/* newBoolLink() - creates an bool type                             */
+/*------------------------------------------------------------------*/
+sym_link *
+newBoolLink ()
+{
+  sym_link *p;
+
+  p = newLink (SPECIFIER);
+  SPEC_NOUN (p) = V_BIT;
+
+  return p;
+}
+
 /*------------------------------------------------------------------*/
 /* getSize - returns size of a type chain in bits                   */
 /*------------------------------------------------------------------*/
@@ -1219,7 +1247,11 @@ compStructSize (int su, structdef * sdef)
 
             /* change it to a unsigned bit */
             SPEC_NOUN (loop->etype) = V_BITFIELD;
-            SPEC_USIGN (loop->etype) = 1;
+            /* ISO/IEC 9899 J.3.9 implementation defined behaviour: */
+            /* a "plain" int bitfield is unsigned */
+            if (!loop->etype->select.s.b_signed)
+              SPEC_USIGN(loop->etype) = 1;
+
             SPEC_BLEN (loop->etype) = loop->bitVar;
 
             if (loop->bitVar == BITVAR_PAD) {
@@ -1478,16 +1510,18 @@ checkSClass (symbol * sym, int isProto)
 
   /* if this is an automatic symbol */
   if (sym->level && (options.stackAuto || reentrant)) {
-    if ((SPEC_SCLS (sym->etype) == S_AUTO ||
-         SPEC_SCLS (sym->etype) == S_FIXED ||
-         SPEC_SCLS (sym->etype) == S_REGISTER ||
-         SPEC_SCLS (sym->etype) == S_STACK ||
-         SPEC_SCLS (sym->etype) == S_XSTACK)) {
-      SPEC_SCLS (sym->etype) = S_AUTO;
-    } else {
-      /* storage class may only be specified for statics */
-      if (!IS_STATIC(sym->etype)) {
-        werror (E_AUTO_ASSUMED, sym->name);
+    if (SPEC_SCLS (sym->etype) != S_BIT) {
+      if ((SPEC_SCLS (sym->etype) == S_AUTO ||
+           SPEC_SCLS (sym->etype) == S_FIXED ||
+           SPEC_SCLS (sym->etype) == S_REGISTER ||
+           SPEC_SCLS (sym->etype) == S_STACK ||
+           SPEC_SCLS (sym->etype) == S_XSTACK)) {
+        SPEC_SCLS (sym->etype) = S_AUTO;
+      } else {
+        /* storage class may only be specified for statics */
+        if (!IS_STATIC(sym->etype)) {
+          werror (E_AUTO_ASSUMED, sym->name);
+        }
       }
     }
   }
@@ -1505,6 +1539,7 @@ checkSClass (symbol * sym, int isProto)
   /* arrays & pointers cannot be defined for bits   */
   /* SBITS or SFRs or BIT                           */
   if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
+      !IS_FUNCPTR (sym->type) &&
       (SPEC_NOUN (sym->etype) == V_BIT ||
        SPEC_NOUN (sym->etype) == V_SBIT ||
        SPEC_NOUN (sym->etype) == V_BITFIELD ||
@@ -1609,6 +1644,9 @@ copyLinkChain (sym_link * p)
   while (curr)
     {
       memcpy (loop, curr, sizeof (sym_link));   /* copy it */
+if (getenv ("SDCCCOPYSTRUCT")) // this breaks regression test bug-221220??
+      if (IS_STRUCT (loop))
+        SPEC_STRUCT (loop) = copyStruct (SPEC_STRUCT (loop));
       loop->next = (curr->next ? newLink (curr->next->class) : (void *) NULL);
       loop = loop->next;
       curr = curr->next;
@@ -1751,24 +1789,20 @@ computeType (sym_link * type1, sym_link * type2,
   /* which ever is greater in size */
   if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
     rType = newFloatLink ();
-  else
-    /* if both are fixed16x16 then result is float */
-  if (IS_FIXED16X16(etype1) && IS_FIXED16X16(etype2))
+  /* if both are fixed16x16 then result is float */
+  else if (IS_FIXED16X16(etype1) && IS_FIXED16X16(etype2))
     rType = newFixed16x16Link();
-  else
-  if (IS_FIXED16X16(etype1) && IS_FLOAT (etype2))
+  else if (IS_FIXED16X16(etype1) && IS_FLOAT (etype2))
     rType = newFloatLink ();
-  if (IS_FLOAT (etype1) && IS_FIXED16X16 (etype2) )
+  else if (IS_FLOAT (etype1) && IS_FIXED16X16 (etype2) )
     rType = newFloatLink ();
-  else
-    /* if both are bitvars choose the larger one */
-  if (IS_BITVAR (etype1) && IS_BITVAR (etype2))
-    {
-      rType = SPEC_BLEN (etype1) >= SPEC_BLEN (etype2) ?
-                copyLinkChain (type1) : copyLinkChain (type1);
-    }
-    /* if only one of them is a bit variable
-       then the other one prevails */
+            
+  /* if both are bitvars choose the larger one */
+  else if (IS_BITVAR (etype1) && IS_BITVAR (etype2))
+    rType = SPEC_BLEN (etype1) >= SPEC_BLEN (etype2) ?
+            copyLinkChain (type1) : copyLinkChain (type1);
+                          
+  /* if only one of them is a bit variable then the other one prevails */
   else if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
     {
       rType = copyLinkChain (type2);
@@ -1783,10 +1817,9 @@ computeType (sym_link * type1, sym_link * type2,
       if (getSize (etype2) > 1)
         SPEC_NOUN (getSpec (rType)) = V_INT;
     }
-  else
-    /* if one of them is a pointer or array then that
-       prevails */
-  if (IS_PTR (type1) || IS_ARRAY (type1))
+  /* if one of them is a pointer or array then that
+     prevails */
+  else if (IS_PTR (type1) || IS_ARRAY (type1))
     rType = copyLinkChain (type1);
   else if (IS_PTR (type2) || IS_ARRAY (type2))
     rType = copyLinkChain (type2);
@@ -1798,7 +1831,7 @@ computeType (sym_link * type1, sym_link * type2,
   reType = getSpec (rType);
 
   /* avoid conflicting types */
-  reType->select.s._signed = 0;
+  reType->select.s.b_signed = 0;
 
   /* if result is a literal then make not so */
   if (IS_LITERAL (reType))
@@ -2341,13 +2374,6 @@ checkFunction (symbol * sym, symbol *csym)
       return 0;
     }
 
-  /* function cannot return bit */
-  if (IS_BITVAR (sym->type->next))
-    {
-      werror (E_FUNC_BIT, sym->name);
-      return 0;
-    }
-
   /* check if this function is defined as calleeSaves
      then mark it as such */
   FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
@@ -2578,7 +2604,7 @@ processFuncArgs (symbol * func)
          the function does not have VA_ARG
          and as port dictates */
       if (!IFFUNC_HASVARARGS(funcType) &&
-          (argreg = (*port->reg_parm) (val->type)))
+          (argreg = (*port->reg_parm) (val->type, FUNC_ISREENT(funcType))))
         {
           SPEC_REGPARM (val->etype) = 1;
           SPEC_ARGREG(val->etype) = argreg;
@@ -2649,7 +2675,7 @@ processFuncArgs (symbol * func)
             SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) = bit;
           else
             SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
-              (options.model != MODEL_SMALL ? xdata : data);
+              port->mem.default_local_map;
           
           #if 0
           /* ?? static functions shouldn't imply static parameters - EEP */
@@ -2659,6 +2685,8 @@ processFuncArgs (symbol * func)
           }
           #endif
         }
+      if (SPEC_OCLS (val->sym->etype) == pdata)
+        val->sym->iaccess = 1;
       if (!isinSet(operKeyReset, val->sym)) {
         addSet (&operKeyReset, val->sym);
         applyToSet (operKeyReset, resetParmKey);
@@ -3067,7 +3095,7 @@ powof2 (TYPE_UDWORD num)
     }
 
   if (n1s > 1 || nshifts == 0)
-    return 0;
+    return -1;
   return nshifts - 1;
 }