/*
-** LCLint - annotation-assisted static program checker
-** Copyright (C) 1994-2001 University of Virginia,
+** Splint - annotation-assisted static program checker
+** Copyright (C) 1994-2002 University of Virginia,
** Massachusetts Institute of Technology
**
** This program is free software; you can redistribute it and/or modify it
**
** 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 more information: http://www.splint.org
*/
/*
** usymtab
# include "exprChecks.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.
*/
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@*/
*/
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)));
}
}
return (uentry_getName (ue));
}
+# if 0
/*@unused@*/ static void
usymtab_rehash (/*@notnull@*/ usymtab s)
{
cstringTable_insert (s->htable, cstring_copy (uentry_rawName (s->entries[i])), i);
}
}
+# endif
/*
** superficial copy of usymtab
}
}
-
-
-
}
+
void usymtab_load (FILE *f)
/*@globals utab, globtab@*/
/*@modifies utab, *f@*/
{
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)));
{
if (sRef_isStateSpecial (pref))
{
- uentry_setDefState (ue, SS_ALLOCATED);
+ uentry_setDefState (ue, SS_SPECIAL); /* ALLOCATED); */
+ /* evans 2002-01-01: should be unnecessary, the pre clauses
+ ** set the state if necessary.
+ */
}
else
{
{
ctype ct = ctype_realType (uentry_getType (glob));
+ DPRINTF (("Check global destroyed: %s", uentry_unparseFull (glob)));
+
if (ctype_isVisiblySharable (ct))
{
if (optgenerror
else
{
sRef_protectDerivs ();
- (void) checkGlobalDestroyed (sr, g_currentloc);
+ (void) transferChecks_globalDestroyed (sr, g_currentloc);
sRef_clearProtectDerivs ();
}
}
}
else
{
- checkGlobReturn (glob);
+ transferChecks_globalReturn (glob);
}
}
}
void usymtab_checkFinalScope (bool isReturn)
/*@globals utab@*/
{
- bool mustFree = context_getFlag (FLG_MUSTFREE);
+ bool mustFree = context_getFlag (FLG_MUSTFREEONLY) || context_getFlag (FLG_MUSTFREEFRESH); /*@i423 remove this mustFree */
bool mustDefine = context_getFlag (FLG_MUSTDEFINE);
/* bool mustNotAlias = context_getFlag (FLG_MUSTNOTALIAS); */
sRefSet checked = sRefSet_new ();
/*@innercontinue@*/ continue;
}
}
-
+
DPRINTF (("Here check final scope: %s", uentry_unparseFull (ce)));
if (ctype_isFunction (uentry_getType (ce)))
|| sRef_isFileOrGlobalScope (rb))
{
/* 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.
*/
+
+ DPRINTF (("Skipping check 2"));
}
else
{
if (stateValue_isError (fval)
|| sRef_isStateUndefined (sr)) /* No errors for undefined state */
{
- ;
+ DPRINTF (("Skipping check 3"));
}
else
{
} end_valueTable_elements;
}
+ DPRINTF (("Here 1"));
+
if (mustFree)
{
- DPRINTF (("Check entry: %s", uentry_unparseFull (ce)));
+ DPRINTF (("Check mustfree entry: %s", uentry_unparseFull (ce)));
if (!sRefSet_member (checked, sr) && !sRef_isFileOrGlobalScope (rb))
{
if (sRefSet_isEmpty (als))
{
- checkLocalDestroyed (sr, g_currentloc);
+ transferChecks_localDestroyed (sr, g_currentloc);
}
else
{
if (!isReturn)
{
- if (canLoseReference (sr, g_currentloc))
+ if (transferChecks_canLoseReference (sr, g_currentloc))
{
DPRINTF (("Can lose!"));
hasError = FALSE;
sRef ar = sRef_getAliasInfoRef (sr);
if (optgenerror
- (FLG_MUSTFREE,
+ (sRef_isFresh (ar) ? FLG_MUSTFREEFRESH : FLG_MUSTFREEONLY,
message
("Last reference %q to %s storage %qnot %q before %q",
sRef_unparse (sr),
else if (sRef_isNewRef (sr))
{
if (optgenerror
- (FLG_MUSTFREE,
+ (sRef_isFresh (sr) ? FLG_MUSTFREEFRESH : FLG_MUSTFREEONLY,
message
("%q %q not released before %q",
cstring_makeLiteral
{
if (ctype_isRealSU (sRef_getType (sr)))
{
- checkStructDestroyed (sr, g_currentloc);
+ transferChecks_structDestroyed (sr, g_currentloc);
}
else
{
DPRINTF (("Here we are: %s", sRef_unparseFull (sr)));
if (optgenerror
- (FLG_MUSTFREE,
+ (sRef_isFresh (sr) ? FLG_MUSTFREEFRESH : FLG_MUSTFREEONLY,
message
("%s storage %q not %q before %q",
alkind_capName (sRef_getAliasKind (sr)),
;
}
}
- else if (mustDefine && uentry_isOut (ce))
- {
- if (!ynm_toBoolStrict (sRef_isReadable (sr)))
- {
- 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); */
- }
- }
- else
+ }
+
+ if (mustDefine && uentry_isOut (ce))
+ {
+ /* No error if its dead (either only or error already reported */
+ if (!sRef_isReallyDefined (sr) && !sRef_isDead (sr))
{
- ;
+ voptgenerror
+ (FLG_MUSTDEFINE,
+ message ("Out storage %q not defined before %q",
+ uentry_getName (ce),
+ cstring_makeLiteral
+ (isReturn ? "return" : "scope exit")),
+ g_currentloc);
+
+ DPRINTF (("sr: %s", sRef_unparseFull (sr)));
}
+ }
+
+ /*
+ ** 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);
- /*
- ** also check state is okay
- */
+ /* should do something more efficient here */
- if (usymtab_lexicalLevel () > functionScope
- && uentry_isVariable (ce)
- && (sRef_isLocalVar (sr)
- && (sRef_isDependent (sr) || sRef_isLocalState (sr))))
+ if (sRefSet_isEmpty (ab))
{
- 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)));
- checkLoseRef (ce);
- }
- else
- {
- ;
- }
-
- sRefSet_free (ab);
+ /* and no local ref */
+ DPRINTF (("Check lose ref: %s", uentry_unparseFull (ce)));
+ transferChecks_loseReference (ce);
}
- else
+ else
{
;
}
- checked = sRefSet_insert (checked, sr);
+ sRefSet_free (ab);
+ }
+ else
+ {
+ ;
}
+
+ checked = sRefSet_insert (checked, sr);
}
llassert (usymtab_isDefined (stab->env));
{
uentry param = usymtab_lookupQuiet (utab, uentry_rawName (arg));
DPRINTF (("Check param return: %s", uentry_unparseFull (param)));
- checkParamReturn (param);
+ transferChecks_paramReturn (param);
}
}
} end_uentryList_elements;
/*@i@*/ lctab->env = utab;
/*@i@*/ utab = ctab;
/*@-branchstate@*/ } /*@=branchstate@*/
-/*@-globstate@*/
-}
+ /*@-globstate@*/
+/*@i523@*/ }
/*@=globstate@*/
/*
mstring_free (ind);
}
+# ifdef S_SPLINT_S
static /*@only@*/ cstring /*@unused@*/
usymtab_unparseLocalAux (/*@notnull@*/ usymtab s)
{
return (c);
}
+# endif
void
usymtab_printLocal (void)