Internal error compiling bug-524691 regression test
[fw/sdcc] / src / SDCCast.c
index b4933cb2b5c3fbd7ad4613f00ebbaa5a49756317..64dc380d458246d7f2b178962627d5213d1a9db7 100644 (file)
@@ -966,14 +966,10 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
                                   newAst_VALUE (valueFromLit ((float) i))),
                               newAst_VALUE (valueFromLit (*s))));
 
-      // now we don't need iexpr's symbol anymore
-      {
-       symbol *sym=AST_SYMBOL(iexpr);
-       memmap *segment=SPEC_OCLS(sym->etype);
-       deleteSetItem(&segment->syms, sym);
-      }
-      
-      return decorateType(resolveSymbols (rast));
+      // now WE don't need iexpr's symbol anymore
+      freeStringSymbol(AST_SYMBOL(iexpr));
+
+      return decorateType (resolveSymbols (rast));
     }
 
   return NULL;
@@ -1058,9 +1054,8 @@ gatherAutoInit (symbol * autoChain)
     {
 
       /* resolve the symbols in the ival */
-      if (sym->ival) {
+      if (sym->ival)
        resolveIvalSym (sym->ival);
-      }
 
       /* if this is a static variable & has an */
       /* initial value the code needs to be lifted */
@@ -1137,6 +1132,20 @@ gatherAutoInit (symbol * autoChain)
   return init;
 }
 
+/*-----------------------------------------------------------------*/
+/* freeStringSymbol - delete a literal string if no more usage     */
+/*-----------------------------------------------------------------*/
+void freeStringSymbol(symbol *sym) {
+  /* make sure this is a literal string */
+  assert (sym->isstrlit);
+  if (--sym->isstrlit == 0) { // lower the usage count
+    memmap *segment=SPEC_OCLS(sym->etype);
+    if (segment) {
+      deleteSetItem(&segment->syms, sym);
+    }
+  }
+}
+  
 /*-----------------------------------------------------------------*/
 /* stringToSymbol - creates a symbol from a literal string         */
 /*-----------------------------------------------------------------*/
@@ -1146,6 +1155,18 @@ stringToSymbol (value * val)
   char name[SDCC_NAME_MAX + 1];
   static int charLbl = 0;
   symbol *sym;
+  set *sp;
+
+  // have we heard this before?
+  for (sp=statsg->syms; sp; sp=sp->next) {
+    sym=sp->item;
+    if (sym->isstrlit && 
+       !strcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char)) {
+      // yes, this is old news. Don't publish it again.
+      sym->isstrlit++; // but raise the usage count
+      return symbolVal(sym);
+    }
+  }
 
   sprintf (name, "_str_%d", charLbl++);
   sym = newSymbol (name, 0);   /* make it @ level 0 */