X-Git-Url: http://andersk.mit.edu/gitweb/splint.git/blobdiff_plain/12f2ffe97c533d1f0c79204b67cd82d3530af162..abd7f89523564e5e238e5852585b98f72c3b48f4:/src/sRef.c?ds=sidebyside diff --git a/src/sRef.c b/src/sRef.c index d6223b3..ed43a68 100644 --- a/src/sRef.c +++ b/src/sRef.c @@ -1,6 +1,6 @@ /* -** 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 @@ -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 */ /* ** storeRef.c @@ -34,7 +34,7 @@ ** */ -# include "lclintMacros.nf" +# include "splintMacros.nf" # include "basic.h" # include "exprChecks.h" # include "transferChecks.h" @@ -63,10 +63,6 @@ static void sRef_updateNullState (sRef p_res, sRef p_other) /*@modifies p_res@*/ 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 @@ -78,17 +74,24 @@ 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 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@*/ @@ -359,12 +362,15 @@ static /*@dependent@*/ /*@notnull@*/ /*@special@*/ sRef s->safe = TRUE; s->modified = FALSE; s->immut = FALSE; + s->val = multiVal_undefined; s->type = ctype_unknown; s->defstate = SS_UNKNOWN; /* start modifications */ s->bufinfo.bufstate = BB_NOTNULLTERMINATED; + s->bufinfo.size = -1; /*@i24 unknown@*/ + s->bufinfo.len = -1; /*@i24 unknown@*/ /* end modifications */ s->aliaskind = AK_UNKNOWN; @@ -584,20 +590,21 @@ static bool && (fileloc_isDefined (s->aliasinfo->loc))); } -static /*@falsenull@*/ bool +static /*@falsewhennull@*/ bool sRef_hasStateInfoLoc (sRef s) { return (sRef_isValid (s) && (s->definfo != NULL) && (fileloc_isDefined (s->definfo->loc))); } -static /*@falsenull@*/ bool +static /*@falsewhennull@*/ bool sRef_hasExpInfoLoc (sRef s) { return (sRef_isValid (s) && (s->expinfo != NULL) && (fileloc_isDefined (s->expinfo->loc))); } +# if 0 static /*@observer@*/ /*@unused@*/ stateInfo sRef_getInfo (sRef s, cstring key) { stateValue sv; @@ -615,7 +622,7 @@ static /*@observer@*/ /*@unused@*/ stateInfo sRef_getInfo (sRef s, cstring key) return stateInfo_undefined; } - +# endif static bool sRef_hasNullInfoLoc (sRef s) @@ -725,6 +732,14 @@ void sRef_clearGlobalScopeSafe () 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; @@ -1015,10 +1030,8 @@ void sRef_setModified (sRef s) { sRef base = sRef_getBase (s); - llassert (s->kind == SK_FIELD); - if (sRef_isPointer (base)) { base = sRef_getBase (base); @@ -1053,7 +1066,6 @@ sRef_canModifyVal (sRef s, sRefSet sl) bool sRef_canModify (sRef s, sRefSet sl) { - if (context_getFlag (FLG_MUSTMOD)) { return (sRef_doModify (s, sl)); @@ -2155,6 +2167,7 @@ sRef_closeEnough (sRef s1, sRef s2) 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; @@ -2166,7 +2179,7 @@ sRef_closeEnough (sRef s1, sRef s2) { case SK_RESULT: { - // s = sRef_saveCopy(s); + /* s = sRef_saveCopy(s); */ /*@i523@*/ ce = constraintExpr_makeTermsRef (s); return ce; } @@ -2183,7 +2196,7 @@ sRef_closeEnough (sRef s1, sRef s2) { 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; } @@ -2219,7 +2232,8 @@ sRef_closeEnough (sRef s1, sRef s2) 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); @@ -2227,9 +2241,6 @@ sRef_closeEnough (sRef s1, sRef s2) return ce; } } - - - } /*@exposed@*/ sRef @@ -2274,9 +2285,14 @@ sRef_fixBaseParam (/*@returned@*/ sRef s, exprNodeList args) (sRef_fixBaseParam (s->info->arrayfetch->arr, args))); } case SK_FIELD: - return (sRef_makeField (sRef_fixBaseParam (s->info->field->rec, args), - s->info->field->field)); - + { + sRef res; + DPRINTF (("Fix field: %s", sRef_unparseFull (s))); + res = sRef_makeField (sRef_fixBaseParam (s->info->field->rec, args), + s->info->field->field); + DPRINTF (("Returns: %s", sRef_unparseFull (res))); + return res; + } case SK_PTR: return (sRef_makePointer (sRef_fixBaseParam (s->info->ref, args))); @@ -2322,7 +2338,7 @@ sRef_undumpGlobal (char **c) 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; @@ -2355,8 +2371,7 @@ sRef_undumpGlobal (char **c) BADEXIT; } -/*@exposed@*/ sRef -sRef_undump (char **c) +static /*@exposed@*/ sRef sRef_undumpBody (char **c) { char p = **c; @@ -2365,9 +2380,9 @@ sRef_undump (char **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_makeResult (ctype_undump (c))); case 'a': @@ -2457,8 +2472,21 @@ sRef_undump (char **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)) { @@ -2526,8 +2554,22 @@ sRef_dump (sRef 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 ("-")); @@ -2769,9 +2811,7 @@ sRef_unparseWithArgs (sRef s, uentryList args) return uentry_getName (ue); } - return (message ("info->paramno + 1)); } case SK_ARRAYFETCH: if (s->info->arrayfetch->indknown) @@ -2941,7 +2981,14 @@ sRef_unparseDebug (sRef s) case SK_TYPE: return (message ("", ctype_unparse (s->type))); case SK_CONST: - return (message ("", ctype_unparse (s->type))); + if (sRef_hasValue (s)) + { + return (message ("", ctype_unparse (s->type), multiVal_unparse (sRef_getValue (s)))); + } + else + { + return (message ("", ctype_unparse (s->type))); + } case SK_RESULT: return (message ("", ctype_unparse (s->type))); case SK_SPECIAL: @@ -3070,7 +3117,7 @@ bool sRef_isUnconstrained (sRef s) } 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 (); @@ -3111,13 +3158,13 @@ static /*@dependent@*/ /*@notnull@*/ sRef 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) @@ -3139,9 +3186,9 @@ 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 @@ -3153,7 +3200,7 @@ sRef_setParamNo (sRef s, int l) } /*@dependent@*/ sRef -sRef_makeParam (int l, ctype ct) +sRef_makeParam (int l, ctype ct, stateInfo stinfo) { sRef s = sRef_new (); @@ -3167,7 +3214,7 @@ sRef_makeParam (int l, ctype ct) /* (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; } @@ -3255,7 +3302,7 @@ static bool sRef_isZerothArrayFetch (/*@notnull@*/ sRef s) } llassert (valueTable_isUndefined (s->state)); - s->state = context_createValueTable (s); + s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc)); return s; } } @@ -3350,7 +3397,7 @@ sRef_getRootBaseAux (sRef s, int depth) ("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); @@ -3428,7 +3475,7 @@ sRef_makeObject (ctype o) 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; } @@ -3447,7 +3494,7 @@ sRef sRef_makeExternal (sRef t) 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; } @@ -3463,7 +3510,7 @@ sRef sRef_makeExternal (sRef t) 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 @@ -3680,6 +3727,10 @@ sRef_mergeStateAux (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other, 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); @@ -4136,7 +4187,6 @@ static bool checkDeadState (/*@notnull@*/ sRef el, bool tbranch, fileloc loc) ? "kept" : "released")), loc)) { - if (sRef_isKept (el)) { sRef_showAliasInfo (el); @@ -4274,7 +4324,7 @@ sRef sRef_makeConj (/*@exposed@*/ /*@returned@*/ sRef a, /*@exposed@*/ sRef b) 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 @@ -4292,7 +4342,7 @@ sRef_makeUnknown () return s; } -static /*@owned@*/ sRef +static /*@owned@*/ /*@notnull@*/ sRef sRef_makeSpecial (speckind sk) /*@*/ { sRef s = sRef_new (); @@ -4359,7 +4409,7 @@ sRef_makeGlobalMarker (void) { sRef s = sRef_makeSpecial (SR_GLOBALMARKER); llassert (valueTable_isUndefined (s->state)); - s->state = context_createGlobalMarkerValueTable (); + s->state = context_createGlobalMarkerValueTable (stateInfo_undefined); return s; } @@ -4374,7 +4424,7 @@ sRef_makeResult (ctype c) 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; @@ -4548,10 +4598,17 @@ bool sRef_hasNoStorage (sRef 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; @@ -4561,9 +4618,9 @@ ynm sRef_isReadable (sRef s) 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; } @@ -4571,7 +4628,7 @@ ynm sRef_isReadable (sRef s) } else { - if (ynm_toBoolStrict (sRef_isReadable (sRef_getConjB (s)))) + if (ynm_toBoolStrict (sRef_isValidLvalue (sRef_getConjB (s)))) { return MAYBE; } @@ -4595,9 +4652,9 @@ ynm sRef_isReadable (sRef s) || 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)); } @@ -4614,7 +4671,7 @@ static /*@exposed@*/ sRef whatUndefined (/*@exposed@*/ sRef fref, int depth) ("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); @@ -4830,7 +4887,7 @@ void sRef_clearAliasState (sRef s, fileloc loc) 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) @@ -5093,6 +5150,7 @@ static void sRef_setDefinedAux (sRef s, fileloc loc, bool clear) /* evans 2001-07-12: need to define the derived references */ sRefSet_elements (s->deriv, el) { + llassert (sRef_isValid (el)); el->defstate = SS_DEFINED; } end_sRefSet_elements ; } @@ -5117,7 +5175,29 @@ void sRef_setPartialDefinedComplete (sRef s, fileloc loc) void sRef_setDefinedComplete (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); } @@ -5195,6 +5275,7 @@ void sRef_setPdefined (sRef s, fileloc loc) { sRef nb; + DPRINTF (("set pdefined: %s", sRef_unparseFull (base))); base->defstate = SS_PDEFINED; nb = sRef_getBaseSafe (base); base = nb; @@ -5232,9 +5313,9 @@ static void sRef_setStateAux (sRef s, sstate ss, fileloc loc) if (base->defstate == SS_DEFINED) { sRef nb; - + + DPRINTF (("set pdefined: %s", sRef_unparseFull (s))); base->defstate = SS_PDEFINED; - nb = sRef_getBaseSafe (base); base = nb; } @@ -5244,8 +5325,7 @@ static void sRef_setStateAux (sRef s, sstate ss, fileloc loc) } } } - - } + } } void sRef_setAllocatedComplete (sRef s, fileloc loc) @@ -5321,7 +5401,8 @@ void sRef_setNullStateAux (/*@notnull@*/ sRef s, nstate ns, fileloc loc) 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); @@ -5338,8 +5419,12 @@ void sRef_setNotNull (sRef s, fileloc loc) void sRef_setNullStateN (sRef s, nstate n) { - sRef_checkMutable (s); - s->nullstate = n; + if (sRef_isValid (s)) + { + sRef_checkMutable (s); + s->nullstate = n; + sRef_resetAliasKind (s); + } } void sRef_setNullState (sRef s, nstate n, fileloc loc) @@ -5350,22 +5435,23 @@ 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); - sRef_setLen (s, b.len); - break; - case BB_POSSIBLYNULLTERMINATED: - sRef_setPossiblyNullTerminatedState(s); - break; - case BB_NOTNULLTERMINATED: - sRef_setNotNullTerminatedState (s); - break; + case BB_NULLTERMINATED: + sRef_setNullTerminatedState (s); + sRef_setLen (s, b.len); + break; + case BB_POSSIBLYNULLTERMINATED: + sRef_setPossiblyNullTerminatedState(s); + break; + case BB_NOTNULLTERMINATED: + sRef_setNotNullTerminatedState (s); + break; } - sRef_setSize (s, b.size); + sRef_setSize (s, b.size); + /* PL: TO BE DONE : Aliases are not modified right now, have to be similar to * setNullStateInnerComplete. */ @@ -5493,13 +5579,12 @@ void sRef_setKept (sRef s, fileloc loc) if (base->defstate == SS_DEFINED) { base->defstate = SS_PDEFINED; - base = sRef_getBaseSafe (base); + base = sRef_getBaseSafe (base); } else { break; } - } s->aliaskind = AK_KEPT; @@ -5693,6 +5778,7 @@ sRef sRef_copy (sRef 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; @@ -6096,7 +6182,7 @@ sRef_buildNCField (/*@exposed@*/ sRef rec, /*@exposed@*/ cstring f) else { ctype ct = ctype_realType (rec->type); - + DPRINTF (("Field of: %s", sRef_unparse (rec))); s = sRef_newRef (); @@ -6140,7 +6226,7 @@ sRef_buildNCField (/*@exposed@*/ sRef rec, /*@exposed@*/ cstring f) s->oaliaskind = s->aliaskind; s->oexpkind = s->expkind; - + DPRINTF (("sref: %s", sRef_unparseFull (s))); } else @@ -6232,6 +6318,10 @@ void sRef_setArrayFetchState (/*@notnull@*/ /*@exposed@*/ sRef 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; @@ -6434,6 +6524,7 @@ void sRef_setArrayFetchState (/*@notnull@*/ /*@exposed@*/ sRef s, check (sRefSet_delete (arr->deriv, s)); res = sRef_buildArrayFetch (arr); sRef_copyState (res, s); + llassert (res->info->arrayfetch->arr == arr); return res; } @@ -6459,8 +6550,10 @@ void sRef_setArrayFetchState (/*@notnull@*/ /*@exposed@*/ sRef 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); } @@ -6477,25 +6570,28 @@ void sRef_setArrayFetchState (/*@notnull@*/ /*@exposed@*/ sRef 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; } @@ -6509,16 +6605,16 @@ void sRef_setArrayFetchState (/*@notnull@*/ /*@exposed@*/ sRef s, 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); } } @@ -6710,6 +6806,8 @@ sRef_constructPointerAux (/*@notnull@*/ /*@exposed@*/ sRef t) 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*/ @@ -6720,7 +6818,7 @@ sRef_constructPointerAux (/*@notnull@*/ /*@exposed@*/ sRef t) } st = ctype_realType (s->type); - + if (t->defstate == SS_UNDEFINED) { s->defstate = SS_UNUSEABLE; @@ -6742,15 +6840,18 @@ sRef_constructPointerAux (/*@notnull@*/ /*@exposed@*/ sRef t) { 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; } @@ -7099,7 +7200,7 @@ sRef_makeType (ctype ct) 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; @@ -7136,7 +7237,7 @@ sRef_makeConst (ctype 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; } @@ -7633,7 +7734,7 @@ sRef_showMetaStateInfo (sRef s, cstring key) if (stateValue_hasLoc (val)) { llgenindentmsg - (message ("Meta state %qbecomes %q", sRef_unparseOpt (s), + (message ("%qbecomes %q", sRef_unparseOpt (s), stateValue_unparseValue (val, minfo)), stateValue_getLoc (val)); } @@ -7927,7 +8028,7 @@ bool sRef_isJustAllocated (sRef s) 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))); } @@ -8124,7 +8225,6 @@ sRef_aliasCheckPred (bool (predf) (sRef, exprNode, sRef, exprNode), else { sRefSet aliases = usymtab_allAliases (s); - sRefSet_realElements (aliases, current) { @@ -8211,7 +8311,7 @@ sRef_aliasCompleteSimplePred (bool (predf) (sRef), sRef s) return result; } -static void +void sRef_aliasSetComplete (void (predf) (sRef, fileloc), sRef s, fileloc loc) { sRefSet aliases; @@ -8234,12 +8334,44 @@ sRef_aliasSetComplete (void (predf) (sRef, fileloc), sRef s, fileloc loc) 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)) { @@ -8273,7 +8405,6 @@ sRef_innerAliasSetComplete (void (predf) (sRef, fileloc), sRef s, fileloc loc) if (!sRef_isValid (s)) return; - /* ** Type equivalence checking is necessary --- there might be casting. */ @@ -8327,13 +8458,19 @@ sRef_innerAliasSetComplete (void (predf) (sRef, fileloc), sRef s, fileloc loc) { sRef af = sRef_makeArrayFetchKnown (current, s->info->arrayfetch->ind); DPRINTF (("Defining: %s", sRef_unparseFull (af))); - llassert (af->info->arrayfetch->arr == current); + /* 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); - llassert (af->info->arrayfetch->arr == 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)); } @@ -8353,7 +8490,6 @@ sRef_innerAliasSetComplete (void (predf) (sRef, fileloc), sRef s, fileloc loc) inner = s->info->field->rec; aliases = usymtab_allAliases (inner); ct = sRef_getType (inner); - sRefSet_realElements (aliases, current) { @@ -8399,7 +8535,6 @@ sRef_innerAliasSetCompleteParam (void (predf) (sRef, sRef), sRef s, sRef t) if (!sRef_isValid (s)) return; - /* ** Type equivalence checking is necessary --- there might be casting. */ @@ -8416,8 +8551,7 @@ sRef_innerAliasSetCompleteParam (void (predf) (sRef, sRef), sRef s, sRef t) inner = s->info->ref; aliases = usymtab_allAliases (inner); ct = sRef_getType (inner); - - + sRefSet_realElements (aliases, current) { if (sRef_isValid (current)) @@ -8698,6 +8832,8 @@ static void 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) @@ -8710,12 +8846,14 @@ static void 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)) { ; } @@ -8904,6 +9042,8 @@ extern /*@exposed@*/ sRef sRef_makeArrow (sRef s, /*@dependent@*/ cstring f) p = sRef_makePointer (s); ret = sRef_makeField (p, f); + DPRINTF (("Arrow: %s => %s", + sRef_unparseFull (s), sRef_unparseFull (ret))); return ret; } @@ -9268,11 +9408,12 @@ static speckind speckind_fromInt (int i) } -static void sRef_updateNullState (sRef res, sRef other) +static void sRef_updateNullState (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other) /*@modifies res@*/ { res->nullstate = other->nullstate; res->nullinfo = stateInfo_update (res->nullinfo, other->nullinfo); + sRef_resetAliasKind (res); } void sRef_combineNullState (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other) @@ -9332,6 +9473,7 @@ void sRef_combineNullState (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other) } res->nullstate = nn; + sRef_resetAliasKind (res); } cstring sRef_nullMessage (sRef s) @@ -9744,14 +9886,14 @@ bool sRef_makeStateSpecial (sRef s) 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; } @@ -9859,3 +10001,25 @@ long int sRef_getArraySize (sRef p_s) /*@*/ { 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; +}