]> andersk Git - splint.git/blobdiff - src/usymtab.c
Fixed problem with NULL being changed.
[splint.git] / src / usymtab.c
index 1c15b5c272eeab69a6adcf06531fe5520954831b..1d26d49de9f168f7d634709a2b73acf6e7ee21f4 100644 (file)
@@ -1,6 +1,6 @@
 /*
-** LCLint - annotation-assisted static program checker
-** Copyright (C) 1994-2000 University of Virginia,
+** Splint - annotation-assisted static program checker
+** Copyright (C) 1994-2003 University of Virginia,
 **         Massachusetts Institute of Technology
 **
 ** This program is free software; you can redistribute it and/or modify it
@@ -17,9 +17,9 @@
 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 ** MA 02111-1307, USA.
 **
-** For information on lclint: lclint-request@cs.virginia.edu
-** To report a bug: lclint-bug@cs.virginia.edu
-** For more information: http://lclint.cs.virginia.edu
+** For information on splint: info@splint.org
+** To report a bug: splint-bug@splint.org
+** For more information: http://www.splint.org
 */
 /*
 ** usymtab
 **                      weird C syntax.
 */
 
-# include "lclintMacros.nf"
+# include "splintMacros.nf"
 # include "basic.h"
 # include "structNames.h"
 # include "exprChecks.h"
-# include "aliasChecks.h"
+# include "transferChecks.h"
+
+/* Needed to install macros when loading libraries */
+
+# include "cpplib.h"
+# include "cpperror.h"
+# include "cpphash.h"
 
 /*
 ** Keep track of type definitions inside a function.
@@ -61,7 +67,7 @@ static uentryList functypes = uentryList_undefined;
 static bool dbgfree = FALSE;
 static bool dbgload = TRUE;
 
-/*@access ekind usymId@*/
+/*@access ekind@*/
 
 /*
 ** Hack to prevent shadow errors from appearing when function parameters
@@ -95,22 +101,36 @@ static /*@checkedstrict@*/ /*@dependent@*/ usymtab filetab;
 static /*@checkedstrict@*/ /*@owned@*/ usymtab oldtab;
 
 static int usymtab_lexicalLevel (void) /*@globals utab@*/ ;
-static bool usymtab_isProbableNullAltBranch (sRef p_s) /*@globals utab@*/ ;
+static bool usymtab_isAltDefinitelyNull (sRef p_s) /*@globals utab@*/ ;
 static void refTable_free (/*@only@*/ /*@null@*/ refTable p_x, int p_nentries);
 static ctype usymtab_suFieldsType (uentryList p_f, bool p_isStruct) /*@globals globtab@*/ ;
 
+static void usymtab_freeAux (/*@only@*/ usymtab p_u)
+     /*@globals globtab, utab, filetab@*/
+     /*@modifies p_u@*/ ;
+
+extern int usymtab_getCurrentDepth (void) /*@globals utab@*/ 
+{
+  return utab->lexlevel;
+}
+
 static void
 usymtab_freeLevel (/*@notnull@*/ /*@only@*/ usymtab p_u)
   /*@globals globtab, utab, filetab@*/ /*@modifies p_u@*/ ;
 
-static bool usymtab_isProbableNullAux (sRef p_s) /*@globals utab@*/ ;
+static bool usymtab_isDefinitelyNullAux (sRef p_s) /*@globals utab@*/ ;
 static /*@only@*/ cstring usymtab_unparseStackTab (usymtab p_t);
 static /*@exposed@*/ /*@dependent@*/ uentry 
   usymtab_getRefTab (/*@notnull@*/ usymtab p_u, int p_level, usymId p_index);
+
+# ifdef S_SPLINT_S
+/* These are not used anymore... */
 static /*@unused@*/ /*@only@*/ cstring 
   usymtab_unparseLocalAux (/*@notnull@*/ usymtab p_s);
 static /*@unused@*/ /*@only@*/ cstring 
   usymtab_unparseLocalList (/*@notnull@*/ usymtab p_s);
+# endif
+
 static /*@only@*/ cstring usymtab_typeName (/*@notnull@*/ usymtab p_t);
 static void usymtab_handleParams (void)
    /*@globals utab, globtab, filetab@*/ 
@@ -123,24 +143,36 @@ static /*@exposed@*/ /*@dependent@*/ usymtab
 static /*@exposed@*/ /*@dependent@*/ uentry 
   usymtab_getRefNoisy (/*@notnull@*/ usymtab p_s, int p_level, usymId p_index);
 
+static /*@exposed@*/ /*@dependent@*/ uentry 
+  usymtab_lookupQuietAux (usymtab p_s, cstring p_k, bool p_noalt);
+
 static /*@exposed@*/ /*@dependent@*/ uentry 
   usymtab_lookupQuiet (usymtab p_s, cstring p_k);
-static void usymtab_printAllAux (usymtab p_s) /*@modifies g_msgstream@*/ ;
-static int usymtab_getIndex (/*@notnull@*/ usymtab p_s, cstring p_k);
-static /*@exposed@*/ uentry usymtab_fetchIndex (/*@notnull@*/ usymtab p_s, int p_i);
-static /*@exposed@*/ uentry 
-  usymtab_lookupAux (usymtab p_s, cstring p_k);
-static /*@exposed@*/ /*@dependent@*/ /*@notnull@*/ usymtab 
-  usymtab_getFileTab (void) /*@globals filetab@*/ ;
-static int refTable_lookup (/*@notnull@*/ usymtab p_ut, int p_level, int p_index);
+
+static /*@exposed@*/ /*@dependent@*/ uentry 
+  usymtab_lookupQuietNoAlt (usymtab p_s, cstring p_k);
+
+static void usymtab_printAllAux (usymtab p_s) /*@modifies g_warningstream@*/ ;
+
+/*@function bool usymtab_indexFound (usymId) @*/
+# define usymtab_indexFound(u) ((u) != usymId_notfound)
+
+static usymId usymtab_getIndex (/*@notnull@*/ usymtab p_s, cstring p_k);
+static /*@exposed@*/ uentry usymtab_fetchIndex (/*@notnull@*/ usymtab p_s, usymId p_ui);
+static /*@exposed@*/ uentry usymtab_lookupAux (usymtab p_s, cstring p_k);
+
+static /*@exposed@*/ /*@dependent@*/ /*@notnull@*/ 
+   usymtab usymtab_getFileTab (void) /*@globals filetab@*/ ;
+
+static int refTable_lookup (/*@notnull@*/ usymtab p_ut, int p_level, usymId p_index);
 static bool usymtab_mustBreak (usymtab p_s);
 static bool usymtab_mustEscape (usymtab p_s);
 
 static void recordFunctionType (uentry ue)
 {
-    llassert (uentry_isDatatype (ue) || uentry_isAnyTag (ue)
+  llassert (uentry_isDatatype (ue) || uentry_isAnyTag (ue)
            || uentry_isEnumConstant (ue));
-
+  DPRINTF (("Function type: %s", uentry_unparseFull (ue)));
   /*@-temptrans@*/
   functypes = uentryList_add (functypes, ue);
   /*@=temptrans@*/
@@ -153,9 +185,9 @@ static void clearFunctionTypes (void)
     {
       if (cstring_isDefined (uentry_rawName (el)))
        {
-         if (globtab->htable != NULL)
+         if (cstringTable_isDefined (globtab->htable))
            {
-             hashTable_remove (globtab->htable, uentry_rawName (el));
+             cstringTable_remove (globtab->htable, uentry_rawName (el));
            }
 
          uentry_setName (el, cstring_undefined);
@@ -170,7 +202,7 @@ static void clearFunctionTypes (void)
   uentryList_clear (functypes);
 }
 
-static /*@falsenull@*/ bool usymtab_isBranch (usymtab u)
+static /*@falsewhennull@*/ bool usymtab_isBranch (usymtab u)
 {
   return (usymtab_isDefined (u) && 
          (u->kind == US_TBRANCH || u->kind == US_FBRANCH
@@ -209,12 +241,12 @@ void usymtab_setExitCode (exitkind ex)
     }
 }
 
-bool usymtab_isAltProbablyDeepNull (sRef s)
+bool usymtab_isAltDefinitelyNullDeep (sRef s)
 {
-  return (sRef_deepPred (usymtab_isProbableNullAltBranch, s));
+  return (sRef_deepPred (usymtab_isAltDefinitelyNull, s));
 }
 
-static bool usymtab_isProbableNullAltBranch (sRef s) 
+static bool usymtab_isAltDefinitelyNull (sRef s) 
    /*@globals utab@*/
 {
   guardSet t;
@@ -230,7 +262,7 @@ static bool usymtab_isProbableNullAltBranch (sRef s)
   /*@=mods@*/
 
   llassert (usymtab_isDefined (utab));
-  res = usymtab_isProbableNull (s);
+  res = usymtab_isDefinitelyNull (s);
 
   /*
   ** This reports a spurious error.  It is okay, because of
@@ -255,22 +287,27 @@ static /*@notnull@*/ /*@special@*/ usymtab
   t->nentries = 0;
   t->nspace = CBASESIZE;
   t->entries = (uentry *) dmalloc (sizeof (*t->entries) * CBASESIZE);
+
+  /* We only use a reftable for branch-level symbol tables. 
+  */
+
   t->reftable = (nextlevel 
                 ? NULL
                 : (refentry *) dmalloc (sizeof (*t->reftable) * CBASESIZE));
   
   t->kind = kind;
   t->lexlevel = (env == GLOBAL_ENV ? 0 : env->lexlevel) + (nextlevel ? 1 : 0); 
-
+  
   t->env = env;
   t->htable = NULL;
 
   t->guards = guardSet_undefined;
   t->aliases = aliasTable_undefined;
 
-    t->mustBreak = FALSE;
+  t->mustBreak = FALSE;
   t->exitCode = XK_NEVERESCAPE;
 
+  DPRINTF (("Create usymtab [%p]", t));
   return t;
 }
 
@@ -288,9 +325,9 @@ static /*@only@*/ /*@notnull@*/ usymtab
   u->entries = (uentry *) dmalloc (sizeof (*u->entries) * CGLOBBASESIZE);
   u->env = GLOBAL_ENV;
   u->lexlevel = 0;
-  u->htable = hashTable_create (CGLOBHASHSIZE);
+  u->htable = cstringTable_create (CGLOBHASHSIZE);
   u->reftable = NULL;
-
+  
   u->guards = guardSet_new ();
   u->aliases = aliasTable_new ();
 
@@ -298,7 +335,7 @@ static /*@only@*/ /*@notnull@*/ usymtab
   u->exitCode = XK_NEVERESCAPE;
   u->kind = US_NORMAL;
 
-  /*@i23@*/ return (u);
+  return (u);
 }
 
 void
@@ -312,6 +349,28 @@ usymtab_initMod (void)
   oldtab = usymtab_undefined;
 }
 
+void 
+usymtab_destroyMod (void) /*@modifies utab, globtab, filetab@*/ /*@globals killed utab@*/ 
+{
+  DPRINTF (("Destroy usymtab [%p]: %d", utab, utab->nentries));
+  usymtab_freeAux (utab);
+  utab = usymtab_undefined;
+  /*@-globstate@*/ 
+} /*@=globstate@*/
+
+void
+usymtab_initGlobalMarker () /*@globals globtab@*/
+{
+  if (uentry_isValid (usymtab_lookupAux (globtab, GLOBAL_MARKER_NAME)))
+    {
+      ; /* Already entered from load table. */
+    }
+  else
+    {
+      usymtab_addGlobalEntry (uentry_makeGlobalMarker ());
+    }
+}
+
 /*
 ** utab should be empty?  (requires?)
 **
@@ -322,12 +381,14 @@ usymtab_initMod (void)
 void
 usymtab_initBool ()
 {
+  DPRINTF (("Init bool!"));
+
   if (context_getFlag (FLG_NOLIB))
     {
       ctype boolt = ctype_bool;
       /* evs 2000-07-24: bool is now treated as abstract (always) */
 
-      uentry boolentry = uentry_makeBoolDatatype (YES);
+      uentry boolentry = uentry_makeBoolDatatype (qual_createAbstract ());
       usymtab_supGlobalEntry (boolentry);
       context_addBoolAccess ();
 
@@ -337,13 +398,14 @@ usymtab_initBool ()
       */
 
       usymtab_supGlobalEntry 
-       (uentry_makeConstantAux (context_getFalseName (), boolt, 
-                                fileloc_getBuiltin (), FALSE,
-                                multiVal_makeInt (0)));
+       (uentry_makeConstantValue (context_getFalseName (), boolt, 
+                                  fileloc_getBuiltin (), FALSE, 
+                                  multiVal_makeInt (0)));
+
       usymtab_supGlobalEntry 
-       (uentry_makeConstantAux (context_getTrueName (), boolt, 
-                                fileloc_getBuiltin (), FALSE,
-                                multiVal_makeInt (1)));
+       (uentry_makeConstantValue (context_getTrueName (), boolt, 
+                                  fileloc_getBuiltin (), FALSE, 
+                                  multiVal_makeInt (1)));
     }
 }
 
@@ -440,9 +502,9 @@ usymtab_addEntryQuiet (/*@notnull@*/ usymtab s, /*@keep@*/ uentry e)
     }
 # endif
 
-  if (s->htable != NULL)
+  if (cstringTable_isDefined (s->htable))
     {
-      hashTable_insert (s->htable, uentry_rawName (e), s->nentries);
+      cstringTable_insert (s->htable, cstring_copy (uentry_rawName (e)), s->nentries);
     }
 
   s->nentries++;
@@ -468,12 +530,14 @@ usymtab_addEntryBase (/*@notnull@*/ usymtab s, /*@only@*/ uentry e)
     }
   else
     {
-      int thisentry = s->nentries;  
+      usymId thisentry = usymId_fromInt (s->nentries); 
       
       if (uentry_isVar (e))
        {
-         uentry_setSref (e, sRef_makeCvar (globScope, thisentry, 
-                                           uentry_getType (e)));
+         uentry_setSref 
+           (e, sRef_makeCvar (globScope, thisentry, 
+                              uentry_getType (e),
+                              stateInfo_makeLoc (uentry_whereLast (e), SA_DECLARED)));
        }
       
       usymtab_addEntryQuiet (s, e);
@@ -481,12 +545,52 @@ usymtab_addEntryBase (/*@notnull@*/ usymtab s, /*@only@*/ uentry e)
     }
 }
 
+
+static /*@observer@*/ uentry /*@alt void@*/
+usymtab_addEntryAlways (/*@notnull@*/ usymtab s, /*@only@*/ uentry e)
+{
+  /* 
+  ** In theory, we shouldn't need this test because it this is
+  ** only called when a library is being read, and it shouldn't
+  ** ever have a duplicate entry.  In practice, its safer to
+  ** leave it in, though.
+  */
+
+  uentry old;
+  usymId thisentry = usymId_fromInt (s->nentries);
+
+  if (uentry_isValid (old = usymtab_lookupQuiet (s, uentry_rawName (e))))
+    {
+      llcontbug 
+       (message ("Duplicate entry in load library: %s. "
+                 "Old entry: %q.  New entry: %q", 
+                 uentry_rawName (e),
+                 uentry_unparseFull (old),
+                 uentry_unparseFull (e)));
+
+      uentry_setName (e, message ("__x_%s", uentry_rawName (e)));
+      /* This shouldn't happen...unless the library is bad! */
+    }
+
+
+  if (uentry_isVar (e) && !uentry_isGlobalMarker (e))
+    {
+      uentry_setSref 
+       (e, sRef_makeCvar (globScope, thisentry, 
+                          uentry_getType (e),
+                          stateInfo_makeLoc (uentry_whereLast (e), SA_DECLARED)));
+    }
+  
+  usymtab_addEntryQuiet (s, e);
+  return e;
+}
+
 static usymId
 usymtab_addEntryAux (/*@notnull@*/ usymtab st, /*@keep@*/ uentry e, bool isSref)
      /*@globals globtab@*/
      /*@modifies st, e@*/
 {
-  usymId thisentry = st->nentries;
+  usymId thisentry = usymId_fromInt (st->nentries);
 
   llassert (!uentry_isElipsisMarker (e));
 
@@ -510,12 +614,13 @@ usymtab_addEntryAux (/*@notnull@*/ usymtab st, /*@keep@*/ uentry e, bool isSref)
 
       if (uentry_isFunction (e) && ctype_isFunction (ct))
        {
-         ct = ctype_returnValue (ct);
+         ct = ctype_getReturnType (ct);
        }
 
       if (uentry_isStatic (e))
        {
-         sRef sr = sRef_makeCvar (st->lexlevel, thisentry, ct);
+         sRef sr = sRef_makeCvar (st->lexlevel, thisentry, ct,
+                                  stateInfo_makeLoc (uentry_whereLast (e), SA_DECLARED));
 
          if (sRef_isStack (sr) || sRef_isLocalState (sr))
            {
@@ -527,15 +632,15 @@ usymtab_addEntryAux (/*@notnull@*/ usymtab st, /*@keep@*/ uentry e, bool isSref)
        }
       else
        {
-         uentry_setSref (e, sRef_makeCvar (st->lexlevel, thisentry, ct));
+         uentry_setSref 
+           (e, sRef_makeCvar (st->lexlevel, thisentry, ct,
+                              stateInfo_makeLoc (uentry_whereLast (e), SA_DECLARED)));
        }
-
-          }
+    }
 
   if (uentry_isDatatype (e))
     {
-      
-      uentry_setDatatype (e, thisentry);
+      uentry_setDatatype (e, typeId_fromUsymId (thisentry));
     }
 
   if (uentry_isFunction (e))
@@ -569,10 +674,10 @@ usymtab_addEntryAux (/*@notnull@*/ usymtab st, /*@keep@*/ uentry e, bool isSref)
       exprChecks_checkExport (e);
     }
   
-  
   uentry_checkName (e);
   
   usymtab_addEntryQuiet (st, e);
+  DPRINTF (("Adding entry: [%p] %s", e, uentry_unparseFull (e)));
   return (thisentry);
 }
 
@@ -580,8 +685,7 @@ usymId
 usymtab_addEntry (uentry e) 
    /*@globals utab, globtab@*/
    /*@modifies utab, e@*/
