Fixed bug-463702
[fw/sdcc] / src / SDCCsymt.c
index 382836fb981a6fc4498187e56c1ad6738b161a85..97634105617769ecf20aeada191e8234d3126715 100644 (file)
@@ -320,6 +320,11 @@ pointerTypes (sym_link * ptr, sym_link * type)
   /* could not find it */
   if (!ptr || IS_SPEC (ptr))
     return;
+  
+  if (IS_PTR(ptr) && DCL_TYPE(ptr)!=UPOINTER) {
+    pointerTypes (ptr->next, type);
+    return;
+  }
 
   /* change the pointer type depending on the
      storage class of the type */
@@ -431,13 +436,13 @@ addDecl (symbol * sym, int type, sym_link * p)
        }
     }
 
-  /* if the type is a unknown pointer and has
+  /* if the type is an unknown pointer and has
      a tspec then take the storage class const & volatile
      attribute from the tspec & make it those of this
      symbol */
   if (p &&
       !IS_SPEC (p) &&
-      DCL_TYPE (p) == UPOINTER &&
+      //DCL_TYPE (p) == UPOINTER &&
       DCL_TSPEC (p))
     {
       if (!IS_SPEC (sym->etype))
@@ -523,31 +528,34 @@ void checkTypeSanity(sym_link *etype, char *name) {
 /*------------------------------------------------------------------*/
 /* mergeSpec - merges two specifiers and returns the new one        */
 /*------------------------------------------------------------------*/
-#define LAST_MINUTE_2_3_0_FIX
 sym_link *
 mergeSpec (sym_link * dest, sym_link * src, char *name)
 {
 
-#ifdef LAST_MINUTE_2_3_0_FIX
   sym_link *symlink;
 
   if (!IS_SPEC(dest)) {
-    // This should not happen
-    fprintf (stderr, "*** internal error: can't merge declarators\n");
+    // This can happen for pointers, find the end type
+    while (dest && !IS_SPEC(dest))
+      dest=dest->next;
   }
   if (!IS_SPEC(src)) {
     // here we have a declarator as source, reverse them
     symlink=src;
     src=dest;
     dest=symlink;
-    while (!IS_SPEC(dest)) {
+    while (dest && !IS_SPEC(dest)) {
       // and find the specifier
       dest=dest->next;
     }
   } else {
     symlink=dest;
   }
-#endif
+
+  if (!IS_SPEC(dest) || !IS_SPEC(src)) {
+    werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "cannot merge declarator");
+    exit (1);
+  }
 
   if (getenv("DEBUG_mergeSpec")) {
     fprintf (stderr, "mergeSpec: \"%s\"\n", name);
@@ -613,11 +621,7 @@ mergeSpec (sym_link * dest, sym_link * src, char *name)
   if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
     SPEC_STRUCT (dest) = SPEC_STRUCT (src);
 
-#ifdef LAST_MINUTE_2_3_0_FIX
   return symlink;
-#else
-  return dest;
-#endif
 }
 
 /*------------------------------------------------------------------*/
@@ -1191,23 +1195,6 @@ checkSClass (symbol * sym, int isProto)
       sym->ival = NULL;
     }
 
-#if 0
-  /* if this is an automatic symbol then */
-  /* storage class will be ignored and   */
-  /* symbol will be allocated on stack/  */
-  /* data depending on flag             */
-  if (sym->level &&
-      (options.stackAuto || reentrant) &&
-      (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))
-    {
-      werror (E_AUTO_ASSUMED, sym->name);
-      SPEC_SCLS (sym->etype) = S_AUTO;
-    }
-#else
   /* if this is an atomatic symbol */
   if (sym->level && (options.stackAuto || reentrant)) {
     if ((SPEC_SCLS (sym->etype) == S_AUTO ||
@@ -1223,7 +1210,6 @@ checkSClass (symbol * sym, int isProto)
       }
     }
   }
-#endif
   
   /* automatic symbols cannot be given   */
   /* an absolute address ignore it      */
@@ -1256,7 +1242,7 @@ checkSClass (symbol * sym, int isProto)
     /* initializers if not an extern */
     if (SPEC_SCLS (sym->etype) == S_CODE &&
        sym->ival == NULL &&
-       !sym->level &&
+       //!sym->level &&
        port->mem.code_ro &&
        !IS_EXTERN (sym->etype) &&
        !funcInChain (sym->type))
@@ -1442,9 +1428,9 @@ computeType (sym_link * type1, sym_link * type2)
   return rType;
 }
 
-/*------------------------------------------------------------------*/
-/* compareType - will do type check return 1 if match                 */
-/*------------------------------------------------------------------*/
+/*--------------------------------------------------------------------*/
+/* compareType - will do type check return 1 if match, -1 if castable */
+/*--------------------------------------------------------------------*/
 int 
 compareType (sym_link * dest, sym_link * src)
 {
@@ -1464,14 +1450,13 @@ compareType (sym_link * dest, sym_link * src)
        {
          if (DCL_TYPE (src) == DCL_TYPE (dest))
            return compareType (dest->next, src->next);
-         else if (IS_PTR (src) && IS_PTR (dest))
+         if (IS_PTR (src) && IS_PTR (dest))
            return -1;
-         else if (IS_PTR (dest) && IS_ARRAY (src))
+         if (IS_PTR (dest) && IS_ARRAY (src))
            return -1;
-         else if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
+         if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
            return -1 * compareType (dest->next, src);
-         else
-           return 0;
+         return 0;
        }
       else if (IS_PTR (dest) && IS_INTEGRAL (src))
        return -1;
@@ -1523,7 +1508,7 @@ compareType (sym_link * dest, sym_link * src)
     return -1;
 
   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
-    return -2;
+    return -1;
 
   return 1;
 }
@@ -1678,10 +1663,10 @@ checkFunction (symbol * sym)
   if (compareType (csym->type, sym->type) <= 0)
     {
       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
-      werror (E_CONTINUE, "previous definition type ");
+      werror (W_CONTINUE, "previous definition type ");
       printTypeChain (csym->type, stderr);
       fprintf (stderr, "\n");
-      werror (E_CONTINUE, "current definition type ");
+      werror (W_CONTINUE, "current definition type ");
       printTypeChain (sym->type, stderr);
       fprintf (stderr, "\n");
       return 0;