fixed bug #463839
[fw/sdcc] / src / SDCCsymt.c
index 382836fb981a6fc4498187e56c1ad6738b161a85..7164549b792881d7cc9ad45c2dc1d1cfc554dc16 100644 (file)
@@ -217,13 +217,12 @@ findSymWithLevel (bucket ** stab, symbol * sym)
    **/
   while (bp)
     {
-
       if (strcmp (bp->name, sym->name) == 0 && bp->level <= sym->level)
        {
          /* if this is parameter then nothing else need to be checked */
          if (((symbol *) (bp->sym))->_isparm)
            return (bp->sym);
-         /* if levels match then block numbers hsould also match */
+         /* if levels match then block numbers should also match */
          if (bp->level && bp->level == sym->level && bp->block == sym->block)
            return (bp->sym);
          /* if levels don't match then we are okay */
@@ -320,6 +319,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 +435,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 +527,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 +620,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
 }
 
 /*------------------------------------------------------------------*/
@@ -953,7 +956,7 @@ addSymChain (symbol * symHead)
          then check if the type match, if the types match then
          delete the current entry and add the new entry      */
       if ((csym = findSymWithLevel (SymbolTab, sym)) &&
-         csym->level == sym->level) {
+         csym->level == sym->level && csym->localof == sym->localof) {
        
        /* one definition extern ? */
        if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype)) {
@@ -1191,23 +1194,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 +1209,6 @@ checkSClass (symbol * sym, int isProto)
       }
     }
   }
-#endif
   
   /* automatic symbols cannot be given   */
   /* an absolute address ignore it      */
@@ -1256,7 +1241,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 +1427,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 +1449,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 +1507,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 +1662,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;
@@ -2293,6 +2277,11 @@ initCSupport ()
 
   int bwd, su, muldivmod, tofrom, rlrr;
 
+  if (getenv("SDCC_NO_C_SUPPORT")) {
+    /* for debugging only */
+    return;
+  }
+
   floatType = newFloatLink ();
 
   for (bwd = 0; bwd < 3; bwd++)