-{
-  
+{  
   llassertprint (!usymtab_exists (uentry_rawName (e)),
                 ("Entry already exists: %s", uentry_unparse (e)));
 
@@ -613,15 +717,17 @@ usymtab_supEntryAux (/*@notnull@*/ usymtab st,
 {
   cstring ename = uentry_rawName (e);
   bool staticEntry = FALSE;
-  int eindex;
+  usymId eindex;
 
+  DPRINTF (("Sup entry aux: %s", uentry_unparseFull (e)));
+  
   /* static tags in global scope */
   if (st->lexlevel == fileScope 
       && (!(uentry_isStatic (e)) || uentry_isAnyTag (e))) 
     {
       eindex = usymtab_getIndex (st, ename);
 
-      if (eindex != NOT_FOUND)
+      if (usymtab_indexFound (eindex))
        {
          uentry ce = st->entries[eindex];      
          
@@ -635,7 +741,7 @@ usymtab_supEntryAux (/*@notnull@*/ usymtab st,
              uentry_showWhereLast (ce);
            }
 
-         if (eindex == st->nentries - 1)
+         if (eindex == usymId_fromInt (st->nentries - 1))
            {
             ;
            }
@@ -644,10 +750,10 @@ usymtab_supEntryAux (/*@notnull@*/ usymtab st,
              st->entries[eindex] = st->entries[st->nentries - 1];
            }
 
-         if (st->htable != NULL)
+         if (cstringTable_isDefined (st->htable))
            {
-             hashTable_replaceKey (st->htable, uentry_rawName (ce), 
-                                   uentry_rawName (e));
+             cstringTable_replaceKey (st->htable, uentry_rawName (ce), 
+                                      cstring_copy (uentry_rawName (e)));
            }
 
          uentry_free (ce);
@@ -659,7 +765,11 @@ usymtab_supEntryAux (/*@notnull@*/ usymtab st,
 
   if (uentry_isStatic (e)) {
     if (uentry_isFunction (e)) {
-      /* Static function declarations are at the file level, even if they are in a deeped scope. */
+      /* 
+      ** Static function declarations are at the file level,
+      ** even if they are in a deeper scope. 
+      */
+
       st = usymtab_getFileTab ();
       staticEntry = TRUE;
     } else {
@@ -672,14 +782,12 @@ usymtab_supEntryAux (/*@notnull@*/ usymtab st,
     }
   }
 
-  DPRINTF (("Using symtab: %s", usymtab_unparseLocalAux (st)));
-
   eindex = usymtab_getIndex (st, ename);
       
-  if (eindex != NOT_FOUND)
+  if (usymtab_indexFound (eindex))
     {
       uentry ce = st->entries[eindex];
-
+      
       DPRINTF (("Found entry: %s", uentry_unparse (ce)));
 
       if (uentry_isPriv (ce)
@@ -697,11 +805,13 @@ usymtab_supEntryAux (/*@notnull@*/ usymtab st,
 
          llassert ((st->lexlevel > fileScope || !sRef_modInFunction ()));
          
+         DPRINTF (("Overloading!"));
+
          st->entries[eindex] = e;
 
          if (uentry_isDatatype (e))
            {
-             uentry_setDatatype (e, eindex);
+             uentry_setDatatype (e, typeId_fromUsymId (eindex));
            }
          
          if (st == globtab && !uentry_isSpecified (e))
@@ -709,10 +819,10 @@ usymtab_supEntryAux (/*@notnull@*/ usymtab st,
              exprChecks_checkExport (e);
            }
 
-         if (st->htable != NULL)
+         if (cstringTable_isDefined (st->htable))
            {
-             hashTable_replaceKey (st->htable, uentry_rawName (ce), 
-                                   uentry_rawName (e));
+             cstringTable_replaceKey (st->htable, uentry_rawName (ce), 
+                                      cstring_copy (uentry_rawName (e)));
            }
 
          uentry_free (ce);
@@ -722,21 +832,22 @@ usymtab_supEntryAux (/*@notnull@*/ usymtab st,
        {
          if (uentry_isSpecified (e))
            {
+             DPRINTF (("Here we are: %s", uentry_unparseFull (e)));
+
              if (fileloc_isImport (uentry_whereSpecified (ce)))
-               {
-                 
-                 if (st->htable != NULL)
+               {                 
+                 if (cstringTable_isDefined (st->htable))
                    {
-                     hashTable_replaceKey (st->htable, 
-                                           uentry_rawName (ce), 
-                                           uentry_rawName (e));
+                     cstringTable_replaceKey (st->htable, 
+                                              uentry_rawName (ce), 
+                                              cstring_copy (uentry_rawName (e)));
                    }
                  
                  uentry_free (ce); 
                  st->entries[eindex] = e;
                  ce = e;
 
-                 if (uentry_isDatatype (e)) uentry_setDatatype (e, eindex);
+                 if (uentry_isDatatype (e)) uentry_setDatatype (e, typeId_fromUsymId (eindex));
                }
              else 
                {
@@ -746,18 +857,21 @@ usymtab_supEntryAux (/*@notnull@*/ usymtab st,
                    }
                  else
                    {
-                     /* respecification errors already reported */
-  
+                     /* Respecification errors already reported */
+                     DPRINTF (("Respecification: %s / %s", 
+                               fileloc_unparse (uentry_whereSpecified (e)),
+                               bool_unparse (fileloc_isSpec (uentry_whereSpecified (e)))));
+
                      if (uentry_isDatatype (e)) 
                        {
-                         uentry_setDatatype (e, eindex);
+                         uentry_setDatatype (e, typeId_fromUsymId (eindex));
                        }
                      
-                     if (st->htable != NULL)
+                     if (cstringTable_isDefined (st->htable))
                        {
-                         hashTable_replaceKey (st->htable, 
-                                               uentry_rawName (ce), 
-                                               uentry_rawName (e));
+                         cstringTable_replaceKey (st->htable, 
+                                                  uentry_rawName (ce), 
+                                                  cstring_copy (uentry_rawName (e)));
                        }
                      
                      llassert ((st->lexlevel > fileScope || !sRef_modInFunction ()));
@@ -769,15 +883,28 @@ usymtab_supEntryAux (/*@notnull@*/ usymtab st,
            }
          else /* e not specified */
            {
+             DPRINTF (("Merging..."));
+
              if (uentry_isDeclared (ce))
                {
-                 llassert ((st->lexlevel > fileScope || !sRef_modInFunction ()));
+                 /* evans 2001-08-26
+                   No - this can happen for internal typedefs
+                   llassert ((st->lexlevel > fileScope || !sRef_modInFunction ()));
+                 */
+
+                 DPRINTF (("Merge defn"));
                  uentry_mergeDefinition (ce, e);
                }
              else 
                {
-                 llassert ((st->lexlevel > fileScope || !sRef_modInFunction ()));
+                 /* evans 2001-08-26
+                   No - this can happen for internal typedefs
+                   llassert ((st->lexlevel > fileScope || !sRef_modInFunction ()));
+                 */
+
+                 DPRINTF (("Merge entries..."));
                  uentry_mergeEntries (ce, e);
+                 DPRINTF (("After: %s", uentry_unparseFull (ce)));
                }
            }
        }
@@ -786,7 +913,8 @@ usymtab_supEntryAux (/*@notnull@*/ usymtab st,
          if (!(st->lexlevel > fileScope || !sRef_modInFunction ()))
            {
              if (uentry_isDatatype (e) || uentry_isAnyTag (e)
-                 || uentry_isEnumConstant (e))
+                 || uentry_isEnumConstant (e)
+                 || uentry_isStatic (e)) /* bug fix from Brian St. Pierre */
                {
                  ; /* 
                     ** Not a bug.  Code like,
@@ -809,6 +937,7 @@ usymtab_supEntryAux (/*@notnull@*/ usymtab st,
                }
            }
          
+         DPRINTF (("Merge.."));
          uentry_mergeDefinition (ce, e);
        }
       
@@ -818,11 +947,13 @@ usymtab_supEntryAux (/*@notnull@*/ usymtab st,
          
          if (uentry_isFunction (ce) && ctype_isFunction (ct))
            {
-             ct = ctype_returnValue (ct);
+             ct = ctype_getReturnType (ct);
            }
          
-         uentry_setSref (ce, sRef_makeCvar (st->lexlevel, eindex, ct));
-               }
+         uentry_setSref
+           (ce, sRef_makeCvar (st->lexlevel, eindex, ct,
+                               stateInfo_makeLoc (uentry_whereLast (ce), SA_DECLARED)));
+       }
     }
   else /* no previous entry */
     {
@@ -843,7 +974,7 @@ usymtab_supEntryAux (/*@notnull@*/ usymtab st,
          
          eindex = usymtab_getIndex (filetab, ename);
          
-         if (eindex != NOT_FOUND)
+         if (usymtab_indexFound (eindex))
            {
              uentry ce = filetab->entries[eindex];
 
@@ -856,6 +987,9 @@ usymtab_supEntryAux (/*@notnull@*/ usymtab st,
       
       outer = usymtab_lookupQuiet (st->env, ename);
 
+      DPRINTF (("New  : [%p] %s", e, uentry_unparseFull (e)));
+      DPRINTF (("Outer: [%p] %s", outer, uentry_unparseFull (outer)));
+
       /*
       ** no previous definition, add the new one
       */
@@ -864,7 +998,9 @@ usymtab_supEntryAux (/*@notnull@*/ usymtab st,
          && uentry_isValid (outer)
          && !(uentry_isYield (e) || uentry_isYield (outer))
          && fileloc_isDefined (uentry_whereLast (e))
-         && fileloc_isDefined (uentry_whereLast (outer)))
+         && !fileloc_isXHFile (uentry_whereLast (e))
+         && fileloc_isDefined (uentry_whereLast (outer))
+         && !fileloc_isXHFile (uentry_whereLast (outer)))
        {
          if (!uentry_sameKind (outer, e))
            {
@@ -904,27 +1040,27 @@ usymtab_supEntryAux (/*@notnull@*/ usymtab st,
     }
 
  exitPoint:
-    return (staticEntry ? USYMIDINVALID : eindex);
+    return (staticEntry ? usymId_invalid : eindex);
 }
 
-# ifndef NOLCL
 static void
 usymtab_replaceEntryAux (/*@notnull@*/ usymtab st, /*@only@*/ uentry e)
    /*@globals globtab@*/ /*@modifies st, e@*/
 {
   cstring ename = uentry_rawName (e);
-  int eindex;
+  usymId eindex;
 
   /* static tags in global scope */
   eindex = usymtab_getIndex (st, ename);
   
-  if (eindex != NOT_FOUND)
+  if (usymtab_indexFound (eindex))
     {
       uentry ce = st->entries[eindex];      
       
-      if (st->htable != NULL)
+      if (cstringTable_isDefined (st->htable))
        {
-         hashTable_replaceKey (st->htable, uentry_rawName (ce), uentry_rawName (e));
+         cstringTable_replaceKey (st->htable, uentry_rawName (ce), 
+                                  cstring_copy (uentry_rawName (e)));
        }
 
       uentry_free (ce);
@@ -935,7 +1071,6 @@ usymtab_replaceEntryAux (/*@notnull@*/ usymtab st, /*@only@*/ uentry e)
       eindex = usymtab_addEntryAux (st, e, FALSE);
     }
 }
-# endif
 
 /*@=deparrays@*/ 
 
@@ -960,7 +1095,6 @@ static /*@exposed@*/ uentry
   bool stat = (tab == globtab) && uentry_isStatic (e);
   uentry ret;
 
-    
   (void) usymtab_supEntryAux (tab, e, isref);
 
   if (stat)
@@ -1006,6 +1140,12 @@ static /*@exposed@*/ uentry
 
   ret = usymtab_supEntryReturnAux (globtab, e, FALSE);
 
+  /*
+  ** We need to keep track of internal function declarations, so
+  ** we can remove them from the symbol table after exiting this
+  ** function.  This is a bit bogus, of course.
+  */
+
   if (sRef_modInFunction ())
     {
       recordFunctionType (ret);
@@ -1024,13 +1164,14 @@ usymtab_supTypeEntry (/*@only@*/ uentry e)
 
   if (uentry_isAbstractDatatype (e))
     {
-      uid = usymtab_supAbstractTypeEntry (e, FALSE);
-      ret = ctype_createAbstract (uid);
+      typeId tid = usymtab_supAbstractTypeEntry (e, FALSE);
+      ret = ctype_createAbstract (tid);
+      uid = typeId_toUsymId (tid);
     }
   else
     {
       uid = usymtab_supEntryAux (globtab, e, FALSE);
-      ret = ctype_createUser (uid);
+      ret = ctype_createUser (typeId_fromUsymId (uid));
     }
 
   if (sRef_modInFunction ())
@@ -1047,14 +1188,71 @@ usymtab_supReturnTypeEntry (/*@only@*/ uentry e)
   /*@modifies globtab@*/
 {
   usymId uid;
-  
+
+  DPRINTF (("Abstract? %s", uentry_unparseFull (e)));
+
   if (uentry_isAbstractDatatype (e))
     {
-      uid = usymtab_supAbstractTypeEntry (e, FALSE);
+      uid = typeId_toUsymId (usymtab_supAbstractTypeEntry (e, FALSE));
+    }
+  else if (uentry_isMaybeAbstract (e) && context_getFlag (FLG_IMPABSTRACT))
+    {
+      bool maybeabs = TRUE;
+      cstring sname = uentry_getName (e);
+      uentry ue = usymtab_lookupGlobSafe (sname);
+      cstring_free (sname);
+
+      if (uentry_isValid (ue)) 
+       {
+         DPRINTF (("Lookup: %s", uentry_unparseFull (ue)));
+
+         if (uentry_isDatatype (ue)) 
+           {
+             if (uentry_isMaybeAbstract (ue))
+               {
+                 ;
+               }
+             else
+               {
+                 maybeabs = FALSE;
+               }
+           }
+         else
+           {
+             DPRINTF (("Not datatype!"));
+           }
+       }
+      
+      if (maybeabs)
+       {
+         uentry ux;
+         typeId tid = usymtab_supAbstractTypeEntry (e, FALSE);
+         ux = usymtab_getTypeEntry (tid);
+         uentry_setAbstract (ux);
+         uid = typeId_toUsymId (tid);
+       }
+      else
+       {
+         uid = usymtab_supEntryAux (globtab, e, FALSE);
+         e = usymtab_getTypeEntry (typeId_fromUsymId (uid));
+         
+         if (uentry_isMaybeAbstract (e))
+           {
+             uentry_setConcrete (e);
+           }
+       }
     }
   else
     {
       uid = usymtab_supEntryAux (globtab, e, FALSE);
+      e = usymtab_getTypeEntry (typeId_fromUsymId (uid));
+
+      /*? evans 2002-12-16 removed this? it doesn't make sense
+      if (uentry_isMaybeAbstract (e))
+       {
+         uentry_setConcrete (e);
+       }
+      */
     }
   
   if (sRef_modInFunction ())
@@ -1065,21 +1263,23 @@ usymtab_supReturnTypeEntry (/*@only@*/ uentry e)
     return (globtab->entries[uid]);
 }
 
-usymId
+typeId
 usymtab_supAbstractTypeEntry (/*@only@*/ uentry e, bool dodef)
   /*@globals globtab, filetab@*/
   /*@modifies globtab, e@*/
 {
-  usymId uid;
-  uid = usymtab_supEntryAux (globtab, e, FALSE);
+  typeId uid;
+  uentry ue;
+
+  uid = typeId_fromUsymId (usymtab_supEntryAux (globtab, e, FALSE));
+  ue = usymtab_getTypeEntry (uid);
 
   if (dodef)
     {
-      uentry ue = usymtab_getTypeEntry (uid);
       uentry_setDatatype (ue, uid);
     }
 
-  if (context_getFlag (FLG_ACCESSMODULE))
+  if (context_getFlag (FLG_ACCESSMODULE)) /* was accessfile */
     {
       context_addFileAccessType (uid);
     }
@@ -1092,15 +1292,14 @@ usymtab_supAbstractTypeEntry (/*@only@*/ uentry e, bool dodef)
   return (uid);
 }
 
-# ifndef NOLCL
-usymId
+typeId
 usymtab_supExposedTypeEntry (/*@only@*/ uentry e, bool dodef)
   /*@globals globtab, filetab@*/
   /*@modifies globtab, e@*/
 {
-  usymId uid;
+  typeId uid;
 
-  uid = usymtab_supEntryAux (globtab, e, FALSE);
+  uid = typeId_fromUsymId (usymtab_supEntryAux (globtab, e, FALSE));
 
   if (dodef)
     {
@@ -1114,16 +1313,15 @@ usymtab_supExposedTypeEntry (/*@only@*/ uentry e, bool dodef)
       recordFunctionType (globtab->entries[uid]);
     }
 
-  return (uid);
+  return uid;
 }
-# endif
 
 ctype
 usymtab_supForwardTypeEntry (/*@only@*/ uentry e)
   /*@globals globtab, filetab@*/
   /*@modifies globtab, e@*/
 {
-  usymId uid = usymtab_supEntryAux (globtab, e, FALSE);
+  typeId uid = typeId_fromUsymId (usymtab_supEntryAux (globtab, e, FALSE));
   uentry ue = usymtab_getTypeEntry (uid);
 
     uentry_setDatatype (ue, uid);
@@ -1142,7 +1340,6 @@ void
   /*@modifies utab, globtab, e@*/
 {
   sRef old = uentry_getSref (e);
-
   
   if (sRef_isType (old))
     {
@@ -1204,16 +1401,17 @@ usymtab_inDeepScope () /*@globals utab@*/
   return (utab->lexlevel > paramsScope);
 }
 
-static int
+static usymId
 usymtab_getIndex (/*@notnull@*/ usymtab s, cstring k)
 {
   int i;
 
-  if (s->htable != NULL)
-    {
-      i = hashTable_lookup (s->htable, k);
+  DPRINTF (("Lookup %s", k));
 
-      return i;
+  if (cstringTable_isDefined (s->htable))
+    {
+      i = cstringTable_lookup (s->htable, k);
+      return usymId_fromInt (i);
     }
   else
     {
@@ -1221,36 +1419,42 @@ usymtab_getIndex (/*@notnull@*/ usymtab s, cstring k)
        {
          uentry current = s->entries[i];
 
+         DPRINTF (("Check %d: %s", i, uentry_rawName (current)));
+
          if (!uentry_isUndefined (current) 
              && cstring_equal (uentry_rawName (current), k))
            {
-             return i;
+             return usymId_fromInt (i);
            }
        }
 
-      return NOT_FOUND;
+      return usymId_notfound;
     }
 }
 
 static uentry
-usymtab_fetchIndex (/*@notnull@*/ usymtab s, int i)
+usymtab_fetchIndex (/*@notnull@*/ usymtab s, usymId ui)
 {
+  int i = usymId_toInt (ui);
   llassert (i >= 0 && i < s->nentries);
   return (s->entries[i]);
 }
 
-usymId
+typeId
 usymtab_getTypeId (cstring k) /*@globals globtab@*/
 {
   usymId uid = usymtab_getIndex (globtab, k);
 
-  if (uid == NOT_FOUND) return USYMIDINVALID;
-
-  if (!(uentry_isDatatype (usymtab_getTypeEntry (uid)))) {
-    return USYMIDINVALID;
-  }
-
-  return uid;
+  if (!usymtab_indexFound (uid)
+      || !(uentry_isDatatype (usymtab_getTypeEntry (typeId_fromUsymId (uid)))))
+    
+    {
+      return typeId_invalid;
+    }
+  else
+    {
+      return typeId_fromUsymId (uid);
+    }
 }
 
 /*@dependent@*/ uentry
@@ -1258,7 +1462,8 @@ usymtab_lookupStructTag (cstring k)
 {
   cstring sname = makeStruct (k);
   uentry ue = usymtab_lookupGlob (sname);
-    cstring_free (sname);
+  
+  cstring_free (sname);
   return (ue);
 }
 
@@ -1288,16 +1493,16 @@ usymtab_getId (cstring k) /*@globals globtab@*/
   usymId uid = usymtab_getIndex (globtab, k);
   uentry ue;
 
-  if (uid == NOT_FOUND)
+  if (!usymtab_indexFound (uid))
     {
-      return USYMIDINVALID;
+      return usymId_invalid;
     }
 
   ue = usymtab_getGlobalEntry (uid);
 
   if (uentry_isPriv (ue))
     {
-      return USYMIDINVALID;
+      return usymId_invalid;
     }
 
   return uid;
@@ -1306,9 +1511,9 @@ usymtab_getId (cstring k) /*@globals globtab@*/
 static /*@exposed@*/ uentry 
 usymtab_getEntryAux (/*@notnull@*/ usymtab s, usymId uid)
 {
-  llassert (uid != USYMIDINVALID);
+  llassert (uid != usymId_invalid);
  
-  if (uid < 0 || uid >= s->nentries)
+  if (uid < 0 || uid >= usymId_fromInt (s->nentries))
     {
       llcontbug (message ("usymtab_getEntry: out of range: level = %d [%d]",
                          s->lexlevel, uid));
@@ -1338,13 +1543,12 @@ usymtab_getEntryAux (/*@notnull@*/ usymtab s, usymId uid)
     }
 }
 
-/*@dependent@*/ /*@exposed@*/ uentry 
-  usymtab_getTypeEntry (usymId uid)
+/*@dependent@*/ /*@exposed@*/ uentry usymtab_getTypeEntry (typeId uid)
   /*@globals globtab@*/
 {
   if (dbgload)
     {
-      if (uid >= 0 && uid < globtab->nentries)
+      if (uid >= 0 && uid < typeId_fromInt (globtab->nentries))
        {
          return (globtab->entries[uid]);
        }
@@ -1355,8 +1559,7 @@ usymtab_getEntryAux (/*@notnull@*/ usymtab s, usymId uid)
     }
   else
     {
-      llassert (uid >= 0 && uid < globtab->nentries);
-      
+      llassert (uid >= 0 && uid < typeId_fromInt (globtab->nentries));
       return (globtab->entries[uid]);
     }
 }
@@ -1365,30 +1568,27 @@ usymtab_getEntryAux (/*@notnull@*/ usymtab s, usymId uid)
 ** in load files
 */
 
-/*@dependent@*/ /*@exposed@*/ uentry 
-  usymtab_getTypeEntrySafe (usymId uid)
+/*@dependent@*/ /*@exposed@*/ uentry usymtab_getTypeEntrySafe (typeId uid)
   /*@globals globtab@*/
 {
-  if (uid < 0 || uid >= globtab->nentries)
+  if (uid < 0 || uid >= typeId_fromInt (globtab->nentries))
     {
       return uentry_undefined;
     }
-
-      return (globtab->entries[uid]);
+  
+  return (globtab->entries[uid]);
 }
 
-bool
-  usymtab_isBoolType (usymId uid)
+bool usymtab_isBoolType (typeId uid)
   /*@globals globtab@*/
 {
-  llassert (uid >= 0 && uid < globtab->nentries);
+  llassert (uid >= 0 && uid < typeId_fromInt (globtab->nentries));
 
   return (cstring_equal (uentry_rawName (globtab->entries[uid]),
                         context_getBoolName ()));
 }
  
-cstring
-usymtab_getTypeEntryName (usymId uid)
+cstring usymtab_getTypeEntryName (typeId uid)
    /*@globals globtab@*/
 {
   uentry ue;
@@ -1410,23 +1610,25 @@ usymtab_getTypeEntryName (usymId uid)
   return (uentry_getName (ue));
 }
 
-static void
+# if 0
+/*@unused@*/ static void
 usymtab_rehash (/*@notnull@*/ usymtab s)
 {
   int i;
   
-  if (s->htable != NULL)
+  if (cstringTable_isDefined (s->htable))
     {
-      hashTable_free (s->htable);
+      cstringTable_free (s->htable);
     }
   
-  s->htable = hashTable_create (LLHASHSIZE);
+  s->htable = cstringTable_create (LLAHSHSIZE);
 
   for (i = 0; i < s->nentries; i++)
     {
-      hashTable_insert (s->htable, uentry_rawName (s->entries[i]), i);
+      cstringTable_insert (s->htable, cstring_copy (uentry_rawName (s->entries[i])), i);
     }
 }
+# endif
 
 /*
 ** superficial copy of usymtab
@@ -1457,12 +1659,16 @@ usymtab_shallowFree (/*@only@*/ /*@notnull@*/ usymtab s)
   /*@-compdestroy@*/ sfree (s); /*@=compdestroy@*/
 }
 
+usymId usymtab_convertTypeId (typeId uid)
+{
+  return usymtab_convertId (typeId_toUsymId (uid));
+}
+
 /*
-** converts usymId from old table to sorted one
+** usymtab_convertId: converts usymId from old table to sorted one
 */
 
-usymId 
-  usymtab_convertId (usymId uid)
+usymId usymtab_convertId (usymId uid)
   /*@globals oldtab, utab@*/
 {
   uentry ue;
@@ -1478,8 +1684,12 @@ usymId
   name = uentry_rawName (ue);
 
   ret = usymtab_getIndex (utab, name);
+  llassert (ret == uid); /*! for now, no rehash! */
+  DPRINTF (("Convert: %s [%d] -> %s [%d]",
+           uentry_unparse (ue), uid,
+           uentry_unparse (utab->entries[ret]), ret));
 
-  llassertprint (ret != USYMIDINVALID, ("convertId: return is invalid"));
+  llassertprint (ret != usymId_invalid, ("convertId: return is invalid"));
 
   return (ret);
 }
@@ -1490,25 +1700,36 @@ usymtab_prepareDump (void)
    /*@modifies oldtab, utab@*/
 {
   llassert (usymtab_inGlobalScope ());
-
   llassert (oldtab == usymtab_undefined);
 
+  /*
+  DPRINTF (("Preparing to dump:"));
+  usymtab_printAll ();
+  */
+
   oldtab = usymtab_shallowCopy (utab);
 
   /* 
-     alpha compare - make sure order is same on different platforms
-     error messages appear in same order 
+  ** alpha compare - make sure order is same on different platforms
+  ** error messages appear in same order 
   */
 
+  /*
   qsort (utab->entries, (size_t)utab->nentries, 
-        sizeof (*utab->entries), (int (*)(const void *, const void *)) uentry_xcomparealpha);
-
+        sizeof (*utab->entries), 
+        (int (*)(const void *, const void *)) uentry_xcomparealpha);
+  
   usymtab_rehash (utab);
+  */
+
+  /*
+  DPRINTF (("After rehash:"));
+  usymtab_printAll ();
+  */
 }
 
-void
-  usymtab_dump (FILE *fout)
-  /*@globals utab, oldtab@*/
+void usymtab_dump (FILE *fout)
+     /*@globals utab, oldtab@*/
 {
   int i;
   bool neednl = FALSE;
@@ -1527,61 +1748,143 @@ void
       uentry thisentry = utab->entries[i];
       ekind  thisekind = uentry_getKind (thisentry);
 
-      
-      if (uentry_hasRealName (thisentry)) {
-       if (thisekind != lastekind)
-         {
-           if (neednl)
-             {
-               check (fputc ('\n', fout) == (int) '\n');
-             }
-           
-           neednl = FALSE;
-           lastentry = uentry_undefined;
-           fprintf (fout, "*%d (%s)\n", ekind_toInt (thisekind),  
-                    cstring_toCharsSafe (ekind_capName (thisekind)));
-           lastekind = thisekind;
-           linelen = 0;
-         }
-       
-       if (uentry_isInvalid (lastentry) || !uentry_equiv (lastentry, thisentry)
-           || (linelen > (MAX_DUMP_LINE_LENGTH - (2 * MAX_NAME_LENGTH))))
-         {
-           cstring cdump = uentry_dump (thisentry);
-           
-           lastentry = thisentry;
-           if (neednl)
-             {
-               check (fputc ('\n', fout) == (int) '\n');
-               linelen = 0;
-             }
-           
-           linelen += cstring_length (cdump);
-           
-           /* no new line here! */
-           if (cstring_length (cdump) > 0) 
-             {
-               check (fputs (cstring_toCharsSafe (cdump), fout) != EOF);
-             }
-           
-           cstring_free (cdump);
-           neednl = TRUE;
-         }
-       else
-         {
-           cstring cdump = uentry_rawName (thisentry);
-                   linelen += cstring_length (cdump);
-           fprintf (fout, "#%s", cstring_toCharsSafe (cdump));
-         }
-      }
+      if (!uentry_hasRealName (thisentry))
+       {
+         llassert (uentry_isGlobalMarker (thisentry));
+
+         if (neednl)
+           {
+             check (fputc ('\n', fout) == (int) '\n');
+           }
+         
+         fprintf (fout, "*%d (GlobalMarker)\n", KGLOBALMARKER);
+         lastekind = KINVALID;
+         linelen = 0;
+         neednl = FALSE;
+       }
+      else
+       {
+         if (thisekind != lastekind)
+           {
+             if (neednl)
+               {
+                 check (fputc ('\n', fout) == (int) '\n');
+               }
+             
+             neednl = FALSE;
+             lastentry = uentry_undefined;
+             fprintf (fout, "*%d (%s)\n", ekind_toInt (thisekind),  
+                      cstring_toCharsSafe (ekind_capName (thisekind)));
+             lastekind = thisekind;
+             linelen = 0;
+           }
+         
+         /*
+         ** evans - 2001-02-18 - added the - 48 fudge factor...
+         ** extra characters dumped, but I haven't counded them carefully... 
+         */
+         
+         if (uentry_isInvalid (lastentry) || !uentry_equiv (lastentry, thisentry)
+             || (linelen > (MAX_DUMP_LINE_LENGTH - (2 * MAX_NAME_LENGTH) - 48))) 
+           {
+             cstring cdump;
+             
+             DPRINTF (("Dumping entry: %d", i));
+             cdump = message ("^%d %q", i, uentry_dump (thisentry));
+             /* was: cdump = uentry_dump (thisentry)); */
+             
+             lastentry = thisentry;
+             if (neednl)
+               {
+                 check (fputc ('\n', fout) == (int) '\n');
+                 linelen = 0;
+               }
+             
+             linelen += cstring_length (cdump);
+             
+             /* no new line here! */
+             if (cstring_length (cdump) > 0) 
+               {
+                 check (fputs (cstring_toCharsSafe (cdump), fout) != EOF);
+               }
+             
+             cstring_free (cdump);
+             neednl = TRUE;
+           }
+         else
+           {
+             cstring cdump = uentry_rawName (thisentry);
+             DPRINTF (("Raw name: %s", cdump));
+             linelen += (cstring_length (cdump) + 1);
+             fprintf (fout, "#%s", cstring_toCharsSafe (cdump));
+           }
+       }
     }
 
   if (neednl)
     {
       check (fputc ('\n', fout) == (int) '\n');
     }
+
+  lastekind = KINVALID;
+
+  fprintf(fout, ";; Library constraints\n");
+
+ /*drl July 27 added this so that libraries without
+    buffer constraints would be handled correctly.
+    I'm trying to do this without breaking older libraries.
+
+    Splint should still be able to handle libraries without this message.
+ */
+
+  
+  fprintf(fout, "start_Buffer_Constraints\n");
+
+  for (i = 0; i < utab->nentries; i++)
+    {
+      uentry thisentry = utab->entries[i];
+
+      if (uentry_isFunction (thisentry) )
+       {
+         constraintList preconditions;
+         constraintList postconditions;
+
+         preconditions = uentry_getFcnPreconditions (thisentry);
+         postconditions = uentry_getFcnPostconditions (thisentry);
+
+         if ( constraintList_isDefined(preconditions) ||
+              constraintList_isDefined(postconditions) )
+           {
+             fprintf(fout,"%s\n", cstring_toCharsSafe (uentry_rawName(thisentry) ) );
+             if (constraintList_isDefined(preconditions) )
+               {
+                 fprintf(fout,"pre:\n");
+                 constraintList_dump(preconditions, fout);
+                 fprintf (fout, ";; end precondition constraints\n" );
+                 constraintList_free(preconditions);
+               }
+             else
+               {
+                 fprintf(fout,"pre:EMPTY\n");
+               }
+             if (constraintList_isDefined(postconditions) )
+               {
+                 fprintf(fout,"post:\n");
+                 constraintList_dump(postconditions, fout);
+                 fprintf (fout, ";; end precondition constraints\n" );
+                 constraintList_free(postconditions);
+               }
+             else
+               {
+                 fprintf(fout,"post:EMPTY\n");
+               }
+           }
+                 
+       }
+    }
 }
 
+
 void usymtab_load (FILE *f)
   /*@globals utab, globtab@*/
   /*@modifies utab, *f@*/
@@ -1598,37 +1901,92 @@ void usymtab_load (FILE *f)
   llassert (utab == globtab);
   llassert (utab->nentries == 0);
 
-  while (fgets (s, MAX_DUMP_LINE_LENGTH, f) != NULL 
+  while (((s = reader_readLine (f, s, MAX_DUMP_LINE_LENGTH)) != NULL)
         && *s == ';')
     {
-      ; /* ignore ;-comments */
+      /* ignore ; comments */      ;
     }
-
+  
   while (s != NULL && *s != ';')
     {
-      
+      int index;
+
       if (*s == '*')
        {
+         int ek;
          s++;
-         kind = ekind_fromInt (getInt (&s));
+         ek = reader_getInt (&s);
 
-                 goto nextiter;
+         if (ek == KGLOBALMARKER) 
+           {
+             uentry lue = uentry_makeGlobalMarker ();
+             DPRINTF (("Adding global marker: %s", uentry_unparseFull (lue)));
+             usymtab_addEntryAlways (utab, lue);
+             kind = KINVALID;
+             goto nextiter;
+           }
+         else
+           {
+             kind = ekind_fromInt (ek);
+             goto nextiter;
+           }
        }
 
       if (*s == '$')
        {
          llfatalerror
            (cstring_makeLiteral 
-            ("Library is in obsolete format.  Use lclint +whichlib "
+            ("Library is in obsolete format.  Use splint +whichlib "
              "to see which library is being loaded."));
        }
 
+      if (reader_optCheckChar (&s, '^'))
+       {
+         index = reader_getInt (&s);
+       }
+      else
+       {
+         index = -1;
+       }
+
+      llassert (kind != KINVALID);
       ue = uentry_undump (kind, loc, &s);
-      DPRINTF (("Load: %s", uentry_unparseFull (ue)));
+
+      llassert (utab->nentries == index || index == -1);
 
       if (uentry_isValid (ue))
        {       
-         ue = usymtab_addEntryBase (utab, ue);
+         int lastindex = utab->nentries;
+         ue = usymtab_addEntryAlways (utab, ue);
+
+
+# if 0
+         if (uentry_isConstant (ue)) /*@i23! isPreProcessorMacro */
+           {
+             cstring uname = uentry_getName (ue);
+             
+             /* Also check its a macro... */
+             DPRINTF (("Installing: %s", uname));
+
+             cpphash_installMacro 
+               (mstring_copy (cstring_toCharsSafe (uname)),
+                cstring_length (uname),
+                cpplib_createDefinition (message ("%s 255", uname),
+                                         loc,
+                                         FALSE, FALSE).defn,
+                cpphash_hashCode (cstring_toCharsSafe (uname),
+                                  cstring_length (uname),
+                                  CPP_HASHSIZE));
+             
+             DPRINTF (("After install: %s", uname));
+           }
+# endif
+
+         if (utab->nentries != lastindex + 1)
+           {
+             DPRINTF (("No add: %s", uentry_unparseFull (ue)));
+             BADBRANCH;
+           }
          /*@-branchstate@*/ 
        } 
       /*@=branchstate@*/
@@ -1639,11 +1997,14 @@ void usymtab_load (FILE *f)
 
       while (*(s++) == '#')
        {
-         cstring name = cstring_fromCharsO (getWord (&s));
+         cstring name = cstring_fromCharsO (reader_getWord (&s));
          uentry nue = uentry_nameCopy (name, ue);
+         /*
+           DPRINTF (("Name copy: %s", uentry_unparseFull (nue)));
+           BADBRANCH;
+         */
 
-         DPRINTF (("Name copy: %s", uentry_unparseFull (nue)));
-         usymtab_addEntryBase (utab, nue);
+         usymtab_addEntryAlways (utab, nue);
        }
 
       while ((c = *s) != '\0' && (c !='\n'))
@@ -1657,9 +2018,85 @@ void usymtab_load (FILE *f)
        }
 
     nextiter:
-      s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
+      {
+       s = reader_readLine (f, os, MAX_DUMP_LINE_LENGTH);
+      }
     }
 
+  /*DRL added 6/21/01
+    to handle reading of buffer overflow related constraints
+   */
+  while (fgets (s, MAX_DUMP_LINE_LENGTH, f) != NULL 
+        && *s == ';')
+    {
+      ; /* ignore ;-comments */
+    }
+
+  /*drl July 27 added this so that libraries without
+    buffer constraints would be handled correctly.
+    I'm trying to do this without breaking older libraries*/
+  
+  /*check for "optional" start buffer constraints message*/
+
+  if (mstring_equalPrefix (s, "start_Buffer_Constraints")) 
+    {
+      (void) fgets (s, MAX_DUMP_LINE_LENGTH, f);
+    }
+  
+  while (s != NULL && *s != ';')
+    {
+      constraintList preconditions;
+      constraintList postconditions;
+      cstring name = cstring_fromChars (reader_getWord (&s));
+      cstring temp;
+
+      ue = usymtab_lookup (name);
+      cstring_free (name);
+      
+      preconditions = constraintList_undefined;
+      postconditions = constraintList_undefined;
+      
+      if (!uentry_isValid(ue) )
+       {
+         llfatalbug ((message("Invalid uentry for %s library file may be corrupted", cstring_fromChars(s) ) ));
+       }
+      s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
+
+      temp = cstring_fromChars (reader_getWord(&s) );
+      
+      if (cstring_compareLit (temp,"pre:") == 0 )
+       {
+         preconditions = constraintList_undump (f);
+       }
+      else
+       {
+         if (cstring_compareLit (temp,"pre:EMPTY") != 0 )
+           llfatalbug ((message("Error reading library file pre:EMPTY expected but got %s", temp ) ));
+       }
+      
+      cstring_free(temp);
+      
+      s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
+
+      temp = cstring_fromChars(reader_getWord(&s) );
+      if (cstring_compareLit (temp, "post:") == 0 )
+       {
+         postconditions = constraintList_undump (f);
+       }
+      else
+       {
+         if (cstring_compareLit (temp, "post:EMPTY") != 0 )
+           llfatalbug ((message("Error reading library file post:EMPTY expected but got %s", temp ) ));
+       }
+      
+      cstring_free (temp);
+
+      uentry_setPreconditions (ue, functionConstraint_createBufferConstraint (preconditions));
+      uentry_setPostconditions (ue, functionConstraint_createBufferConstraint (postconditions));
+      
+      s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
+    }
+    
   dbgload = FALSE;
   sfree (os);
 }
@@ -1682,8 +2119,8 @@ usymtab_enterFile ()
     {
       if (sRef_hasDerived (uentry_getSref (ue)))
        {
-         fprintf (g_msgstream, "Derived Global: %s\n", uentry_unparse (ue));
-         fprintf (g_msgstream, "sRef: %s\n", sRef_unparseFull (ue->sref));
+         fprintf (g_warningstream, "Derived Global: %s\n", uentry_unparse (ue));
+         fprintf (g_warningstream, "sRef: %s\n", sRef_unparseFull (ue->sref));
        }
     } end_usymtab_entries ;
 
@@ -1740,7 +2177,6 @@ usymtab_handleParams (void)
   usymtab ptab = utab->env;
   uentry fcn = context_getHeader ();
 
-  
   usymtab_entries (ptab, param)
     {
       uentry ue;
@@ -1749,147 +2185,192 @@ usymtab_handleParams (void)
        {
          sRef uref;
          sRef pref = uentry_getSref (param);
-         
-         llassertprint (uentry_isAnyParam (param), 
-                        ("not param: %s", 
-                         uentry_unparseFull (param)));
-         
-         
-         ue = uentry_makeVariable (fixParamName (uentry_rawName (param)),
-                                   uentry_getType (param),
-                                   fileloc_copy (uentry_whereDeclared (param)),
-                                   FALSE);
 
-         uentry_copyState (ue, param);
-         uentry_setRefParam (ue);
-         
-         ue = usymtab_supEntrySrefReturn (ue);
-                 
-         /* must be after supercede! */
+         /* Could be a global. */
          
-         if (!sRef_stateKnown (pref))
-           {
-             uentry_setDefState (ue, SS_DEFINED);
-             uentry_setDefState (param, SS_DEFINED);
-           }
-         else
-           {
-             if (sRef_isStateSpecial (pref))
+         if (uentry_isAnyParam (param))
+           {     
+             ue = uentry_makeVariable (fixParamName (uentry_rawName (param)),
+                                       uentry_getType (param),
+                                       fileloc_copy (uentry_whereDeclared (param)),
+                                       FALSE);
+             
+             uentry_copyState (ue, param);
+             uentry_setRefParam (ue);
+             
+             ue = usymtab_supEntrySrefReturn (ue);
+             
+             /* must be after supercede! */
+             
+             if (!sRef_stateKnown (pref))
                {
-                 uentry_setDefState (ue, SS_ALLOCATED);
+                 uentry_setDefState (ue, SS_DEFINED);
+                 uentry_setDefState (param, SS_DEFINED);
                }
              else
                {
-                 uentry_setDefState (ue, sRef_getDefState (pref));
+                 if (sRef_isStateSpecial (pref))
+                   {
+                     uentry_setDefState (ue, SS_SPECIAL); /* ALLOCATED); */
+                     /* evans 2002-01-01: should be unnecessary, the pre clauses
+                     **    set the state if necessary.
+                     */
+                   }
+                 else
+                   {
+                     uentry_setDefState (ue, sRef_getDefState (pref));
+                   }
                }
-           }
-
-         uref = uentry_getSref (ue);
-         
-         if (sRef_isStack (uref))
-           {
-             alkind pkind = sRef_getAliasKind (pref);
+             
+             uref = uentry_getSref (ue);
+             
+             if (sRef_isStack (uref))
+               {
+                 alkind pkind = sRef_getAliasKind (pref);
+                 
+                 if (alkind_isKnown (pkind) && !alkind_isLocal (pkind)
+                     && !alkind_isStack (pkind))
+                   {
+                     sRef_setAliasKind (uref, pkind, fileloc_undefined);
+                     sRef_setOrigAliasKind (uref, pkind);
+                   }
+                 else
+                   {
+                     sRef_setAliasKind (uref, AK_IMPTEMP, fileloc_undefined);
+                     sRef_setOrigAliasKind (uref, AK_IMPTEMP);
+                     
+                     if (uentry_isOut (param))
+                       {
+                         ;
+                       }
+                     else
+                       {
+                         sRef_setDefined (uref, fileloc_undefined);
+                       }
+                   }
+                 
+               }
+             
+             usymtab_addMustAlias (uref, pref);   
+             
+             if (!(uentry_isOnly (param) || uentry_isUnique (param)))
+               {
+                 /*
+                 ** This is needed for detecting possibly aliased parameters.
+                 */
 
-             if (alkind_isKnown (pkind) && !alkind_isLocal (pkind)
-                 && !alkind_isStack (pkind))
+                 sRef s = sRef_makeExternal (uref);
+                 usymtab_addMustAlias (uref, s);   
+               }
+             
+             if (sRef_isKillRef (pref))
+               {
+                 sRef_setAliasKind (uref, AK_NEWREF, fileloc_undefined);
+                 sRef_setOrigAliasKind (uref, AK_KILLREF);
+               }
+             else if (sRef_isRefCounted (uref))
                {
-                 sRef_setAliasKind (uref, pkind, fileloc_undefined);
-                 sRef_setOrigAliasKind (uref, pkind);
+                 sRef_setOrigAliasKind (uref, AK_REFCOUNTED);
                }
              else
                {
-                 sRef_setAliasKind (uref, AK_IMPTEMP, fileloc_undefined);
-                 sRef_setOrigAliasKind (uref, AK_IMPTEMP);
-
-                 if (uentry_isOut (param))
-                   {
-                     ;
-                   }
-                 else
-                   {
-                     sRef_setDefined (uref, fileloc_undefined);
-                   }
+                 /* was AK_UNIQUE */
+                 sRef_setOrigAliasKind (uref, AK_LOCAL);
                }
-
-                   }
-
-                 usymtab_addMustAlias (uref, pref);   
-
-         if (!(uentry_isOnly (param) || uentry_isUnique (param)))
-           {
-             sRef s = sRef_makeExternal (uref);
-
-                     usymtab_addMustAlias (uref, s);   
-           }
-         
-         if (sRef_isKillRef (pref))
-           {
-             sRef_setAliasKind (uref, AK_NEWREF, fileloc_undefined);
-             sRef_setOrigAliasKind (uref, AK_KILLREF);
-           }
-         else if (sRef_isRefCounted (uref))
-           {
-             sRef_setOrigAliasKind (uref, AK_REFCOUNTED);
            }
          else
            {
-             /* was AK_UNIQUE */
-             sRef_setOrigAliasKind (uref, AK_LOCAL);
            }
        }
-      else
-       {
-               }
     } end_usymtab_entries;
-
-
-  if (uentry_hasSpecialClauses (fcn))
+  
+  
+  if (uentry_hasStateClauseList (fcn))
     {
-      specialClauses clauses = uentry_getSpecialClauses (fcn);
-
-      specialClauses_preElements (clauses, cl)
+      stateClauseList clauses = uentry_getStateClauseList (fcn);
+      
+      stateClauseList_preElements (clauses, cl)
        {
-         sRefSet refs = specialClause_getRefs (cl);
-         sRefMod modf = specialClause_getEntryFunction (cl);
-
+         fileloc loc = stateClause_loc (cl);
+         sRefSet osrs = sRefSet_undefined;
+         sRefSet srs;
+         
+         if (stateClause_isGlobal (cl))
+           {
+             DPRINTF (("Global Marker: %s",
+                       sRef_unparseFull (usymtab_lookupGlobalMarker ())));
+             llassert (sRef_isGlobalMarker (usymtab_lookupGlobalMarker ()));
+             srs = sRefSet_single (usymtab_lookupGlobalMarker ());
+             osrs = srs;
+           }
+         else
+           {
+             srs = stateClause_getRefs (cl);
+           }
          
-         sRefSet_elements (refs, el)
+         sRefSet_elements (srs, el)
            {
              sRef base = sRef_getRootBase (el);
-             
+             sRef sb = sRef_updateSref (el);
+
              if (sRef_isResult (base))
                {
                  ; /* nothing to do before */
                }
-             else if (sRef_isParam (base))
+             else if (sRef_isParam (base) || sRef_isGlobalMarker (base))
                {
-                 if (modf != NULL)
+                 if (stateClause_setsMetaState (cl))
                    {
-                     sRef sb = sRef_updateSref (el);
-                     sRefSet aliases = usymtab_allAliases (sb);
+                     /* copied from exprNode.c:3040 */
+                     qual ql = stateClause_getMetaQual (cl);
+                     annotationInfo ainfo = qual_getAnnotationInfo (ql);
+                     metaStateInfo minfo = annotationInfo_getState (ainfo);
+                     cstring key = metaStateInfo_getName (minfo);
+                     int mvalue = annotationInfo_getValue (ainfo);
                      
-                                     modf (sb, fileloc_undefined);
-                                     
-                     sRefSet_elements (aliases, sr)
+                     DPRINTF (("Sets meta state! %s", stateClause_unparse (cl)));
+                         
+                     if (sRef_isResult (base))
                        {
-                                                 modf (sr, fileloc_undefined);
-                                               } end_sRefSet_elements ;
-
-                     sRefSet_free (aliases);
+                         BADBRANCH;
+                       }
+                     else 
+                       {
+                         sRef_setMetaStateValueComplete (sb, key, mvalue, loc);
+                       }
+                   }
+                 else
+                   {
+                     sRefMod modf = stateClause_getEntryFunction (cl);
+                     
+                     if (modf != NULL)
+                       {
+                         sRefSet aliases = usymtab_allAliases (sb);
+                         
+                         modf (sb, loc);
+                         
+                         sRefSet_elements (aliases, sr)
+                           {
+                             modf (sr, loc);
+                           } end_sRefSet_elements ;
+                           
+                         sRefSet_free (aliases);
+                       }
                    }
                }
              else
                {
                  if (sRef_isValid (base))
                    {
+                     DPRINTF (("Base: %s", sRef_unparseFull (base)));
                      BADBRANCH;
                    }
                }
            } end_sRefSet_elements ;      
-       } end_specialClauses_preElements ;
+       } end_stateClauseList_preElements ;
     }
-  }
-  
+}
+
 void
 usymtab_enterFunctionScope (uentry fcn)
   /*@globals utab, filetab, globtab@*/
@@ -1897,11 +2378,13 @@ usymtab_enterFunctionScope (uentry fcn)
 {
   usymtab t = usymtab_create (US_NORMAL, utab, TRUE);
 
+  DPRINTF (("Enter function: %s", uentry_unparse (fcn)));
+
   if (utab->lexlevel != fileScope)
     {
       if (utab->lexlevel > fileScope)
        {
-         llparseerror (cstring_makeLiteral ("New function scope inside function."));
+         llparseerror (cstring_makeLiteral ("New function scope inside function"));
          
          while (utab->lexlevel > fileScope)
            {
@@ -1916,15 +2399,22 @@ usymtab_enterFunctionScope (uentry fcn)
        }
     /*@-branchstate@*/ } /*@=branchstate@*/
 
+  utab = t;
+  
+  DPRINTF (("Globs: %s", globSet_unparse (uentry_getGlobs (fcn))));
+
   globSet_allElements (uentry_getGlobs (fcn), el)
     {
+      DPRINTF (("Here we go: %s", sRef_unparseFull (el)));
       
       if (sRef_isUndefGlob (el))
        {
-         int index = sRef_getScopeIndex (el);
+         usymId index = sRef_getScopeIndex (el);
          sRef sr = sRef_updateSref (el);
          fileloc loc = uentry_whereEarliest (fcn);
-         
+       
+         DPRINTF (("update: %s", sRef_unparseFull (sr)));
+         DPRINTF (("Undef!"));
          if (sRef_isFileStatic (el))
            {
              ctype ct = sRef_getType (el);
@@ -1974,11 +2464,22 @@ usymtab_enterFunctionScope (uentry fcn)
        }
       else
        {
-         /* defined */ ;
+         /*
+         sRef sr = sRef_updateSref (el);
+         fileloc loc = uentry_whereEarliest (fcn);
+
+         sRef_setDefined (sr, loc);
+         */
+
+         /* defined */
+         /* shouldn't need to do anything! */ 
        }
     } end_globSet_allElements;
 
-  utab = t;
+  DPRINTF (("Globs after: %s", globSet_unparse (uentry_getGlobs (fcn))));
+# ifdef DEBUGSPLINT
+  usymtab_checkAllValid ();
+# endif
 }
 
 static void
@@ -1996,7 +2497,7 @@ usymtab_switchBranch (/*@unused@*/ exprNode s)
   usymtab t = usymtab_create (US_SWITCH, utab, FALSE);
 
   t->aliases = aliasTable_copy (utab->aliases);
-    utab = t;
+  utab = t;
 }
 
 void
@@ -2015,11 +2516,11 @@ usymtab_trueBranch (/*@only@*/ guardSet guards)
 
   guardSet_free (t->guards);
   t->guards = guards;
-
-    aliasTable_free (t->aliases);
+  
+  aliasTable_free (t->aliases);
   t->aliases = aliasTable_copy (utab->aliases);
   
-    utab = t;
+  utab = t;
 }
 
 /*
@@ -2030,7 +2531,7 @@ usymtab_trueBranch (/*@only@*/ guardSet guards)
 */
 
 void
-usymtab_popTrueBranch (exprNode pred, exprNode expr, clause cl)
+usymtab_popTrueBranch (exprNode pred, exprNode expr, clause cl) /*@modifies utab@*/
 {
   /*
   ** add a false branch
@@ -2038,8 +2539,17 @@ usymtab_popTrueBranch (exprNode pred, exprNode expr, clause cl)
   ** it is better to only maintain one version of the code)
   */
 
-  usymtab_altBranch (guardSet_invert (exprNode_getGuards (pred)));
-  usymtab_popBranches (pred, expr, exprNode_undefined, TRUE, cl);
+  if (utab->kind != US_TBRANCH 
+      && context_inIterDef ())
+    {
+      usymtab_exitScope (expr);
+    }
+  else
+    {
+      DPRINTF (("pop true branch.."));
+      usymtab_altBranch (guardSet_invert (exprNode_getGuards (pred)));
+      usymtab_popBranches (pred, expr, exprNode_undefined, TRUE, cl);
+    }
 }
 
 void
@@ -2130,6 +2640,8 @@ usymtab_newCase (/*@unused@*/ exprNode pred, exprNode last)
   bool mustReturn = usymtab_mustEscape (utab);
   usymtab stab = utab;
 
+  DPRINTF (("New case!"));
+
   /*
   ** Find last case (or outer switch)
   */
@@ -2139,9 +2651,7 @@ usymtab_newCase (/*@unused@*/ exprNode pred, exprNode last)
       stab = stab->env;
       llassert (stab != GLOBAL_ENV);
     }
-
-  /* ??? */
-
+  
   while (stab->kind == US_CBRANCH)
     {
       stab = stab->env;
@@ -2207,7 +2717,7 @@ usymtab_popAndBranch (exprNode pred, /*@unused@*/ exprNode expr)
   usymtab otab= utab;
   int i = 0;
 
-    llassert (utab->kind == US_TBRANCH);
+  llassert (utab->kind == US_TBRANCH);
 
   /*
   ** merge each entry in table with its original
@@ -2239,6 +2749,10 @@ usymtab_popAndBranch (exprNode pred, /*@unused@*/ exprNode expr)
        }
     }
 
+  DPRINTF (("Popping and: %s / %s",
+           guardSet_unparse (utab->guards),
+           guardSet_unparse (exprNode_getGuards (pred))));
+
   utab->guards = guardSet_levelUnionFree (utab->guards, 
                                          guardSet_invert (exprNode_getGuards (pred)), 
                                          utab->lexlevel);
@@ -2344,7 +2858,7 @@ usymtab_exitSwitch (/*@unused@*/ exprNode sw, bool allpaths)
            {
              usymtab_entries (stab, current)
                {
-                 if (usymtab_getIndex (ttab, uentry_rawName (current)) == NOT_FOUND)
+                 if (!usymtab_indexFound (usymtab_getIndex (ttab, uentry_rawName (current))))
                    {
                      uentry old = /*@-compmempass@*/
                        usymtab_lookupAux (ltab, uentry_rawName (current));
@@ -2431,9 +2945,7 @@ updateNullState (sRef el, /*@notnull@*/ usymtab ttab,
                 /*@notnull@*/ usymtab ftab, bool trueGuard)
 {
   sRef base = sRef_getRootBase (el);
-  int level = sRef_lexLevel (base);
-  
-        
+  int level = sRef_lexLevel (base);        
     
   if (sRef_isCvar (base))
     {
@@ -2453,13 +2965,17 @@ updateNullState (sRef el, /*@notnull@*/ usymtab ttab,
              if (!guardSet_isGuarded (ttab->guards, el) 
                  && !sRef_isNotNull (sr))
                {
+                 DPRINTF (("Here! %s / %s",
+                           sRef_unparseFull (sr),
+                           sRef_unparseFull (el)));
                  sRef_setDerivNullState (sr, el, NS_DEFNULL);
-                               }
+               }
            }
        }
       else
        {
-               }
+         ;
+       }
       
       ue = usymtab_getRefTab (ftab, level, index);
       
@@ -2467,7 +2983,6 @@ updateNullState (sRef el, /*@notnull@*/ usymtab ttab,
        {
          sRef sr = uentry_getSref (ue);
          
-         
          if (!trueGuard) /* yikes!  forgot the ! */
            {
              sRef_setDerivNullState (sr, el, NS_NOTNULL);
@@ -2479,16 +2994,15 @@ updateNullState (sRef el, /*@notnull@*/ usymtab ttab,
                  && !sRef_isNotNull (sr))
                {
                  sRef_setDerivNullState (sr, el, NS_DEFNULL);
-                               }
+               }
            }
        }
       else
        {
-               }
-      
-          }
-
-      }
+         ;
+       }
+    }  
+}
 
 void
 usymtab_popBranches (exprNode pred, exprNode tbranch, exprNode fbranch, 
@@ -2506,7 +3020,11 @@ usymtab_popBranches (exprNode pred, exprNode tbranch, exprNode fbranch,
   sRefSet fguards = guardSet_getFalseGuards (guards);
   bool mustReturnT = exprNode_mustEscape (tbranch);
   bool mustReturnF = exprNode_mustEscape (fbranch);
-  
+
+  DPRINTF (("Pop branches: %s [mustreturn: %s/%s]", exprNode_unparse (pred),
+           bool_unparse (mustReturnT),
+           bool_unparse (mustReturnF)));
+
   if (exprNode_isDefined (fbranch))
     {
       loc = exprNode_loc (fbranch);
@@ -2553,23 +3071,28 @@ usymtab_popBranches (exprNode pred, exprNode tbranch, exprNode fbranch,
   **
   ** if an entry is in one table, merge it with the original.
   */
-    
+  
+  DPRINTF (("ftab: %d", ftab->nentries));
+
   for (i = 0; i < ftab->nentries; i++)
     {
       uentry fthis = ftab->entries[i];
       uentry old = usymtab_lookupAux (env, uentry_rawName (fthis));
-      int    tindex = usymtab_getIndex (ttab, uentry_rawName (fthis));
+      usymId tindex = usymtab_getIndex (ttab, uentry_rawName (fthis));
       
+      DPRINTF (("Entry: %s / %s", uentry_unparseFull (fthis), uentry_unparseFull (old)));
+         
       if (uentry_isUndefined (old))
        {
          /* possible entry was added as an undefined id */
+         DPRINTF (("Undefined! %s", uentry_rawName (fthis)));
          continue;
        }
       
-      if (tindex != NOT_FOUND)
+      if (usymtab_indexFound (tindex))
        {
          uentry tthis = ttab->entries[tindex];
-         
+
          /* note that is this is in a nested branch,
             it may create a "new" old entry. */
          
@@ -2577,7 +3100,6 @@ usymtab_popBranches (exprNode pred, exprNode tbranch, exprNode fbranch,
            {
              if (!mustReturnT)
                {
-                 
                  uentry_mergeState (fthis, tthis, loc,
                                     mustReturnT, FALSE, FALSE, cl);
                }
@@ -2611,12 +3133,20 @@ usymtab_popBranches (exprNode pred, exprNode tbranch, exprNode fbranch,
     {
       uentry current = ttab->entries[i];
       
+      DPRINTF (("ttab: %s", uentry_unparseFull (current)));
+      
       if (!uentry_isUndefined (current)) 
        {
          uentry old = usymtab_lookupAux (env, uentry_rawName (current));
 
-         llassertprint (!uentry_isUndefined (old), ("name: <%s>", 
-                                                    uentry_rawName (current)));
+         DPRINTF (("Old: %s", uentry_unparseFull (old)));
+
+         if (uentry_isUndefined (old))
+           {
+             llcontbug (message ("Undefined entry: %s", uentry_rawName (current)));
+             continue;
+           }
+
          if (mustReturnF)
            {
              uentry_mergeUses (current, old); 
@@ -2625,7 +3155,7 @@ usymtab_popBranches (exprNode pred, exprNode tbranch, exprNode fbranch,
          else
            {
              /*
-              ** assumes false branch is a fall-through if
+              ** Assumes false branch is a fall-through if
               ** fbranch is not defined.  This is true, unless
               ** where was some greivous error in processing
               ** the else branch of an if-then, in which case
@@ -2635,9 +3165,10 @@ usymtab_popBranches (exprNode pred, exprNode tbranch, exprNode fbranch,
              uentry_mergeState (old, current, loc, mustReturnT, 
                                 FALSE, isOpt, cl);
            }
+
+         DPRINTF (("==> %s", uentry_unparseFull (old)));
        }
     }
-
   
   /*
   ** Plain levelUnion doesn't work, since we need to use the sRef's in env->aliases
@@ -2653,6 +3184,8 @@ usymtab_popBranches (exprNode pred, exprNode tbranch, exprNode fbranch,
                                           ftab->aliases, env->lexlevel);
 
   aliasTable_fixSrefs (env->aliases);
+
+  DPRINTF (("Aliases: %s", aliasTable_unparse (env->aliases)));
   
   /* exit true and false scopes */
   usymtab_quietPlainExitScope ();
@@ -2689,9 +3222,11 @@ void
 usymtab_altBranch (/*@only@*/ guardSet guards)
   /*@modifies utab@*/
 {
-  usymtab t = usymtab_create (US_FBRANCH, utab, FALSE);
+  usymtab t;
   usymtab parent = utab->env;
 
+  t = usymtab_create (US_FBRANCH, utab, FALSE);
+
   /*
   ** If we are in a case, need to close it.  The C syntax
   ** is very liberal, so this kludge is necessary.
@@ -2700,15 +3235,16 @@ usymtab_altBranch (/*@only@*/ guardSet guards)
   usymtab_fixCases ();
 
   DPRINTF (("Current kind: %s", usymtab_unparseStack ()));
+
   llassert (utab->kind == US_TBRANCH);
   llassert (parent != GLOBAL_ENV);
-
+  
   guardSet_free (t->guards);
   t->guards = guards;
-
+  
   aliasTable_free (t->aliases);
   t->aliases = aliasTable_copy (parent->aliases);
-    
+  
   utab = t;
 }
 
@@ -2752,7 +3288,7 @@ usymtab_allDefined (void)
            {
              fileloc dloc = uentry_whereDeclared (e);
              
-             if (fileloc_isLib (dloc))
+             if (fileloc_isLib (dloc) || fileloc_isXHFile (dloc))
                {
                 ;
                }
@@ -2768,6 +3304,7 @@ usymtab_allDefined (void)
                                      ekind_capName (uentry_getKind (e)),
                                      uentry_getName (e)),
                             dloc);
+                         DPRINTF (("decl: %s", uentry_unparseFull (e)));
                        }
                    }
                }
@@ -2831,6 +3368,7 @@ void usymtab_exportHeader (void)
 
          if (fileloc_isDefined (fwhere) 
              && !fileloc_isHeader (fwhere)
+             && !fileloc_isXHFile (fwhere)
              && !(fileloc_isSpecialFile (fwhere)
                   && !context_getFlag (FLG_UNUSEDSPECIAL)))
            {
@@ -2881,12 +3419,10 @@ void usymtab_exportLocal (void)
    /*@globals utab@*/
 {
   int i;
-
   
   for (i = 0; i < utab->nentries; i++)
     {
       uentry ce = utab->entries[i];
-
       
       if (!uentry_isDatatype (ce) && !uentry_isAnyTag (ce) 
          && !uentry_isEitherConstant (ce) 
@@ -3114,7 +3650,7 @@ usymtab_allUsed (void)
              ; /* no errors */
            }
        } /* unused */
-      else if (uentry_isDatatype (ce) || uentry_isAnyTag (ce))
+      else if ((uentry_isDatatype (ce) || uentry_isAnyTag (ce)))
        { /* check all fields */
          ctype ct = uentry_getRealType (ce); 
 
@@ -3124,7 +3660,6 @@ usymtab_allUsed (void)
              ct = ctype_getBaseType (ct);
            }
 
-         
          if (ctype_isSU (ct))
            {
              uentryList fields = ctype_getFields (ct);
@@ -3146,6 +3681,13 @@ usymtab_allUsed (void)
                        }
                      else
                        {
+                         /*
+                         ** evans 2001-06-08
+                         ** Can't report these errors for unnamed structs.
+                         ** No way to tell when there are multiple consistent
+                         ** unnamed structure types.  (Could go through table
+                         ** and mark them all unused...)
+
                          hasError |= optgenerror 
                            (FLG_FIELDUNUSED,
                             message ("Field %q of unnamed %s declared but not used", 
@@ -3153,6 +3695,8 @@ usymtab_allUsed (void)
                                      cstring_makeLiteralTemp
                                      (ctype_isStruct (ct) ? "structure" : "union")),
                             uentry_whereEarliest (field));
+
+                         */
                        }
                      
                      uentry_setUsed (field, fileloc_undefined);
@@ -3189,9 +3733,17 @@ checkGlobalReturn (uentry glob, sRef orig)
 {
   sRef sr = uentry_getSref (glob);
   
-  
+  DPRINTF (("Check global return: %s / orig: %s / sr: %s",
+           uentry_unparseFull (glob),
+           sRef_unparseFull (orig),
+           sRef_unparseFull (sr)));
+
+  DPRINTF (("Is killed: %s", bool_unparse (sRef_isKilledGlob (orig))));
+
   if (context_getFlag (FLG_GLOBSTATE))
     {
+      DPRINTF (("Is killed: %s", sRef_unparseFull (orig)));
+      
       if (sRef_isKilledGlob (orig))
        {
          if (sRef_isStateUndefined (sr)
@@ -3204,23 +3756,26 @@ checkGlobalReturn (uentry glob, sRef orig)
          else
            {
              ctype ct = ctype_realType (uentry_getType (glob));
+             
+             DPRINTF (("Check global destroyed: %s", uentry_unparseFull (glob)));
 
              if (ctype_isVisiblySharable (ct))
                {
                  if (optgenerror 
                      (FLG_GLOBSTATE,
                       message 
-                      ("Killed global %q not released before return",
-                       uentry_getName (glob)),
+                      ("Killed global %q (type %s) not released before return",
+                       uentry_getName (glob),
+                       ctype_unparse (ct)),
                       g_currentloc))
                    {
                      sRef_showStateInfo (sr);
-                                   }
+                   }
                }
              else
                {
-                                 sRef_protectDerivs ();
-                 (void) checkGlobalDestroyed (sr, g_currentloc);
+                 sRef_protectDerivs ();
+                 (void) transferChecks_globalDestroyed (sr, g_currentloc);
                  sRef_clearProtectDerivs ();
                }
            }
@@ -3240,22 +3795,36 @@ checkGlobalReturn (uentry glob, sRef orig)
            }
          else 
            {
-             if (sRef_isDead (sr))
+             if (sRef_isDead (sr) || sRef_isKept (sr))
                {
                  if (optgenerror 
                      (FLG_GLOBSTATE,
                       message ("Function returns with global %q "
-                               "referencing released storage",
-                               uentry_getName (glob)),
+                               "referencing %s storage",
+                               uentry_getName (glob),
+                               cstring_makeLiteralTemp (sRef_isDead (sr) ? "released" : "kept")),
                       g_currentloc))
                    {
-                     sRef_showStateInfo (sr);
+                     if (sRef_isKept (sr))
+                       {
+                         sRef_showAliasInfo (sr);      
+                       }
+                     else
+                       {
+                         sRef_showStateInfo (sr);
+                       }
+
                      sRef_setDefState (sr, SS_UNKNOWN, fileloc_undefined);
                    }
                }
              
-             if (ctype_isRealPointer (uentry_getType (glob)) &&
-                 sRef_possiblyNull (sr) && !uentry_possiblyNull (glob))
+             DPRINTF (("Here: %s / %s",
+                       uentry_unparseFull (glob),
+                       sRef_unparseFull (sr)));
+
+             if (ctype_isRealPointer (uentry_getType (glob))
+                 && sRef_possiblyNull (sr)
+                 && !uentry_possiblyNull (glob))
                {
                  if (optgenerror 
                      (FLG_GLOBSTATE,
@@ -3269,7 +3838,8 @@ checkGlobalReturn (uentry glob, sRef orig)
                }
              else
                {
-                 checkGlobReturn (glob);
+                 DPRINTF (("Check transfer: %s", uentry_unparseFull (glob)));
+                 transferChecks_globalReturn (glob);
                }
            }
        }
@@ -3283,9 +3853,7 @@ checkGlobalReturn (uentry glob, sRef orig)
 void usymtab_checkFinalScope (bool isReturn)
   /*@globals utab@*/
 {
-  bool mustFree = context_getFlag (FLG_MUSTFREE);
   bool mustDefine = context_getFlag (FLG_MUSTDEFINE);
-  /* bool mustNotAlias = context_getFlag (FLG_MUSTNOTALIAS); */
   sRefSet checked = sRefSet_new ();
   usymtab stab = utab;
   int i;
@@ -3301,186 +3869,275 @@ void usymtab_checkFinalScope (bool isReturn)
          uentry ce = stab->entries[i];
          sRef sr = uentry_getSref (ce);
          sRef rb = sRef_getRootBase (sr);
+         valueTable tvalues;
+
+         /*
+         ** Shouldn't check if shadow checked in deeper scope:
+         */
+
+         if (stab != utab)
+           {
+             uentry oue = usymtab_lookupQuietNoAlt (utab, uentry_observeRealName (ce));
 
+             if (!uentry_sameObject (ce, oue))
+               {
+                 /* what if it is one an alternate branch? */
+                 /*@innercontinue@*/ continue;
+               }
+           }
+         
+         DPRINTF (("Here check final scope: %s", uentry_unparseFull (ce)));
+         
          if (ctype_isFunction (uentry_getType (ce)))
            {
              /*@innercontinue@*/ continue;
            }
 
-         if (mustFree)
+         if (uentry_isAnyParam (ce)
+             || uentry_isRefParam (ce)
+             || sRef_isFileOrGlobalScope (rb))
            {
-             DPRINTF (("Check entry: %s", uentry_unparseFull (ce)));
-
-             if (!sRefSet_member (checked, sr) && !sRef_isGlobal (rb))
-               {
-                 if (ctype_isRealSU (uentry_getType (ce))
-                     && !uentry_isAnyParam (ce)
-                     && !uentry_isRefParam (ce)
-                     && !uentry_isStatic (ce)
-                     && !sRef_isDependent (sr)
-                     && !sRef_isOwned (sr))
-                   {
-                     sRefSet als = usymtab_allAliases (sr);
-
-                     
-                     if (sRefSet_isEmpty (als))
-                       {
-                         checkLocalDestroyed (sr, g_currentloc);
-                       }
-                     else
-                       {
-                         /* aliased, no problem */ ;
-                       }
+             /* Don't do the loseref check...but should check state! */
+             DPRINTF (("Skipping check 1"));
+           }
+         else if (sRef_isDefinitelyNull (sr)
+                  || usymtab_isDefinitelyNull (sr))
+           {
+             /*
+             ** No state reference errors for definitely null references.
+             */
 
-                     sRefSet_free (als);
-                   }
-                 else if
-                   (!uentry_isStatic (ce)
-                    && ((sRef_isNewRef (sr))
-                        || (((sRef_isOnly (sr) || sRef_isFresh (sr) 
-                              || sRef_isKeep (sr) || sRef_isOwned (sr))
-                             && !sRef_isDead (sr))
-                            && (!sRef_definitelyNull (sr))
-                            && (!usymtab_isProbableNull (sr)))))
+             DPRINTF (("Skipping check 2"));
+           }
+         else
+           {
+             DPRINTF (("Lose ref: %s / %s", uentry_unparse (ce), 
+                       sRef_unparseFull (sr)));
+             
+             tvalues = sRef_getValueTable (sr);
+             
+             valueTable_elements (tvalues, fkey, fval) {
+               metaStateInfo minfo;
+               cstring msg = cstring_undefined;
+               int nval;
+               
+               minfo = context_lookupMetaStateInfo (fkey);
+               llassert (metaStateInfo_isDefined (minfo));
+               
+               if (stateValue_isError (fval)
+                   || sRef_isStateUndefined (sr)) /* No errors for undefined state */
+                 {
+                   DPRINTF (("Skipping check 3"));
+                 }
+               else 
+                 {
+                   DPRINTF (("Check: %s / %s / %s", fkey,
+                             metaStateInfo_unparse (minfo),
+                             stateValue_unparse (fval)));
+                   
+                   minfo = context_lookupMetaStateInfo (fkey);
+                   
+                   nval = stateCombinationTable_lookupLoseReference 
+                     (metaStateInfo_getTransferTable (minfo), 
+                      stateValue_getValue (fval), &msg);
+                   
+                   if (cstring_isDefined (msg)) 
                      {
-                       bool hasError = TRUE;
-                       
-                       /*
-                       ** If its a scope exit, check if there is an alias.
-                       ** If so, make it only.  If not, there is an error.
-                       */
-                       
-                       if (!isReturn)
+                       if (optgenerror 
+                           (FLG_STATETRANSFER,
+                            message
+                            ("%s loses reference %q in invalid state %q (%s)",
+                             cstring_makeLiteralTemp (isReturn ? "Return" : "Scope exit"),
+                             uentry_getName (ce),
+                             stateValue_unparseValue (fval, minfo),
+                             msg),
+                            g_currentloc))
                          {
-                           if (canLoseReference (sr, g_currentloc))
-                             {
-                               hasError = FALSE;
-                             }
+                           stateValue_show (fval, minfo);
                          }
-                       
-                       if (hasError)
+                       else
                          {
-                           if (sRef_hasLastReference (sr))
-                             {
-                               sRef ar = sRef_getAliasInfoRef (sr);
-                               
-                               if (optgenerror 
-                                   (FLG_MUSTFREE,
-                                    message
-                                    ("Last reference %q to %s storage %qnot %q before %q",
-                                     sRef_unparse (sr),
-                                     alkind_unparse (sRef_getAliasKind (sr)),
-                                     sRef_unparseOpt (ar),
-                                     cstring_makeLiteral (sRef_isKeep (sr) 
-                                                          ? "transferred" : "released"),
-                                     cstring_makeLiteral (isReturn 
-                                                          ? "return" : "scope exit")),
-                                    g_currentloc))
-                                 {
-                                   sRef_showRefLost (sr);
-                                 }
-                             }
-                           else if (sRef_isNewRef (sr))
-                             {
-                               if (optgenerror
-                                   (FLG_MUSTFREE,
-                                    message 
-                                    ("%q %q not released before %q",
-                                     cstring_makeLiteral 
-                                     (alkind_isKillRef (sRef_getOrigAliasKind (sr))
-                                      ? "Kill reference parameter" : "New reference"),
-                                     uentry_getName (ce),
-                                     cstring_makeLiteral (isReturn
-                                                          ? "return" : "scope exit")),
-                                    g_currentloc))
-                                 {
-                                   sRef_showAliasInfo (sr);
-                                 }
-                             }
-                           else 
-                             {
-                               if (ctype_isRealSU (sRef_getType (sr)))
-                                 {
-                                                                   checkStructDestroyed (sr, g_currentloc);
-                                 }
-                               else
-                                 {
-                                   if (optgenerror
-                                       (FLG_MUSTFREE,
-                                        message 
-                                        ("%s storage %q not %q before %q",
-                                         alkind_capName (sRef_getAliasKind (sr)),
-                                         uentry_getName (ce),
-                                         cstring_makeLiteral (sRef_isKeep (sr) 
-                                                              ? "transferred" : "released"),
-                                         cstring_makeLiteral (isReturn 
-                                                              ? "return" : "scope exit")),
-                                        g_currentloc))
-                                     {
-                                       sRef_showAliasInfo (sr);
-                                     }
-                                 }
-                             }
+                           DPRINTF (("Suppressed transfer error: %s", msg));
                          }
                      }
+                 }
+             } end_valueTable_elements;
+           }
+
+         DPRINTF (("Check mustfree entry: %s", uentry_unparseFull (ce)));
+         
+         if (!sRefSet_member (checked, sr) && !sRef_isFileOrGlobalScope (rb))
+           {
+             if (ctype_isRealSU (uentry_getType (ce))
+                 && !uentry_isAnyParam (ce)
+                 && !uentry_isRefParam (ce)
+                 && !uentry_isStatic (ce)
+                 && !sRef_isDependent (sr)
+                 && !sRef_isOwned (sr))
+               {
+                 sRefSet als = usymtab_allAliases (sr);
+                 
+                 if (sRefSet_isEmpty (als))
+                   {
+                     transferChecks_localDestroyed (sr, g_currentloc);
+                   }
                  else
                    {
-                     ;
+                     /* aliased, no problem */ ;
                    }
+                 
+                 sRefSet_free (als);
                }
-             else if (mustDefine && uentry_isOut (ce))
+             else if
+               (!uentry_isStatic (ce)
+                && ((sRef_isNewRef (sr))
+                    || (((sRef_isOnly (sr) || sRef_isFresh (sr) 
+                          || sRef_isKeep (sr) || sRef_isOwned (sr))
+                         && !sRef_isDead (sr))
+                        && (!sRef_definitelyNull (sr))
+                        && (!usymtab_isDefinitelyNull (sr)))))
                {
-                 if (!ynm_toBoolStrict (sRef_isReadable (sr)))
+                 bool hasError = TRUE;
+                 
+                 DPRINTF (("Checking: %s", sRef_unparseFull (sr)));
+                 
+                 /*
+                 ** If its a scope exit, check if there is an alias.
+                 ** If so, make it only.  If not, there is an error.
+                 */
+                 
+                 if (!isReturn)
                    {
-                     voptgenerror 
-                       (FLG_MUSTDEFINE,
-                        message ("Out storage %q not defined before %q",
-                                 uentry_getName (ce),
-                                 cstring_makeLiteral 
-                                 (isReturn ? "return" : "scope exit")),
-                        g_currentloc);
-                     
-                     /* uentry_showWhereDeclared (ce); */
+                     if (transferChecks_canLoseReference (sr, g_currentloc))
+                       {
+                         DPRINTF (("Can lose!"));
+                         hasError = FALSE;
+                       }
+                   }
+                 
+                 if (hasError)
+                   {
+                     if (sRef_hasLastReference (sr))
+                       {
+                         sRef ar = sRef_getAliasInfoRef (sr);
+                         
+                         if (optgenerror 
+                             (sRef_isFresh (ar) ? FLG_MUSTFREEFRESH : FLG_MUSTFREEONLY,
+                              message
+                              ("Last reference %q to %s storage %qnot %q before %q",
+                               sRef_unparse (sr),
+                               alkind_unparse (sRef_getAliasKind (sr)),
+                               sRef_unparseOpt (ar),
+                               cstring_makeLiteral (sRef_isKeep (sr) 
+                                                    ? "transferred" : "released"),
+                               cstring_makeLiteral (isReturn 
+                                                    ? "return" : "scope exit")),
+                              g_currentloc))
+                           {
+                             sRef_showRefLost (sr);
+                           }
+                       }
+                     else if (sRef_isNewRef (sr))
+                       {
+                         if (optgenerror
+                             (sRef_isFresh (sr) ? FLG_MUSTFREEFRESH : FLG_MUSTFREEONLY,
+                              message 
+                              ("%q %q not released before %q",
+                               cstring_makeLiteral 
+                               (alkind_isKillRef (sRef_getOrigAliasKind (sr))
+                                ? "Kill reference parameter" : "New reference"),
+                               uentry_getName (ce),
+                               cstring_makeLiteral (isReturn
+                                                    ? "return" : "scope exit")),
+                              g_currentloc))
+                           {
+                             sRef_showAliasInfo (sr);
+                           }
+                       }
+                     else 
+                       {
+                         if (ctype_isRealSU (sRef_getType (sr)))
+                           {
+                             transferChecks_structDestroyed (sr, g_currentloc);
+                           }
+                         else
+                           {
+                             if (optgenerror
+                                 (sRef_isFresh (sr) ? FLG_MUSTFREEFRESH : FLG_MUSTFREEONLY,
+                                  message 
+                                  ("%s storage %q not %q before %q",
+                                   alkind_capName (sRef_getAliasKind (sr)),
+                                   uentry_getName (ce),
+                                   cstring_makeLiteral (sRef_isKeep (sr) 
+                                                        ? "transferred" : "released"),
+                                   cstring_makeLiteral (isReturn 
+                                                        ? "return" : "scope exit")),
+                                  g_currentloc))
+                               {
+                                 sRef_showAliasInfo (sr);
+                                 DPRINTF (("Storage: %s", sRef_unparseFull (sr)));
+                               }
+                           }
+                       }
                    }
                }
              else
                {
-                 ; 
+                 ;
                }
-             
-             /*
-             ** also check state is okay
-             */
+           }
 
-             if (usymtab_lexicalLevel () > functionScope
-                 && uentry_isVariable (ce)
-                 && (sRef_isLocalVar (sr)
-                     && (sRef_isDependent (sr) || sRef_isLocalState (sr))))
+         if (mustDefine && uentry_isOut (ce))
+           {
+             /* No error if its dead (either only or error already reported */
+             if (!sRef_isReallyDefined (sr) && !sRef_isDead (sr))
                {
-                 sRefSet ab = usymtab_aliasedBy (sr);
-
-                 /* should do something more efficient here */
+                 voptgenerror 
+                   (FLG_MUSTDEFINE,
+                    message ("Out storage %q not defined before %q",
+                             uentry_getName (ce),
+                             cstring_makeLiteral 
+                             (isReturn ? "return" : "scope exit")),
+                    g_currentloc);
 
-                 if (sRefSet_isEmpty (ab))
-                   {
-                     /* and no local ref */
-                     checkLoseRef (ce);
-                   }
-                 else
-                   {
-                     ;
-                   }
-                 
-                 sRefSet_free (ab);
+                 DPRINTF (("sr: %s", sRef_unparseFull (sr)));
                }
-             else 
+           }
+         
+         /*
+         ** also check state is okay
+         */
+         
+         if (usymtab_lexicalLevel () > functionScope
+             && uentry_isVariable (ce)
+             && (sRef_isLocalVar (sr)
+                 && (sRef_isDependent (sr) || sRef_isLocalState (sr))))
+           {
+             sRefSet ab = usymtab_aliasedBy (sr);
+             
+             /* should do something more efficient here */
+             
+             if (sRefSet_isEmpty (ab))
+               {
+                 /* and no local ref */
+                 DPRINTF (("Check lose ref: %s", uentry_unparseFull (ce)));
+                 transferChecks_loseReference (ce);
+               }
+             else
                {
                  ;
                }
              
-             checked = sRefSet_insert (checked, sr);
+             sRefSet_free (ab);
+           }
+         else 
+           {
+             ;
            }
+         
+         checked = sRefSet_insert (checked, sr);
        }
+
       llassert (usymtab_isDefined (stab->env));
 
       if (usymtab_isBranch (stab))
@@ -3491,12 +4148,12 @@ void usymtab_checkFinalScope (bool isReturn)
        {
          stab = stab->env;
        }
-
+      
       llassert (stab != usymtab_undefined);
     } while (isReturn && (stab->lexlevel >= paramsScope));
-
-    sRefSet_free (checked);
-
+  
+  sRefSet_free (checked);
+  
   /*
   ** for returns:
   **      all globals are appropriately defined
@@ -3510,7 +4167,6 @@ void usymtab_checkFinalScope (bool isReturn)
       uentryList params = context_getParams ();
       globSet uglobs = context_getUsedGlobs ();
       globSet sglobs = context_getGlobs ();
-
             
       if (isReturn && context_maybeSet (FLG_GLOBALIAS))
        { 
@@ -3518,63 +4174,127 @@ void usymtab_checkFinalScope (bool isReturn)
        }
 
       /*
-      ** special clauses (defines, sets, allocates, releases) 
+      ** state clauses (ensures, defines, sets, allocates, releases) 
       */
-
-      if (uentry_hasSpecialClauses (fcn))
+      
+      if (uentry_hasStateClauseList (fcn))
        {
-         specialClauses clauses = uentry_getSpecialClauses (fcn);
+         stateClauseList clauses = uentry_getStateClauseList (fcn);
 
-         specialClauses_elements (clauses, cl)
+         stateClauseList_elements (clauses, cl)
            {
-             if (specialClause_isAfter (cl)) 
-               { /* evs - 2000 07 10 - added this */
-                 sRefTest tst = specialClause_getPostTestFunction (cl);
-                 sRefSet rfs = specialClause_getRefs (cl);
-                 
-                 sRefSet_elements (rfs, el)
+             if (stateClause_isAfter (cl) && !stateClause_isGlobal (cl)) 
+               { 
+                 if (stateClause_setsMetaState (cl)) 
                    {
-                     sRef base = sRef_getRootBase (el);
-                     
-                     if (sRef_isResult (base))
-                       {
-                         ; 
-                       }
-                     else if (sRef_isParam (base))
+                     sRefSet rfs = stateClause_getRefs (cl);
+                     qual q = stateClause_getMetaQual (cl);
+                     annotationInfo ainfo = qual_getAnnotationInfo (q);
+                     metaStateInfo minfo = annotationInfo_getState (ainfo);
+                     cstring key = metaStateInfo_getName (minfo);
+                     int mvalue = annotationInfo_getValue (ainfo);
+
+                     DPRINTF (("Post meta state clause: %s", stateClause_unparse (cl)));
+
+                     sRefSet_elements (rfs, el)
                        {
-                         sRef sr = sRef_updateSref (base);
-                         sr = sRef_fixBase (el, sr);
+                         sRef base = sRef_getRootBase (el);
                          
-                         if (tst != NULL && !tst (sr))
+                         if (sRef_isResult (base))
                            {
-                             if (optgenerror 
-                                 (specialClause_postErrorCode (cl),
-                                  message ("%s storage %qcorresponds to "
-                                           "storage listed in %q clause",
-                                           specialClause_postErrorString (cl, sr),
-                                           sRef_unparseOpt (sr),
-                                           specialClause_unparseKind (cl)),
-                                  g_currentloc))
+                             /* 
+                             ** This is checked for return transfers. 
+                             */
+                             ;
+                           }
+                         else if (sRef_isParam (base) || sRef_isGlobalMarker (base))
+                           {
+                             sRef sr = sRef_updateSref (base);
+                             sr = sRef_fixBase (el, sr);
+                             
+                             if (!sRef_checkMetaStateValue (sr, key, mvalue))
                                {
-                                 sRefShower ss = specialClause_getPostTestShower (cl);
-                                 
-                                 if (ss != NULL)
+                                 if (optgenerror 
+                                     (FLG_STATETRANSFER,
+                                      message
+                                      ("Ensures clause not satisfied%q (state is %q): %q",
+                                       sRef_isGlobalMarker (sr) 
+                                       ? message ("") 
+                                       : message (" by %q", sRef_unparse (sr)),
+                                       stateValue_unparseValue (sRef_getMetaStateValue (sr, key), 
+                                                                minfo),
+                                       stateClause_unparse (cl)),
+                                      g_currentloc))
                                    {
-                                     ss (sr);
-                                   }
-                               }  
+                                     sRef_showMetaStateInfo (sr, key);
+                                   }  
+                               }
                            }
-                       }
-                     else
+                         else
+                           {
+                             if (sRef_isMeaningful (el))
+                               {
+                                 BADBRANCH;
+                               }
+                           }
+                       } end_sRefSet_elements ;
+                   }
+                 else
+                   {
+                     /* evs - 2000 07 10 - added this */
+                     sRefTest tst = stateClause_getPostTestFunction (cl);
+                     sRefSet rfs = stateClause_getRefs (cl);
+                     
+                     sRefSet_elements (rfs, el)
                        {
-                         if (sRef_isMeaningful (el))
+                         sRef base = sRef_getRootBase (el);
+                         
+                         if (sRef_isResult (base))
                            {
-                             BADBRANCH;
+                             /* 
+                             ** This is checked for return transfers. 
+                             */
+
+                             ; 
                            }
-                       }
-                   } end_sRefSet_elements ;
+                         else if (sRef_isParam (base))
+                           {
+                             sRef sr = sRef_updateSref (base);
+                             sr = sRef_fixBase (el, sr);
+                             
+                             if (tst != NULL && !tst (sr))
+                               {
+                                 if (optgenerror 
+                                     (stateClause_postErrorCode (cl),
+                                      message ("%s storage %qcorresponds to "
+                                               "storage listed in %q clause",
+                                               stateClause_postErrorString (cl, sr),
+                                               sRef_unparseOpt (sr),
+                                               stateClause_unparseKind (cl)),
+                                      g_currentloc))
+                                   {
+                                     sRefShower ss = stateClause_getPostTestShower (cl);
+                                     
+                                     if (ss != NULL)
+                                       {
+                                         ss (sr);
+                                       }
+                                     
+                                     DPRINTF (("Storage: %s", sRef_unparseFull (sr)));
+                                   }  
+                               }
+                           }
+                         else
+                           {
+                             if (sRef_isMeaningful (el))
+                               {
+                                 BADBRANCH;
+                               }
+                           }
+                       } end_sRefSet_elements ;
+                   }
                }
-           } end_specialClauses_elements ;
+           } end_stateClauseList_elements ;
        }
       
       /*
@@ -3590,18 +4310,26 @@ void usymtab_checkFinalScope (bool isReturn)
              if (ctype_isMutable (rt) || ctype_isSU (rt))
                {
                  uentry param = usymtab_lookupQuiet (utab, uentry_rawName (arg));
-                 checkParamReturn (param);
+                 DPRINTF (("Check param return: %s", uentry_unparseFull (param)));
+                 transferChecks_paramReturn (param);
                }
            }
        } end_uentryList_elements;
       
+      DPRINTF (("Check global return: %s",
+               globSet_unparse (sglobs)));
+
       globSet_allElements (sglobs, el)
        {
+         sRef orig = el; /*! sRef_updateSref (el); */ /*!!!*/
          uentry current = sRef_getUentry (el);
 
+         DPRINTF (("Check global return: %s / %s", sRef_unparseFull (el),
+                   uentry_unparseFull (current)));
+         
          if (uentry_isVariable (current) && !uentry_isRealFunction (current))
            {
-             checkGlobalReturn (current, el);
+             checkGlobalReturn (current, orig);
            }
        } end_globSet_allElements;
 
@@ -3611,7 +4339,6 @@ void usymtab_checkFinalScope (bool isReturn)
            {
              uentry current = sRef_getUentry (el);
              
-                     
              if (uentry_isVariable (current)
                  && !uentry_isRealFunction (current))
                {
@@ -3619,9 +4346,8 @@ void usymtab_checkFinalScope (bool isReturn)
                }
            }
        } end_globSet_allElements;
-    }
-  
-  }
+    }  
+}
 
 void
 usymtab_quietExitScope (fileloc loc) 
@@ -3630,6 +4356,8 @@ usymtab_quietExitScope (fileloc loc)
 {
   usymtab t = utab->env;
 
+  DPRINTF (("Quiet exit scope [%p]", utab));
+
   if (utab->reftable != NULL)
     {
       int i;
@@ -3656,9 +4384,14 @@ usymtab_quietExitScope (fileloc loc)
   t->mustBreak = utab->mustBreak;
   t->exitCode = utab->exitCode;
 
+  DPRINTF (("Free level [%p]", utab));
   usymtab_freeLevel (utab);
 
   utab = t;
+
+# ifdef DEBUGSPLINT
+  usymtab_checkAllValid ();
+# endif
 }
 
 /*
@@ -3685,7 +4418,9 @@ void usymtab_exitScope (exprNode expr)
   usymtab ctab = usymtab_undefined;
   usymtab lctab = usymtab_undefined;
   bool mustReturn = exprNode_mustEscape (expr);
-  
+
+  DPRINTF (("Exit scope [%p]", utab));
+
   if (utab->kind == US_CBRANCH)
     {
       /*
@@ -3703,29 +4438,34 @@ void usymtab_exitScope (exprNode expr)
     }
   
   if (utab->kind == US_TBRANCH || utab->kind == US_FBRANCH
-      || utab->kind == US_CBRANCH || utab->kind == US_SWITCH) {
-   
-    if (context_inMacro ()) {
-      /* evs 2000-07-25 */
-      /* Unparseable macro may end inside nested scope.  Deal with it. */
-      
-      llerror (FLG_SYNTAX, message ("Problem parsing macro body of %s (unbalanced scopes).  Attempting to recover, recommend /*@notfunction@*/ before macro definition.", 
-                                   context_inFunctionName ()));
-      
-      while (utab->kind == US_TBRANCH
-            || utab->kind == US_FBRANCH
-            || utab->kind == US_CBRANCH
-            || utab->kind == US_SWITCH) 
+      || utab->kind == US_CBRANCH || utab->kind == US_SWITCH) 
+    {
+      if (context_inMacro ()) 
        {
-         utab = utab->env;
-         llassert (utab != GLOBAL_ENV);
-       }
-    } else {
-      llcontbug (("exitScope: in branch: %s", usymtab_unparseStack ()));
-      /*@-branchstate@*/ 
-    } /*@=branchstate@*/
-  }
-
+         /* evs 2000-07-25 */
+         /* Unparseable macro may end inside nested scope.  Deal with it. */
+         
+         llerror (FLG_SYNTAX, 
+                  message ("Problem parsing macro body of %s (unbalanced scopes). "
+                           "Attempting to recover, recommend /*@notfunction@*/ before "
+                           "macro definition.", 
+                           context_inFunctionName ()));
+         
+         while (utab->kind == US_TBRANCH
+                || utab->kind == US_FBRANCH
+                || utab->kind == US_CBRANCH
+                || utab->kind == US_SWITCH) 
+           {
+             utab = utab->env;
+             llassert (utab != GLOBAL_ENV);
+           }
+       } else 
+         {
+           llcontbug (message ("exitScope: in branch: %q", usymtab_unparseStack ()));
+           /*@-branchstate@*/ 
+         } /*@=branchstate@*/
+    }
+  
   /*
   ** check all variables in scope were used
   */
@@ -3751,7 +4491,7 @@ void usymtab_exitScope (exprNode expr)
   ** NOTE: note for exiting paramsScope, since checkReturn should be
   ** called first.
   */
-
+  
   if (!mustReturn && (usymtab_lexicalLevel () > functionScope))
     {
       /*
@@ -3770,7 +4510,6 @@ void usymtab_exitScope (exprNode expr)
       uentryList params = context_getParams ();
       globSet    globs = context_getUsedGlobs ();
 
-                  
       uentryList_elements (params, ue)
        {
          uentry_fixupSref (ue);
@@ -3778,13 +4517,16 @@ void usymtab_exitScope (exprNode expr)
 
       clearFunctionTypes ();
 
-      
+      DPRINTF (("Fixing up globals: %s", globSet_unparse (globs)));
+
       globSet_allElements (globs, el)
        {
+         DPRINTF (("Fix: %s", sRef_unparseDebug (el)));
+
          if (sRef_isCvar (el))
            {
              uentry current;
-             int index = sRef_getScopeIndex (el);
+             usymId index = sRef_getScopeIndex (el);
              
              if (sRef_isFileStatic (el))
                {
@@ -3798,13 +4540,17 @@ void usymtab_exitScope (exprNode expr)
              
              if (uentry_isVariable (current))
                {
+                 DPRINTF (("Fixup: %s", uentry_unparse (current)));
                  uentry_fixupSref (current);
                }
              else
                {
+                 DPRINTF (("Clear: %s", uentry_getSref (current)));
                  sRef_clearDerived (uentry_getSref (current));
                }
            }
+
+         sRef_clearDerived (el); /* evans 2002-03-14 - this is the likely source of many crashes! */
        } end_globSet_allElements;
     }
   
@@ -3815,7 +4561,12 @@ void usymtab_exitScope (exprNode expr)
       /*@i@*/ lctab->env = utab;  
       /*@i@*/ utab = ctab;
     /*@-branchstate@*/ } /*@=branchstate@*/
-/*@-globstate@*/
+  /*@-globstate@*/
+
+
+# ifdef DEBUGSPLINT
+  usymtab_checkAllValid ();
+# endif
 }
 /*@=globstate@*/
 
@@ -3823,8 +4574,8 @@ void usymtab_exitScope (exprNode expr)
 ** yikes!  don't let the '170 kids see this one...
 */
 
-int
-uentry_directParamNo (uentry ue)
+usymId
+usymtab_directParamNo (uentry ue)
 {
   if (uentry_isVar (ue))
     {
@@ -3832,17 +4583,15 @@ uentry_directParamNo (uentry ue)
 
       if (sRef_lexLevel (sr) == functionScope)
        {
-         /*@access sRef@*/ /*@-null@*/
-         int index = sr->info->cvar->index;
-         /*@noaccess sRef@*/ /*@=null@*/
+         usymId index = sRef_getScopeIndex (sr);
 
-         if (index < uentryList_size (context_getParams ()))
+         if (index < usymId_fromInt (uentryList_size (context_getParams ())))
            {
              return index;
            }
        }
     }
-  return -1;
+  return usymId_invalid;
 }
 
 /*@dependent@*/ /*@exposed@*/ uentry
@@ -3890,16 +4639,13 @@ usymtab_getRefTab (/*@notnull@*/ usymtab u, int level, usymId index)
 {
   uentry ue;
 
-  
   ue = usymtab_getRefNoisy (u, level, index);
 
-  
   if (uentry_isUndefined (ue))
     {
       llbug (message ("usymtab_getRef: out of range: %d. level = %d",
                    index, level));
     }
-
   
   return ue;
 }
@@ -3947,8 +4693,7 @@ static /*@dependent@*/ /*@exposed@*/ usymtab
   llassert (index >= 0);
 
   if (level > s->lexlevel)
-    {
-            
+    {            
       return uentry_undefined;
     }
 
@@ -3982,7 +4727,7 @@ static /*@dependent@*/ /*@exposed@*/ usymtab
       s = usymtab_dropEnv (s);
     }
  
-  if (index >= s->nentries)
+  if (index >= usymId_fromInt (s->nentries))
     {
       return uentry_undefined;
     }
@@ -3997,14 +4742,11 @@ usymtab_getRefNoisy (/*@notnull@*/ usymtab s, int level, usymId index)
 {
   usymtab otab = s;
   uentry ue = uentry_undefined;
-
   
   llassert (index >= 0);
-
   
   while (s->lexlevel > level)
     {
-      
       if (usymtab_isBranch (s))
        {
          int eindex = refTable_lookup (s, level, index);
@@ -4043,7 +4785,6 @@ usymtab_getRefNoisy (/*@notnull@*/ usymtab s, int level, usymId index)
   while (usymtab_isBranch (s) && s->lexlevel == level)
     {
       int eindex = refTable_lookup (s, level, index);
-
       
       if (eindex != NOT_FOUND)
        {
@@ -4070,7 +4811,7 @@ usymtab_getRefNoisy (/*@notnull@*/ usymtab s, int level, usymId index)
       s = usymtab_dropEnv (s);
           }
 
-  if (s->lexlevel == level && (index < s->nentries))
+  if (s->lexlevel == level && (index < usymId_fromInt (s->nentries)))
     {
       ue = s->entries[index];
       
@@ -4092,14 +4833,14 @@ usymtab_getRefNoisy (/*@notnull@*/ usymtab s, int level, usymId index)
            }
          else
            {
-                   }
+           }
        }
-
+      
       return ue;
     }
 
   
-  if (index >= s->nentries)
+  if (index >= usymId_fromInt (s->nentries))
     {
       return uentry_undefined;
     }
@@ -4117,23 +4858,22 @@ usymtab_getRefNoisy (/*@notnull@*/ usymtab s, int level, usymId index)
 */
 
 static
-int refTable_lookup (/*@notnull@*/ usymtab ut, int level, int index)
+int refTable_lookup (/*@notnull@*/ usymtab ut, int level, usymId index)
 {
   refTable rt = ut->reftable;
   int i;
 
   llassert (rt != NULL);
 
-  
   for (i = 0; i < ut->nentries; i++)
     {
-      if (rt[i]->level == level && rt[i]->index == index)
+      if (rt[i]->level == level && rt[i]->index == usymId_toInt (index))
        {
-                 return i;
+         return i;
        }
     }
-
-    return NOT_FOUND;
+  
+  return NOT_FOUND;
 }
   
 static
@@ -4150,16 +4890,21 @@ static
 static /*@dependent@*/ /*@exposed@*/ uentry
 usymtab_addRefEntry (/*@notnull@*/ usymtab s, cstring k)
 {
-  int eindex;
   usymtab ut = s;
 
-  llassert (ut->reftable != NULL);
+  if (ut->reftable == NULL) 
+    {
+      DPRINTF (("Adding ref entry without reftable: %s", k));
+      return uentry_undefined;
+    }
 
+  llassert (ut->reftable != NULL);
+  
   while (s != GLOBAL_ENV)
     {
-      eindex = usymtab_getIndex (s, k);
+      usymId eindex = usymtab_getIndex (s, k);
       
-      if (eindex != NOT_FOUND)
+      if (usymtab_indexFound (eindex))
        {
          uentry current = s->entries[eindex];
 
@@ -4167,18 +4912,23 @@ usymtab_addRefEntry (/*@notnull@*/ usymtab s, cstring k)
            {
              uentry ue;
 
-             DPRINTF (("Here: copying %s", uentry_unparseFull (current)));
-
-             ue = uentry_copy (current);
-
-             DPRINTF (("Here: copying %s", uentry_unparseFull (ue)));
+             DPRINTF (("Here: copying %s", uentry_unparse (current)));
+             if (uentry_isNonLocal (current))
+               {
+                 ue = uentry_copy (current);
+               }
+             else
+               {
+                 ue = uentry_copyNoSave (current);
+               }
 
+             DPRINTF (("Here: copying %s", uentry_unparse (ue)));
              usymtab_addEntryQuiet (ut, ue);
-
+             DPRINTF (("Okay..."));
+             
              if (s->reftable != NULL)
                {
                  refentry ref = s->reftable[eindex];
-
                  
                  ut->reftable[ut->nentries - 1] 
                    = refentry_create (ref->level, ref->index);
@@ -4186,7 +4936,7 @@ usymtab_addRefEntry (/*@notnull@*/ usymtab s, cstring k)
              else
                {
                  ut->reftable[ut->nentries - 1] 
-                   = refentry_create (s->lexlevel, eindex);
+                   = refentry_create (s->lexlevel, usymId_toInt (eindex));
                }
              
              return (ue);
@@ -4209,21 +4959,37 @@ static uentry usymtab_lookupAux (usymtab s, cstring k)
 
   while (s != GLOBAL_ENV)
     {
-      int eindex = usymtab_getIndex (s, k);
+      usymId eindex = usymtab_getIndex (s, k);
 
-      if (eindex != NOT_FOUND)
+      if (usymtab_indexFound (eindex))
        {
          uentry ret = s->entries[eindex];
+# if 0   
+
          
+         if (s->kind == US_TBRANCH 
+             || s->kind == US_FBRANCH
+             || s->kind == US_CBRANCH)
+             /* uentry_isGlobalVariable (ret) && os->lexlevel > fileScope) */
+           {
+             uentry ret;
+             DPRINTF (("Adding global ref entry: %s", k));
+             ret = usymtab_addRefEntry (os, k);
+             DPRINTF (("Adding ref entry: %s", uentry_unparseFull (ret)));
+             return ret;
+           }
+
+# endif
          DPRINTF (("Found: %s", uentry_unparseFull (ret)));
          return (ret);
        }
-
+      
       if (s->kind == US_TBRANCH || s->kind == US_FBRANCH 
          || s->kind == US_CBRANCH)
        {
+         /* why isn't this os??? */
          uentry ret = usymtab_addRefEntry (s, k);
-         DPRINTF (("Ref entry: %s", uentry_unparseFull (ret)));
+         DPRINTF (("Adding ref entry: %s", uentry_unparseFull (ret)));
          return ret;
        }
       
@@ -4234,26 +5000,44 @@ static uentry usymtab_lookupAux (usymtab s, cstring k)
 }
 
 static /*@dependent@*/ /*@exposed@*/ uentry
-usymtab_lookupQuiet (usymtab s, cstring k)
+usymtab_lookupQuietAux (usymtab s, cstring k, bool noalt)
 {
-  int eindex;
-
   while (s != GLOBAL_ENV)
     {
-      eindex = usymtab_getIndex (s, k);
+      usymId eindex = usymtab_getIndex (s, k);
       
-      if (eindex != NOT_FOUND)
+      if (usymtab_indexFound (eindex))
        {
          uentry ret = s->entries[eindex];
          return (ret);
        }
       
-      s = s->env;
+      if (noalt && usymtab_isBranch (s))
+       {
+         s = usymtab_dropEnv (s);
+       }
+      else
+       {
+         llassert (s != NULL); 
+         s = s->env;
+       }
     }
 
   return uentry_undefined;
 }
 
+static /*@exposed@*/ /*@dependent@*/ uentry 
+usymtab_lookupQuiet (usymtab s, cstring k)
+{
+  return usymtab_lookupQuietAux (s, k, FALSE);
+}
+
+static /*@exposed@*/ /*@dependent@*/ uentry 
+usymtab_lookupQuietNoAlt (usymtab s, cstring k)
+{
+  return usymtab_lookupQuietAux (s, k, TRUE);
+}
+
 /*@dependent@*/ /*@observer@*/ uentry
   usymtab_lookupSafe (cstring k)
   /*@globals utab@*/
@@ -4262,6 +5046,35 @@ usymtab_lookupQuiet (usymtab s, cstring k)
   return (usymtab_lookupAux (utab, k));
 }
 
+/*@dependent@*/ /*@observer@*/ uentry
+  usymtab_lookupSafeScope (cstring k, int lexlevel)
+  /*@globals utab@*/
+{
+  /*
+  ** This is necessary to deal with shadowed variables that are referenced
+  ** through aliases inside the shadowed scope.  It would be better if
+  ** lookup could take an sRef as a parameter.
+  */
+
+  usymtab tab = utab;
+
+  while (tab != GLOBAL_ENV && tab->lexlevel > lexlevel) {
+    uentry ret = usymtab_lookupAux (tab, k);
+    
+    if (uentry_isValid (ret)) {
+      sRef sr = uentry_getSref (ret);
+      
+      if (sRef_isCvar (sr) && sRef_lexLevel (sr) > lexlevel) {
+       tab = usymtab_dropEnv (tab);
+      } else {
+       return ret;
+      }
+    }
+  }
+
+  return uentry_undefined;
+}
+
 uentry
   usymtab_lookupExpose (cstring k)
   /*@globals utab@*/
@@ -4297,6 +5110,7 @@ uentry usymtab_lookupGlob (cstring k)
   if (uentry_isPriv (ce))
     llfatalbug (message ("usymtab_lookup: private: %s", k));
 
+  DPRINTF (("Lookup global: %s", uentry_unparseFull (ce)));
   return ce;
 }
 
@@ -4305,7 +5119,7 @@ uentry usymtab_lookupGlob (cstring k)
   /*@globals globtab@*/
 {
   uentry ce = usymtab_lookupAux (globtab, k);
-
+  DPRINTF (("Lookup global: %s", uentry_unparseFull (ce)));
   return ce;
 }
 
@@ -4317,17 +5131,17 @@ uentry usymtab_lookupEither (cstring k)
   if (uentry_isUndefined (ce))
     llfatalerror (message ("usymtab_lookup: not found: %s", k));
 
+  DPRINTF (("Lookup either: %s", uentry_unparseFull (ce)));
   return ce;
 }
 
-# ifndef NOLCL
 ctype
 usymtab_lookupType (cstring k)
    /*@globals globtab@*/
 {
-  usymId uid = usymtab_getTypeId (k);
+  typeId uid = usymtab_getTypeId (k);
 
-  if (uid == USYMIDINVALID)
+  if (typeId_isInvalid (uid))
     {
       llcontbug (message ("usymtab_lookupType: not found: %s", k));
       return ctype_unknown;
@@ -4335,14 +5149,13 @@ usymtab_lookupType (cstring k)
   
   return (uentry_getRealType (usymtab_getTypeEntry (uid)));
 }
-# endif
 
 ctype
 usymtab_lookupAbstractType (cstring k) /*@globals globtab@*/
 {
-  usymId uid = usymtab_getTypeId (k);
+  typeId uid = usymtab_getTypeId (k);
 
-  if (uid == USYMIDINVALID)
+  if (typeId_isInvalid (uid))
     {
       llcontbug (message ("usymtab_lookupType: not found: %s", k));
       return ctype_unknown; 
@@ -4377,7 +5190,12 @@ usymtab_suFieldsType (uentryList f, bool isStruct)
 {
   int i;
 
-  if (fileloc_isSpec (g_currentloc)) return (ctype_undefined);
+  DPRINTF (("Fields: %s", uentryList_unparse (f)));
+
+  if (fileloc_isSpec (g_currentloc)) 
+    {
+      return (ctype_undefined);
+    }
 
   for (i = 0; i < globtab->nentries; i++)
     {
@@ -4389,11 +5207,19 @@ usymtab_suFieldsType (uentryList f, bool isStruct)
          if (isFakeTag (uentry_rawName (current)))
            {
              ctype ct = uentry_getType (current);
+             
+             DPRINTF (("Check: %s", ctype_unparse (ct)));
 
              if ((isStruct ? ctype_isStruct (ct) : ctype_isUnion (ct))
-                 && (uentryList_matchFields (f, ctype_getFields (ct))))
+                 && 
+                 (uentry_isSpecified (current)
+                  && uentryList_equivFields (f, ctype_getFields (ct))))
+               {
+                 return uentry_getAbstractType (current);
+               }
+             else
                {
-                                 return uentry_getAbstractType (current);
+                 ;
                }
            }
        }
@@ -4434,7 +5260,6 @@ usymtab_exists (cstring k)
    /*@globals utab@*/
 {
   uentry ce = usymtab_lookupSafe (k);
-
   return (!(uentry_isUndefined (ce)) && !(uentry_isPriv (ce)));
 }
 
@@ -4458,7 +5283,6 @@ bool
   return (!(uentry_isUndefined (ce)) && !(uentry_isPriv (ce)));
 }
 
-# ifndef NOLCL
 bool
 usymtab_existsEither (cstring k)
   /*@globals utab@*/
@@ -4476,7 +5300,6 @@ bool
   
   return (uentry_isValid (ce));
 }
-# endif
 
 bool
 usymtab_existsType (cstring k)
@@ -4491,9 +5314,9 @@ bool
 usymtab_existsTypeEither (cstring k)
   /*@globals globtab@*/
 {
-  uentry ce = usymtab_lookupAux (globtab, k);
-
-    return (uentry_isValid (ce) && uentry_isDatatype (ce));
+  uentry ce;
+  ce = usymtab_lookupAux (globtab, k);
+  return (uentry_isValid (ce) && uentry_isDatatype (ce));
 }
 
 bool
@@ -4501,10 +5324,7 @@ usymtab_existsStructTag (cstring k) /*@globals globtab@*/
 {
   cstring sname = makeStruct (k);
   uentry ce = usymtab_lookupAux (globtab, sname);
-
-  cstring_free (sname);
-
-  
+  cstring_free (sname);  
   return (!(uentry_isUndefined (ce)) && !(uentry_isPriv (ce)));
 }
 
@@ -4529,7 +5349,6 @@ usymtab_existsEnumTag (cstring k) /*@globals globtab@*/
   return (!(uentry_isUndefined (ce)) && !(uentry_isPriv (ce)));
 }
 
-# ifndef NOLCL
 bool usymtab_existsVar (cstring k)
    /*@globals utab@*/
 {
@@ -4537,7 +5356,6 @@ bool usymtab_existsVar (cstring k)
 
   return (!(uentry_isUndefined (ce)) && !(uentry_isPriv (ce)) && (uentry_isVar (ce)));
 }
-# endif
 
 /*
 ** destructors
@@ -4565,15 +5383,19 @@ usymtab_freeLevel (/*@notnull@*/ /*@only@*/ usymtab u)
 {
   int i;
 
+  DPRINTF (("Free level [%p]", u));
   aliasTable_free (u->aliases);
-  environmentTable_free (u->environment);
+
   refTable_free (u->reftable, u->nentries);
 
   if (u == filetab || u == globtab)
     {
       for (i = 0; i < u->nentries; i++)
        {
+         DPRINTF (("Free complete: %d", i));
+         DPRINTF (("Uentry: %s", uentry_unparse (u->entries[i])));
          uentry_freeComplete (u->entries[i]);
+         u->entries[i] = uentry_undefined;
        }
     }
   else
@@ -4581,6 +5403,7 @@ usymtab_freeLevel (/*@notnull@*/ /*@only@*/ usymtab u)
       for (i = 0; i < u->nentries; i++)
        {
          uentry_free (u->entries[i]);
+         u->entries[i] = uentry_undefined;
        }
     }
 
@@ -4591,12 +5414,11 @@ usymtab_freeLevel (/*@notnull@*/ /*@only@*/ usymtab u)
       && u != utab
       && u != filetab)
     {
-      llassert (u->htable == NULL);
-      sfree (u);
+      llassert (!cstringTable_isDefined (u->htable));
     }
 
-/*@-mustfree@*/
-} /*@=mustfree@*/
+  sfree (u); /* evans 2002-07-12: was inside if */
+}
 
 static void
 usymtab_freeAux (/*@only@*/ usymtab u)
@@ -4619,7 +5441,9 @@ void usymtab_free ()
 {
   dbgfree = TRUE;
   usymtab_freeAux (utab);
-}
+  utab = usymtab_undefined;
+  /*@-globstate@*/
+} /*@=globstate@*/ /* Splint cannot tell that utab is killed */
 
 static int usymtab_lexicalLevel (void) /*@globals utab@*/
 {
@@ -4641,7 +5465,6 @@ bool usymtab_inFunctionScope () /*@globals utab@*/
   return (utab->lexlevel == functionScope);
 }
 
-# ifndef NOLCL
 void
 usymtab_replaceEntry (uentry s)
   /*@globals utab, globtab@*/
@@ -4649,10 +5472,9 @@ usymtab_replaceEntry (uentry s)
 {
   usymtab_replaceEntryAux (utab, s);
 }
-# endif
 
 bool
-usymtab_matchForwardStruct (usymId u1, usymId u2)
+usymtab_matchForwardStruct (typeId u1, typeId u2)
    /*@globals globtab@*/
 {
   uentry ue1 = usymtab_getTypeEntry (u1);
@@ -4672,10 +5494,9 @@ usymtab_matchForwardStruct (usymId u1, usymId u2)
 
              if (u2 == rtuid) return TRUE;
              
-             if (usymId_isValid (rtuid))
+             if (typeId_isValid (rtuid))
                {
-                 reptype = uentry_getType (usymtab_getTypeEntry (rtuid));
-                 
+                 reptype = uentry_getType (usymtab_getTypeEntry (rtuid));                
                  return (ctype_isUA (reptype) && (u2 == (ctype_typeId (reptype))));
                }
            }
@@ -4707,6 +5528,10 @@ static bool usymtab_isGuardedAux (sRef s)
   
   while (tab->lexlevel >= lowlevel)
     {
+      DPRINTF (("Is guarded? [%s] %s", 
+               guardSet_unparse (tab->guards),
+               sRef_unparseFull (s)));
+
       if (guardSet_isGuarded (tab->guards, s))
        {
          /*
@@ -4750,21 +5575,21 @@ void usymtab_unguard (sRef s) /*@modifies utab@*/
 
 bool usymtab_isGuarded (sRef s)
 {
-  
+  DPRINTF (("Is guarded? %s", sRef_unparseFull (s)));
   return (sRef_aliasCompleteSimplePred (usymtab_isGuardedAux, s));
 }
 
-bool usymtab_isProbableNull (sRef s)
+bool usymtab_isDefinitelyNull (sRef s)
 {
-  return (sRef_aliasCheckSimplePred (usymtab_isProbableNullAux, s));
+  return (sRef_aliasCheckSimplePred (usymtab_isDefinitelyNullAux, s));
 }
 
-bool usymtab_isProbableDeepNull (sRef s)
+bool usymtab_isDefinitelyNullDeep (sRef s)
 {
-  return (sRef_deepPred (usymtab_isProbableNull, s));
+  return (sRef_deepPred (usymtab_isDefinitelyNull, s));
 }
 
-static bool usymtab_isProbableNullAux (sRef s)
+static bool usymtab_isDefinitelyNullAux (sRef s)
   /*@globals utab@*/
 {
   usymtab tab = utab;
@@ -4779,7 +5604,7 @@ static bool usymtab_isProbableNullAux (sRef s)
   
   while (tab->lexlevel >= lowlevel)
     {
-      if (guardSet_isProbableNull (tab->guards, s))
+      if (guardSet_mustBeNull (tab->guards, s))
        {
          return TRUE;
        }
@@ -4834,7 +5659,7 @@ usymtab_displayAllUses ()
 
   usymtab_entries (copy, ue)
     {
-      if (uentry_isValid (ue))
+      if (uentry_isValid (ue) && !uentry_isGlobalMarker (ue))
        {
          filelocList uses = uentry_getUses (ue);
          int size = filelocList_realSize (uses);
@@ -4843,7 +5668,7 @@ usymtab_displayAllUses ()
              && !fileloc_isLib (uentry_whereDefined (ue))
              && (size > 0))
            {
-             llmsg (message ("%q (%q), %d use%p:\n   %q", 
+             llmsg (message ("%q (%q), %d use%&:\n   %q", 
                              uentry_getName (ue),
                              fileloc_unparse (uentry_whereDefined (ue)),
                              size, filelocList_unparseUses (uses)));
@@ -4910,47 +5735,12 @@ usymtab_typeName (/*@notnull@*/ usymtab t)
   BADEXIT;
 }
 
-void usymtab_testInRange (sRef s, int index) /*@globals utab;@*/
-{
-  /*@i22*/
-  /*@-globs*/
-  environmentTable_testInRange (utab->environment, s, index);
-  /*@=globs*/
-}
-void usymtab_postopVar (sRef sr) /*@globals utab;@*/
-{
-  environmentTable_postOpvar (utab->environment, sr);
-  
-}
-/* doesn't do much check here assumes checking is done before call*/
-void usymtab_addExactValue(sRef s1, int val)
-{
-  /*@i22@*/ utab->environment = environmentTable_addExactValue (utab->environment, s1, val);
-}
-  
-void usymtab_addMustAlias (sRef s, sRef al)
+void usymtab_addMustAlias (/*@exposed@*/ sRef s, /*@exposed@*/ sRef al)
   /*@modifies utab@*/
 {
-  if (sRef_isMeaningful (s) && sRef_isMeaningful (al)
-      && !(sRef_isConst (s) || sRef_isConst (al))
-      && !(sRef_isAddress (al) && sRef_isDirectParam (sRef_getBase (al)))
-      && !(sRef_similar (s, al)))
-    {
-      utab->aliases = aliasTable_addMustAlias (utab->aliases, s, al); 
-      DPRINTF (("Must alias: %s", aliasTable_unparse (utab->aliases)));
-
-      /*
-      ** for local variable, aliasing is symmetric 
-      */
-      
-      if (sRef_isLocalVar (s) && sRef_isLocalVar (al))
-       {
-         utab->aliases = aliasTable_addMustAlias (utab->aliases, al, s); 
-       }
-    }
-  else
+  if (!sRef_similar (s, al))
     {
-      ;
+      usymtab_addForceMustAlias (s, al);
     }
 }
 
@@ -4958,9 +5748,10 @@ void usymtab_addMustAlias (sRef s, sRef al)
 ** Same as usymtab_addMustAlias, except does not check sRef_isSimilar.
 */
 
-void usymtab_addForceMustAlias (sRef s, sRef al)
+void usymtab_addForceMustAlias (/*@exposed@*/ sRef s, /*@exposed@*/ sRef al)
   /*@modifies utab@*/
 {
+  /* evans 2002-03-3: was sRef_isMeaningful -- but we need to keep aliases for new storage also! */
   if (sRef_isMeaningful (s) 
       && sRef_isMeaningful (al)
       && !(sRef_isConst (s) || sRef_isConst (al))
@@ -4980,10 +5771,17 @@ void usymtab_addForceMustAlias (sRef s, sRef al)
     }
   else
     {
-      ;
+      DPRINTF (("Not aliasing! %s / %s", sRef_unparseFull (s), sRef_unparseFull (al)));
+      DPRINTF (("meaningful: %d %d", sRef_isMeaningful (s), sRef_isMeaningful (al)));
     }
 }
 
+void usymtab_addReallyForceMustAlias (/*@exposed@*/ sRef s, /*@exposed@*/ sRef al)
+  /*@modifies utab@*/
+{
+  utab->aliases = aliasTable_addMustAlias (utab->aliases, s, al); 
+}
+
 void usymtab_clearAlias (sRef s)
   /*@modifies utab, s@*/
 {
@@ -4994,36 +5792,35 @@ void usymtab_clearAlias (sRef s)
 sRefSet usymtab_allAliases (sRef s)
    /*@globals utab@*/  
 {
-  if (sRef_isMeaningful (s))
+  if (sRef_isSomewhatMeaningful (s))
     {
       sRefSet ret;
-
             
       ret = sRefSet_unionFree (aliasTable_aliasedBy (utab->aliases, s),
                               aliasTable_canAlias (utab->aliases, s));
-            return (ret);
+      return (ret);
     }
   else
     {
+      DPRINTF (("NOT A MEANINGFUL SREF!"));
       return sRefSet_undefined;
     }
 }
 
 /*@only@*/ sRefSet usymtab_canAlias (sRef s)
-  /*@globals utab@*/
+     /*@globals utab@*/
 {
-  if (sRef_isMeaningful (s))
+  if (sRef_isSomewhatMeaningful (s))
     {
       sRefSet res = aliasTable_canAlias (utab->aliases, s);
-
       return res;
     }
-
+  
   return sRefSet_undefined;
 }
 
 /*@only@*/ sRefSet usymtab_aliasedBy (sRef s)
-  /*@globals utab@*/
+     /*@globals utab@*/
 {
   return (aliasTable_aliasedBy (utab->aliases, s));
 }
@@ -5050,7 +5847,7 @@ usymtab_printOut (void)
   int depth = 0;
   char *ind = mstring_copy ("               ");
 
-  fprintf (g_msgstream, "<<< [symbol table] >>>\n");
+  fprintf (g_warningstream, "<<< [symbol table] >>>\n");
   
   while (s != GLOBAL_ENV && s->env != GLOBAL_ENV)
     {
@@ -5061,7 +5858,7 @@ usymtab_printOut (void)
          ind[depth * 3 + 1] = '\0';
        }
      
-      fprintf (g_msgstream, "level: %d (%s)\n", s->lexlevel,
+      fprintf (g_warningstream, "level: %d (%s)\n", s->lexlevel,
               cstring_toCharsSafe (tname));
 
       cstring_free (tname);
@@ -5069,17 +5866,17 @@ usymtab_printOut (void)
       for (i = 0; i < s->nentries; i++)
        {
          cstring us = uentry_unparseFull (s->entries[i]);
-         fprintf (g_msgstream, "%s\n", cstring_toCharsSafe (us));
+         fprintf (g_warningstream, "%s\n", cstring_toCharsSafe (us));
          cstring_free (us);
        }
       
       if (s->reftable != NULL && s->nentries > 0)
        {
-         fprintf (g_msgstream, "\t<< Ref table >>\n");
+         fprintf (g_warningstream, "\t<< Ref table >>\n");
 
          for (i = 0; i < s->nentries; i++)
            {
-             fprintf (g_msgstream, "\t%s %3d: %d, %d\n", ind, i, 
+             fprintf (g_warningstream, "\t%s %3d: %d, %d\n", ind, i, 
                       s->reftable[i]->level,
                       s->reftable[i]->index);
            }
@@ -5089,7 +5886,7 @@ usymtab_printOut (void)
       depth++;
       s = s->env;
     }
-  fprintf (g_msgstream, "<<< end usymtab >>>\n");
+  fprintf (g_warningstream, "<<< end usymtab >>>\n");
   mstring_free (ind);
   return;
 }
@@ -5110,7 +5907,7 @@ usymtab_printAll (void)
 
 static void
 usymtab_printAllAux (usymtab s)
-   /*@modifies g_msgstream@*/
+   /*@modifies g_warningstream@*/
 {
   int i;
   int depth = 0;
@@ -5186,7 +5983,7 @@ usymtab_printComplete ()
          for (i = looplow; i < s->nentries; i++)
            {
              printf ("%s%3d %s\n", ind, i, 
-                     cstring_toCharsSafe (uentry_unparse (s->entries[i])));
+                     cstring_toCharsSafe (uentry_unparseFull (s->entries[i])));
            }
        }
       else
@@ -5195,7 +5992,7 @@ usymtab_printComplete ()
          for (i = 0; i < s->nentries; i++)
            {
              printf ("%s%3d %s\n", ind, i, 
-                    cstring_toCharsSafe (uentry_unparse (s->entries[i])));
+                    cstring_toCharsSafe (uentry_unparseFull (s->entries[i])));
            }
        }
       
@@ -5208,6 +6005,7 @@ usymtab_printComplete ()
   mstring_free (ind);
 }
 
+# ifdef S_SPLINT_S
 static /*@only@*/ cstring /*@unused@*/ 
 usymtab_unparseLocalAux (/*@notnull@*/ usymtab s)
 {
@@ -5250,6 +6048,7 @@ usymtab_unparseLocalList (/*@notnull@*/ usymtab s)
 
   return (c);
 }
+# endif
 
 void
 usymtab_printLocal (void)
@@ -5284,9 +6083,9 @@ usymtab_printLocal (void)
 
 static bool checkDistinctExternalName (uentry e)
   /*@globals globtab@*/
-  /*@modifies *g_msgstream@*/
+  /*@modifies *g_warningstream@*/
 {
-  int checklen = context_getValue (FLG_EXTERNALNAMELEN);
+  size_t checklen = size_fromInt (context_getValue (FLG_EXTERNALNAMELEN));
   bool ignorecase = context_getFlag (FLG_EXTERNALNAMECASEINSENSITIVE);
   bool gotone = FALSE;
   bool extras = FALSE;
@@ -5361,7 +6160,7 @@ static bool checkDistinctExternalName (uentry e)
                            "in the first %d characters (%q)",
                            uentry_getName (e),
                            uentry_getName (oe),
-                           checklen,
+                           size_toInt (checklen),
                            cstring_clip (uentry_getName (e), checklen)),
                           /*@=sefparams@*/
                           uentry_whereLast (e)))
@@ -5387,7 +6186,7 @@ static bool checkDistinctExternalName (uentry e)
                            "is ignored",
                            uentry_getName (e),
                            uentry_getName (oe),
-                           checklen),
+                           size_toInt (checklen)),
                           uentry_whereLast (e)))
                        {
                          uentry_showWhereAny (oe);
@@ -5413,7 +6212,7 @@ static bool checkDistinctExternalName (uentry e)
                    "in the first %d characters (%q)",
                    uentry_getName (e),
                    uentry_getName (oe),
-                   checklen,
+                   size_toInt (checklen),
                    cstring_clip (uentry_getName (e), checklen)),
                   /*@=sefparams@*/
                   uentry_whereLast (e)))
