/*
-** 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
*/
/*
** storeRef.c
static bool sRef_isAllocatedStorage (sRef p_s) /*@*/ ;
static void sRef_setNullErrorLoc (sRef p_s, fileloc) /*@*/ ;
-static void
- sRef_aliasSetComplete (void (p_predf) (sRef, fileloc), sRef p_s, fileloc p_loc)
- /*@modifies p_s@*/ ;
-
static int sRef_depth (sRef p_s) /*@*/ ;
static void
sRef_innerAliasSetCompleteParam (void (p_predf) (sRef, sRef), sRef p_s, sRef p_t)
/*@modifies p_s@*/ ;
-static void
- sRef_aliasSetCompleteParam (void (p_predf) (sRef, alkind, fileloc), sRef p_s,
- alkind p_kind, fileloc p_loc)
- /*@modifies p_s@*/ ;
-
static speckind speckind_fromInt (int p_i);
static bool sRef_equivalent (sRef p_s1, sRef p_s2);
static bool sRef_isDeepUnionField (sRef p_s);
static void sRef_addDeriv (/*@notnull@*/ sRef p_s, /*@notnull@*/ /*@exposed@*/ sRef p_t);
-static /*@dependent@*/ sRef sRef_makeResultType (ctype p_ct) /*@*/ ;
static bool sRef_checkModify (sRef p_s, sRefSet p_sl) /*@*/ ;
+/*
+** If s is definitely null, it has no memory state.
+*/
+
+static void sRef_resetAliasKind (/*@notnull@*/ sRef s) /*@modifies s->aliaskind@*/
+{
+ if (s->nullstate == NS_DEFNULL)
+ {
+ /* s->aliaskind = AK_ERROR; */
+ }
+}
+
static void sRef_checkMutable (/*@unused@*/ sRef s)
{
/*@i235@*/
static /*@only@*/ cstring sRef_unparseNoArgs (sRef p_s);
static /*@exposed@*/ sRef sRef_findDerivedPointer (sRef p_s);
+static /*@exposed@*/ sRef sRef_findDerivedArrayFetch (/*@notnull@*/ sRef, bool, int, bool) ;
static /*@exposed@*/ sRef sRef_findDerivedField (/*@notnull@*/ sRef p_rec, cstring p_f);
static /*@exposed@*/ sRef
sRef_getDeriv (/*@notnull@*/ /*@returned@*/ sRef p_set, sRef p_guide);
s->safe = TRUE;
s->modified = FALSE;
s->immut = FALSE;
+ s->val = multiVal_undefined;
s->type = ctype_unknown;
s->defstate = SS_UNKNOWN;
return;
}
+ /* This sometimes fails: (evans 2001-07-12)
+ if (sRef_isArrayFetch (t))
+ {
+ DPRINTF (("Derived fetch: %s / %s / %s",
+ sRef_unparseFull (s), sRef_unparseFull (t),
+ sRef_unparseFull (t->info->arrayfetch->arr)));
+ llassert (t->info->arrayfetch->arr == s);
+ }
+ */
+
if (sRef_isFileOrGlobalScope (s))
{
if (context_inFunctionLike ()
&& (s->expinfo != NULL) && (fileloc_isDefined (s->expinfo->loc)));
}
+# if 0
static /*@observer@*/ /*@unused@*/ stateInfo sRef_getInfo (sRef s, cstring key)
{
stateValue sv;
return stateInfo_undefined;
}
-
+# endif
static bool
sRef_hasNullInfoLoc (sRef s)
}
static bool oldInFunction = FALSE;
+static int nestedScope = 0;
void sRef_setGlobalScopeSafe ()
{
- oldInFunction = inFunction;
- DPRINTF (("leave function"));
+ if (nestedScope == 0)
+ {
+ oldInFunction = inFunction;
+ }
+
+ nestedScope++;
+ DPRINTF (("leave function safe"));
inFunction = FALSE;
}
void sRef_clearGlobalScopeSafe ()
{
- inFunction = oldInFunction;
- DPRINTF (("clear function: %s", bool_unparse (inFunction)));
+ nestedScope--;
+ llassert (nestedScope >= 0);
+
+ if (nestedScope == 0)
+ {
+ inFunction = oldInFunction;
+ }
+
+ DPRINTF (("clear function: %s", bool_unparse (inFunction)));
}
void sRef_enterFunctionScope ()
{
+ /* evans 2001-09-09 - cleanup if we are in a macro! */
+ if (context_inMacro ())
+ {
+ if (inFunction) {
+ sRef_exitFunctionScope ();
+ }
+ }
+
llassert (!inFunction);
llassert (sRefTable_isEmpty (allRefs));
inFunction = TRUE;
}
void sRef_exitFunctionScope ()
-{
-
+{
if (inFunction)
{
DPRINTF (("Exit function scope."));
s is an sRef of a formal paramenter in a function call constraint
we trys to return a constraint expression derived from the actual parementer of a function call.
*/
+
/*@only@*/ constraintExpr sRef_fixConstraintParam (/*@observer@*/ sRef s, /*@observer@*/ /*@temp@*/ exprNodeList args)
{
constraintExpr ce;
{
case SK_RESULT:
{
- // s = sRef_saveCopy(s);
+ /* s = sRef_saveCopy(s); */ /*@i523@*/
ce = constraintExpr_makeTermsRef (s);
return ce;
}
{
sRef temp;
temp = (sRef_makePointer (sRef_fixBaseParam (s->info->ref, args)));
- //temp = sRef_saveCopy(temp);
+ /* temp = sRef_saveCopy(temp); */ /*@i523@*/
ce = constraintExpr_makeTermsRef (temp);
return ce;
}
default:
{
sRef temp;
- llcontbug ((message("Trying to do fixConstraintParam on nonparam, nonglobal: %q for function with arguments %q", sRef_unparse (s), exprNodeList_unparse(args) ) ));
+ llcontbug (message ("Trying to do fixConstraintParam on nonparam, nonglobal: %q for function with arguments %q",
+ sRef_unparse (s), exprNodeList_unparse(args)));
temp = sRef_saveCopy(s);
ce = constraintExpr_makeTermsRef (temp);
reader_checkChar (c, '@');
nullstate = nstate_fromInt (reader_getInt (c));
- ret = sRef_makeGlobal (uid, ctype_unknown);
+ ret = sRef_makeGlobal (uid, ctype_unknown, stateInfo_currentLoc ());
sRef_setNullStateN (ret, nullstate);
ret->defstate = defstate;
return ret;
BADEXIT;
}
-/*@exposed@*/ sRef
-sRef_undump (char **c)
+static /*@exposed@*/ sRef sRef_undumpBody (char **c)
{
char p = **c;
switch (p)
{
case 'g':
- return (sRef_makeGlobal (usymId_fromInt (reader_getInt (c)), ctype_unknown));
+ return (sRef_makeGlobal (usymId_fromInt (reader_getInt (c)), ctype_unknown, stateInfo_currentLoc ()));
case 'p':
- return (sRef_makeParam (reader_getInt (c), ctype_unknown));
+ return (sRef_makeParam (reader_getInt (c), ctype_unknown, stateInfo_makeLoc (g_currentloc)));
case 'r':
- return (sRef_makeResultType (ctype_undump (c)));
+ return (sRef_makeResult (ctype_undump (c)));
case 'a':
{
if ((**c >= '0' && **c <= '9') || **c == '-')
BADEXIT;
}
-/*@only@*/ cstring
-sRef_dump (sRef s)
+/*@exposed@*/ sRef sRef_undump (char **c)
+{
+ sRef res = sRef_undumpBody (c);
+
+ if (reader_optCheckChar (c, '='))
+ {
+ multiVal mv = multiVal_undump (c);
+ sRef_setValue (res, mv);
+ reader_checkChar (c, '=');
+ }
+
+ return res;
+}
+
+static /*@only@*/ cstring sRef_dumpBody (sRef s)
{
if (sRef_isInvalid (s))
{
BADEXIT;
}
+/*@only@*/ cstring sRef_dump (sRef s)
+{
+ cstring res = sRef_dumpBody (s);
+
+ if (sRef_hasValue (s))
+ {
+ res = message ("%q=%q=", res, multiVal_dump (sRef_getValue (s)));
+ }
+
+ return res;
+}
+
cstring sRef_dumpGlobal (sRef s)
{
+ llassert (!sRef_hasValue (s));
+
if (sRef_isInvalid (s))
{
return (cstring_makeLiteral ("-"));
return uentry_getName (ue);
}
- return (message ("<bad param: %q / args %q",
- sRef_unparseDebug (s),
- uentryList_unparse (args)));
+ return (message ("parameter %d", s->info->paramno + 1));
}
case SK_ARRAYFETCH:
if (s->info->arrayfetch->indknown)
case SK_TYPE:
return (message ("<type %s>", ctype_unparse (s->type)));
case SK_CONST:
- return (message ("<const %s>", ctype_unparse (s->type)));
+ if (sRef_hasValue (s))
+ {
+ return (message ("<const %s=%q>", ctype_unparse (s->type), multiVal_unparse (sRef_getValue (s))));
+ }
+ else
+ {
+ return (message ("<const %s>", ctype_unparse (s->type)));
+ }
case SK_RESULT:
return (message ("<result %s>", ctype_unparse (s->type)));
case SK_SPECIAL:
}
static /*@dependent@*/ /*@notnull@*/ sRef
- sRef_makeCvarAux (int level, usymId index, ctype ct)
+ sRef_makeCvarAux (int level, usymId index, ctype ct, /*@only@*/ stateInfo stinfo)
{
sRef s = sRef_newRef ();
DPRINTF (("Made cvar: [%p] %s", s, sRef_unparseDebug (s)));
llassert (valueTable_isUndefined (s->state));
- s->state = context_createValueTable (s);
+ s->state = context_createValueTable (s, stinfo);
return s;
}
-/*@dependent@*/ sRef sRef_makeCvar (int level, usymId index, ctype ct)
+/*@dependent@*/ sRef sRef_makeCvar (int level, usymId index, ctype ct, /*@only@*/ stateInfo stinfo)
{
- return (sRef_makeCvarAux (level, index, ct));
+ return (sRef_makeCvarAux (level, index, ct, stinfo));
}
int sRef_lexLevel (sRef s)
}
sRef
-sRef_makeGlobal (usymId l, ctype ct)
+sRef_makeGlobal (usymId l, ctype ct, /*@only@*/ stateInfo stinfo)
{
- return (sRef_makeCvar (globScope, l, ct));
+ return (sRef_makeCvar (globScope, l, ct, stinfo));
}
void
}
/*@dependent@*/ sRef
-sRef_makeParam (int l, ctype ct)
+sRef_makeParam (int l, ctype ct, stateInfo stinfo)
{
sRef s = sRef_new ();
/* (probably defined, unless its an out parameter) */
llassert (valueTable_isUndefined (s->state));
- s->state = context_createValueTable (s);
+ s->state = context_createValueTable (s, stinfo);
return s;
}
}
llassert (valueTable_isUndefined (s->state));
- s->state = context_createValueTable (s);
+ s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
return s;
}
}
("Warning: reference base limit exceeded for %q. "
"This either means there is a variable with at least "
"%d indirections from this reference, or "
- "there is a bug in LCLint.",
+ "there is a bug in Splint.",
sRef_unparse (s),
MAXBASEDEPTH),
g_currentloc);
s->info = (sinfo) dmalloc (sizeof (*s->info));
s->info->object = o;
llassert (valueTable_isUndefined (s->state));
- s->state = context_createValueTable (s);
+ s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
return s;
}
s->type = t->type;
s->info->ref = t; /* sRef_copy (t); */ /*@i32 was exposed@*/
llassert (valueTable_isUndefined (s->state));
- s->state = context_createValueTable (s);
+ s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
return s;
}
s->type = t->type;
llassert (valueTable_isUndefined (s->state));
- s->state = context_createValueTable (s);
+ s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
return s;
}
else
llassertfatal (sRef_isValid (res));
llassertfatal (sRef_isValid (other));
+ DPRINTF (("Merge aux: %s / %s",
+ bool_unparse (sRef_isDefinitelyNull (res)),
+ bool_unparse (sRef_isDefinitelyNull (other))));
+
sRef_checkMutable (res);
sRef_checkMutable (other);
** Merge value table states
*/
+
+ /*@i3245@*/
+# if 0
+ /*
+ ** This doesn't do anything. And its broken too...
+ */
+
valueTable_elements (res->state, key, sv)
{
stateValue os = valueTable_lookup (other->state, key);
DPRINTF (("Val: %d / %s", val, msg));
*/
} end_valueTable_elements ;
+# endif
+
}
static sRefSet
? "kept" : "released")),
loc))
{
-
if (sRef_isKept (el))
{
sRef_showAliasInfo (el);
s->aliaskind = alkind_resolve (a->aliaskind, b->aliaskind);
llassert (valueTable_isUndefined (s->state));
- s->state = context_createValueTable (s);
+ s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
return s;
}
else
{
sRef s = sRef_makeSpecial (SR_GLOBALMARKER);
llassert (valueTable_isUndefined (s->state));
- s->state = context_createGlobalMarkerValueTable ();
+ s->state = context_createGlobalMarkerValueTable (stateInfo_undefined);
return s;
}
-static sRef
-sRef_makeResultType (ctype ct)
-{
- sRef res = sRef_makeResult ();
-
- res->type = ct;
- return res;
-}
-
sRef
-sRef_makeResult ()
+sRef_makeResult (ctype c)
{
sRef s = sRef_newRef ();
s->kind = SK_RESULT;
- s->type = ctype_unknown;
+ s->type = c;
s->defstate = SS_UNKNOWN;
s->aliaskind = AK_UNKNOWN;
sRef_setNullStateN (s, NS_UNKNOWN);
llassert (valueTable_isUndefined (s->state));
- s->state = context_createValueTable (s);
+ s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
DPRINTF (("Result: [%p] %s", s, sRef_unparseFull (s)));
return s;
bool sRef_isStrictReadable (sRef s)
{
- return (ynm_toBoolStrict (sRef_isReadable (s)));
+ return (ynm_toBoolStrict (sRef_isValidLvalue (s)));
}
-ynm sRef_isReadable (sRef s)
+/*
+** Is this what is does?
+** Returns YES if s can be used as an rvalue,
+** MAYBE if its not clear
+** NO if s cannot be safely used as an rvalue.
+*/
+
+ynm sRef_isValidLvalue (sRef s)
{
sstate ss;
if (sRef_isConj (s) && s->defstate == SS_UNKNOWN)
{
- if (ynm_toBoolStrict (sRef_isReadable (sRef_getConjA (s))))
+ if (ynm_toBoolStrict (sRef_isValidLvalue (sRef_getConjA (s))))
{
- if (ynm_toBoolStrict (sRef_isReadable (sRef_getConjB (s))))
+ if (ynm_toBoolStrict (sRef_isValidLvalue (sRef_getConjB (s))))
{
return YES;
}
}
else
{
- if (ynm_toBoolStrict (sRef_isReadable (sRef_getConjB (s))))
+ if (ynm_toBoolStrict (sRef_isValidLvalue (sRef_getConjB (s))))
{
return MAYBE;
}
|| ss == SS_FIXED
|| ss == SS_RELDEF
|| ss == SS_PDEFINED
- || ss == SS_PARTIAL
+ || ss == SS_PARTIAL
|| ss == SS_SPECIAL
- || ss == SS_ALLOCATED
+ || ss == SS_ALLOCATED
|| ss == SS_KILLED /* evans 2001-05-26: added this for killed globals */
|| ss == SS_UNKNOWN));
}
("Warning: check definition limit exceeded, checking %q. "
"This either means there is a variable with at least "
"%d indirections apparent in the program text, or "
- "there is a bug in LCLint.",
+ "there is a bug in Splint.",
sRef_unparse (fref),
MAXDEPTH),
g_currentloc);
void sRef_setAliasKindComplete (sRef s, alkind kind, fileloc loc)
{
sRef_checkMutable (s);
- sRef_aliasSetCompleteParam (sRef_setAliasKind, s, kind, loc);
+ sRef_aliasSetCompleteAlkParam (sRef_setAliasKind, s, kind, loc);
}
void sRef_setAliasKind (sRef s, alkind kind, fileloc loc)
sRef_checkMutable (s);
if (sRef_isInvalid (s)) return;
+ DPRINTF (("Set defined: %s", sRef_unparseFull (s)));
+
if (s->defstate != SS_DEFINED && fileloc_isDefined (loc))
{
s->definfo = stateInfo_updateLoc (s->definfo, loc);
s->defstate = SS_DEFINED;
+ DPRINTF (("Set defined: %s", sRef_unparseFull (s)));
+
/* e.g., if x is allocated, *x = 3 defines x */
if (s->kind == SK_PTR)
{
sRef p = s->info->ref;
-
- if (p->defstate == SS_ALLOCATED)
+ sRef arr;
+
+ if (p->defstate == SS_ALLOCATED
+ || p->defstate == SS_SPECIAL) /* evans 2001-07-12: shouldn't need this */
{
sRef_setDefinedAux (p, loc, clear);
}
+
+ /*
+ ** Defines a[0] also:
+ */
+
+ arr = sRef_findDerivedArrayFetch (p, FALSE, 0, FALSE);
+
+ if (sRef_isValid (arr))
+ {
+ sRef_setDefinedAux (arr, loc, clear);
+ }
}
else if (s->kind == SK_ARRAYFETCH)
{
{
sRef p = s->info->arrayfetch->arr;
sRef ptr = sRef_constructPointer (p);
-
+
if (sRef_isValid (ptr))
{
if (ptr->defstate == SS_ALLOCATED
- || ptr->defstate == SS_UNDEFINED)
+ || ptr->defstate == SS_UNDEFINED
+ || ptr->defstate == SS_SPECIAL) /* evans 2001-07-12: shouldn't need this */
{
sRef_setDefinedAux (ptr, loc, clear);
}
{
;
}
- else if (p->defstate == SS_ALLOCATED || p->defstate == SS_PDEFINED)
+ else if (p->defstate == SS_ALLOCATED || p->defstate == SS_PDEFINED
+ || p->defstate == SS_SPECIAL) /* evans 2001-07-12: shouldn't need this */
{
p->defstate = SS_DEFINED;
}
if (clear)
{
sRef_clearDerived (s);
- }
+ }
+ else
+ {
+ /* evans 2001-07-12: need to define the derived references */
+ sRefSet_elements (s->deriv, el)
+ {
+ el->defstate = SS_DEFINED;
+ } end_sRefSet_elements ;
+ }
+
+ DPRINTF (("Set defined: %s", sRef_unparseFull (s)));
}
static void sRef_setPartialDefined (sRef s, fileloc loc)
sRef_innerAliasSetComplete (sRef_setDefined, s, loc);
}
+void sRef_setDefinedCompleteDirect (sRef s, fileloc loc)
+{
+ sRefSet aliases;
+
+ aliases = usymtab_allAliases (s);
+ DPRINTF (("Set defined complete: %s", sRef_unparseFull (s)));
+ DPRINTF (("All aliases: %s", sRefSet_unparseFull (aliases)));
+
+ sRef_setDefined (s, loc);
+
+ sRefSet_realElements (aliases, current)
+ {
+ if (sRef_isValid (current))
+ {
+ current = sRef_updateSref (current);
+ sRef_setDefined (current, loc);
+ }
+ } end_sRefSet_realElements;
+
+ sRefSet_free (aliases);
+ sRef_innerAliasSetComplete (sRef_setDefined, s, loc);
+}
+
void sRef_setDefined (sRef s, fileloc loc)
{
sRef_checkMutable (s);
DPRINTF (("Set null state: %s / %s", sRef_unparse (s), nstate_unparse (ns)));
sRef_checkMutable (s);
s->nullstate = ns;
-
+ sRef_resetAliasKind (s);
+
if (fileloc_isDefined (loc))
{
s->nullinfo = stateInfo_updateLoc (s->nullinfo, loc);
{
sRef_checkMutable (s);
s->nullstate = n;
+ sRef_resetAliasKind (s);
}
void sRef_setNullState (sRef s, nstate n, fileloc loc)
}
}
-void sRef_setNullTerminatedStateInnerComplete (sRef s, struct s_bbufinfo b, /*@unused@*/ fileloc loc) {
-
+void sRef_setNullTerminatedStateInnerComplete (sRef s, struct s_bbufinfo b, /*@unused@*/ fileloc loc)
+{
switch (b.bufstate) {
case BB_NULLTERMINATED:
sRef_setNullTerminatedState (s);
t->modified = s->modified;
t->immut = FALSE; /* Note mutability is not copied. */
t->type = s->type;
+ t->val = multiVal_copy (s->val);
t->info = sinfo_copy (s);
t->defstate = s->defstate;
/*@i43@*/ /* valueTable_free (s->state); */
sinfo_free (s);
- /*@i32@*/ sfree (s);
+
+ /* drl added to help locate use after release*/
+ s->expinfo = stateInfo_undefined;
+ s->aliasinfo = stateInfo_undefined;
+ s->definfo = stateInfo_undefined;
+ s->nullinfo = stateInfo_undefined;
+
+ /*@i32@*/ sfree (s);
}
}
}
/* a hack, methinks... makeArrayFetch (&a[0]) ==> a[] */
+ /* evans - 2001-08-27: not sure where this was necessary - it
+ ** causes an assertion in in aliasCheckPred to fail.
+ */
+
if (sRef_isAddress (arr))
{
sRef t = arr->info->ref;
if (sRef_isValid (s))
{
+ /* evans 2001-07-12: this is bogus, clean-up hack */
+ if (s->info->arrayfetch->arr != arr)
+ {
+ sRef res;
+ check (sRefSet_delete (arr->deriv, s));
+ res = sRef_buildArrayFetch (arr);
+ sRef_copyState (res, s);
+ llassert (res->info->arrayfetch->arr == arr);
+ return res;
+ }
+
sRef_setExKind (s, sRef_getExKind (arr), g_currentloc);
return s;
}
sRef_addDeriv (arr, s);
}
- llassert (valueTable_isUndefined (s->state));
- s->state = context_createValueTable (s);
+ if (valueTable_isUndefined (s->state))
+ {
+ s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
+ }
return (s);
}
if (ctype_isRealPointer (arr->type))
{
- (void) sRef_buildPointer (arr); /* do this to define arr! */
+ (void) sRef_buildPointer (arr); /* do this to define arr! */
}
s = sRef_findDerivedArrayFetch (arr, TRUE, i, FALSE);
-
+
if (sRef_isValid (s))
{
+ /* evans 2001-07-12: this is bogus, clean-up hack */
+ if (s->info->arrayfetch->arr != arr)
+ {
+ sRef res;
+
+ check (sRefSet_delete (arr->deriv, s));
+ res = sRef_buildArrayFetchKnown (arr, i);
+
+ llassert (res->info->arrayfetch->arr == arr);
+ sRef_copyState (res, s);
+ llassert (res->info->arrayfetch->arr == arr);
+ return res;
+ }
+
sRef_setExKind (s, sRef_getExKind (arr), g_currentloc);
+ llassert (s->info->arrayfetch->arr == arr);
return s;
}
else
s->info->arrayfetch->arr = arr; /* sRef_copy (arr); */ /*@i32@*/
s->info->arrayfetch->indknown = TRUE;
s->info->arrayfetch->ind = i;
-
+
sRef_setArrayFetchState (s, arr);
-
+ /* evans 2001-08-27 no: can change this - llassert (s->info->arrayfetch->arr == arr); */
+
s->oaliaskind = s->aliaskind;
s->oexpkind = s->expkind;
sRef_addDeriv (arr, s);
llassert (valueTable_isUndefined (s->state));
- s->state = context_createValueTable (s);
-
+ s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
return (s);
}
}
if (sRef_isValid (s))
{
+ DPRINTF (("Found array fetch: %s", sRef_unparseFull (s)));
return s;
}
else
{
sRef ret = sRef_constructPointer (t);
- /*
- ** This is necessary to prevent infinite depth
- ** in checking complete destruction.
- */
+ DPRINTF (("Constructed pointer: %s", sRef_unparseFull (ret)));
- if (isdead)
- {
- /* ret->defstate = SS_UNKNOWN; */
- return ret;
- }
- else
- {
- return ret;
- }
+ return ret;
}
}
else
ctype rt = t->type;
ctype st;
+ llassert (valueTable_isUndefined (s->state));
+
s->kind = SK_PTR;
s->info = (sinfo) dmalloc (sizeof (*s->info));
s->info->ref = t; /* sRef_copy (t); */ /*@i32*/
}
st = ctype_realType (s->type);
-
+
if (t->defstate == SS_UNDEFINED)
{
s->defstate = SS_UNUSEABLE;
{
s->aliaskind = AK_UNKNOWN;
}
-
+
sRef_setExKind (s, sRef_getExKind (t), fileloc_undefined);
sRef_setTypeState (s);
-
+
s->oaliaskind = s->aliaskind;
s->oexpkind = s->expkind;
- llassert (valueTable_isUndefined (s->state));
- s->state = context_createValueTable (s);
+ if (valueTable_isUndefined (s->state))
+ {
+ s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
+ }
+
return s;
}
s->oaliaskind = s->aliaskind;
s->oexpkind = s->expkind;
llassert (valueTable_isUndefined (s->state));
- s->state = context_createValueTable (s);
+ s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
DPRINTF (("Create: %s", sRef_unparseFull (s)));
return s;
/* start modification */
s->bufinfo.bufstate = BB_NULLTERMINATED;
/* end modification */
-
-
if (ctype_isUA (ct))
{
typeId uid = ctype_typeId (ct);
s->oexpkind = s->expkind;
llassert (valueTable_isUndefined (s->state));
- s->state = context_createValueTable (s);
+ s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
return s;
}
if (stateValue_hasLoc (val))
{
llgenindentmsg
- (message ("Meta state %qbecomes %s", sRef_unparseOpt (s),
- metaStateInfo_unparseValue (minfo, stateValue_getValue (val))),
+ (message ("%qbecomes %q", sRef_unparseOpt (s),
+ stateValue_unparseValue (val, minfo)),
stateValue_getLoc (val));
}
}
static bool
sRef_isAllocatedStorage (sRef s)
{
- if (sRef_isValid (s) && ynm_toBoolStrict (sRef_isReadable (s)))
+ if (sRef_isValid (s) && ynm_toBoolStrict (sRef_isValidLvalue (s)))
{
return (ctype_isVisiblySharable (sRef_getType (s)));
}
else
{
sRefSet aliases = usymtab_allAliases (s);
-
sRefSet_realElements (aliases, current)
{
return result;
}
-static void
+void
sRef_aliasSetComplete (void (predf) (sRef, fileloc), sRef s, fileloc loc)
{
sRefSet aliases;
sRefSet_free (aliases);
}
-static void
-sRef_aliasSetCompleteParam (void (predf) (sRef, alkind, fileloc), sRef s,
- alkind kind, fileloc loc)
+void
+sRef_aliasSetCompleteParam (void (predf) (sRef, int, fileloc), sRef s,
+ int kind, fileloc loc)
{
sRefSet aliases;
+
+ if (sRef_isDeep (s))
+ {
+ aliases = usymtab_allAliases (s);
+ }
+ else
+ {
+ aliases = usymtab_aliasedBy (s);
+ }
+ (*predf)(s, kind, loc);
+
+ sRefSet_realElements (aliases, current)
+ {
+ if (sRef_isValid (current))
+ {
+ current = sRef_updateSref (current);
+ ((*predf)(current, kind, loc));
+ }
+ } end_sRefSet_realElements;
+
+ sRefSet_free (aliases);
+}
+
+/*
+** Version of aliasSetCompleteParam for alkind parameters
+*/
+
+void
+sRef_aliasSetCompleteAlkParam (void (predf) (sRef, alkind, fileloc), sRef s,
+ alkind kind, fileloc loc)
+{
+ sRefSet aliases;
if (sRef_isDeep (s))
{
if (!sRef_isValid (s)) return;
-
/*
** Type equivalence checking is necessary --- there might be casting.
*/
inner = s->info->ref;
aliases = usymtab_allAliases (inner);
ct = sRef_getType (inner);
-
sRefSet_realElements (aliases, current)
{
aliases = usymtab_allAliases (inner);
ct = sRef_getType (inner);
+ DPRINTF (("Array fetch: %s", sRefSet_unparse (aliases)));
+
sRefSet_realElements (aliases, current)
{
if (sRef_isValid (current))
{
current = sRef_updateSref (current);
-
+ DPRINTF (("Current: %s", sRef_unparseFull (current)));
+
if (ctype_equal (ct, sRef_getType (current)))
{
-
if (s->info->arrayfetch->indknown)
{
sRef af = sRef_makeArrayFetchKnown (current, s->info->arrayfetch->ind);
-
+ DPRINTF (("Defining: %s", sRef_unparseFull (af)));
+ /* evans 2001-08-27 This isn't true:
+ llassert (af->info->arrayfetch->arr == current);
+ see comments in buildArrayFetchKnown
+ */
((*predf)(af, loc));
}
else
{
sRef af = sRef_makeArrayFetch (current);
-
+ /* evans 2001-08-27 This isn't true:
+ llassert (af->info->arrayfetch->arr == current);
+ see comments in buildArrayFetch
+ */
+ DPRINTF (("Defining: %s", sRef_unparseFull (af)));
((*predf)(af, loc));
}
}
+ else
+ {
+ DPRINTF (("Type mismatch: %s / %s",
+ ctype_unparse (ct),
+ ctype_unparse (sRef_getType (current))));
+ }
}
} end_sRefSet_realElements;
inner = s->info->field->rec;
aliases = usymtab_allAliases (inner);
ct = sRef_getType (inner);
-
sRefSet_realElements (aliases, current)
{
if (!sRef_isValid (s)) return;
-
/*
** Type equivalence checking is necessary --- there might be casting.
*/
inner = s->info->ref;
aliases = usymtab_allAliases (inner);
ct = sRef_getType (inner);
-
-
+
sRefSet_realElements (aliases, current)
{
if (sRef_isValid (current))
sRef_checkMutable (res);
+ DPRINTF (("Combine alias kinds: \n\t%s / \n\t%s",
+ sRef_unparseFull (res), sRef_unparseFull (other)));
if (alkind_equal (ares, aother)
|| aother == AK_UNKNOWN
|| aother == AK_ERROR)
res ->aliaskind = AK_ERROR;
}
else if (ares == AK_UNKNOWN || ares == AK_ERROR
- || sRef_isStateUndefined (res))
+ || sRef_isStateUndefined (res)
+ || sRef_isDefinitelyNull (res))
{
res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
res->aliaskind = aother;
}
- else if (sRef_isStateUndefined (other))
+ else if (sRef_isStateUndefined (other)
+ || sRef_isDefinitelyNull (other))
{
;
}
p = sRef_makePointer (s);
ret = sRef_makeField (p, f);
+ DPRINTF (("Arrow: %s => %s",
+ sRef_unparseFull (s), sRef_unparseFull (ret)));
return ret;
}
{
res->nullstate = other->nullstate;
res->nullinfo = stateInfo_update (res->nullinfo, other->nullinfo);
+ sRef_resetAliasKind (res);
}
void sRef_combineNullState (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other)
}
res->nullstate = nn;
+ sRef_resetAliasKind (res);
}
cstring sRef_nullMessage (sRef s)
{
DPRINTF (("Updating state: %s: %s %d / %s", sRef_unparse (s), key, value,
fileloc_unparse (loc)));
- valueTable_update
- (s->state, key, stateValue_create (value, stateInfo_makeLoc (loc)));
+ if (valueTable_contains (s->state, key))
+ {
+ valueTable_update
+ (s->state, key, stateValue_create (value, stateInfo_makeLoc (loc)));
+ }
+ else
+ {
+ valueTable_insert
+ (s->state, cstring_copy (key), stateValue_create (value, stateInfo_makeLoc (loc)));
+ }
+
DPRINTF (("After: %s", sRef_unparseFull (s)));
}
}
stateValue val;
val = valueTable_lookup (s->state, key);
- llassert (stateValue_isDefined (val));
+ /* Okay if its not defined, just returns stateValue_undefined */
return val;
}
else
if (s->defstate == SS_UNKNOWN || s->defstate == SS_DEFINED || s->defstate == SS_SPECIAL)
{
- s->aliaskind = AK_IMPTEMP;
+ /* s->aliaskind = AK_IMPTEMP; */ /* evans 2001-07-23 shouldn't effect alias state */
s->defstate = SS_SPECIAL;
DPRINTF (("Made special: %s", sRef_unparseFull (s)));
return TRUE;
}
else
{
- s->aliaskind = AK_IMPTEMP;
+ /* s->aliaskind = AK_IMPTEMP; */
s->defstate = SS_SPECIAL;
return FALSE;
}
return (ctype_getArraySize (c) );
}
+void sRef_setValue (sRef s, multiVal val)
+{
+ llassert (sRef_isValid (s));
+ multiVal_free (s->val);
+ s->val = val;
+}
+bool sRef_hasValue (sRef s)
+{
+ return (sRef_isValid (s)
+ && multiVal_isDefined (s->val));
+}
+multiVal sRef_getValue (sRef s)
+{
+ if (sRef_isValid (s))
+ {
+ return s->val;
+ }
-
-
-
-
-
+ return multiVal_undefined;
+}