* src/SDCCsymt.c, src/SDCCglue.c,
[fw/sdcc] / src / SDCCsymt.c
index e950c5800ae4f118f7519cc6661b917558659176..a27c0ec60c9f80a5486768c1f2b253fbbb6ec088 100644 (file)
@@ -1213,6 +1213,8 @@ structElemType (sym_link * stype, value * id)
             etype = getSpec (type);
             SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
                                  SPEC_SCLS (etype) : SPEC_SCLS (petype));
+            SPEC_OCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
+                                 SPEC_OCLS (etype) : SPEC_OCLS (petype));
             if (IS_SPEC (type))
               SPEC_CONST (type) |= SPEC_CONST (stype);
             else
@@ -1278,16 +1280,17 @@ compStructSize (int su, structdef * sdef)
       if (!loop->etype->select.s.b_signed)
         SPEC_USIGN(loop->etype) = 1;
 
-      SPEC_BLEN (loop->etype) = loop->bitVar;
-
       if (loop->bitVar == BITVAR_PAD) {
         /* A zero length bitfield forces padding */
-        SPEC_BSTR (loop->etype) = bitOffset;
         SPEC_BLEN (loop->etype) = 0;
-        bitOffset = 8;
+        SPEC_BSTR (loop->etype) = bitOffset;
+        if (bitOffset > 0)
+          bitOffset = 8; /* padding is not needed when at bit 0 */
         loop->offset = sum;
       }
       else {
+        SPEC_BLEN (loop->etype) = loop->bitVar;
+
         if (bitOffset == 8) {
           bitOffset = 0;
           sum++;
@@ -2044,8 +2047,28 @@ computeType (sym_link * type1, sym_link * type2,
   return rType;
 }
 
+int
+comparePtrType (sym_link * dest, sym_link * src, bool bMustCast)
+{
+  int res;
+
+  if (IS_VOID (src->next) && IS_VOID (dest->next))
+    return bMustCast ? -1 : 1;
+  if ((IS_VOID (src->next) && !IS_VOID (dest->next)) ||
+      (!IS_VOID (src->next) && IS_VOID (dest->next)) )
+    return -1;
+  res = compareType (dest->next, src->next);
+  if (res == 1)
+    return bMustCast ? -1 : 1;
+  else if (res == -2)
+    return -2;
+  else
+    return 0;
+}
+
 /*--------------------------------------------------------------------*/
-/* compareType - will do type check return 1 if match, -1 if castable */
+/* compareType - will do type check return 1 if match, 0 if no match, */
+/*               -1 if castable, -2 if only signedness differs        */
 /*--------------------------------------------------------------------*/
 int
 compareType (sym_link * dest, sym_link * src)
@@ -2071,15 +2094,7 @@ compareType (sym_link * dest, sym_link * src)
                 return -1;
               if (IS_FUNC (dest->next) && IS_VOID(src->next))
                 return -1;
-              if (IS_VOID (src->next) && IS_VOID (dest->next))
-                return 1;
-              if ((IS_VOID (src->next) && !IS_VOID (dest->next)) ||
-                  (!IS_VOID (src->next) && IS_VOID (dest->next)) )
-                return -1;
-              if (compareType (dest->next, src->next) == 1)
-                return 1;
-              else
-                return 0;
+              return comparePtrType(dest, src, FALSE);
             }
 
           if (DCL_TYPE (src) == DCL_TYPE (dest))
@@ -2088,15 +2103,7 @@ compareType (sym_link * dest, sym_link * src)
                 {
                   //checkFunction(src,dest);
                 }
-              if (IS_VOID (src->next) && IS_VOID (dest->next))
-                return 1;
-              if ((IS_VOID (src->next) && !IS_VOID (dest->next)) ||
-                  (!IS_VOID (src->next) && IS_VOID (dest->next)) )
-                return -1;
-              if (compareType (dest->next, src->next) == 1)
-                return 1;
-              else
-                return 0;
+              return comparePtrType(dest, src, FALSE);
             }
           if (IS_PTR (dest) && IS_GENPTR (src) && IS_VOID(src->next))
             {
@@ -2107,10 +2114,7 @@ compareType (sym_link * dest, sym_link * src)
                ((DCL_TYPE(src) == POINTER) && (DCL_TYPE(dest) == IPOINTER))
              ))
             {
-              if (compareType (dest->next, src->next))
-                return -1;
-              else
-                return 0;
+              return comparePtrType(dest, src, TRUE);
             }
           if (IS_PTR (dest) && IS_ARRAY (src))
             {
@@ -2182,7 +2186,7 @@ compareType (sym_link * dest, sym_link * src)
     return -1;
 
   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
-    return -1;
+    return -2;
 
   return 1;
 }
@@ -2423,6 +2427,8 @@ aggregateToPointer (value * val)
           }
           break;
         case S_AUTO:
+          DCL_TYPE (val->type) = PTR_TYPE(SPEC_OCLS(val->etype));
+          break;
         case S_DATA:
         case S_REGISTER:
           DCL_TYPE (val->type) = POINTER;