@@ -5445,11 +6244,11 @@ static bool checkDistinctExternalName (uentry e)
 
 static bool checkDistinctInternalName (uentry e)
   /*@globals utab@*/
-  /*@modifies *g_msgstream@*/
+  /*@modifies *g_warningstream@*/
 {
   usymtab ttab = utab;
   cstring name = uentry_rawName (e);
-  int numchars = context_getValue (FLG_INTERNALNAMELEN);
+  size_t numchars = size_fromInt (context_getValue (FLG_INTERNALNAMELEN));
   bool caseinsensitive = context_getFlag (FLG_INTERNALNAMECASEINSENSITIVE);
   bool lookalike = context_getFlag (FLG_INTERNALNAMELOOKALIKE);
 
@@ -5489,7 +6288,7 @@ static bool checkDistinctInternalName (uentry e)
                        "in the first %d characters (%q)",
                        uentry_getName (e),
                        uentry_getName (oe),
-                       numchars,
+                       size_toInt (numchars),
                        cstring_clip (uentry_getName (e), numchars)),
                       /*@=sefparams@*/
                       uentry_whereLast (e)))
@@ -5502,8 +6301,7 @@ static bool checkDistinctInternalName (uentry e)
              /*@switchbreak@*/
              break;
            case CGE_CASE:
