X-Git-Url: http://andersk.mit.edu/gitweb/splint.git/blobdiff_plain/2934b455c4074408a0f819009c071456f021ba21..210066f9dd04de7d7d2f04d320b39a52f28b290b:/src/usymtab.c diff --git a/src/usymtab.c b/src/usymtab.c index 28ce76a..1d26d49 100644 --- a/src/usymtab.c +++ b/src/usymtab.c @@ -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 @@ -46,11 +46,17 @@ ** 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_DEFINED); + uentry_setDefState (param, SS_DEFINED); + } + else + { + 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); + + 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))) { - uentry_setDefState (ue, SS_ALLOCATED); + /* + ** This is needed for detecting possibly aliased parameters. + */ + + sRef s = sRef_makeExternal (uref); + usymtab_addMustAlias (uref, s); } - else + + if (sRef_isKillRef (pref)) { - uentry_setDefState (ue, sRef_getDefState (pref)); + sRef_setAliasKind (uref, AK_NEWREF, fileloc_undefined); + sRef_setOrigAliasKind (uref, AK_KILLREF); } - } - - uref = uentry_getSref (ue); - - if (sRef_isStack (uref)) - { - alkind pkind = sRef_getAliasKind (pref); - - if (alkind_isKnown (pkind) && !alkind_isLocal (pkind) - && !alkind_isStack (pkind)) + 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 (message ("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; } -// oid 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 + + + + + +