-             if (numchars == 0 
-                 || (cstring_length (name) <= numchars))
+             if (numchars == 0 || (cstring_length (name) <= numchars))
                {
                  if (optgenerror 
                      (FLG_DISTINCTINTERNALNAMES,
@@ -5528,7 +6326,7 @@ static bool checkDistinctInternalName (uentry e)
                        "in the first %d characters without case sensitivity",
                        uentry_getName (e),
                        uentry_getName (oe),
-                       numchars),
+                       size_toInt (numchars)),
                       uentry_whereLast (e)))
                    {
                      uentry_showWhereAny (oe);
@@ -5565,7 +6363,7 @@ static bool checkDistinctInternalName (uentry e)
                        "in the first %d characters except by lookalike characters",
                        uentry_getName (e),
                        uentry_getName (oe),
-                       numchars),
+                       size_toInt (numchars)),
                       uentry_whereLast (e)))
                    {
                      uentry_showWhereAny (oe);
@@ -5606,7 +6404,50 @@ void usymtab_checkDistinctName (uentry e, int scope)
 
   if (hasError)
     {
-            uentry_setHasNameError (e);
+      uentry_setHasNameError (e);
     }
 }
 
+/*@exposed@*/ sRef usymtab_lookupGlobalMarker (void) /*@globals utab@*/
+{
+  uentry ue;
+
+  ue = usymtab_lookupAux (utab, GLOBAL_MARKER_NAME);
+  llassert (uentry_isValid (ue));
+
+  return uentry_getSref (ue);
+}
+
+
+# ifdef DEBUGSPLINT
+/*
+** For debugging only
+*/
+
+void
+usymtab_checkAllValid () /*@globals utab@*/ 
+{
+  usymtab tab = utab;
+
+  while (tab != GLOBAL_ENV)
+    {
+      int i;
+
+      for (i = 0; i < utab->nentries; i++)
+       {
+         uentry e = utab->entries[i];
+         
+         uentry_checkValid (e);
+       }
+
+      aliasTable_checkValid (tab->aliases);
+      tab = tab->env;
+    }
+}
+# endif
+
+
+
+
+
+
This page took 0.229289 seconds and 4 git commands to generate.