2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 University of Virginia,
4 ** Massachusetts Institute of Technology
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
28 ** storeRef's are kept in allRefs for each function scope, and all are
29 ** free'd at the end of the function. This relies on the constraint that
30 ** no storeRef created while checking a function is used outside that
33 ** storeRefs in the file and global scopes are free'd by the uentry.
37 # include "splintMacros.nf"
39 # include "exprChecks.h"
40 # include "transferChecks.h"
41 # include "sRefTable.h"
42 # include "structNames.h"
45 ** Predicate functions that evaluate both arguments in order.
49 # define OR(a,b) (a ? (b, TRUE) : b)
52 # define AND(a,b) (a ? b : (b, FALSE))
54 static void sRef_checkValidAux (sRef p_s, sRefSet p_checkedsofar) /*@modifies p_checkedsofar@*/ ;
56 static bool sRef_isDerived (sRef p_s) /*@*/ ;
58 static /*@exposed@*/ sRef sRef_fixDirectBase (sRef p_s, sRef p_base)
59 /*@modifies p_base@*/ ;
61 static void sRef_updateNullState (sRef p_res, sRef p_other) /*@modifies p_res@*/ ;
63 static bool sRef_isAllocatedStorage (sRef p_s) /*@*/ ;
64 static void sRef_setNullErrorLoc (sRef p_s, fileloc) /*@*/ ;
65 static void sRef_setNullStateN (sRef p_s, nstate p_n) /*@modifies p_s@*/ ;
67 static int sRef_depth (sRef p_s) /*@*/ ;
70 sRef_innerAliasSetComplete (void (p_predf) (sRef, fileloc), sRef p_s,
75 sRef_innerAliasSetCompleteParam (void (p_predf) (sRef, sRef), sRef p_s, sRef p_t)
78 static speckind speckind_fromInt (int p_i);
79 static bool sRef_equivalent (sRef p_s1, sRef p_s2);
80 static bool sRef_isDeepUnionField (sRef p_s);
81 static void sRef_addDeriv (/*@notnull@*/ sRef p_s, /*@notnull@*/ /*@exposed@*/ sRef p_t);
82 static bool sRef_checkModify (sRef p_s, sRefSet p_sl) /*@*/ ;
85 ** If s is definitely null, it has no memory state.
88 static void sRef_resetAliasKind (/*@notnull@*/ sRef s) /*@modifies s->aliaskind@*/
90 if (s->nullstate == NS_DEFNULL)
92 /* s->aliaskind = AK_ERROR; */
97 extern void sRef_checkCompletelyReasonable (sRef s) /*@*/
99 DPRINTF (("Check sRef: [%p] %s / %s", s, sRef_unparse (s),
100 sRefSet_unparse (sRef_derivedFields (s))));
102 if (sRef_isReasonable (s))
104 sRefSet_elements (s->deriv, el)
107 sRef_checkCompletelyReasonable (el);
108 } end_sRefSet_elements ;
113 /*@falsewhennull@*/ bool sRef_isReasonable (sRef s) /*@*/
115 if (sRef_isValid (s))
118 if (!bool_isReasonable (s->safe)
119 || !bool_isReasonable (s->modified)
120 || !bool_isReasonable (s->immut))
122 llcontbug (message ("Unreasonable sRef [%p]", s));
126 if (!sstate_isValid (s->defstate))
128 llcontbug (message ("Unreasonable sRef [%p]", s));
132 if (!nstate_isValid (s->nullstate))
134 llcontbug (message ("Unreasonable sRef [%p]", s));
138 if (!alkind_isValid (s->aliaskind)
139 || !alkind_isValid (s->oaliaskind))
141 llcontbug (message ("Unreasonable sRef [%p]", s));
145 if (!exkind_isValid (s->expkind)
146 || !exkind_isValid (s->oexpkind))
148 llcontbug (message ("Unreasonable sRef [%p]", s));
159 static /*@nullwhentrue@*/ bool sRef_isUnreasonable (sRef s) /*@*/
161 return (!sRef_isReasonable (s));
164 static void sRef_checkMutable (/*@unused@*/ sRef s)
166 if (sRef_isReasonable (s) && s->immut)
168 llcontbug (message ("Modification to sRef marked immutable: %q",
169 sRef_unparseFull (s)));
173 static bool skind_isSimple (skind sk)
177 case SK_PARAM: case SK_CVAR: case SK_CONST:
178 case SK_OBJECT: case SK_UNKNOWN: case SK_NEW:
185 static void sinfo_free (/*@special@*/ /*@temp@*/ /*@notnull@*/ sRef p_s)
186 /*@uses p_s->kind, p_s->info@*/
187 /*@releases p_s->info@*/ ;
189 static /*@null@*/ sinfo sinfo_copy (/*@notnull@*/ sRef p_s) /*@*/ ;
190 static void sRef_setPartsFromUentry (sRef p_s, uentry p_ue)
192 static bool checkDeadState (/*@notnull@*/ sRef p_el, /*@null@*/ sRef p_e2,
193 bool p_tbranch, fileloc p_loc);
194 static /*@dependent@*/ sRef sRef_constructPointerAux (/*@notnull@*/ /*@exposed@*/ sRef p_t) /*@*/ ;
197 sRef_combineExKinds (/*@notnull@*/ sRef p_res, /*@notnull@*/ sRef p_other)
198 /*@modifies p_res@*/ ;
201 sRef_combineAliasKinds (/*@notnull@*/ sRef p_res, /*@notnull@*/ sRef p_other,
202 clause p_cl, fileloc p_loc)
203 /*@modifies p_res@*/ ;
206 sRef_combineNullState (/*@notnull@*/ sRef p_res, /*@notnull@*/ sRef p_other)
207 /*@modifies p_res@*/ ;
210 sRef_combineDefState (/*@notnull@*/ sRef p_res, /*@notnull@*/ sRef p_other)
211 /*@modifies p_res@*/ ;
213 static void sRef_setStateFromAbstractUentry (sRef p_s, uentry p_ue)
217 sinfo_update (/*@notnull@*/ /*@exposed@*/ sRef p_res,
218 /*@notnull@*/ /*@exposed@*/ sRef p_other);
219 static void sRef_setDefinedAux (sRef p_s, fileloc p_loc, bool p_clear)
221 static void sRef_setDefinedNoClear (sRef p_s, fileloc p_loc)
223 static void sRef_setStateAux (sRef p_s, sstate p_ss, fileloc p_loc)
226 static /*@exposed@*/ sRef
227 sRef_buildNCField (/*@exposed@*/ sRef p_rec, /*@exposed@*/ cstring p_f);
230 sRef_mergeStateAux (/*@notnull@*/ sRef p_res, /*@notnull@*/ sRef p_other,
231 clause p_cl, bool p_opt, fileloc p_loc,
233 /*@modifies p_res, p_other@*/ ;
235 static /*@null@*/ sinfo sinfo_fullCopy (/*@notnull@*/ sRef p_s);
236 static bool sRef_doModify (sRef p_s, sRefSet p_sl) /*@modifies p_s@*/ ;
237 static bool sRef_doModifyVal (sRef p_s, sRefSet p_sl) /*@modifies p_s@*/;
238 static bool sRef_checkModifyVal (sRef p_s, sRefSet p_sl) /*@*/ ;
240 static /*@only@*/ sRefSet
241 sRef_mergeDerivs (/*@only@*/ sRefSet p_res, sRefSet p_other,
242 bool p_opt, clause p_cl, fileloc p_loc);
244 static /*@only@*/ sRefSet
245 sRef_mergeUnionDerivs (/*@only@*/ sRefSet p_res,
246 /*@exposed@*/ sRefSet p_other,
247 bool p_opt, clause p_cl, fileloc p_loc);
249 static /*@only@*/ sRefSet
250 sRef_mergePdefinedDerivs (/*@only@*/ sRefSet p_res, sRefSet p_other, bool p_opt,
251 clause p_cl, fileloc p_loc);
253 static /*@only@*/ cstring sRef_unparseWithArgs (sRef p_s, uentryList p_args);
254 static /*@only@*/ cstring sRef_unparseNoArgs (sRef p_s);
256 static /*@exposed@*/ sRef sRef_findDerivedPointer (sRef p_s);
257 static /*@exposed@*/ sRef sRef_findDerivedArrayFetch (/*@notnull@*/ sRef, bool, int, bool) ;
258 static /*@exposed@*/ sRef sRef_findDerivedField (/*@notnull@*/ sRef p_rec, cstring p_f);
259 static /*@exposed@*/ sRef
260 sRef_getDeriv (/*@notnull@*/ /*@returned@*/ sRef p_set, sRef p_guide);
262 static bool inFunction = FALSE;
263 static /*@only@*/ sRefTable allRefs;
265 /* # define DEBUGREFS */
269 static totnsrefs = 0;
270 static maxnsrefs = 0;
271 static ntotrefers = 0;
275 static /*@checked@*/ bool protectDerivs = FALSE;
278 ** Result of sRef_alloc is dependent since allRefs may
279 ** reference it. It is only if !inFunction.
282 static /*@dependent@*/ /*@out@*/ /*@notnull@*/ sRef
285 sRef s = (sRef) dmalloc (sizeof (*s));
289 DPRINTF (("Alloc sref: [%p]", s));
293 allRefs = sRefTable_add (allRefs, s);
298 DPRINTF (("Not in function!"));
304 if (nsrefs >= maxnsrefs)
313 /*@-mustfree@*/ /*@-freshtrans@*/
315 /*@=mustfree@*/ /*@=freshtrans@*/
318 static void sRef_checkValidAux (sRef s, sRefSet checkedsofar)
322 if (!sRef_isReasonable (s)) return;
324 if (sRefSet_containsSameObject (checkedsofar, s))
330 checkedsofar = sRefSet_insert (checkedsofar, s);
331 /*@=temptrans@*/ /* checksofar will be destroyed before checkValid returns */
335 case SK_UNCONSTRAINED:
336 llassert (cstring_length (s->info->fname) < 100);
340 llassert (s->info->cvar->lexlevel >= 0);
341 /* llassert (s->info->cvar->lexlevel <= usymtab_getCurrentDepth ()); */
345 llassert (s->info->paramno >= -1);
346 llassert (s->info->paramno <= 999); /* sanity check */
350 sRef_checkValidAux (s->info->arrayfetch->arr, checkedsofar);
354 sRef_checkValidAux (s->info->field->rec, checkedsofar);
355 llassert (cstring_length (s->info->field->field) < 100);
359 sRef_checkValidAux (s->info->ref, checkedsofar);
363 sRef_checkValidAux (s->info->ref, checkedsofar);
367 /* check ctype s->info->object */
371 sRef_checkValidAux (s->info->conj->a, checkedsofar);
372 sRef_checkValidAux (s->info->conj->b, checkedsofar);
376 llassert (cstring_length (s->info->fname) < 100);
380 sRef_checkValidAux (s->info->ref, checkedsofar);
384 sRef_checkValidAux (s->info->ref, checkedsofar);
390 /* check ctyp s->type */
394 llassert (s->info->spec == SR_NOTHING
395 || s->info->spec == SR_INTERNAL
396 || s->info->spec == SR_SPECSTATE
397 || s->info->spec == SR_SYSTEM);
407 sRefSet_elements (s->deriv, el)
409 sRef_checkValidAux (el, checkedsofar);
410 } end_sRefSet_elements ;
413 void sRef_checkValid (/*@unused@*/ sRef s)
417 sRefSet checkedsofar = sRefSet_new ();
418 sRef_checkValidAux (s, checkedsofar);
422 static /*@dependent@*/ /*@notnull@*/ /*@special@*/ sRef
425 /*@ensures isnull result->aliasinfo, result->definfo,
426 result->expinfo, result->info, result->deriv, result->state@*/
428 sRef s = sRef_alloc ();
430 s->kind = SK_UNKNOWN;
434 s->val = multiVal_undefined;
436 s->type = ctype_unknown;
437 s->defstate = SS_UNKNOWN;
439 /* start modifications */
440 s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
441 s->bufinfo.size = -1;
443 /* end modifications */
445 s->aliaskind = AK_UNKNOWN;
446 s->oaliaskind = AK_UNKNOWN;
448 s->nullstate = NS_UNKNOWN;
450 s->expkind = XO_UNKNOWN;
451 s->oexpkind = XO_UNKNOWN;
453 s->aliasinfo = stateInfo_undefined;
454 s->definfo = stateInfo_undefined;
455 s->nullinfo = stateInfo_undefined;
456 s->expinfo = stateInfo_undefined;
459 s->deriv = sRefSet_undefined;
461 s->state = valueTable_undefined;
466 static /*@dependent@*/ /*@notnull@*/ /*@special@*/ sRef
469 /*@ensures isnull result->aliasinfo, result->definfo,
470 result->expinfo, result->info, result->deriv@*/
472 sRef res = sRef_new ();
474 res->state = valueTable_undefined;
479 void sRef_protectDerivs (void) /*@modifies protectDerivs@*/
481 llassert (!protectDerivs);
482 protectDerivs = TRUE;
485 void sRef_clearProtectDerivs (void) /*@modifies protectDerivs@*/
487 llassert (protectDerivs);
488 protectDerivs = FALSE;
492 ** hmmm...here be kind of a hack. This function mysteriously appeared
493 ** in my code, but I'm sure I didn't write it.
497 sRef_isRecursiveField (sRef s)
499 if (sRef_isField (s))
501 if (sRef_depth (s) > 13)
506 fieldname = sRef_getField (s);
507 base = sRef_getBase (s);
509 while (sRef_isReasonable (base))
511 if (sRef_isField (base))
513 if (cstring_equal (fieldname, sRef_getField (base)))
519 base = sRef_getBaseSafe (base);
528 sRef_addDeriv (/*@notnull@*/ sRef s, /*@notnull@*/ /*@exposed@*/ sRef t)
530 if (!context_inProtectVars ()
532 && sRef_isReasonable (s)
533 && sRef_isReasonable (t)
534 && !sRef_isConst (s))
536 int sd = sRef_depth (s);
537 int td = sRef_depth (t);
544 /* This sometimes fails: (evans 2001-07-12)
545 if (sRef_isArrayFetch (t))
547 DPRINTF (("Derived fetch: %s / %s / %s",
548 sRef_unparseFull (s), sRef_unparseFull (t),
549 sRef_unparseFull (t->info->arrayfetch->arr)));
550 llassert (t->info->arrayfetch->arr == s);
554 if (sRef_isFileOrGlobalScope (s))
556 if (context_inFunctionLike ()
557 && ctype_isKnown (sRef_getType (s))
558 && !ctype_isFunction (sRef_getType (s)))
560 globSet g = context_getUsedGlobs ();
562 if (!globSet_member (g, s))
565 ** don't report as a bug
569 (message ("sRef_addDeriv: global variable not in used "
570 "globs: %q / %s / %q",
572 ctype_unparse (sRef_getType (s)),
573 sRefSet_unparse (s->deriv)));
578 DPRINTF (("Add deriv: [%p] %s / [%p] %s",
580 t, sRef_unparse (t)));
582 s->deriv = sRefSet_insert (s->deriv, t);
588 DPRINTF (("Add deriv: [%p] %s / [%p] %s",
590 t, sRef_unparse (t)));
592 s->deriv = sRefSet_insert (s->deriv, t);
598 sRef_deepPred (bool (predf) (sRef), sRef s)
600 if (sRef_isReasonable (s))
602 if ((*predf)(s)) return TRUE;
607 return (sRef_deepPred (predf, s->info->ref));
609 return (sRef_deepPred (predf, s->info->arrayfetch->arr));
611 return (sRef_deepPred (predf, s->info->field->rec));
613 return (sRef_deepPred (predf, s->info->conj->a)
614 || sRef_deepPred (predf, s->info->conj->b));
623 bool sRef_modInFunction (void)
628 void sRef_setStateFromType (sRef s, ctype ct)
630 if (sRef_isReasonable (s))
632 if (ctype_isUser (ct))
634 DPRINTF (("Here we are: %s", sRef_unparseFull (s)));
635 sRef_setStateFromUentry
636 (s, usymtab_getTypeEntry (ctype_typeId (ct)));
638 else if (ctype_isAbstract (ct))
640 DPRINTF (("Here we are: %s", sRef_unparseFull (s)));
641 sRef_setStateFromAbstractUentry
642 (s, usymtab_getTypeEntry (ctype_typeId (ct)));
646 ; /* not a user type */
651 static void sRef_setTypeState (sRef s)
653 if (sRef_isReasonable (s))
655 sRef_setStateFromType (s, s->type);
659 bool sRef_hasAliasInfoLoc (sRef s)
661 return (sRef_isReasonable (s) && (s->aliasinfo != NULL)
662 && (fileloc_isDefined (s->aliasinfo->loc)));
665 /*@falsewhennull@*/ bool sRef_hasStateInfoLoc (sRef s)
667 return (sRef_isReasonable (s) && (s->definfo != NULL)
668 && (fileloc_isDefined (s->definfo->loc)));
671 /*@falsewhennull@*/ bool sRef_hasExpInfoLoc (sRef s)
673 return (sRef_isReasonable (s)
674 && (s->expinfo != NULL) && (fileloc_isDefined (s->expinfo->loc)));
678 static /*@observer@*/ /*@unused@*/ stateInfo sRef_getInfo (sRef s, cstring key)
682 if (!sRef_isReasonable (s)) {
683 return stateInfo_undefined;
686 sv = valueTable_lookup (s->state, key);
688 if (stateValue_isDefined (sv))
690 return stateValue_getInfo (sv);
693 return stateInfo_undefined;
698 sRef_hasNullInfoLoc (sRef s)
700 return (sRef_isReasonable (s) && s->nullinfo != NULL
701 && (fileloc_isDefined (s->nullinfo->loc)));
705 sRef_hasAliasInfoRef (sRef s)
707 return (sRef_isReasonable (s) && (s->aliasinfo != NULL)
708 && (sRef_isReasonable (s->aliasinfo->ref)));
711 static /*@observer@*/ fileloc
712 sRef_getAliasInfoLoc (/*@exposed@*/ sRef s)
714 llassert (sRef_isReasonable (s) && s->aliasinfo != NULL
715 && (fileloc_isDefined (s->aliasinfo->loc)));
716 return (s->aliasinfo->loc);
719 static /*@observer@*/ fileloc
720 sRef_getStateInfoLoc (/*@exposed@*/ sRef s)
722 llassert (sRef_isReasonable (s) && s->definfo != NULL
723 && (fileloc_isDefined (s->definfo->loc)));
724 return (s->definfo->loc);
727 static /*@observer@*/ fileloc
728 sRef_getExpInfoLoc (/*@exposed@*/ sRef s)
730 llassert (sRef_isReasonable (s) && s->expinfo != NULL
731 && (fileloc_isDefined (s->expinfo->loc)));
732 return (s->expinfo->loc);
735 static /*@observer@*/ fileloc
736 sRef_getNullInfoLoc (/*@exposed@*/ sRef s)
738 llassert (sRef_isReasonable (s) && s->nullinfo != NULL
739 && (fileloc_isDefined (s->nullinfo->loc)));
740 return (s->nullinfo->loc);
744 sRef_getAliasInfoRef (/*@temp@*/ sRef s)
746 llassert (sRef_isReasonable (s) && s->aliasinfo != NULL);
747 return (s->aliasinfo->ref);
750 bool sRef_inGlobalScope ()
756 ** This function should be called before new sRefs are created
757 ** somewhere where they will have a lifetime greater than the
758 ** current function scope.
761 void sRef_setGlobalScope ()
763 llassert (inFunction);
764 DPRINTF (("leave function"));
768 void sRef_clearGlobalScope ()
770 llassert (!inFunction);
771 DPRINTF (("enter function"));
775 static bool oldInFunction = FALSE;
776 static int nestedScope = 0;
778 void sRef_setGlobalScopeSafe ()
780 if (nestedScope == 0)
782 oldInFunction = inFunction;
786 DPRINTF (("leave function safe"));
790 void sRef_clearGlobalScopeSafe ()
793 llassert (nestedScope >= 0);
795 if (nestedScope == 0)
797 inFunction = oldInFunction;
800 DPRINTF (("clear function: %s", bool_unparse (inFunction)));
803 void sRef_enterFunctionScope ()
805 /* evans 2001-09-09 - cleanup if we are in a macro! */
806 if (context_inMacro ())
809 sRef_exitFunctionScope ();
813 llassert (!inFunction);
814 llassert (sRefTable_isEmpty (allRefs));
816 DPRINTF (("enter function"));
819 void sRef_exitFunctionScope ()
823 DPRINTF (("Exit function scope."));
824 sRefTable_clear (allRefs);
825 DPRINTF (("Exit function scope done."));
830 llbuglit ("sRef_exitFunctionScope: not in function");
834 void sRef_destroyMod () /*@globals killed allRefs;@*/
837 llmsg (message ("Live: %d / %d ", nsrefs, totnsrefs));
840 sRefTable_free (allRefs);
844 static /*@notnull@*/ /*@exposed@*/ sRef
845 sRef_fixConj (/*@notnull@*/ sRef s)
850 s = sRef_getConjA (s);
851 } while (sRef_isConj (s));
853 llassert (sRef_isReasonable (s));
854 return s; /* don't need to ref */
863 sRef_isExternallyVisibleAux (sRef s)
866 sRef base = sRef_getRootBase (s);
868 if (sRef_isReasonable (base))
870 res = sRef_isParam (base) || sRef_isFileOrGlobalScope (base) || sRef_isExternal (base);
877 sRef_isExternallyVisible (sRef s)
879 return (sRef_aliasCheckSimplePred (sRef_isExternallyVisibleAux, s));
883 sRef_getBaseUentry (sRef s)
885 sRef base = sRef_getRootBase (s);
886 uentry res = uentry_undefined;
888 if (sRef_isReasonable (base))
893 res = usymtab_getRefQuiet (paramsScope, usymId_fromInt (base->info->paramno));
897 res = usymtab_getRefQuiet (base->info->cvar->lexlevel,
898 base->info->cvar->index);
910 ** lookup the current uentry corresponding to s, and return the corresponding sRef.
911 ** yuk yuk yuk yuk yuk yuk yuk yuk
915 sRef_updateSref (sRef s)
921 if (!sRef_isReasonable (s)) return sRef_undefined;
930 case SK_UNCONSTRAINED:
937 sRef r = sRef_updateSref (s->info->ref);
939 if (r != s->info->ref)
941 return sRef_makeExternal (r);
951 uentry ue = sRef_getUentry (s);
953 /* must be raw name! (need the marker) */
954 /* Must be in the correct scope! */
956 ue = usymtab_lookupSafeScope (uentry_rawName (ue), sRef_lexLevel (s));
958 if (uentry_isUndefined (ue))
964 DPRINTF (("Update sref: %s", uentry_unparseFull (ue)));
965 return (uentry_getSref (ue));
969 /* special case if ind known */
970 inner = s->info->arrayfetch->arr;
971 ret = sRef_updateSref (inner);
979 res = sRef_makeArrayFetch (ret);
985 inner = s->info->field->rec;
986 ret = sRef_updateSref (inner);
994 res = (sRef_makeField (ret, s->info->field->field));
999 inner = s->info->ref;
1000 ret = sRef_updateSref (inner);
1007 res = sRef_makePointer (ret);
1013 inner = s->info->ref;
1014 ret = sRef_updateSref (inner);
1022 res = sRef_makeAddress (ret);
1029 sRef innera = s->info->conj->a;
1030 sRef innerb = s->info->conj->b;
1031 sRef reta = sRef_updateSref (innera);
1032 sRef retb = sRef_updateSref (innerb);
1034 if (innera == reta && innerb == retb)
1040 res = sRef_makeConj (reta, retb);
1051 sRef_getUentry (sRef s)
1053 llassert (sRef_isReasonable (s));
1058 return (usymtab_getRefQuiet (paramsScope, usymId_fromInt (s->info->paramno)));
1060 return (usymtab_getRefQuiet (s->info->cvar->lexlevel, s->info->cvar->index));
1063 if (sRef_isCvar (s->info->conj->a) || sRef_isParam (s->info->conj->a)
1064 || sRef_isConj (s->info->conj->a))
1066 return sRef_getUentry (s->info->conj->a);
1070 return sRef_getUentry (s->info->conj->b);
1073 case SK_FIELD: /* evans 2002-07-17: added case for SK_FIELD */
1076 return uentry_undefined;
1082 sRef_getParam (sRef s)
1084 llassert (sRef_isReasonable (s));
1085 llassert (s->kind == SK_PARAM);
1087 return s->info->paramno;
1091 sRef_isModified (sRef s)
1093 return (!sRef_isReasonable (s) || s->modified);
1096 void sRef_setModified (sRef s)
1098 if (sRef_isReasonable (s))
1103 if (sRef_isRefsField (s))
1105 sRef base = sRef_getBase (s);
1107 llassert (s->kind == SK_FIELD);
1109 if (sRef_isPointer (base))
1111 base = sRef_getBase (base);
1114 if (sRef_isRefCounted (base))
1116 base->aliaskind = AK_NEWREF;
1123 ** note: this side-effects sRefSet to set modified to TRUE
1124 ** for any sRef similar to s.
1128 sRef_canModifyVal (sRef s, sRefSet sl)
1130 if (context_getFlag (FLG_MUSTMOD))
1132 return (sRef_doModifyVal (s, sl));
1136 return (sRef_checkModifyVal (s, sl));
1141 sRef_canModify (sRef s, sRefSet sl)
1143 if (context_getFlag (FLG_MUSTMOD))
1145 return (sRef_doModify (s, sl));
1149 return (sRef_checkModify (s, sl));
1158 bool sRef_checkModifyVal (sRef s, sRefSet sl)
1160 DPRINTF (("Check modify val: %s", sRef_unparse (s)));
1162 if (sRef_isInvalid (s))
1169 case SK_UNCONSTRAINED:
1173 DPRINTF (("Modify var: %s", sRef_unparse (s)));
1175 if (sRef_isFileOrGlobalScope (s))
1177 if (context_checkGlobMod (s))
1179 return (sRefSet_member (sl, s));
1189 return (sRefSet_member (sl, s)
1190 || alkind_isOnly (sRef_getOrigAliasKind (s)));
1192 /* special case if ind known */
1193 return (sRefSet_member (sl, s) ||
1194 sRef_checkModifyVal (s->info->arrayfetch->arr, sl));
1196 return (sRefSet_member (sl, s) || sRef_checkModifyVal (s->info->field->rec, sl));
1198 return (sRefSet_member (sl, s) || sRef_checkModifyVal (s->info->ref, sl));
1200 return (sRefSet_member (sl, s) || sRef_checkModifyVal (s->info->ref, sl));
1202 return ((sRef_checkModifyVal (s->info->conj->a, sl)) &&
1203 (sRef_checkModifyVal (s->info->conj->b, sl)));
1214 switch (s->info->spec)
1216 case SR_NOTHING: return TRUE;
1218 if (context_getFlag (FLG_INTERNALGLOBS))
1220 return (sRefSet_member (sl, s));
1226 case SR_SPECSTATE: return TRUE;
1227 case SR_SYSTEM: return (sRefSet_member (sl, s));
1228 case SR_GLOBALMARKER: BADBRANCH;
1231 case SK_RESULT: BADBRANCH;
1237 ** this should probably be elsewhere...
1239 ** returns TRUE iff sl indicates that s can be modified
1242 static bool sRef_checkModify (sRef s, sRefSet sl)
1244 llassert (sRef_isReasonable (s));
1248 case SK_UNCONSTRAINED:
1252 if (sRef_isFileOrGlobalScope (s))
1254 if (context_checkGlobMod (s))
1256 return (sRefSet_member (sl, s));
1268 return (sRefSet_member (sl, s) ||
1269 sRef_checkModifyVal (s->info->arrayfetch->arr, sl));
1272 sRef sr = s->info->field->rec;
1274 if (sr->kind == SK_PARAM)
1275 return TRUE; /* structs are copied on call */
1277 return (sRefSet_member (sl, s) || sRef_checkModifyVal (s->info->field->rec, sl));
1283 sm = sRefSet_member (sl, s);
1288 return (sRef_checkModifyVal (s->info->ref, sl));
1291 return (sRefSet_member (sl, s) || sRef_checkModifyVal (s->info->ref, sl));
1293 return ((sRef_checkModify (s->info->conj->a, sl)) &&
1294 (sRef_checkModify (s->info->conj->b, sl)));
1304 switch (s->info->spec)
1306 case SR_NOTHING: return TRUE;
1308 if (context_getFlag (FLG_INTERNALGLOBS))
1310 return (sRefSet_member (sl, s));
1316 case SR_SPECSTATE: return TRUE;
1317 case SR_SYSTEM: return (sRefSet_member (sl, s));
1318 case SR_GLOBALMARKER: BADBRANCH;
1321 case SK_RESULT: BADBRANCH;
1326 cstring sRef_stateVerb (sRef s)
1328 if (sRef_isDead (s))
1330 return cstring_makeLiteralTemp ("released");
1332 else if (sRef_isKept (s))
1334 return cstring_makeLiteralTemp ("kept");
1336 else if (sRef_isDependent (s))
1338 return cstring_makeLiteralTemp ("dependent");
1346 cstring sRef_stateAltVerb (sRef s)
1348 if (sRef_isDead (s))
1350 return cstring_makeLiteralTemp ("live");
1352 else if (sRef_isKept (s))
1354 return cstring_makeLiteralTemp ("not kept");
1356 else if (sRef_isDependent (s))
1358 return cstring_makeLiteralTemp ("independent");
1367 bool sRef_doModifyVal (sRef s, sRefSet sl)
1369 llassert (sRef_isReasonable (s));
1374 case SK_UNCONSTRAINED:
1378 if (sRef_isFileOrGlobalScope (s))
1381 if (context_checkGlobMod (s))
1383 return (sRefSet_modifyMember (sl, s));
1387 (void) sRefSet_modifyMember (sl, s);
1397 return (sRefSet_modifyMember (sl, s)
1398 || alkind_isOnly (sRef_getOrigAliasKind (s)));
1400 /* special case if ind known */
1401 /* unconditional OR, need side effect */
1402 return (OR (sRefSet_modifyMember (sl, s),
1403 sRef_doModifyVal (s->info->arrayfetch->arr, sl)));
1405 return (OR (sRefSet_modifyMember (sl, s),
1406 sRef_doModifyVal (s->info->field->rec, sl)));
1408 return (OR (sRefSet_modifyMember (sl, s),
1409 sRef_doModifyVal (s->info->ref, sl)));
1411 return (OR (sRefSet_modifyMember (sl, s),
1412 sRef_doModifyVal (s->info->ref, sl)));
1414 return (AND (sRef_doModifyVal (s->info->conj->a, sl) ,
1415 sRef_doModifyVal (s->info->conj->b, sl)));
1425 switch (s->info->spec)
1427 case SR_NOTHING: return TRUE;
1429 if (context_getFlag (FLG_INTERNALGLOBS))
1431 return (sRefSet_modifyMember (sl, s));
1435 (void) sRefSet_modifyMember (sl, s);
1438 case SR_SPECSTATE: return TRUE;
1439 case SR_SYSTEM: return (sRefSet_modifyMember (sl, s));
1440 case SR_GLOBALMARKER: BADBRANCH;
1444 case SK_RESULT: BADBRANCH;
1450 ** this should probably be elsewhere...
1452 ** returns TRUE iff sl indicates that s can be modified
1456 bool sRef_doModify (sRef s, sRefSet sl)
1458 llassert (sRef_isReasonable (s));
1462 case SK_UNCONSTRAINED:
1466 if (sRef_isFileOrGlobalScope (s))
1468 if (context_checkGlobMod (s))
1470 return (sRefSet_modifyMember (sl, s));
1474 (void) sRefSet_modifyMember (sl, s);
1486 return (OR (sRefSet_modifyMember (sl, s),
1487 sRef_doModifyVal (s->info->arrayfetch->arr, sl)));
1490 sRef sr = s->info->field->rec;
1492 if (sr->kind == SK_PARAM)
1494 return TRUE; /* structs are shallow-copied on call */
1497 return (OR (sRefSet_modifyMember (sl, s),
1498 sRef_doModifyVal (s->info->field->rec, sl)));
1502 return (OR (sRefSet_modifyMember (sl, s),
1503 sRef_doModifyVal (s->info->ref, sl)));
1506 return (OR (sRefSet_modifyMember (sl, s),
1507 sRef_doModifyVal (s->info->ref, sl)));
1509 return (AND (sRef_doModify (s->info->conj->a, sl),
1510 (sRef_doModify (s->info->conj->b, sl))));
1521 switch (s->info->spec)
1523 case SR_NOTHING: return TRUE;
1524 case SR_INTERNAL: return TRUE;
1525 case SR_SPECSTATE: return TRUE;
1526 case SR_SYSTEM: return (sRefSet_modifyMember (sl, s));
1527 case SR_GLOBALMARKER: BADBRANCH;
1530 case SK_RESULT: BADBRANCH;
1535 static /*@exposed@*/ sRef
1536 sRef_leastCommon (/*@exposed@*/ sRef s1, sRef s2)
1538 llassert (sRef_similar (s1, s2));
1540 if (!sRef_isReasonable (s1)) return s1;
1541 if (!sRef_isReasonable (s2)) return s1;
1543 sRef_combineDefState (s1, s2);
1544 sRef_combineNullState (s1, s2);
1545 sRef_combineExKinds (s1, s2);
1547 if (s1->aliaskind != s2->aliaskind)
1549 if (s1->aliaskind == AK_UNKNOWN)
1551 s1->aliaskind = s2->aliaskind;
1553 else if (s2->aliaskind == AK_UNKNOWN)
1559 s1->aliaskind = AK_ERROR;
1566 int sRef_compare (sRef s1, sRef s2)
1568 if (s1 == s2) return 0;
1570 if (sRef_isInvalid (s1)) return -1;
1571 if (sRef_isInvalid (s2)) return 1;
1573 INTCOMPARERETURN (s1->kind, s2->kind);
1574 INTCOMPARERETURN (s1->defstate, s2->defstate);
1575 INTCOMPARERETURN (s1->aliaskind, s2->aliaskind);
1577 DPRINTF (("Compare null state: %s / %s",
1578 sRef_unparseFull (s1),
1579 sRef_unparseFull (s2)));
1581 COMPARERETURN (nstate_compare (sRef_getNullState (s1),
1582 sRef_getNullState (s2)));
1587 return (int_compare (s1->info->paramno, s2->info->paramno));
1590 COMPARERETURN (sRef_compare (s1->info->arrayfetch->arr,
1591 s2->info->arrayfetch->arr));
1593 if (s1->info->arrayfetch->indknown && s2->info->arrayfetch->indknown)
1595 return (int_compare (s1->info->arrayfetch->ind,
1596 s2->info->arrayfetch->ind));
1598 if (!s1->info->arrayfetch->indknown && !s2->info->arrayfetch->indknown)
1605 COMPARERETURN (sRef_compare (s1->info->field->rec, s2->info->field->rec));
1607 if (cstring_equal (s1->info->field->field, s2->info->field->field))
1614 return (sRef_compare (s1->info->ref, s2->info->ref));
1616 COMPARERETURN (sRef_compare (s1->info->conj->a, s2->info->conj->a));
1617 return (sRef_compare (s1->info->conj->b, s2->info->conj->b));
1618 case SK_UNCONSTRAINED:
1619 return (cstring_compare (s1->info->fname, s2->info->fname));
1631 return (generic_compare (s1->info->spec, s2->info->spec));
1636 static bool cref_equal (cref c1, cref c2)
1638 return ((c1->lexlevel == c2->lexlevel) &&
1639 (usymId_equal (c1->index, c2->index)));
1643 ** returns true if s1 could be the same storage as s2.
1644 ** i.e., a[?] ~ a[3]. Note its not symmetric ... s1
1645 ** should be more specific.
1649 ** like similar, but matches objects <-> non-objects
1653 sRef_uniqueReference (sRef s)
1655 return (sRef_isFresh (s) || sRef_isUnique (s)
1656 || sRef_isOnly (s) || sRef_isStack (s)
1657 || sRef_isAddress (s));
1661 sRef_similarRelaxedAux (sRef s1, sRef s2)
1665 if (sRef_isUnknownArrayFetch (s1))
1675 if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
1677 if (sRef_isConj (s2))
1678 return (sRef_similarRelaxedAux (s1, sRef_getConjA (s2)) ||
1679 sRef_similarRelaxedAux (s1, sRef_getConjB (s2)));
1684 return ((s2->kind == SK_CVAR)
1685 && (cref_equal (s1->info->cvar, s2->info->cvar)));
1687 return ((s2->kind == SK_PARAM)
1688 && (s1->info->paramno == s2->info->paramno));
1690 if (s2->kind == SK_ARRAYFETCH)
1692 if (sRef_similarRelaxedAux (s1->info->arrayfetch->arr,
1693 s2->info->arrayfetch->arr))
1695 if (s1->info->arrayfetch->indknown)
1697 if (s2->info->arrayfetch->indknown)
1699 return (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind);
1714 return ((s2->kind == SK_FIELD
1715 && (sRef_similarRelaxedAux (s1->info->field->rec,
1716 s2->info->field->rec)
1717 && cstring_equal (s1->info->field->field,
1718 s2->info->field->field))));
1720 return ((s2->kind == SK_PTR)
1721 && sRef_similarRelaxedAux (s1->info->ref, s2->info->ref));
1723 return ((s2->kind == SK_ADR)
1724 && sRef_similarRelaxedAux (s1->info->ref, s2->info->ref));
1726 return ((sRef_similarRelaxedAux (s1->info->conj->a, s2) ||
1727 (sRef_similarRelaxedAux (s1->info->conj->b, s2))));
1729 return (s1->info->spec == s2->info->spec);
1730 case SK_UNCONSTRAINED:
1731 return (cstring_equal (s1->info->fname, s2->info->fname));
1746 sRef_similarRelaxed (sRef s1, sRef s2)
1752 if (sRef_isThroughArrayFetch (s1))
1762 if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
1764 us1 = sRef_uniqueReference (s1);
1765 us2 = sRef_uniqueReference (s2);
1767 if ((s1->kind == SK_EXTERNAL && (s2->kind != SK_EXTERNAL && !us2))
1768 || (s2->kind == SK_EXTERNAL && (s1->kind != SK_EXTERNAL && !us1)))
1771 ** Previously, also:
1772 ** || (sRef_isExposed (s1) && !us2) || (sRef_isExposed (s2) && !us1)) ????
1774 ** No clue why this was there?!
1778 if (sRef_isExposed (s1) && sRef_isCvar (s1))
1780 uentry ue1 = sRef_getUentry (s1);
1782 if (uentry_isRefParam (ue1))
1784 return sRef_similarRelaxedAux (s1, s2);
1788 if (sRef_isExposed (s2) && sRef_isCvar (s2))
1790 uentry ue2 = sRef_getUentry (s2);
1792 if (uentry_isRefParam (ue2))
1794 return sRef_similarRelaxedAux (s1, s2);
1798 return (ctype_match (s1->type, s2->type));
1802 return sRef_similarRelaxedAux (s1, s2);
1807 sRef_similar (sRef s1, sRef s2)
1809 if (s1 == s2) return TRUE;
1810 if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
1812 if (sRef_isConj (s2))
1814 return (sRef_similar (s1, sRef_getConjA (s2)) ||
1815 sRef_similar (s1, sRef_getConjB (s2)));
1818 if (sRef_isDerived (s2))
1820 return (sRef_includedBy (s1, s2->info->ref));
1826 return ((s2->kind == SK_CVAR)
1827 && (cref_equal (s1->info->cvar, s2->info->cvar)));
1829 return ((s2->kind == SK_PARAM)
1830 && (s1->info->paramno == s2->info->paramno));
1832 if (s2->kind == SK_ARRAYFETCH)
1834 if (sRef_similar (s1->info->arrayfetch->arr,
1835 s2->info->arrayfetch->arr))
1837 if (s1->info->arrayfetch->indknown)
1839 if (s2->info->arrayfetch->indknown)
1841 return (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind);
1856 if (s2->kind == SK_PTR)
1858 if (sRef_similar (s1->info->arrayfetch->arr,
1868 return ((s2->kind == SK_FIELD
1869 && (sRef_similar (s1->info->field->rec,
1870 s2->info->field->rec)
1871 && cstring_equal (s1->info->field->field,
1872 s2->info->field->field))));
1874 if (s2->kind == SK_PTR)
1876 return sRef_similar (s1->info->ref, s2->info->ref);
1880 if (s2->kind == SK_ARRAYFETCH)
1882 if (sRef_similar (s2->info->arrayfetch->arr,
1892 return ((s2->kind == SK_ADR)
1893 && sRef_similar (s1->info->ref, s2->info->ref));
1895 return ((sRef_similar (s1->info->conj->a, s2) ||
1896 (sRef_similar (s1->info->conj->b, s2))));
1898 return (sRef_includedBy (s2, s1->info->ref));
1899 case SK_UNCONSTRAINED:
1900 return (s2->kind == SK_UNCONSTRAINED
1901 && cstring_equal (s1->info->fname, s2->info->fname));
1911 return (s2->kind == SK_SPECIAL
1912 && (s1->info->spec == s2->info->spec));
1915 /*@notreached@*/ DPRINTF (("Fell through for: %s / %s", sRef_unparse (s1), sRef_unparse (s2)));
1920 ** return TRUE iff small can be derived from big.
1922 ** (e.g. x, x.a is includedBy x;
1923 ** x.a is included By x.a;
1927 sRef_includedBy (sRef small, sRef big)
1929 if (small == big) return TRUE;
1930 if (sRef_isInvalid (small) || sRef_isInvalid (big)) return FALSE;
1932 if (sRef_isConj (big))
1933 return (sRef_similar (small, sRef_getConjA (big)) ||
1934 sRef_similar (small, sRef_getConjB (big)));
1936 switch (small->kind)
1940 return (sRef_same (small, big));
1942 if (big->kind == SK_ARRAYFETCH)
1944 if (sRef_same (small->info->arrayfetch->arr, big->info->arrayfetch->arr))
1946 if (small->info->arrayfetch->indknown)
1948 if (big->info->arrayfetch->indknown)
1950 return (small->info->arrayfetch->ind == big->info->arrayfetch->ind);
1963 return (sRef_includedBy (small->info->arrayfetch->arr, big));
1965 if (big->kind == SK_FIELD)
1968 (sRef_same (small->info->field->rec, big->info->field->rec) &&
1969 cstring_equal (small->info->field->field, big->info->field->field));
1973 return (sRef_includedBy (small->info->field->rec, big));
1977 if (big->kind == SK_PTR)
1979 return sRef_same (small->info->ref, big->info->ref);
1983 return (sRef_includedBy (small->info->ref, big));
1987 return ((big->kind == SK_ADR) && sRef_similar (small->info->ref, big->info->ref));
1989 return ((sRef_includedBy (small->info->conj->a, big) ||
1990 (sRef_includedBy (small->info->conj->b, big))));
1992 return (sRef_includedBy (small->info->ref, big));
1993 case SK_UNCONSTRAINED:
2003 switch (small->info->spec)
2005 case SR_NOTHING: return TRUE;
2007 case SR_INTERNAL: return (sRef_isSpecInternalState (big) ||
2008 sRef_isFileStatic (big));
2009 case SR_SYSTEM: return (sRef_isSystemState (big));
2010 case SR_GLOBALMARKER: BADBRANCH;
2017 ** Same is similar to similar, but not quite the same.
2018 ** same and realSame aren't the same, but they are really similar.
2019 ** similarly, same is the same as same. but realSame is
2020 ** not really the same as same, or similar to similar.
2022 ** Similarly to similar, same checks if two sRefs are the same.
2023 ** The similarities end, however, when same compares arrays
2024 ** with unknown indexes. Similar returns false; same returns true.
2026 ** Similarly to similar and same, realSame is the same as same,
2027 ** except they do not behave the same when face with unknown
2028 ** sRefs. Same thinks they are not the same, but realSame thinks
2034 sRef_realSame (sRef s1, sRef s2)
2036 if (s1 == s2) return TRUE;
2038 if (sRef_isUnreasonable (s1)
2039 || sRef_isUnreasonable (s2))
2047 return ((s2->kind == SK_CVAR) && (cref_equal (s1->info->cvar, s2->info->cvar)));
2049 return ((s2->kind == SK_PARAM) && (s1->info->paramno == s2->info->paramno));
2051 if (s2->kind == SK_ARRAYFETCH)
2053 if (sRef_realSame (s1->info->arrayfetch->arr, s2->info->arrayfetch->arr))
2055 if (s1->info->arrayfetch->indknown && s2->info->arrayfetch->indknown)
2057 return (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind);
2059 if (!s1->info->arrayfetch->indknown && !s2->info->arrayfetch->indknown)
2068 return ((s2->kind == SK_FIELD &&
2069 (sRef_realSame (s1->info->field->rec, s2->info->field->rec) &&
2070 cstring_equal (s1->info->field->field, s2->info->field->field))));
2072 return ((s2->kind == SK_PTR) && sRef_realSame (s1->info->ref, s2->info->ref));
2074 return ((s2->kind == SK_ADR) && sRef_realSame (s1->info->ref, s2->info->ref));
2076 return ((sRef_realSame (s1->info->conj->a, s2) ||
2077 (sRef_realSame (s1->info->conj->b, s2))));
2079 return ((s2->kind == SK_OBJECT)
2080 && ctype_match (s1->info->object, s2->info->object));
2082 return ((s2->kind == SK_EXTERNAL)
2083 && sRef_realSame (s1->info->ref, s2->info->ref));
2085 return ((s2->kind == SK_SPECIAL) && s1->info->spec == s2->info->spec);
2087 return ((s2->kind == SK_DERIVED) && sRef_realSame (s1->info->ref, s2->info->ref));
2088 case SK_UNCONSTRAINED:
2089 return ((s2->kind == SK_UNCONSTRAINED)
2090 && (cstring_equal (s1->info->fname, s2->info->fname)));
2096 return TRUE; /* changed this! was false */
2102 sRef_sameObject (sRef s1, sRef s2)
2108 ** same is similar to similar, but not quite the same.
2110 ** Similarly to similar, same checks is two sRefs are the same.
2111 ** The similarities end, however, when same compares arrays
2112 ** with unknown indexes. Similar returns false; same returns true.
2116 sRef_same (sRef s1, sRef s2)
2118 if (s1 == s2) return TRUE;
2119 if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
2124 return ((s2->kind == SK_CVAR) && (cref_equal (s1->info->cvar, s2->info->cvar)));
2126 return ((s2->kind == SK_PARAM) && (s1->info->paramno == s2->info->paramno));
2128 if (s2->kind == SK_ARRAYFETCH)
2130 llassert (s1->info->field->rec != s1);
2131 if (sRef_same (s1->info->arrayfetch->arr, s2->info->arrayfetch->arr))
2133 if (s1->info->arrayfetch->indknown && s2->info->arrayfetch->indknown)
2135 return (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind);
2143 llassert (s1->info->field->rec != s1);
2144 return ((s2->kind == SK_FIELD &&
2145 (sRef_same (s1->info->field->rec, s2->info->field->rec) &&
2146 cstring_equal (s1->info->field->field, s2->info->field->field))));
2150 llassert (s1->info->ref != s1);
2151 return ((s2->kind == SK_PTR) && sRef_same (s1->info->ref, s2->info->ref));
2155 llassert (s1->info->ref != s1);
2156 return ((s2->kind == SK_ADR) && sRef_same (s1->info->ref, s2->info->ref));
2159 llassert (s1->info->conj->a != s1);
2160 llassert (s1->info->conj->b != s1);
2161 return ((sRef_same (s1->info->conj->a, s2)) && /* or or and? */
2162 (sRef_same (s1->info->conj->b, s2)));
2164 return ((s2->kind == SK_SPECIAL) && s1->info->spec == s2->info->spec);
2166 llassert (s1->info->ref != s1);
2167 return ((s2->kind == SK_DERIVED) && sRef_same (s1->info->ref, s2->info->ref));
2169 case SK_UNCONSTRAINED:
2182 ** sort of similar, for use in def/use
2186 sRef_closeEnough (sRef s1, sRef s2)
2188 if (s1 == s2) return TRUE;
2189 if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
2194 return (((s2->kind == SK_CVAR) &&
2195 (cref_equal (s1->info->cvar, s2->info->cvar))) ||
2196 (s2->kind == SK_UNCONSTRAINED && s1->info->cvar->lexlevel == 0));
2197 case SK_UNCONSTRAINED:
2198 return (s2->kind == SK_UNCONSTRAINED
2199 || ((s2->kind == SK_CVAR) && (s2->info->cvar->lexlevel == 0)));
2201 return ((s2->kind == SK_PARAM)
2202 && (s1->info->paramno == s2->info->paramno));
2204 if (s2->kind == SK_ARRAYFETCH)
2206 if (sRef_closeEnough (s1->info->arrayfetch->arr, s2->info->arrayfetch->arr))
2208 if (s1->info->arrayfetch->indknown && s2->info->arrayfetch->indknown)
2210 return (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind);
2217 return ((s2->kind == SK_FIELD &&
2218 (sRef_closeEnough (s1->info->field->rec, s2->info->field->rec) &&
2219 cstring_equal (s1->info->field->field, s2->info->field->field))));
2221 return ((s2->kind == SK_PTR) && sRef_closeEnough (s1->info->ref, s2->info->ref));
2223 return ((s2->kind == SK_ADR) && sRef_closeEnough (s1->info->ref, s2->info->ref));
2225 return ((s2->kind == SK_DERIVED) && sRef_closeEnough (s1->info->ref, s2->info->ref));
2227 return ((sRef_closeEnough (s1->info->conj->a, s2)) ||
2228 (sRef_closeEnough (s1->info->conj->b, s2)));
2230 return ((s2->kind == SK_SPECIAL) && s1->info->spec == s2->info->spec);
2246 s is an sRef of a formal paramenter in a function call constraint
2247 we trys to return a constraint expression derived from the actual parementer of a function call.
2250 /*@only@*/ constraintExpr sRef_fixConstraintParam (/*@observer@*/ sRef s, /*@observer@*/ /*@temp@*/ exprNodeList args)
2254 if (sRef_isInvalid (s))
2255 llfatalbug((message("Invalid sRef")));
2261 ce = constraintExpr_makeTermsRef (s);
2268 temp = (sRef_makeField (sRef_fixBaseParam (s->info->field->rec, args),
2269 s->info->field->field));
2270 ce = constraintExpr_makeTermsRef (temp);
2276 temp = (sRef_makePointer (sRef_fixBaseParam (s->info->ref, args)));
2277 ce = constraintExpr_makeTermsRef (temp);
2284 temp = sRef_saveCopy(s);
2285 temp = sRef_fixBaseParam (temp, args);
2286 ce = constraintExpr_makeTermsRef (temp);
2294 temp = sRef_saveCopy(s);
2295 ce = constraintExpr_makeTermsRef (temp);
2302 llassert (exprNodeList_size (args) > s->info->paramno);
2303 e = exprNodeList_nth (args, s->info->paramno);
2305 llassert (!(exprNode_isError (e)));
2306 ce = constraintExpr_makeExprNode (e);
2313 llcontbug (message ("Trying to do fixConstraintParam on nonparam, nonglobal: %q for function with arguments %q",
2314 sRef_unparse (s), exprNodeList_unparse(args)));
2315 temp = sRef_saveCopy(s);
2316 ce = constraintExpr_makeTermsRef (temp);
2325 sRef_fixBaseParam (/*@returned@*/ sRef s, exprNodeList args)
2327 if (sRef_isInvalid (s)) return (sRef_undefined);
2331 case SK_UNCONSTRAINED:
2336 if (exprNodeList_size (args) > s->info->paramno)
2338 exprNode e = exprNodeList_nth (args, s->info->paramno);
2340 if (exprNode_isError (e))
2342 return sRef_makeUnknown ();
2345 return (exprNode_getSref (e));
2349 return sRef_makeUnknown ();
2354 if (s->info->arrayfetch->indknown)
2356 return (sRef_makeArrayFetchKnown
2357 (sRef_fixBaseParam (s->info->arrayfetch->arr, args),
2358 s->info->arrayfetch->ind));
2362 return (sRef_makeArrayFetch
2363 (sRef_fixBaseParam (s->info->arrayfetch->arr, args)));
2368 DPRINTF (("Fix field: %s", sRef_unparseFull (s)));
2369 res = sRef_makeField (sRef_fixBaseParam (s->info->field->rec, args),
2370 s->info->field->field);
2371 DPRINTF (("Returns: %s", sRef_unparseFull (res)));
2375 return (sRef_makePointer (sRef_fixBaseParam (s->info->ref, args)));
2378 return (sRef_makeAddress (sRef_fixBaseParam (s->info->ref, args)));
2381 return (sRef_makeConj (sRef_fixBaseParam (s->info->conj->a, args),
2382 sRef_fixBaseParam (s->info->conj->b, args)));
2398 sRef_undumpGlobal (char **c)
2408 usymId uid = usymId_fromInt (reader_getInt (c));
2413 reader_checkChar (c, '@');
2414 defstate = sstate_fromInt (reader_getInt (c));
2416 reader_checkChar (c, '@');
2417 nullstate = nstate_fromInt (reader_getInt (c));
2419 ret = sRef_makeGlobal (uid, ctype_unknown, stateInfo_currentLoc ());
2420 sRef_setNullStateN (ret, nullstate);
2421 ret->defstate = defstate;
2426 int i = reader_getInt (c);
2427 speckind sk = speckind_fromInt (i);
2431 case SR_NOTHING: return (sRef_makeNothing ());
2432 case SR_INTERNAL: return (sRef_makeInternalState ());
2433 case SR_SPECSTATE: return (sRef_makeSpecState ());
2434 case SR_SYSTEM: return (sRef_makeSystemState ());
2435 case SR_GLOBALMARKER: BADBRANCH;
2440 return sRef_undefined;
2442 return sRef_makeUnknown ();
2444 return sRef_makeUnknown ();
2446 llfatalerror (message ("sRef_undumpGlobal: bad line: %s",
2447 cstring_fromChars (*c)));
2452 static /*@exposed@*/ sRef sRef_undumpBody (char **c)
2461 return (sRef_makeGlobal (usymId_fromInt (reader_getInt (c)),
2462 ctype_unknown, stateInfo_currentLoc ()));
2464 return (sRef_makeParam (reader_getInt (c), ctype_unknown,
2465 stateInfo_makeLoc (g_currentloc, SA_DECLARED)));
2467 return (sRef_makeResult (ctype_undump (c)));
2470 if ((**c >= '0' && **c <= '9') || **c == '-')
2472 int i = reader_getInt (c);
2473 sRef arr = sRef_undump (c);
2474 sRef ret = sRef_buildArrayFetchKnown (arr, i);
2480 sRef arr = sRef_undump (c);
2481 sRef ret = sRef_buildArrayFetch (arr);
2488 cstring fname = cstring_undefined;
2493 fname = cstring_appendChar (fname, **c);
2498 ret = sRef_buildField (sRef_undump (c), fname);
2499 cstring_markOwned (fname);
2504 int i = reader_getInt (c);
2505 speckind sk = speckind_fromInt (i);
2509 case SR_NOTHING: return (sRef_makeNothing ());
2510 case SR_INTERNAL: return (sRef_makeInternalState ());
2511 case SR_SPECSTATE: return (sRef_makeSpecState ());
2512 case SR_SYSTEM: return (sRef_makeSystemState ());
2513 case SR_GLOBALMARKER: BADBRANCH;
2519 sRef ptr = sRef_undump (c);
2520 sRef ret = sRef_makePointer (ptr);
2526 sRef adr = sRef_undump (c);
2527 sRef ret = sRef_makeAddress (adr);
2533 return (sRef_makeObject (ctype_undump (c)));
2537 sRef s1 = sRef_undump (c);
2538 sRef s2 = ((*c)++, sRef_undump (c));
2539 sRef ret = sRef_makeConj (s1, s2);
2544 return sRef_undefined;
2546 return sRef_makeUnknown ();
2548 return sRef_makeUnknown ();
2550 llfatalerror (message ("sRef_undump: bad line: %s", cstring_fromChars (*c)));
2555 /*@exposed@*/ sRef sRef_undump (char **c)
2557 sRef res = sRef_undumpBody (c);
2559 if (reader_optCheckChar (c, '='))
2561 multiVal mv = multiVal_undump (c);
2562 sRef_setValue (res, mv);
2563 reader_checkChar (c, '=');
2569 static /*@only@*/ cstring sRef_dumpBody (sRef s)
2571 if (sRef_isInvalid (s))
2573 return (cstring_makeLiteral ("-"));
2580 return (message ("p%d", s->info->paramno));
2582 if (s->info->arrayfetch->indknown)
2584 return (message ("a%d%q", s->info->arrayfetch->ind,
2585 sRef_dump (s->info->arrayfetch->arr)));
2589 return (message ("a%q", sRef_dump (s->info->arrayfetch->arr)));
2592 return (message ("f%s.%q", s->info->field->field,
2593 sRef_dump (s->info->field->rec)));
2595 return (message ("t%q", sRef_dump (s->info->ref)));
2597 return (message ("d%q", sRef_dump (s->info->ref)));
2599 return (message ("o%q", ctype_dump (s->info->object)));
2601 return (message ("s%d", (int) s->info->spec));
2603 return (message ("c%q.%q",
2604 sRef_dump (s->info->conj->a),
2605 sRef_dump (s->info->conj->b)));
2607 if (sRef_isFileOrGlobalScope (s))
2609 return (message ("g%d",
2610 usymtab_convertId (s->info->cvar->index)));
2614 llcontbug (message ("Dumping local variable: %q",
2615 sRef_unparseDebug (s)));
2616 return (cstring_makeLiteral ("u"));
2619 return (cstring_makeLiteral ("u"));
2621 return (message ("r%q", ctype_dump (s->type)));
2627 case SK_UNCONSTRAINED:
2628 llcontbug (message ("sRef_dump: bad kind: %q",
2629 sRef_unparseFull (s)));
2630 return (cstring_makeLiteral ("x"));
2637 /*@only@*/ cstring sRef_dump (sRef s)
2639 cstring res = sRef_dumpBody (s);
2641 if (sRef_hasValue (s))
2643 res = message ("%q=%q=", res, multiVal_dump (sRef_getValue (s)));
2649 cstring sRef_dumpGlobal (sRef s)
2651 llassert (!sRef_hasValue (s));
2653 if (sRef_isInvalid (s))
2655 return (cstring_makeLiteral ("-"));
2662 if (sRef_isFileOrGlobalScope (s))
2664 return (message ("g%d@%d@%d",
2665 usymtab_convertId (s->info->cvar->index),
2667 (int) sRef_getNullState (s)));
2671 llcontbug (message ("Dumping local variable: %q",
2672 sRef_unparseDebug (s)));
2673 return (cstring_makeLiteral ("u"));
2676 return (cstring_makeLiteral ("u"));
2678 return (message ("s%d", (int) s->info->spec));
2680 llcontbug (message ("sRef_dumpGlobal: bad kind: %q",
2681 sRef_unparseFull (s)));
2682 return (cstring_makeLiteral ("x"));
2690 sRef_deriveType (sRef s, uentryList cl)
2692 if (sRef_isInvalid (s)) return ctype_unknown;
2697 return (uentry_getType (usymtab_getRefQuiet (s->info->cvar->lexlevel,
2698 s->info->cvar->index)));
2699 case SK_UNCONSTRAINED:
2700 return (ctype_unknown);
2702 if (s->info->paramno >= 0)
2704 return uentry_getType (uentryList_getN (cl, s->info->paramno));
2708 return ctype_unknown;
2712 ctype ca = sRef_deriveType (s->info->arrayfetch->arr, cl);
2714 if (ctype_isArray (ca))
2716 return (ctype_baseArrayPtr (ca));
2718 else if (ctype_isUnknown (ca))
2724 llcontbuglit ("sRef_deriveType: inconsistent array type");
2730 ctype ct = sRef_deriveType (s->info->field->rec, cl);
2732 if (ctype_isStructorUnion (ct))
2734 uentry ue = uentryList_lookupField (ctype_getFields (ct),
2735 s->info->field->field);
2737 if (uentry_isValid (ue))
2739 return (uentry_getType (ue));
2743 llcontbuglit ("sRef_deriveType: bad field");
2744 return ctype_unknown;
2747 else if (ctype_isUnknown (ct))
2753 llcontbuglit ("sRef_deriveType: inconsistent field type");
2759 ctype ct = sRef_deriveType (s->info->ref, cl);
2761 if (ctype_isUnknown (ct)) return ct;
2762 if (ctype_isPointer (ct)) return (ctype_baseArrayPtr (ct));
2765 llcontbuglit ("sRef_deriveType: inconsistent pointer type");
2771 ctype ct = sRef_deriveType (s->info->ref, cl);
2773 if (ctype_isUnknown (ct)) return ct;
2774 return ctype_makePointer (ct);
2778 return sRef_deriveType (s->info->ref, cl);
2782 return (s->info->object);
2786 return (ctype_makeConj (sRef_deriveType (s->info->conj->a, cl),
2787 sRef_deriveType (s->info->conj->b, cl)));
2799 return ctype_unknown;
2805 sRef_getType (sRef s)
2807 if (sRef_isInvalid (s)) return ctype_unknown;
2813 sRef_unparseOpt (sRef s)
2815 sRef rb = sRef_getRootBase (s);
2817 if (sRef_isMeaningful (rb) && !sRef_isConst (rb))
2819 cstring ret = sRef_unparse (s);
2821 llassertprint (!cstring_equalLit (ret, "?"), ("print: %s", sRef_unparseDebug (s)));
2823 if (!cstring_isEmpty (ret))
2825 return (cstring_appendChar (ret, ' '));
2833 return cstring_undefined;
2837 sRef_unparsePreOpt (sRef s)
2839 sRef rb = sRef_getRootBase (s);
2841 if (sRef_isMeaningful (rb) && !sRef_isConst (rb))
2843 cstring ret = sRef_unparse (s);
2845 llassertprint (!cstring_equalLit (ret, "?"), ("print: %s", sRef_unparseDebug (s)));
2846 return (cstring_prependCharO (' ', ret));
2849 return cstring_undefined;
2853 sRef_unparse (sRef s)
2855 if (sRef_isInvalid (s)) return (cstring_makeLiteral ("?"));
2857 if (context_inFunctionLike ())
2859 return (sRef_unparseWithArgs (s, context_getParams ()));
2863 DPRINTF (("Not in function like: %s", context_unparse ()));
2864 return (sRef_unparseNoArgs (s));
2868 static /*@only@*/ cstring
2869 sRef_unparseWithArgs (sRef s, uentryList args)
2871 if (sRef_isInvalid (s))
2873 return (cstring_makeLiteral ("?"));
2879 return (uentry_getName (usymtab_getRefQuiet (s->info->cvar->lexlevel,
2880 s->info->cvar->index)));
2881 case SK_UNCONSTRAINED:
2882 return (cstring_copy (s->info->fname));
2885 if (s->info->paramno < uentryList_size (args)
2886 && s->info->paramno >= 0)
2888 uentry ue = uentryList_getN (args, s->info->paramno);
2890 if (uentry_isValid (ue))
2891 return uentry_getName (ue);
2894 return (message ("parameter %d", s->info->paramno + 1));
2897 if (s->info->arrayfetch->indknown)
2899 return (message ("%q[%d]", sRef_unparseWithArgs (s->info->arrayfetch->arr, args),
2900 s->info->arrayfetch->ind));
2904 return (message ("%q[]", sRef_unparseWithArgs (s->info->arrayfetch->arr, args)));
2907 if (s->info->field->rec->kind == SK_PTR)
2909 sRef ptr = s->info->field->rec;
2911 return (message ("%q->%s", sRef_unparseWithArgs (ptr->info->ref, args),
2912 s->info->field->field));
2914 return (message ("%q.%s", sRef_unparseWithArgs (s->info->field->rec, args),
2915 s->info->field->field));
2919 sRef ref = sRef_fixConj (s->info->ref);
2920 skind sk = ref->kind;
2925 ret = message ("storage pointed to by %q",
2926 sRef_unparseWithArgs (ref, args));
2928 else if (skind_isSimple (sk) || sk == SK_PTR)
2930 ret = message ("*%q", sRef_unparseWithArgs (ref, args));
2934 ret = message ("*(%q)", sRef_unparseWithArgs (ref, args));
2940 return (message ("&%q", sRef_unparseWithArgs (s->info->ref, args)));
2942 return (cstring_copy (ctype_unparse (s->info->object)));
2944 return (sRef_unparseWithArgs (sRef_getConjA (s), args));
2946 if (cstring_isDefined (s->info->fname))
2948 return (message ("[result of %s]", s->info->fname));
2952 return (cstring_makeLiteral ("<new>"));
2955 return (cstring_makeLiteral ("?"));
2957 return (message ("<derived %q>", sRef_unparse (s->info->ref)));
2959 return (message ("<external %q>", sRef_unparse (s->info->ref)));
2961 return (message ("<type %s>", ctype_unparse (s->type)));
2963 return (message ("<const %s>", ctype_unparse (s->type)));
2965 switch (s->info->spec)
2967 case SR_NOTHING: return cstring_makeLiteral ("nothing");
2968 case SR_INTERNAL: return cstring_makeLiteral ("internal state");
2969 case SR_SPECSTATE: return cstring_makeLiteral ("spec state");
2970 case SR_SYSTEM: return cstring_makeLiteral ("file system state");
2971 case SR_GLOBALMARKER: return cstring_makeLiteral ("<global marker>");
2975 return cstring_makeLiteral ("result");
2978 llbug (message ("Bad sref, kind = %d", (int) s->kind));
2986 sRef_unparseDebug (sRef s)
2988 if (sRef_isInvalid (s))
2990 return (cstring_makeLiteral ("<undef>"));
2996 case SK_UNCONSTRAINED:
2997 return (message ("<unconstrained %s>", s->info->fname));
3002 ce = usymtab_getRefQuiet (s->info->cvar->lexlevel, s->info->cvar->index);
3004 if (uentry_isInvalid (ce))
3006 return (message ("<scope: %d.%d *invalid*>",
3007 s->info->cvar->lexlevel,
3008 s->info->cvar->index));
3012 return (message ("<scope: %d.%d *%q*>",
3013 s->info->cvar->lexlevel,
3014 s->info->cvar->index,
3015 uentry_getName (ce)));
3021 return (message ("<parameter %d>", s->info->paramno + 1));
3024 if (s->info->arrayfetch->indknown)
3026 return (message ("%q[%d]", sRef_unparseDebug (s->info->arrayfetch->arr),
3027 s->info->arrayfetch->ind));
3031 return (message ("%q[]", sRef_unparseDebug (s->info->arrayfetch->arr)));
3034 return (message ("%q.%s", sRef_unparseDebug (s->info->field->rec),
3035 s->info->field->field));
3037 if (sRef_isField (s->info->ref))
3039 sRef fld = s->info->ref;
3041 return (message ("%q->%s", sRef_unparseDebug (fld->info->field->rec),
3042 fld->info->field->field));
3046 return (message ("*(%q)", sRef_unparseDebug (s->info->ref)));
3049 return (message ("&%q", sRef_unparseDebug (s->info->ref)));
3051 return (message ("<object type %s>", ctype_unparse (s->info->object)));
3053 return (message ("%q | %q", sRef_unparseDebug (s->info->conj->a),
3054 sRef_unparseDebug (s->info->conj->b)));
3056 return message ("<new: %s>", s->info->fname);
3058 return (message ("<derived %q>", sRef_unparseDebug (s->info->ref)));
3060 return (message ("<external %q>", sRef_unparseDebug (s->info->ref)));
3062 return (message ("<type %s>", ctype_unparse (s->type)));
3064 if (sRef_hasValue (s))
3066 return (message ("<const %s=%q>", ctype_unparse (s->type), multiVal_unparse (sRef_getValue (s))));
3070 return (message ("<const %s>", ctype_unparse (s->type)));
3073 return (message ("<result %s>", ctype_unparse (s->type)));
3075 return (message ("<spec %s>",
3076 cstring_makeLiteralTemp
3077 (s->info->spec == SR_NOTHING ? "nothing"
3078 : s->info->spec == SR_INTERNAL ? "internalState"
3079 : s->info->spec == SR_SPECSTATE ? "spec state"
3080 : s->info->spec == SR_SYSTEM ? "fileSystem"
3083 return cstring_makeLiteral ("<unknown>");
3089 static /*@only@*/ cstring
3090 sRef_unparseNoArgs (sRef s)
3092 if (sRef_isInvalid (s)) return (cstring_makeLiteral ("?"));
3096 case SK_UNCONSTRAINED:
3097 return (cstring_copy (s->info->fname));
3100 uentry ce = usymtab_getRefQuiet (s->info->cvar->lexlevel,
3101 s->info->cvar->index);
3103 if (uentry_isInvalid (ce))
3105 llcontbug (message ("sRef_unparseNoArgs: bad cvar: %q",
3106 sRef_unparseDebug (s)));
3107 return (sRef_unparseDebug (s));
3111 return (uentry_getName (ce));
3115 if (s->info->arrayfetch->indknown)
3117 return (message ("%q[%d]", sRef_unparseNoArgs (s->info->arrayfetch->arr),
3118 s->info->arrayfetch->ind));
3122 return (message ("%q[]", sRef_unparseNoArgs (s->info->arrayfetch->arr)));
3125 return (message ("%q.%s", sRef_unparseNoArgs (s->info->field->rec),
3126 s->info->field->field));
3129 sRef ref = sRef_fixConj (s->info->ref);
3130 skind sk = ref->kind;
3133 if (skind_isSimple (sk) || sk == SK_PTR)
3135 ret = message ("*%q", sRef_unparseNoArgs (ref));
3139 ret = message ("*(%q)", sRef_unparseNoArgs (ref));
3145 return (message ("&%q", sRef_unparseNoArgs (s->info->ref)));
3147 return (cstring_copy (ctype_unparse (s->info->object)));
3149 return (sRef_unparseNoArgs (s->info->conj->a));
3151 return (message ("result of %s", s->info->fname));
3153 return (message ("<der %q>", sRef_unparseNoArgs (s->info->ref)));
3155 return message ("<ext %q>", sRef_unparseNoArgs (s->info->ref));
3157 return (cstring_makeLiteral
3158 (s->info->spec == SR_NOTHING ? "nothing"
3159 : s->info->spec == SR_INTERNAL ? "internal state"
3160 : s->info->spec == SR_SPECSTATE ? "spec state"
3161 : s->info->spec == SR_SYSTEM ? "file system state"
3164 return cstring_makeLiteral ("result");
3168 return cstring_makeLiteral ("?");
3170 /* llcontbug (message ("sRef_unparseNoArgs: bad case: %q", sRef_unparseDebug (s))); */
3171 return (sRef_unparseDebug (s));
3176 /*@dependent@*/ sRef sRef_makeUnconstrained (cstring fname)
3178 sRef s = sRef_new ();
3180 s->kind = SK_UNCONSTRAINED;
3181 s->info = (sinfo) dmalloc (sizeof (*s->info));
3182 s->info->fname = cstring_copy (fname); /* evans 2002-07-12: this was exposed, causing memory errors */
3187 cstring sRef_unconstrainedName (sRef s)
3189 llassert (sRef_isUnconstrained (s));
3191 return s->info->fname;
3194 bool sRef_isUnconstrained (sRef s)
3196 return (sRef_isReasonable(s) && s->kind == SK_UNCONSTRAINED);
3199 static /*@dependent@*/ /*@notnull@*/ sRef
3200 sRef_makeCvarAux (int level, usymId index, ctype ct, /*@only@*/ stateInfo stinfo)
3202 sRef s = sRef_newRef ();
3205 s->info = (sinfo) dmalloc (sizeof (*s->info));
3207 s->info->cvar = (cref) dmalloc (sizeof (*s->info->cvar));
3208 s->info->cvar->lexlevel = level;
3209 s->info->cvar->index = index;
3211 /* for now, all globals are defined; all locals, aren't */
3213 if (level <= fileScope)
3215 s->defstate = SS_UNKNOWN;
3219 ctype rct = ctype_realType (ct);
3221 if (level != paramsScope
3222 && (ctype_isStructorUnion (rct) || ctype_isRealArray (rct)))
3224 s->defstate = SS_ALLOCATED;
3225 s->oaliaskind = s->aliaskind = AK_STACK;
3229 s->defstate = SS_UNDEFINED;
3230 s->oaliaskind = s->aliaskind = AK_LOCAL;
3236 llassert (level >= globScope);
3237 llassert (usymId_isValid (index));
3239 DPRINTF (("Made cvar: [%p] %s", s, sRef_unparseDebug (s)));
3240 llassert (valueTable_isUndefined (s->state));
3241 s->state = context_createValueTable (s, stinfo);
3245 /*@dependent@*/ sRef sRef_makeCvar (int level, usymId index, ctype ct, /*@only@*/ stateInfo stinfo)
3247 return (sRef_makeCvarAux (level, index, ct, stinfo));
3250 int sRef_lexLevel (sRef s)
3252 if (sRef_isReasonable (s))
3256 conj = sRef_fixConj (s);
3257 s = sRef_getRootBase (conj);
3259 if (sRef_isReasonable (s) && s->kind == SK_CVAR)
3261 return (s->info->cvar->lexlevel);
3269 sRef_makeGlobal (usymId l, ctype ct, /*@only@*/ stateInfo stinfo)
3271 return (sRef_makeCvar (globScope, l, ct, stinfo));
3275 sRef_setParamNo (sRef s, int l)
3277 llassert (sRef_isReasonable (s) && s->kind == SK_PARAM);
3278 s->info->paramno = l;
3282 /*@dependent@*/ sRef
3283 sRef_makeParam (int l, ctype ct, stateInfo stinfo)
3285 sRef s = sRef_new ();
3290 s->info = (sinfo) dmalloc (sizeof (*s->info));
3291 s->info->paramno = l;
3293 s->defstate = SS_UNKNOWN;
3294 /* (probably defined, unless its an out parameter) */
3296 llassert (valueTable_isUndefined (s->state));
3297 s->state = context_createValueTable (s, stinfo);
3302 sRef_isIndexKnown (sRef arr)
3306 llassert (sRef_isReasonable (arr));
3307 arr = sRef_fixConj (arr);
3309 llassert (arr->kind == SK_ARRAYFETCH);
3310 res = arr->info->arrayfetch->indknown;
3315 sRef_getIndex (sRef arr)
3319 llassert (sRef_isReasonable (arr));
3320 arr = sRef_fixConj (arr);
3322 llassert (arr->kind == SK_ARRAYFETCH);
3324 if (!arr->info->arrayfetch->indknown)
3326 llcontbug (message ("sRef_getIndex: unknown: %q", sRef_unparse (arr)));
3331 result = arr->info->arrayfetch->ind;
3337 static bool sRef_isZerothArrayFetch (/*@notnull@*/ sRef s)
3339 return (s->kind == SK_ARRAYFETCH
3340 && s->info->arrayfetch->indknown
3341 && (s->info->arrayfetch->ind == 0));
3344 /*@exposed@*/ sRef sRef_makeAddress (/*@exposed@*/ sRef t)
3347 if (sRef_isInvalid (t)) return sRef_undefined;
3349 if (sRef_isPointer (t))
3351 return (t->info->ref);
3353 else if (sRef_isZerothArrayFetch (t))
3355 return (t->info->arrayfetch->arr);
3359 sRef s = sRef_newRef ();
3362 s->type = ctype_makePointer (t->type);
3363 s->info = (sinfo) dmalloc (sizeof (*s->info));
3366 if (t->defstate == SS_UNDEFINED)
3367 /* no! it is allocated even still: && !ctype_isPointer (t->type)) */
3369 s->defstate = SS_ALLOCATED;
3373 s->defstate = t->defstate;
3376 if (t->aliaskind == AK_LOCAL)
3378 if (sRef_isLocalVar (t))
3380 s->aliaskind = AK_STACK;
3384 llassert (valueTable_isUndefined (s->state));
3385 s->state = context_createValueTable (s,
3386 stateInfo_makeLoc (g_currentloc, SA_CREATED));
3391 cstring sRef_getField (sRef s)
3395 llassert (sRef_isReasonable (s));
3396 s = sRef_fixConj (s);
3398 llassertprint (sRef_isReasonable (s) && (s->kind == SK_FIELD),
3399 ("s = %s", sRef_unparseDebug (s)));
3401 res = s->info->field->field;
3405 sRef sRef_getBase (sRef s)
3409 if (sRef_isInvalid (s)) return (sRef_undefined);
3411 s = sRef_fixConj (s);
3422 res = s->info->field->rec;
3426 res = s->info->arrayfetch->arr;
3430 res = sRef_undefined; /* shouldn't need it */
3437 ** same as getBase, except returns invalid
3438 ** (and doesn't use adr's)
3442 sRef_getBaseSafe (sRef s)
3446 if (sRef_isInvalid (s)) { return sRef_undefined; }
3448 s = sRef_fixConj (s);
3456 res = s->info->field->rec; break;
3458 res = s->info->arrayfetch->arr;
3461 res = sRef_undefined; break;
3467 /*@constant int MAXBASEDEPTH;@*/
3468 # define MAXBASEDEPTH 25
3470 static /*@exposed@*/ sRef
3471 sRef_getRootBaseAux (sRef s, int depth)
3473 if (sRef_isInvalid (s)) return sRef_undefined;
3475 if (depth > MAXBASEDEPTH)
3478 ("Warning: reference base limit exceeded for %q. "
3479 "This either means there is a variable with at least "
3480 "%d indirections from this reference, or "
3481 "there is a bug in Splint.",
3486 return sRef_undefined;
3493 return (sRef_getRootBaseAux (s->info->ref, depth + 1));
3495 return (sRef_getRootBaseAux (s->info->field->rec, depth + 1));
3497 return (sRef_getRootBaseAux (s->info->arrayfetch->arr, depth + 1));
3499 return (sRef_getRootBaseAux (sRef_fixConj (s), depth + 1));
3505 sRef sRef_getRootBase (sRef s)
3507 return (sRef_getRootBaseAux (s, 0));
3510 static bool sRef_isDeep (sRef s)
3512 if (sRef_isInvalid (s)) return FALSE;
3522 return (sRef_isDeep (sRef_fixConj (s)));
3528 static int sRef_depth (sRef s)
3530 if (sRef_isInvalid (s)) return 0;
3538 return 1 + sRef_depth (s->info->ref);
3540 return 1 + sRef_depth (s->info->field->rec);
3542 return 1 + sRef_depth (s->info->arrayfetch->arr);
3544 return (sRef_depth (sRef_fixConj (s)));
3551 sRef_makeObject (ctype o)
3553 sRef s = sRef_newRef ();
3555 s->kind = SK_OBJECT;
3556 s->info = (sinfo) dmalloc (sizeof (*s->info));
3557 s->info->object = o;
3558 llassert (valueTable_isUndefined (s->state));
3559 s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_CREATED));
3564 ** This is used to represent storage referenced by a parameter.
3567 sRef sRef_makeExternal (sRef t)
3569 sRef s = sRef_newRef ();
3571 llassert (sRef_isReasonable (t));
3573 s->kind = SK_EXTERNAL;
3574 s->info = (sinfo) dmalloc (sizeof (*s->info));
3577 llassert (valueTable_isUndefined (s->state));
3578 s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_DECLARED));
3582 /*@dependent@*/ sRef sRef_makeDerived (/*@exposed@*/ sRef t)
3584 if (sRef_isReasonable (t))
3586 sRef s = sRef_newRef ();
3588 s->kind = SK_DERIVED;
3589 s->info = (sinfo) dmalloc (sizeof (*s->info));
3593 llassert (valueTable_isUndefined (s->state));
3594 s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_CREATED));
3599 return sRef_undefined;
3604 ** definitely NOT symmetric:
3606 ** res fills in unknown state information from other
3610 sRef_mergeStateQuiet (sRef res, sRef other)
3612 llassert (sRef_isReasonable (res));
3613 llassert (sRef_isReasonable (other));
3615 res->modified = res->modified || other->modified;
3616 res->safe = res->safe && other->safe;
3618 if (res->defstate == SS_UNKNOWN)
3620 res->defstate = other->defstate;
3621 res->definfo = stateInfo_update (res->definfo, other->definfo);
3624 if (res->aliaskind == AK_UNKNOWN ||
3625 (res->aliaskind == AK_LOCAL && alkind_isKnown (other->aliaskind)))
3627 res->aliaskind = other->aliaskind;
3628 res->oaliaskind = other->oaliaskind;
3629 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
3632 if (res->expkind == XO_UNKNOWN)
3634 res->expkind = other->expkind;
3635 res->oexpkind = other->oexpkind;
3636 res->expinfo = stateInfo_update (res->expinfo, other->expinfo);
3639 /* out takes precedence over implicitly defined */
3640 if (res->defstate == SS_DEFINED && other->defstate != SS_UNKNOWN)
3642 res->defstate = other->defstate;
3643 res->definfo = stateInfo_update (res->definfo, other->definfo);
3646 if (sRef_getNullState (other) == NS_ERROR || sRef_getNullState (res) == NS_ERROR)
3648 sRef_setNullState (res, NS_ERROR, fileloc_undefined);
3652 if (sRef_getNullState (other) != NS_UNKNOWN
3653 && (sRef_getNullState (res) == NS_UNKNOWN || sRef_getNullState (res) == NS_NOTNULL
3654 || sRef_getNullState (res) == NS_MNOTNULL))
3656 sRef_updateNullState (res, other);
3662 ** definitely NOT symmetric:
3664 ** res fills in known state information from other
3668 sRef_mergeStateQuietReverse (/*@dependent@*/ sRef res, /*@dependent@*/ sRef other)
3670 bool changed = FALSE;
3672 llassert (sRef_isReasonable (res));
3673 llassert (sRef_isReasonable (other));
3674 sRef_checkMutable (res);
3676 if (res->kind != other->kind)
3682 res->kind = other->kind;
3683 res->type = other->type;
3684 res->info = sinfo_fullCopy (other);
3688 if (!ctype_equal (res->type, other->type))
3691 res->type = other->type;
3694 sinfo_update (res, other);
3697 res->modified = res->modified || other->modified;
3698 res->safe = res->safe && other->safe;
3700 if (res->aliaskind != other->aliaskind
3701 && (res->aliaskind == AK_UNKNOWN
3702 || ((res->aliaskind == AK_LOCAL
3703 || (res->aliaskind == AK_REFCOUNTED
3704 && other->aliaskind != AK_LOCAL))
3705 && other->aliaskind != AK_UNKNOWN)))
3708 res->aliaskind = other->aliaskind;
3709 res->oaliaskind = other->oaliaskind;
3710 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
3713 if (other->expkind != XO_UNKNOWN && other->expkind != res->expkind)
3716 res->expkind = other->expkind;
3717 res->expinfo = stateInfo_update (res->expinfo, other->expinfo);
3720 if (other->oexpkind != XO_UNKNOWN)
3722 res->oexpkind = other->oexpkind;
3725 /* out takes precedence over implicitly defined */
3727 if (res->defstate != other->defstate)
3729 if (other->defstate != SS_UNKNOWN)
3731 res->defstate = other->defstate;
3732 res->definfo = stateInfo_update (res->definfo, other->definfo);
3736 if (sRef_getNullState (other) == NS_ERROR || sRef_getNullState (res) == NS_ERROR)
3738 if (sRef_getNullState (res) != NS_ERROR)
3740 sRef_setNullStateN (res, NS_ERROR);
3746 if (sRef_getNullState (other) != NS_UNKNOWN
3747 && sRef_getNullState (other) != sRef_getNullState (res))
3750 sRef_updateNullState (res, other);
3756 sRef_clearDerived (res);
3761 sRef_mergeState (sRef res, sRef other, clause cl, fileloc loc)
3763 if (sRef_isReasonable (res) && sRef_isReasonable (other))
3765 sRef_mergeStateAux (res, other, cl, FALSE, loc, TRUE);
3769 if (sRef_isInvalid (res))
3771 llbug (message ("sRef_mergeState: invalid res sRef: %q",
3772 sRef_unparseDebug (other)));
3776 llbug (message ("sRef_mergeState: invalid other sRef: %q",
3777 sRef_unparseDebug (res)));
3783 sRef_mergeOptState (sRef res, sRef other, clause cl, fileloc loc)
3785 if (sRef_isReasonable (res) && sRef_isReasonable (other))
3787 sRef_mergeStateAux (res, other, cl, TRUE, loc, TRUE);
3791 if (sRef_isInvalid (res))
3793 llbug (message ("sRef_mergeOptState: invalid res sRef: %q",
3794 sRef_unparseDebug (other)));
3798 llbug (message ("sRef_mergeOptState: invalid other sRef: %q",
3799 sRef_unparseDebug (res)));
3805 sRef_mergeStateAux (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other,
3806 clause cl, bool opt, fileloc loc,
3810 llassertfatal (sRef_isReasonable (res));
3811 llassertfatal (sRef_isReasonable (other));
3813 DPRINTF (("Merge aux: %s / %s",
3814 sRef_unparseFull (res),
3815 sRef_unparseFull (other)));
3817 sRef_checkMutable (res);
3818 sRef_checkMutable (other);
3820 res->modified = res->modified || other->modified;
3822 if (res->kind == other->kind
3823 || (other->kind == SK_UNKNOWN || res->kind == SK_UNKNOWN))
3825 sstate odef = other->defstate;
3826 sstate rdef = res->defstate;
3827 nstate onull = sRef_getNullState (other);
3830 ** yucky stuff to handle
3835 if (other->defstate == SS_DEAD
3836 && ((sRef_isOnly (res) && sRef_definitelyNull (res))
3837 || (res->defstate == SS_UNDEFINED
3838 || res->defstate == SS_UNUSEABLE)))
3840 if (res->defstate == SS_UNDEFINED
3841 || res->defstate == SS_UNUSEABLE)
3843 res->defstate = SS_UNUSEABLE;
3847 res->defstate = SS_DEAD;
3850 res->definfo = stateInfo_update (res->definfo, other->definfo);
3851 sRef_clearDerived (other);
3852 sRef_clearDerived (res);
3854 else if (res->defstate == SS_DEAD
3855 && ((sRef_isOnly (other) && sRef_definitelyNull (other))
3856 || (other->defstate == SS_UNDEFINED
3857 || other->defstate == SS_UNUSEABLE)))
3859 if (other->defstate == SS_UNDEFINED
3860 || other->defstate == SS_UNUSEABLE)
3862 res->defstate = SS_UNUSEABLE;
3866 res->defstate = SS_DEAD;
3869 res->definfo = stateInfo_update (res->definfo, other->definfo);
3870 sRef_clearDerived (other);
3871 sRef_clearDerived (res);
3873 else if (res->defstate == SS_DEFINED
3874 && (other->defstate == SS_ALLOCATED
3875 && sRef_definitelyNull (other)))
3877 other->defstate = SS_DEFINED; /* definitely null! */
3879 else if (other->defstate == SS_DEFINED
3880 && (res->defstate == SS_ALLOCATED && sRef_definitelyNull (res)))
3882 res->defstate = SS_DEFINED;
3883 res->definfo = stateInfo_update (res->definfo, other->definfo);
3890 if (res->defstate == SS_DEAD && other->defstate == SS_DEAD)
3892 sRef_clearDerived (other);
3893 sRef_clearDerived (res);
3897 ** only & dead isn't really an only!
3900 if (alkind_isOnly (other->aliaskind) && other->defstate == SS_DEAD)
3902 other->aliaskind = AK_UNKNOWN;
3905 if (alkind_isOnly (res->aliaskind) && res->defstate == SS_DEAD)
3907 res->aliaskind = AK_UNKNOWN;
3911 ** Dead and dependent -> dead
3914 if (alkind_isDependent (other->aliaskind) && res->defstate == SS_DEAD)
3916 other->aliaskind = AK_UNKNOWN;
3917 other->defstate = SS_DEAD;
3918 sRef_clearDerived (res);
3919 sRef_clearDerived (other);
3922 if (alkind_isDependent (res->aliaskind) && other->defstate == SS_DEAD)
3924 res->aliaskind = AK_UNKNOWN;
3925 res->defstate = SS_DEAD;
3926 sRef_clearDerived (res);
3927 sRef_clearDerived (other);
3931 ** must do alias combine first, since it depends on
3932 ** original values of state and null.
3935 sRef_combineAliasKinds (res, other, cl, loc);
3936 sRef_combineDefState (res, other);
3937 sRef_combineNullState (res, other);
3939 if (rdef == SS_ALLOCATED || rdef == SS_SPECIAL)
3941 if (odef == SS_DEFINED)
3943 if (onull == NS_DEFNULL || onull == NS_CONSTNULL)
3945 res->deriv = sRefSet_copyInto (res->deriv, other->deriv);
3946 DPRINTF (("Copy derivs: %s", sRef_unparseFull (res)));
3949 else if (odef == SS_ALLOCATED || odef == SS_SPECIAL)
3954 if (ctype_isUnion (ctype_realType (sRef_getType (res))))
3956 res->deriv = sRef_mergeUnionDerivs (res->deriv,
3959 DPRINTF (("Copy derivs: %s", sRef_unparseFull (res)));
3963 res->deriv = sRef_mergeDerivs (res->deriv, other->deriv,
3965 DPRINTF (("Copy derivs: %s", sRef_unparseFull (res)));
3973 res->deriv = sRef_mergeDerivs (res->deriv, other->deriv,
3975 DPRINTF (("Copy derivs: %s", sRef_unparseFull (res)));
3985 if (rdef == SS_PDEFINED
3986 || (rdef == SS_DEFINED && odef == SS_PDEFINED))
3990 res->deriv = sRef_mergePdefinedDerivs (res->deriv, other->deriv,
3992 DPRINTF (("Copy derivs: %s", sRef_unparseFull (res)));
3997 if ((rdef == SS_DEFINED || rdef == SS_UNKNOWN)
3998 && res->defstate == SS_ALLOCATED)
4000 res->deriv = sRefSet_copyInto (res->deriv, other->deriv);
4006 res->deriv = sRef_mergeDerivs (res->deriv, other->deriv,
4008 DPRINTF (("Copy derivs: %s", sRef_unparseFull (res)));
4015 sRef_combineExKinds (res, other);
4019 if (res->kind == SK_ARRAYFETCH && other->kind == SK_PTR)
4021 sRef nother = sRef_buildArrayFetchKnown (sRef_getBase (other), 0);
4023 sRef_copyState (nother, other);
4024 sRef_mergeStateAux (res, nother, cl, opt, loc, doDerivs);
4026 else if (res->kind == SK_PTR && other->kind == SK_ARRAYFETCH)
4028 sRef nother = sRef_buildPointer (sRef_getBase (other));
4030 if (sRef_isReasonable (nother))
4032 sRef_copyState (nother, other);
4033 sRef_mergeStateAux (res, nother, cl, opt, loc, doDerivs);
4038 llcontbug (message ("merge conj: %q / %q", sRef_unparseFull (res),
4039 sRef_unparseFull (other)));
4045 ** Merge value table states
4050 ** This doesn't do anything. And its broken too...
4053 valueTable_elements (res->state, key, sv)
4055 stateValue os = valueTable_lookup (other->state, key);
4056 /*@unused@*/ int val;
4057 /*@unused@*/ char *msg;
4059 llassert (stateValue_isDefined (os));
4061 DPRINTF (("Merge state: %s / %s",
4062 cstring_toCharsSafe (stateValue_unparse (sv)),
4063 cstring_toCharsSafe (stateValue_unparse (os))));
4065 val = valueMatix_lookup (key,
4066 stateValue_getValue (os),
4067 stateValue_getValue (sv),
4069 DPRINTF (("Val: %d / %s", val, msg));
4071 } end_valueTable_elements ;
4074 DPRINTF (("Merge aux: %s / %s",
4075 sRef_unparseFull (res),
4076 sRef_unparseFull (other)));
4080 sRef_mergeUnionDerivs (/*@only@*/ sRefSet res,
4081 /*@exposed@*/ sRefSet other, bool opt,
4082 clause cl, fileloc loc)
4084 if (sRefSet_isEmpty (res))
4086 return sRefSet_copyInto (res, other);
4090 sRefSet_allElements (other, el)
4092 if (sRef_isReasonable (el))
4094 sRef e2 = sRefSet_lookupMember (other, el);
4096 if (sRef_isReasonable (e2))
4098 sRef_mergeStateAux (el, e2, cl, opt, loc, FALSE);
4102 res = sRefSet_insert (res, el);
4105 } end_sRefSet_allElements ;
4111 static /*@only@*/ sRefSet
4112 sRef_mergeDerivs (/*@only@*/ sRefSet res, sRefSet other,
4113 bool opt, clause cl, fileloc loc)
4115 sRefSet ret = sRefSet_new ();
4117 sRefSet_allElements (res, el)
4119 if (sRef_isReasonable (el))
4121 sRef e2 = sRefSet_lookupMember (other, el);
4123 if (sRef_isReasonable (e2))
4125 if (el->defstate == SS_ALLOCATED &&
4126 e2->defstate == SS_PDEFINED)
4128 e2->defstate = SS_ALLOCATED;
4130 else if (e2->defstate == SS_ALLOCATED &&
4131 el->defstate == SS_PDEFINED)
4133 el->defstate = SS_ALLOCATED;
4134 el->definfo = stateInfo_update (el->definfo, e2->definfo);
4135 sRef_clearDerived (el);
4137 else if ((el->defstate == SS_DEAD || sRef_isKept (el)) &&
4138 (e2->defstate == SS_DEFINED && !sRef_isKept (e2)))
4140 DPRINTF (("Checking dead: %s / %s", sRef_unparseFull (el),
4141 sRef_unparseFull (e2)));
4143 if (checkDeadState (el, e2, TRUE, loc))
4145 if (sRef_isThroughArrayFetch (el))
4147 sRef_maybeKill (el, loc);
4148 sRef_maybeKill (e2, loc);
4152 else if ((e2->defstate == SS_DEAD || sRef_isKept (e2)) &&
4153 (el->defstate == SS_DEFINED && !sRef_isKept (el)))
4155 DPRINTF (("Checking dead: %s / %s", sRef_unparseFull (el),
4156 sRef_unparseFull (e2)));
4158 if (checkDeadState (e2, el, FALSE, loc))
4160 if (sRef_isThroughArrayFetch (el))
4162 sRef_maybeKill (el, loc);
4163 sRef_maybeKill (e2, loc);
4167 else if (el->defstate == SS_DEFINED &&
4168 e2->defstate == SS_PDEFINED)
4170 DPRINTF (("set pdefined: %s", sRef_unparseFull (el)));
4171 el->defstate = SS_PDEFINED;
4172 el->definfo = stateInfo_update (el->definfo, e2->definfo);
4174 else if (e2->defstate == SS_DEFINED &&
4175 el->defstate == SS_PDEFINED)
4177 DPRINTF (("set pdefined: %s", sRef_unparseFull (e2)));
4178 e2->defstate = SS_PDEFINED;
4179 e2->definfo = stateInfo_update (e2->definfo, el->definfo);
4186 if (ctype_isUnion (ctype_realType (sRef_getType (el))))
4188 el->deriv = sRef_mergeUnionDerivs (el->deriv, e2->deriv,
4193 el->deriv = sRef_mergeDerivs (el->deriv, e2->deriv, opt, cl, loc);
4196 if (sRef_equivalent (el, e2))
4198 ret = sRefSet_insert (ret, el);
4202 sRef sr = sRef_leastCommon (el, e2);
4204 if (sRef_isReasonable (sr))
4206 ret = sRefSet_insert (ret, sr);
4214 (void) sRefSet_delete (other, e2);
4216 else /* not defined */
4218 DPRINTF (("Checking dead: %s", sRef_unparseFull (el)));
4219 (void) checkDeadState (el, e2, TRUE, loc);
4222 } end_sRefSet_allElements;
4224 sRefSet_allElements (other, el)
4226 if (sRef_isReasonable (el))
4228 DPRINTF (("Checking dead: %s", sRef_unparseFull (el)));
4229 (void) checkDeadState (el, sRef_undefined, FALSE, loc);
4231 } end_sRefSet_allElements;
4238 ** Returns TRUE is there is an error.
4241 static bool checkDeadState (/*@notnull@*/ sRef el, sRef e2, bool tbranch, fileloc loc)
4244 ** usymtab_isGuarded --- the utab should still be in the
4245 ** state of the alternate branch.
4247 ** tbranch TRUE means el is released in the last branch, e.g.
4248 ** if (x != NULL) { ; } else { sfree (x); }
4249 ** so, if x is null in the other branch no error is reported.
4251 ** tbranch FALSE means this is the other branch:
4252 ** if (x != NULL) { sfree (x); } else { ; }
4253 ** so, if x is null in this branch there is no error.
4257 if ((sRef_isDead (el) || sRef_isKept (el))
4258 && !sRef_isDeepUnionField (el)
4259 && !sRef_isThroughArrayFetch (el))
4264 if (usymtab_isDefinitelyNullDeep (el))
4271 if (usymtab_isAltDefinitelyNullDeep (el))
4279 message ("Storage %q is %q in one path, but live in another.",
4281 cstring_makeLiteral (sRef_isKept (el)
4282 ? "kept" : "released")),
4285 if (sRef_isKept (el))
4287 sRef_showAliasInfo (el);
4291 sRef_showStateInfo (el);
4294 if (sRef_isValid (e2))
4296 if (sRef_isKept (e2))
4298 sRef_showAliasInfo (e2);
4302 sRef_showStateInfo (e2);
4306 /* prevent further errors */
4307 el->defstate = SS_UNKNOWN;
4308 sRef_setAliasKind (el, AK_ERROR, fileloc_undefined);
4317 checkDerivDeadState (/*@notnull@*/ sRef el, bool tbranch, fileloc loc)
4319 if (checkDeadState (el, sRef_undefined, tbranch, loc))
4321 sRefSet_allElements (el->deriv, t)
4323 if (sRef_isReasonable (t))
4325 checkDerivDeadState (t, tbranch, loc);
4327 } end_sRefSet_allElements;
4332 sRef_mergePdefinedDerivs (sRefSet res, sRefSet other, bool opt,
4333 clause cl, fileloc loc)
4335 sRefSet ret = sRefSet_new ();
4337 sRefSet_allElements (res, el)
4339 if (sRef_isReasonable (el))
4341 sRef e2 = sRefSet_lookupMember (other, el);
4343 if (sRef_isReasonable (e2))
4345 if (sRef_isAllocated (el) && !sRef_isAllocated (e2))
4349 else if (sRef_isAllocated (e2) && !sRef_isAllocated (el))
4351 el->deriv = sRefSet_copyInto (el->deriv, e2->deriv);
4355 el->deriv = sRef_mergePdefinedDerivs (el->deriv, e2->deriv,
4359 sRef_mergeStateAux (el, e2, cl, opt, loc, FALSE);
4361 ret = sRefSet_insert (ret, el);
4362 (void) sRefSet_delete (other, e2);
4368 checkDerivDeadState (el, (cl == FALSECLAUSE), loc);
4371 ret = sRefSet_insert (ret, el);
4374 } end_sRefSet_allElements;
4376 sRefSet_allElements (other, el)
4378 if (sRef_isReasonable (el))
4380 if (!sRefSet_member (ret, el))
4382 /* was cl == FALSECLAUSE */
4383 checkDerivDeadState (el, FALSE, loc);
4384 ret = sRefSet_insert (ret, el);
4389 ** it's okay --- member is a different equality test
4393 } end_sRefSet_allElements;
4399 sRef sRef_makeConj (/*@exposed@*/ /*@returned@*/ sRef a, /*@exposed@*/ sRef b)
4401 llassert (sRef_isReasonable (a));
4402 llassert (sRef_isReasonable (b));
4404 if (!sRef_equivalent (a, b))
4406 sRef s = sRef_newRef ();
4409 s->info = (sinfo) dmalloc (sizeof (*s->info));
4410 s->info->conj = (cjinfo) dmalloc (sizeof (*s->info->conj));
4411 s->info->conj->a = a;
4412 s->info->conj->b = b;
4414 if (ctype_equal (a->type, b->type)) s->type = a->type;
4415 else s->type = ctype_makeConj (a->type, b->type);
4417 if (a->defstate == b->defstate)
4419 s->defstate = a->defstate;
4420 s->definfo = stateInfo_update (s->definfo, a->definfo);
4421 s->definfo = stateInfo_update (s->definfo, b->definfo);
4425 s->defstate = SS_UNKNOWN;
4428 sRef_setNullStateN (s, NS_UNKNOWN);
4430 s->safe = a->safe && b->safe;
4431 s->aliaskind = alkind_resolve (a->aliaskind, b->aliaskind);
4433 llassert (valueTable_isUndefined (s->state));
4434 s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_MERGED));
4439 /*@-exposetrans@*/ return a; /*@=exposetrans@*/
4443 /*@dependent@*/ sRef
4446 sRef s = sRef_new ();
4448 s->kind = SK_UNKNOWN;
4452 static /*@owned@*/ /*@notnull@*/ sRef
4453 sRef_makeSpecial (speckind sk) /*@*/
4455 sRef s = sRef_new ();
4457 s->kind = SK_SPECIAL;
4458 s->info = (sinfo) dmalloc (sizeof (*s->info));
4460 /*@-dependenttrans@*/
4462 /*@=dependenttrans@*/
4465 static /*@owned@*/ sRef srnothing = sRef_undefined;
4466 static /*@owned@*/ sRef srinternal = sRef_undefined;
4467 static /*@owned@*/ sRef srsystem = sRef_undefined;
4468 static /*@owned@*/ sRef srspec = sRef_undefined;
4470 /*@dependent@*/ sRef
4471 sRef_makeNothing (void)
4473 if (sRef_isInvalid (srnothing))
4475 srnothing = sRef_makeSpecial (SR_NOTHING);
4482 sRef_makeInternalState (void)
4484 if (sRef_isInvalid (srinternal))
4486 srinternal = sRef_makeSpecial (SR_INTERNAL);
4493 sRef_makeSpecState (void)
4495 if (sRef_isInvalid (srspec))
4497 srspec = sRef_makeSpecial (SR_SPECSTATE);
4504 sRef_makeSystemState (void)
4506 if (sRef_isInvalid (srsystem))
4508 srsystem = sRef_makeSpecial (SR_SYSTEM);
4515 sRef_makeGlobalMarker (void)
4517 sRef s = sRef_makeSpecial (SR_GLOBALMARKER);
4518 llassert (valueTable_isUndefined (s->state));
4519 s->state = context_createGlobalMarkerValueTable (stateInfo_undefined);
4524 sRef_makeResult (ctype c)
4526 sRef s = sRef_newRef ();
4528 s->kind = SK_RESULT;
4530 s->defstate = SS_UNKNOWN;
4531 s->aliaskind = AK_UNKNOWN;
4532 sRef_setNullStateN (s, NS_UNKNOWN);
4533 llassert (valueTable_isUndefined (s->state));
4534 s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_DECLARED));
4536 DPRINTF (("Result: [%p] %s", s, sRef_unparseFull (s)));
4542 sRef_isNothing (sRef s)
4544 return (sRef_isKindSpecial (s) && s->info->spec == SR_NOTHING);
4548 sRef_isInternalState (sRef s)
4550 return (sRef_isKindSpecial (s) && s->info->spec == SR_INTERNAL);
4554 sRef_isSpecInternalState (sRef s)
4556 return (sRef_isKindSpecial (s)
4557 && (s->info->spec == SR_INTERNAL || s->info->spec == SR_SPECSTATE));
4561 sRef_isSpecState (sRef s)
4563 return (sRef_isKindSpecial (s) && s->info->spec == SR_SPECSTATE);
4567 sRef_isResult (sRef s)
4569 return (sRef_isReasonable (s) && s->kind == SK_RESULT);
4573 sRef_isSystemState (sRef s)
4575 return (sRef_isKindSpecial (s) && s->info->spec == SR_SYSTEM);
4579 sRef_isGlobalMarker (sRef s)
4581 return (sRef_isKindSpecial (s) && s->info->spec == SR_GLOBALMARKER);
4585 sRef_getScopeIndex (sRef s)
4587 llassert (sRef_isReasonable (s));
4588 llassert (sRef_isCvar (s));
4590 return (s->info->cvar->index);
4594 sRef_makeSafe (sRef s)
4596 if (sRef_isReasonable (s))
4603 sRef_makeUnsafe (sRef s)
4605 if (sRef_isReasonable (s))
4612 ** memory state operations
4615 /*@only@*/ cstring sRef_unparseFull (sRef s)
4617 if (sRef_isInvalid (s)) return (cstring_undefined);
4619 return (message ("[%p] %q - %q { %q } [%s] { %q } < %q >",
4621 sRef_unparseDebug (s),
4622 sRef_unparseState (s),
4623 stateInfo_unparse (s->definfo),
4624 exkind_unparse (s->oexpkind),
4625 sRefSet_unparseDebug (s->deriv),
4626 valueTable_unparse (s->state)));
4629 /*@unused@*/ cstring sRef_unparseDeep (sRef s)
4631 cstring st = cstring_undefined;
4633 st = message ("%q:", sRef_unparseFull (s));
4635 if (sRef_isReasonable (s))
4637 sRefSet_allElements (s->deriv, el)
4639 st = message("%q\n%q", st, sRef_unparseDeep (el));
4640 } end_sRefSet_allElements ;
4646 /*@only@*/ cstring sRef_unparseState (sRef s)
4648 if (sRef_isConj (s))
4650 return (message ("%q | %q",
4651 sRef_unparseState (s->info->conj->a),
4652 sRef_unparseState (s->info->conj->b)));
4655 if (sRef_isInvalid (s))
4657 return (cstring_makeLiteral ("<invalid>"));
4660 return (message ("%s.%s.%s.%s",
4661 alkind_unparse (s->aliaskind),
4662 nstate_unparse (sRef_getNullState (s)),
4663 exkind_unparse (s->expkind),
4664 sstate_unparse (s->defstate)));
4667 bool sRef_isNotUndefined (sRef s)
4669 return (sRef_isInvalid (s)
4670 || (s->defstate != SS_UNDEFINED
4671 && s->defstate != SS_UNUSEABLE
4672 && s->defstate != SS_DEAD));
4675 ynm sRef_isWriteable (sRef s)
4677 if (sRef_isInvalid (s)) return MAYBE;
4679 if (sRef_isConj (s) && s->defstate == SS_UNKNOWN)
4681 if (ynm_toBoolStrict (sRef_isWriteable (sRef_getConjA (s))))
4683 if (ynm_toBoolStrict (sRef_isWriteable (sRef_getConjB (s))))
4691 if (ynm_toBoolStrict (sRef_isWriteable (sRef_getConjB (s))))
4699 return (ynm_fromBool (s->defstate != SS_UNUSEABLE));
4702 bool sRef_hasNoStorage (sRef s)
4704 return (!sRef_isAllocatedStorage (s) || sRef_isDefinitelyNull (s));
4707 bool sRef_isStrictReadable (sRef s)
4709 return (ynm_toBoolStrict (sRef_isValidLvalue (s)));
4713 ** Is this what is does?
4714 ** Returns YES if s can be used as an rvalue,
4715 ** MAYBE if its not clear
4716 ** NO if s cannot be safely used as an rvalue.
4719 ynm sRef_isValidLvalue (sRef s)
4723 if (sRef_isInvalid (s)) return YES;
4727 if (sRef_isConj (s) && s->defstate == SS_UNKNOWN)
4729 if (ynm_toBoolStrict (sRef_isValidLvalue (sRef_getConjA (s))))
4731 if (ynm_toBoolStrict (sRef_isValidLvalue (sRef_getConjB (s))))
4739 if (ynm_toBoolStrict (sRef_isValidLvalue (sRef_getConjB (s))))
4746 else if (ss == SS_HOFFA)
4748 if (context_getFlag (FLG_STRICTUSERELEASED))
4759 return (ynm_fromBool (ss == SS_DEFINED
4762 || ss == SS_PDEFINED
4765 || ss == SS_ALLOCATED
4766 || ss == SS_KILLED /* evans 2001-05-26: added this for killed globals */
4767 || ss == SS_UNKNOWN));
4771 static /*@exposed@*/ sRef whatUndefined (/*@exposed@*/ sRef fref, int depth)
4776 if (depth > MAXDEPTH)
4779 ("Warning: check definition limit exceeded, checking %q. "
4780 "This either means there is a variable with at least "
4781 "%d indirections apparent in the program text, or "
4782 "there is a bug in Splint.",
4783 sRef_unparse (fref),
4787 return sRef_undefined;
4790 if (!sRef_isKnown (fref) || sRef_isAnyDefined (fref))
4792 return sRef_undefined;
4795 if (sRef_isUnuseable (fref) || sRef_isStateUndefined (fref))
4800 ct = ctype_realType (sRef_getType (fref));
4802 if (ctype_isUnknown (ct))
4804 return sRef_undefined;
4806 else if (ctype_isPointer (ct) || ctype_isArray (ct))
4808 if (sRef_isStateUnknown (fref))
4810 return sRef_undefined;
4814 sRef fptr = sRef_constructDeref (fref);
4816 return (whatUndefined (fptr, depth + 1));
4819 else if (ctype_isStruct (ct))
4821 bool hasOneDefined = FALSE;
4823 if (sRef_isStateUnknown (fref))
4828 if (sRef_isPdefined (fref) || sRef_isAnyDefined (fref))
4830 sRefSet_realElements (sRef_derivedFields (fref), sr)
4832 hasOneDefined = TRUE;
4834 if (sRef_isField (sr))
4836 cstring fieldname = sRef_getField (sr);
4837 sRef fldref = sRef_makeField (fref, fieldname);
4838 bool shouldCheck = !sRef_isRecursiveField (fldref);
4842 sRef wdef = whatUndefined (fldref, depth + 1);
4844 if (sRef_isReasonable (wdef))
4850 } end_sRefSet_realElements;
4852 else if (sRef_isAllocated (fref))
4855 ** for structures, each field must be completely defined
4858 uentryList fields = ctype_getFields (ct);
4860 uentryList_elements (fields, ue)
4862 cstring name = uentry_getRealName (ue);
4863 sRef ffield = sRef_makeField (fref, name);
4864 bool shouldCheck = !sRef_isRecursiveField (ffield);
4866 if (sRef_isRelDef (uentry_getSref (ue)))
4874 sRef wdef = whatUndefined (ffield, depth + 1);
4876 if (sRef_isInvalid (wdef))
4882 } end_uentryList_elements;
4889 else if (ctype_isUnion (ct))
4898 return sRef_undefined;
4901 static bool checkDefined (/*@temp@*/ sRef sr)
4903 /*@-temptrans@*/ /* the result from whatUndefined is lost */
4904 return (sRef_isInvalid (whatUndefined (sr, 0)));
4908 bool sRef_isReallyDefined (sRef s)
4910 if (sRef_isReasonable (s))
4912 if (sRef_isAnyDefined (s))
4918 if (sRef_isAllocated (s) || sRef_isPdefined (s))
4920 return checkDefined (s);
4934 void sRef_showNotReallyDefined (sRef s)
4936 if (sRef_isReasonable (s))
4938 if (sRef_isAnyDefined (s))
4944 if (sRef_isAllocated (s) || sRef_isPdefined (s))
4946 /*@-temptrans@*/ /* the result of whatUndefined is lost */
4947 sRef ref = whatUndefined (s, 0);
4949 llassert (sRef_isReasonable (ref));
4954 (message ("This sub-reference is %s: %q",
4955 sstate_unparse (sRef_getDefState (ref)),
4956 sRef_unparse (ref)));
4971 sstate sRef_getDefState (sRef s)
4973 if (sRef_isInvalid (s)) return (SS_UNKNOWN);
4974 return (s->defstate);
4977 void sRef_setDefState (sRef s, sstate defstate, fileloc loc)
4979 sRef_checkMutable (s);
4980 sRef_setStateAux (s, defstate, loc);
4983 static void sRef_clearAliasStateAux (sRef s, fileloc loc)
4985 sRef_checkMutable (s);
4986 sRef_setAliasKind (s, AK_ERROR, loc);
4989 void sRef_clearAliasState (sRef s, fileloc loc)
4991 sRef_checkMutable (s);
4992 sRef_aliasSetComplete (sRef_clearAliasStateAux, s, loc);
4995 void sRef_setAliasKindComplete (sRef s, alkind kind, fileloc loc)
4997 sRef_checkMutable (s);
4998 sRef_aliasSetCompleteAlkParam (sRef_setAliasKind, s, kind, loc);
5001 void sRef_setAliasKind (sRef s, alkind kind, fileloc loc)
5003 sRef_checkMutable (s);
5005 if (sRef_isReasonable (s))
5007 sRef_clearDerived (s);
5009 if ((kind != s->aliaskind && kind != s->oaliaskind)
5010 && fileloc_isDefined (loc))
5012 s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, stateAction_fromAlkind (kind), loc);
5015 s->aliaskind = kind;
5019 void sRef_setOrigAliasKind (sRef s, alkind kind)
5021 sRef_checkMutable (s);
5023 if (sRef_isReasonable (s))
5025 s->oaliaskind = kind;
5029 exkind sRef_getExKind (sRef s)
5031 if (sRef_isReasonable (s))
5033 return (s->expkind);
5041 exkind sRef_getOrigExKind (sRef s)
5043 if (sRef_isReasonable (s))
5045 return (s->oexpkind);
5053 static void sRef_clearExKindAux (sRef s, fileloc loc)
5055 sRef_checkMutable (s);
5056 sRef_setExKind (s, XO_UNKNOWN, loc);
5059 void sRef_setObserver (sRef s, fileloc loc)
5061 sRef_checkMutable (s);
5062 sRef_setExKind (s, XO_OBSERVER, loc);
5065 void sRef_setExposed (sRef s, fileloc loc)
5067 sRef_checkMutable (s);
5068 sRef_setExKind (s, XO_EXPOSED, loc);
5071 void sRef_clearExKindComplete (sRef s, fileloc loc)
5073 (void) sRef_aliasSetComplete (sRef_clearExKindAux, s, loc);
5076 void sRef_setExKind (sRef s, exkind exp, fileloc loc)
5078 sRef_checkMutable (s);
5080 if (sRef_isReasonable (s))
5082 if (s->expkind != exp)
5084 s->expinfo = stateInfo_updateLoc (s->expinfo, stateAction_fromExkind (exp), loc);
5092 ** s1->derived = s2->derived
5095 static void sRef_copyRealDerived (sRef s1, sRef s2)
5097 DPRINTF (("Copy real: %s / %s", sRef_unparse (s1), sRef_unparse (s2)));
5098 sRef_checkMutable (s1);
5100 if (sRef_isReasonable (s1) && sRef_isReasonable (s2))
5102 sRef sb = sRef_getRootBase (s1);
5104 sRefSet_clear (s1->deriv);
5106 sRefSet_allElements (s2->deriv, el)
5108 if (sRef_isReasonable (el))
5110 sRef rb = sRef_getRootBase (el);
5112 if (!sRef_same (rb, sb))
5114 sRef fb = sRef_fixDirectBase (el, s1);
5116 if (sRef_isReasonable (fb))
5118 sRef_copyRealDerived (fb, el);
5119 sRef_addDeriv (s1, fb);
5124 sRef_addDeriv (s1, el);
5127 } end_sRefSet_allElements ;
5132 void sRef_copyRealDerivedComplete (sRef s1, sRef s2)
5134 sRef_innerAliasSetCompleteParam (sRef_copyRealDerived, s1, s2);
5137 void sRef_setUndefined (sRef s, fileloc loc)
5139 sRef_checkMutable (s);
5141 if (sRef_isReasonable (s))
5143 s->defstate = SS_UNDEFINED;
5144 s->definfo = stateInfo_updateLoc (s->definfo, SA_UNDEFINED, loc);
5146 sRef_clearDerived (s);
5150 static void sRef_setDefinedAux (sRef s, fileloc loc, bool clear)
5152 sRef_checkMutable (s);
5153 if (sRef_isInvalid (s)) return;
5155 DPRINTF (("Set defined: %s", sRef_unparseFull (s)));
5157 s->definfo = stateInfo_updateLoc (s->definfo, SA_DEFINED, loc);
5158 s->defstate = SS_DEFINED;
5160 DPRINTF (("Set defined: %s", sRef_unparseFull (s)));
5162 /* e.g., if x is allocated, *x = 3 defines x */
5164 if (s->kind == SK_PTR)
5166 sRef p = s->info->ref;
5169 if (p->defstate == SS_ALLOCATED
5170 || p->defstate == SS_SPECIAL) /* evans 2001-07-12: shouldn't need this */
5172 sRef_setDefinedAux (p, loc, clear);
5176 ** Defines a[0] also:
5179 arr = sRef_findDerivedArrayFetch (p, FALSE, 0, FALSE);
5181 if (sRef_isReasonable (arr))
5183 sRef_setDefinedAux (arr, loc, clear);
5186 else if (s->kind == SK_ARRAYFETCH)
5188 if (!s->info->arrayfetch->indknown
5189 || (s->info->arrayfetch->ind == 0))
5191 sRef p = s->info->arrayfetch->arr;
5192 sRef ptr = sRef_constructPointer (p);
5194 if (sRef_isReasonable (ptr))
5196 if (ptr->defstate == SS_ALLOCATED
5197 || ptr->defstate == SS_UNDEFINED
5198 || ptr->defstate == SS_SPECIAL) /* evans 2001-07-12: shouldn't need this */
5200 sRef_setDefinedAux (ptr, loc, clear);
5204 if (p->defstate == SS_RELDEF)
5208 else if (p->defstate == SS_ALLOCATED || p->defstate == SS_PDEFINED
5209 || p->defstate == SS_SPECIAL) /* evans 2001-07-12: shouldn't need this */
5211 p->defstate = SS_DEFINED;
5218 else if (s->kind == SK_FIELD)
5220 sRef parent = s->info->field->rec;
5222 if (sRef_isReasonable (parent))
5224 if (ctype_isUnion (ctype_realType (parent->type)))
5227 ** Should not clear derived from here.
5230 sRef_setDefinedNoClear (parent, loc);
5234 ; /* Nothing to do for structures. */
5246 sRef_clearDerived (s);
5250 /* evans 2001-07-12: need to define the derived references */
5251 sRefSet_elements (s->deriv, el)
5253 llassert (sRef_isReasonable (el));
5254 el->defstate = SS_DEFINED;
5255 } end_sRefSet_elements ;
5258 DPRINTF (("Set defined: %s", sRef_unparseFull (s)));
5261 static void sRef_setPartialDefined (sRef s, fileloc loc)
5263 sRef_checkMutable (s);
5265 if (!sRef_isPartial (s))
5267 sRef_setDefined (s, loc);
5271 void sRef_setPartialDefinedComplete (sRef s, fileloc loc)
5273 sRef_innerAliasSetComplete (sRef_setPartialDefined, s, loc);
5276 void sRef_setDefinedComplete (sRef s, fileloc loc)
5278 sRef_innerAliasSetComplete (sRef_setDefined, s, loc);
5281 void sRef_setDefinedCompleteDirect (sRef s, fileloc loc)
5285 aliases = usymtab_allAliases (s);
5286 DPRINTF (("Set defined complete: %s", sRef_unparseFull (s)));
5287 DPRINTF (("All aliases: %s", sRefSet_unparseFull (aliases)));
5289 sRef_setDefined (s, loc);
5291 sRefSet_realElements (aliases, current)
5293 if (sRef_isReasonable (current))
5295 current = sRef_updateSref (current);
5296 sRef_setDefined (current, loc);
5298 } end_sRefSet_realElements;
5300 sRefSet_free (aliases);
5301 sRef_innerAliasSetComplete (sRef_setDefined, s, loc);
5304 void sRef_setDefined (sRef s, fileloc loc)
5306 sRef_checkMutable (s);
5307 sRef_setDefinedAux (s, loc, TRUE);
5310 static void sRef_setDefinedNoClear (sRef s, fileloc loc)
5312 sRef_checkMutable (s);
5313 DPRINTF (("Defining: %s", sRef_unparseFull (s)));
5314 sRef_setDefinedAux (s, loc, FALSE);
5315 DPRINTF (("==> %s", sRef_unparseFull (s)));
5318 void sRef_setDefinedNCComplete (sRef s, fileloc loc)
5320 sRef_checkMutable (s);
5321 DPRINTF (("Set Defined Complete: %s", sRef_unparseFull (s)));
5322 sRef_innerAliasSetComplete (sRef_setDefinedNoClear, s, loc);
5323 DPRINTF (("==> %s", sRef_unparseFull (s)));
5326 static bool sRef_isDeepUnionField (sRef s)
5328 return (sRef_deepPred (sRef_isUnionField, s));
5331 bool sRef_isUnionField (sRef s)
5333 if (sRef_isReasonable (s) && s->kind == SK_FIELD)
5336 ** defining one field of a union defines the union
5339 sRef base = s->info->field->rec;
5341 if (sRef_isReasonable (base))
5343 return (ctype_isUnion (ctype_realType (base->type)));
5350 void sRef_setPdefined (sRef s, fileloc loc)
5352 sRef_checkMutable (s);
5353 if (sRef_isReasonable (s) && !sRef_isPartial (s))
5355 sRef base = sRef_getBaseSafe (s);
5357 if (s->defstate == SS_ALLOCATED)
5362 s->definfo = stateInfo_updateLoc (s->definfo, SA_PDEFINED, loc);
5363 s->defstate = SS_PDEFINED;
5365 /* e.g., if x is allocated, *x = 3 defines x */
5367 while (sRef_isReasonable (base) && sRef_isKnown (base))
5369 if (base->defstate == SS_DEFINED)
5373 DPRINTF (("set pdefined: %s", sRef_unparseFull (base)));
5374 base->defstate = SS_PDEFINED;
5375 nb = sRef_getBaseSafe (base);
5386 static void sRef_setStateAux (sRef s, sstate ss, fileloc loc)
5388 sRef_checkMutable (s);
5390 DPRINTF (("Set state: %s => %s", sRef_unparseFull (s), sstate_unparse (ss)));
5392 if (sRef_isReasonable (s))
5394 /* if (s->defstate == SS_RELDEF) return; */
5396 if (s->defstate != ss && fileloc_isDefined (loc))
5398 s->definfo = stateInfo_updateLoc (s->definfo,
5399 stateAction_fromSState (ss), loc);
5403 sRef_clearDerived (s);
5405 if (ss == SS_ALLOCATED)
5407 sRef base = sRef_getBaseSafe (s);
5409 while (sRef_isReasonable (base) && sRef_isKnown (base))
5411 if (base->defstate == SS_DEFINED)
5415 DPRINTF (("set pdefined: %s", sRef_unparseFull (s)));
5416 base->defstate = SS_PDEFINED;
5417 nb = sRef_getBaseSafe (base);
5429 void sRef_setAllocatedComplete (sRef s, fileloc loc)
5431 sRef_innerAliasSetComplete (sRef_setAllocated, s, loc);
5434 static void sRef_setAllocatedShallow (sRef s, fileloc loc)
5436 sRef_checkMutable (s);
5438 if (sRef_isReasonable (s))
5440 if (s->defstate == SS_DEAD || s->defstate == SS_UNDEFINED)
5442 s->defstate = SS_ALLOCATED;
5443 s->definfo = stateInfo_updateLoc (s->definfo, SA_ALLOCATED, loc);
5448 void sRef_setAllocatedShallowComplete (sRef s, fileloc loc)
5450 sRef_innerAliasSetComplete (sRef_setAllocatedShallow, s, loc);
5453 void sRef_setAllocated (sRef s, fileloc loc)
5455 sRef_checkMutable (s);
5456 sRef_setStateAux (s, SS_ALLOCATED, loc);
5459 void sRef_setPartial (sRef s, fileloc loc)
5461 sRef_checkMutable (s);
5462 sRef_setStateAux (s, SS_PARTIAL, loc);
5465 void sRef_setShared (sRef s, fileloc loc)
5467 sRef_checkMutable (s);
5469 if (sRef_isReasonable (s))
5471 if (s->aliaskind != AK_SHARED && fileloc_isDefined (loc))
5473 s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, SA_SHARED, loc);
5476 s->aliaskind = AK_SHARED;
5477 /* don't! sRef_clearDerived (s); */
5481 void sRef_setLastReference (sRef s, /*@exposed@*/ sRef ref, fileloc loc)
5483 sRef_checkMutable (s);
5485 if (sRef_isReasonable (s))
5487 s->aliaskind = sRef_getAliasKind (ref);
5488 s->aliasinfo = stateInfo_updateRefLoc (s->aliasinfo, ref, stateAction_fromAlkind (s->aliaskind), loc);
5493 void sRef_setNullStateAux (/*@notnull@*/ sRef s, nstate ns, fileloc loc)
5495 sRef_checkMutable (s);
5497 sRef_resetAliasKind (s);
5499 if (fileloc_isDefined (loc))
5501 s->nullinfo = stateInfo_updateLoc (s->nullinfo, stateAction_fromNState (ns), loc);
5505 void sRef_setNotNull (sRef s, fileloc loc)
5507 if (sRef_isReasonable (s))
5509 sRef_setNullStateAux (s, NS_NOTNULL, loc);
5513 void sRef_setNullStateN (sRef s, nstate n)
5515 if (sRef_isReasonable (s))
5517 sRef_checkMutable (s);
5519 sRef_resetAliasKind (s);
5523 void sRef_setNullState (sRef s, nstate n, fileloc loc)
5525 if (sRef_isReasonable (s))
5527 sRef_setNullStateAux (s, n, loc);
5531 void sRef_setNullTerminatedStateInnerComplete (sRef s, struct s_bbufinfo b, /*@unused@*/ fileloc loc)
5533 switch (b.bufstate) {
5534 case BB_NULLTERMINATED:
5535 sRef_setNullTerminatedState (s);
5536 sRef_setLen (s, b.len);
5538 case BB_POSSIBLYNULLTERMINATED:
5539 sRef_setPossiblyNullTerminatedState(s);
5541 case BB_NOTNULLTERMINATED:
5542 sRef_setNotNullTerminatedState (s);
5546 sRef_setSize (s, b.size);
5548 /* PL: TO BE DONE : Aliases are not modified right now, have to be similar to
5549 * setNullStateInnerComplete.
5553 void sRef_setNullStateInnerComplete (sRef s, nstate n, fileloc loc)
5555 DPRINTF (("Set null state: %s", nstate_unparse (n)));
5557 sRef_setNullState (s, n, loc);
5562 sRef_innerAliasSetComplete (sRef_setPosNull, s, loc);
5565 sRef_innerAliasSetComplete (sRef_setDefNull, s, loc);
5568 sRef_innerAliasSetComplete (sRef_setNullUnknown, s, loc);
5571 sRef_innerAliasSetComplete (sRef_setNotNull, s, loc);
5574 sRef_innerAliasSetComplete (sRef_setNotNull, s, loc);
5577 sRef_innerAliasSetComplete (sRef_setNullUnknown, s, loc);
5580 sRef_innerAliasSetComplete (sRef_setDefNull, s, loc);
5583 sRef_innerAliasSetComplete (sRef_setNullUnknown, s, loc);
5586 sRef_innerAliasSetComplete (sRef_setNullErrorLoc, s, loc);
5591 void sRef_setPosNull (sRef s, fileloc loc)
5593 if (sRef_isReasonable (s))
5595 sRef_setNullStateAux (s, NS_POSNULL, loc);
5599 void sRef_setDefNull (sRef s, fileloc loc)
5601 if (sRef_isReasonable (s))
5603 sRef_setNullStateAux (s, NS_DEFNULL, loc);
5607 void sRef_setNullUnknown (sRef s, fileloc loc)
5609 if (sRef_isReasonable (s))
5611 sRef_setNullStateAux (s, NS_UNKNOWN, loc);
5615 void sRef_setNullError (sRef s)
5617 if (sRef_isReasonable (s) && !sRef_isConst (s))
5619 sRef_setNullStateAux (s, NS_UNKNOWN, fileloc_undefined);
5623 void sRef_setNullErrorLoc (sRef s, fileloc loc)
5625 if (sRef_isReasonable (s) && !sRef_isConst (s))
5627 sRef_setNullStateAux (s, NS_UNKNOWN, loc);
5631 void sRef_setOnly (sRef s, fileloc loc)
5633 if (sRef_isReasonable (s) && s->aliaskind != AK_ONLY)
5635 sRef_checkMutable (s);
5636 s->aliaskind = AK_ONLY;
5637 s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, SA_ONLY, loc);
5641 void sRef_setDependent (sRef s, fileloc loc)
5643 if (sRef_isReasonable (s) && !sRef_isConst (s) && (s->aliaskind != AK_DEPENDENT))
5645 sRef_checkMutable (s);
5646 DPRINTF (("Setting dependent: %s", sRef_unparseFull (s)));
5647 s->aliaskind = AK_DEPENDENT;
5648 s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, SA_DEPENDENT, loc);
5652 void sRef_setOwned (sRef s, fileloc loc)
5654 if (sRef_isReasonable (s) && !sRef_isConst (s) && (s->aliaskind != AK_OWNED))
5656 sRef_checkMutable (s);
5657 s->aliaskind = AK_OWNED;
5658 s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, SA_OWNED, loc);
5662 void sRef_setKept (sRef s, fileloc loc)
5664 if (sRef_isReasonable (s) && !sRef_isConst (s) && (s->aliaskind != AK_KEPT))
5666 sRef base = sRef_getBaseSafe (s);
5668 while (sRef_isReasonable (base) && sRef_isKnown (base))
5670 if (base->defstate == SS_DEFINED)
5672 sRef_checkMutable (base);
5673 base->defstate = SS_PDEFINED;
5674 base = sRef_getBaseSafe (base);
5682 sRef_checkMutable (s);
5683 s->aliaskind = AK_KEPT;
5684 s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, SA_KEPT, loc);
5688 static void sRef_setKeptAux (sRef s, fileloc loc)
5690 if (!sRef_isShared (s))
5692 sRef_setKept (s, loc);
5696 static void sRef_setDependentAux (sRef s, fileloc loc)
5698 if (!sRef_isShared (s))
5700 sRef_setDependent (s, loc);
5704 void sRef_setKeptComplete (sRef s, fileloc loc)
5706 sRef_aliasSetComplete (sRef_setKeptAux, s, loc);
5709 void sRef_setDependentComplete (sRef s, fileloc loc)
5711 sRef_aliasSetComplete (sRef_setDependentAux, s, loc);
5714 void sRef_setFresh (sRef s, fileloc loc)
5716 if (sRef_isReasonable (s) && !sRef_isConst (s))
5718 sRef_checkMutable (s);
5719 s->aliaskind = AK_FRESH;
5720 s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, SA_CREATED, loc);
5721 DPRINTF (("SetFresh: %s", sRef_unparseFull (s)));
5725 void sRef_kill (sRef s, fileloc loc)
5727 DPRINTF (("Kill: %s", sRef_unparseFull (s)));
5729 if (sRef_isReasonable (s) && !sRef_isShared (s) && !sRef_isConst (s))
5731 sRef base = sRef_getBaseSafe (s);
5732 sRef_checkMutable (s);
5734 while (sRef_isReasonable (base) && sRef_isKnown (base))
5736 if (base->defstate == SS_DEFINED)
5738 sRef_checkMutable (base);
5739 base->defstate = SS_PDEFINED;
5740 base = sRef_getBaseSafe (base);
5748 s->aliaskind = s->oaliaskind;
5749 s->defstate = SS_DEAD;
5750 s->definfo = stateInfo_updateLoc (s->definfo, SA_KILLED, loc);
5751 DPRINTF (("State info: %s", stateInfo_unparse (s->definfo)));
5752 sRef_clearDerived (s);
5756 void sRef_maybeKill (sRef s, fileloc loc)
5758 if (sRef_isReasonable (s))
5760 sRef base = sRef_getBaseSafe (s);
5761 sRef_checkMutable (s);
5763 while (sRef_isReasonable (base) && sRef_isKnown (base))
5765 if (base->defstate == SS_DEFINED || base->defstate == SS_RELDEF)
5767 sRef_checkMutable (base);
5768 base->defstate = SS_PDEFINED;
5769 base = sRef_getBaseSafe (base);
5778 s->aliaskind = s->oaliaskind;
5779 s->defstate = SS_HOFFA;
5780 s->definfo = stateInfo_updateLoc (s->definfo, SA_PKILLED, loc);
5781 DPRINTF (("State info: %s / %s", sRef_unparse (s),
5782 stateInfo_unparse (s->definfo)));
5783 sRef_clearDerived (s);
5789 ** just for type checking...
5792 static void sRef_killAux (sRef s, fileloc loc)
5794 if (sRef_isReasonable (s) && !sRef_isShared (s))
5796 if (sRef_isUnknownArrayFetch (s))
5798 sRef_maybeKill (s, loc);
5808 ** kills s and all aliases to s
5811 void sRef_killComplete (sRef s, fileloc loc)
5813 DPRINTF (("Kill complete: %s", sRef_unparseFull (s)));
5814 sRef_aliasSetComplete (sRef_killAux, s, loc);
5817 static bool sRef_equivalent (sRef s1, sRef s2)
5819 return (sRef_compare (s1, s2) == 0);
5823 ** returns an sRef that will not be free'd on function exit.
5826 /*@only@*/ sRef sRef_saveCopy (sRef s)
5830 if (sRef_isReasonable (s))
5832 bool old = inFunction;
5835 ** Exit the function scope, so this sRef is not
5836 ** stored in the deallocation table.
5840 DPRINTF (("Copying sref: %s", sRef_unparseFull(s)));
5841 ret = sRef_copy (s);
5842 DPRINTF (("Copying ===>: %s", sRef_unparseFull(ret)));
5847 ret = sRef_undefined;
5850 /*@-dependenttrans@*/
5852 /*@=dependenttrans@*/
5855 sRef sRef_copy (sRef s)
5857 if (sRef_isKindSpecial (s) && !sRef_isGlobalMarker (s))
5860 return s; /* don't copy specials (except for global markers) */
5864 if (sRef_isReasonable (s))
5866 sRef t = sRef_alloc ();
5868 DPRINTF (("Copying: [%p] %s", s, sRef_unparse (s)));
5869 DPRINTF (("Full: %s", sRef_unparseFull (s)));
5873 t->modified = s->modified;
5874 t->immut = FALSE; /* Note mutability is not copied. */
5876 t->val = multiVal_copy (s->val);
5878 t->info = sinfo_copy (s);
5879 t->defstate = s->defstate;
5880 t->nullstate = s->nullstate;
5882 /* start modifications */
5883 t->bufinfo.bufstate = s->bufinfo.bufstate;
5884 t->bufinfo.len = s->bufinfo.len;
5885 t->bufinfo.size = s->bufinfo.size;
5886 /* end modifications */
5888 t->aliaskind = s->aliaskind;
5889 t->oaliaskind = s->oaliaskind;
5891 t->expkind = s->expkind;
5892 t->oexpkind = s->oexpkind;
5894 t->nullinfo = stateInfo_copy (s->nullinfo);
5895 t->aliasinfo = stateInfo_copy (s->aliasinfo);
5896 t->definfo = stateInfo_copy (s->definfo);
5897 t->expinfo = stateInfo_copy (s->expinfo);
5899 t->deriv = sRefSet_newDeepCopy (s->deriv);
5900 t->state = valueTable_copy (s->state);
5902 DPRINTF (("Made copy: %s => %s", sRef_unparseFull (s), sRef_unparseFull (t)));
5907 return sRef_undefined;
5912 # define PREDTEST(func,s) \
5913 do { if (sRef_isInvalid (s)) { return FALSE; } \
5914 else { if (sRef_isConj (s)) \
5915 { return (func (sRef_getConjA (s)) \
5916 || func (sRef_getConjB (s))); }}} while (FALSE);
5918 bool sRef_isAddress (sRef s)
5920 PREDTEST (sRef_isAddress, s);
5921 return (s->kind == SK_ADR);
5925 ** pretty weak... maybe a flag should control this.
5928 bool sRef_isThroughArrayFetch (sRef s)
5930 if (sRef_isReasonable (s))
5938 if (sRef_isArrayFetch (tref))
5943 lt = sRef_getBase (tref);
5945 } while (sRef_isReasonable (tref));
5951 bool sRef_isArrayFetch (sRef s)
5953 PREDTEST (sRef_isArrayFetch, s);
5954 return (s->kind == SK_ARRAYFETCH);
5957 bool sRef_isMacroParamRef (sRef s)
5959 if (context_inMacro () && sRef_isCvar (s))
5961 uentry ue = sRef_getUentry (s);
5962 cstring pname = makeParam (uentry_rawName (ue));
5963 uentry mac = usymtab_lookupSafe (pname);
5965 cstring_free (pname);
5966 return (uentry_isValid (mac));
5972 bool sRef_isCvar (sRef s)
5974 PREDTEST (sRef_isCvar, s);
5975 return (s->kind == SK_CVAR);
5978 bool sRef_isConst (sRef s)
5980 PREDTEST (sRef_isConst, s);
5981 return (s->kind == SK_CONST);
5984 bool sRef_isObject (sRef s)
5986 PREDTEST (sRef_isObject, s);
5987 return (s->kind == SK_OBJECT);
5990 bool sRef_isExternal (sRef s)
5992 PREDTEST (sRef_isExternal, s);
5993 return (s->kind == SK_EXTERNAL);
5996 static bool sRef_isDerived (sRef s)
5998 PREDTEST (sRef_isDerived, s);
5999 return (s->kind == SK_DERIVED);
6002 bool sRef_isField (sRef s)
6004 PREDTEST (sRef_isField, s);
6005 return (s->kind == SK_FIELD);
6008 static bool sRef_isIndex (sRef s)
6010 PREDTEST (sRef_isIndex, s);
6011 return (s->kind == SK_ARRAYFETCH);
6014 bool sRef_isAnyParam (sRef s)
6016 PREDTEST (sRef_isAnyParam, s);
6017 return (s->kind == SK_PARAM);
6020 bool sRef_isParam (sRef s)
6022 PREDTEST (sRef_isParam, s);
6023 return (s->kind == SK_PARAM);
6026 bool sRef_isDirectParam (sRef s)
6028 PREDTEST (sRef_isDirectParam, s);
6030 return ((s->kind == SK_CVAR) &&
6031 (s->info->cvar->lexlevel == functionScope) &&
6032 (context_inFunction () &&
6033 (s->info->cvar->index <= usymId_fromInt (uentryList_size (context_getParams ())))));
6036 bool sRef_isPointer (sRef s)
6038 PREDTEST (sRef_isPointer, s);
6039 return (s->kind == SK_PTR);
6043 ** returns true if storage referenced by s is visible
6046 bool sRef_isReference (sRef s)
6048 PREDTEST (sRef_isReference, s);
6050 return (sRef_isPointer (s) || sRef_isIndex (s) || sRef_isFileOrGlobalScope (s)
6051 || (sRef_isField (s) && (sRef_isReference (s->info->field->rec))));
6054 bool sRef_isIReference (sRef s)
6056 return (sRef_isPointer (s) || sRef_isAddress (s) || sRef_isIndex (s)
6057 || sRef_isField (s) || sRef_isArrayFetch (s));
6060 bool sRef_isFileOrGlobalScope (sRef s)
6062 return (sRef_isCvar (s) && (s->info->cvar->lexlevel <= fileScope));
6065 bool sRef_isRealGlobal (sRef s)
6067 return (sRef_isCvar (s) && (s->info->cvar->lexlevel == globScope));
6070 bool sRef_isFileStatic (sRef s)
6072 return (sRef_isCvar (s) && (s->info->cvar->lexlevel == fileScope));
6075 bool sRef_isAliasCheckedGlobal (sRef s)
6077 if (sRef_isFileOrGlobalScope (s))
6079 uentry ue = sRef_getUentry (s);
6081 return context_checkAliasGlob (ue);
6089 void sRef_free (/*@only@*/ sRef s)
6091 if (s != sRef_undefined && s->kind != SK_SPECIAL)
6093 DPRINTF (("Free sref: [%p]", s));
6095 sRef_checkValid (s);
6097 multiVal_free (s->val); /* evans 2002-07-12 */
6099 stateInfo_free (s->expinfo);
6100 stateInfo_free (s->aliasinfo);
6101 stateInfo_free (s->definfo);
6102 stateInfo_free (s->nullinfo);
6104 sRefSet_free (s->deriv);
6105 s->deriv = sRefSet_undefined;
6107 valueTable_free (s->state);
6111 /* drl added to help locate use after release*/
6112 s->expinfo = stateInfo_undefined;
6113 s->aliasinfo = stateInfo_undefined;
6114 s->definfo = stateInfo_undefined;
6115 s->nullinfo = stateInfo_undefined;
6121 void sRef_setType (sRef s, ctype t)
6123 if (sRef_isReasonable (s))
6125 sRef_checkMutable (s);
6130 void sRef_setTypeFull (sRef s, ctype t)
6132 if (sRef_isReasonable (s))
6134 sRef_checkMutable (s);
6137 sRefSet_allElements (s->deriv, current)
6139 sRef_setTypeFull (current, ctype_unknown);
6140 } end_sRefSet_allElements ;
6145 sRef_buildField (/*@exposed@*/ sRef rec, /*@dependent@*/ cstring f)
6147 return (sRef_buildNCField (rec, f));
6150 static /*@exposed@*/ sRef
6151 sRef_findDerivedField (/*@notnull@*/ sRef rec, cstring f)
6153 sRefSet_allElements (sRef_derivedFields (rec), sr)
6155 if (sRef_isReasonable (sr))
6157 if (sRef_isReasonable (sr))
6159 if (sr->info != NULL)
6161 if (sr->kind == SK_FIELD && cstring_equal (sr->info->field->field, f))
6169 llcontbug (message ("Invalid sRef as derived field of %s", sRef_unparse (rec)));
6172 } end_sRefSet_allElements;
6174 return sRef_undefined;
6177 /*@dependent@*/ /*@observer@*/ sRefSet sRef_derivedFields (/*@temp@*/ sRef rec)
6179 if (sRef_isReasonable (rec))
6187 return (sRefSet_undefined);
6191 static /*@exposed@*/ sRef
6192 sRef_findDerivedPointer (sRef s)
6194 if (sRef_isReasonable (s))
6196 sRefSet_realElements (s->deriv, sr)
6198 if (sRef_isReasonable (sr) && sr->kind == SK_PTR)
6202 } end_sRefSet_realElements;
6205 return sRef_undefined;
6209 sRef_isUnknownArrayFetch (sRef s)
6211 return (sRef_isReasonable (s)
6212 && s->kind == SK_ARRAYFETCH
6213 && !s->info->arrayfetch->indknown);
6216 static /*@exposed@*/ sRef
6217 sRef_findDerivedArrayFetch (/*@notnull@*/ sRef s, bool isknown, int idx, bool dead)
6222 sRefSet_realElements (s->deriv, sr)
6224 if (sRef_isReasonable (sr)
6225 && sr->kind == SK_ARRAYFETCH
6226 && sr->info->arrayfetch->indknown
6227 && (sr->info->arrayfetch->ind == idx))
6231 } end_sRefSet_realElements;
6235 sRefSet_realElements (s->deriv, sr)
6237 if (sRef_isReasonable (sr)
6238 && sr->kind == SK_ARRAYFETCH
6239 && (!sr->info->arrayfetch->indknown
6240 || (sr->info->arrayfetch->indknown &&
6241 sr->info->arrayfetch->ind == 0)))
6243 if (sRef_isDead (sr) || sRef_isKept (sr))
6245 if (dead || context_getFlag (FLG_STRICTUSERELEASED))
6255 } end_sRefSet_realElements;
6258 return sRef_undefined;
6261 static /*@exposed@*/ sRef
6262 sRef_buildNCField (/*@exposed@*/ sRef rec, /*@exposed@*/ cstring f)
6266 DPRINTF (("Build nc field: %s / %s",
6267 sRef_unparseFull (rec), f));
6269 if (sRef_isInvalid (rec))
6271 return sRef_undefined;
6275 ** check if the field already has been referenced
6278 s = sRef_findDerivedField (rec, f);
6280 if (sRef_isReasonable (s))
6286 ctype ct = ctype_realType (rec->type);
6288 DPRINTF (("Field of: %s", sRef_unparse (rec)));
6292 s->info = (sinfo) dmalloc (sizeof (*s->info));
6293 s->info->field = (fldinfo) dmalloc (sizeof (*s->info->field));
6294 s->info->field->rec = rec;
6295 s->info->field->field = f; /* doesn't copy f */
6297 if (ctype_isKnown (ct) && ctype_isSU (ct))
6299 uentry ue = uentryList_lookupField (ctype_getFields (ct), f);
6301 if (!uentry_isUndefined (ue))
6303 DPRINTF (("lookup: %s for %s", uentry_unparseFull (ue),
6304 ctype_unparse (ct)));
6306 s->type = uentry_getType (ue);
6308 if (ctype_isMutable (s->type)
6309 && rec->aliaskind != AK_STACK
6310 && !alkind_isStatic (rec->aliaskind))
6312 s->aliaskind = rec->aliaskind;
6316 s->aliaskind = AK_UNKNOWN;
6319 if (sRef_isStateDefined (rec) || sRef_isStateUnknown (rec)
6320 || sRef_isPdefined (rec))
6322 sRef_setStateFromUentry (s, ue);
6326 sRef_setPartsFromUentry (s, ue);
6329 s->oaliaskind = s->aliaskind;
6330 s->oexpkind = s->expkind;
6332 DPRINTF (("sref: %s", sRef_unparseFull (s)));
6337 Never report this as an error. It can happen whenever there
6338 is casting involved.
6342 llcontbug (message ("buildNCField --- no field %s: %q / %s",
6343 f, sRef_unparse (s), ctype_unparse (ct)));
6347 return sRef_undefined;
6351 if (rec->defstate == SS_DEFINED
6352 && (s->defstate == SS_UNDEFINED || s->defstate == SS_UNKNOWN))
6354 s->defstate = SS_DEFINED;
6356 else if (rec->defstate == SS_PARTIAL)
6358 s->defstate = SS_PARTIAL;
6360 else if (rec->defstate == SS_ALLOCATED)
6362 if (ctype_isStackAllocated (ct) && ctype_isStackAllocated (s->type))
6364 s->defstate = SS_ALLOCATED;
6368 s->defstate = SS_UNDEFINED;
6371 else if (s->defstate == SS_UNKNOWN)
6373 s->defstate = rec->defstate;
6380 if (s->defstate == SS_UNDEFINED)
6382 ctype rt = ctype_realType (s->type);
6384 if (ctype_isArray (rt) || ctype_isSU (rt))
6386 s->defstate = SS_ALLOCATED;
6390 sRef_addDeriv (rec, s);
6391 DPRINTF (("Add deriv: %s", sRef_unparseFull (rec)));
6393 if (ctype_isInt (s->type) && cstring_equal (f, REFSNAME))
6395 s->aliaskind = AK_REFS;
6396 s->oaliaskind = AK_REFS;
6399 DPRINTF (("Build field ==> %s", sRef_unparseFull (s)));
6405 sRef_isStackAllocated (sRef s)
6407 return (sRef_isReasonable(s)
6408 && s->defstate == SS_ALLOCATED && ctype_isStackAllocated (s->type));
6412 void sRef_setArrayFetchState (/*@notnull@*/ /*@exposed@*/ sRef s,
6413 /*@notnull@*/ /*@exposed@*/ sRef arr)
6415 sRef_checkMutable (s);
6417 if (ctype_isRealAP (arr->type))
6419 s->type = ctype_baseArrayPtr (arr->type);
6422 /* a hack, methinks... makeArrayFetch (&a[0]) ==> a[] */
6423 /* evans - 2001-08-27: not sure where this was necessary - it
6424 ** causes an assertion in in aliasCheckPred to fail.
6427 if (sRef_isAddress (arr))
6429 sRef t = arr->info->ref;
6431 if (sRef_isArrayFetch (t))
6433 s->info->arrayfetch->arr = t->info->arrayfetch->arr;
6436 else if (ctype_isRealPointer (arr->type))
6438 sRef sp = sRef_findDerivedPointer (arr);
6440 if (sRef_isReasonable (sp))
6443 if (ctype_isMutable (s->type))
6445 s->expkind = sRef_getExKind (sp);
6446 s->expinfo = stateInfo_copy (sp->expinfo);
6448 s->aliaskind = sp->aliaskind;
6449 s->aliasinfo = stateInfo_copy (sp->aliasinfo);
6452 s->defstate = sp->defstate;
6454 if (s->defstate == SS_DEFINED)
6456 if (!context_getFlag (FLG_STRICTDESTROY))
6458 s->defstate = SS_PARTIAL;
6462 DPRINTF (("Set null state: %s / %s", sRef_unparseFull (s), sRef_unparseFull (sp)));
6463 sRef_setNullStateN (s, sRef_getNullState (sp));
6467 if (arr->defstate == SS_UNDEFINED)
6469 s->defstate = SS_UNUSEABLE;
6471 else if ((arr->defstate == SS_ALLOCATED) && !ctype_isSU (s->type))
6473 s->defstate = SS_UNDEFINED;
6477 if (!context_getFlag (FLG_STRICTDESTROY))
6479 s->defstate = SS_PARTIAL;
6483 s->defstate = SS_DEFINED;
6487 ** Very weak checking for array elements.
6489 ** s->defstate = arr->defstate;
6493 s->expkind = sRef_getExKind (arr);
6494 s->expinfo = stateInfo_copy (arr->expinfo);
6496 if (arr->aliaskind == AK_LOCAL || arr->aliaskind == AK_FRESH)
6498 s->aliaskind = AK_LOCAL;
6502 s->aliaskind = AK_UNKNOWN;
6505 sRef_setTypeState (s);
6510 if (arr->defstate == SS_DEFINED)
6513 ** Very weak checking for array elements.
6515 ** s->defstate = arr->defstate;
6518 if (context_getFlag (FLG_STRICTDESTROY))
6520 s->defstate = SS_DEFINED;
6524 s->defstate = SS_PARTIAL;
6527 else if (arr->defstate == SS_ALLOCATED)
6529 if (ctype_isRealArray (s->type))
6531 s->defstate = SS_ALLOCATED;
6535 if (!s->info->arrayfetch->indknown)
6538 ** is index is unknown, elements is defined or
6539 ** allocated is any element is!
6542 s->defstate = SS_UNDEFINED;
6544 sRefSet_allElements (arr->deriv, sr)
6546 if (sRef_isReasonable (sr))
6548 if (sRef_isReasonable (sr))
6550 if (sr->defstate == SS_ALLOCATED)
6552 s->defstate = SS_ALLOCATED;
6556 if (sr->defstate == SS_DEFINED)
6558 if (context_getFlag (FLG_STRICTDESTROY))
6560 s->defstate = SS_DEFINED;
6564 s->defstate = SS_PARTIAL;
6573 llcontbug (message ("Invalid sRef as derived element of %s", sRef_unparse (arr)));
6576 } end_sRefSet_allElements;
6580 s->defstate = SS_UNDEFINED;
6586 s->defstate = arr->defstate;
6591 ** kludgey way to guess where aliaskind applies
6594 if (ctype_isMutable (s->type)
6595 && !ctype_isPointer (arr->type)
6596 && !alkind_isStatic (arr->aliaskind)
6597 && !alkind_isStack (arr->aliaskind)) /* evs - 2000-06-20: don't pass stack allocation to members */
6599 s->aliaskind = arr->aliaskind;
6603 s->aliaskind = AK_UNKNOWN;
6606 sRef_setTypeState (s);
6609 if (sRef_isObserver (arr))
6611 s->expkind = XO_OBSERVER;
6612 s->expinfo = stateInfo_copy (arr->expinfo);
6616 /*@exposed@*/ sRef sRef_buildArrayFetch (/*@exposed@*/ sRef arr)
6620 if (!sRef_isReasonable (arr)) {
6621 /*@-nullret@*/ return arr /*@=nullret@*/;
6624 if (ctype_isRealPointer (arr->type))
6626 (void) sRef_buildPointer (arr); /* do this to define arr! */
6629 s = sRef_findDerivedArrayFetch (arr, FALSE, 0, FALSE);
6631 if (sRef_isReasonable (s))
6633 /* evans 2001-07-12: this is bogus, clean-up hack */
6634 if (s->info->arrayfetch->arr != arr)
6637 check (sRefSet_delete (arr->deriv, s));
6638 res = sRef_buildArrayFetch (arr);
6639 sRef_copyState (res, s);
6640 llassert (res->info->arrayfetch->arr == arr);
6644 s->expkind = sRef_getExKind (arr);
6645 s->expinfo = stateInfo_copy (arr->expinfo);
6653 s->kind = SK_ARRAYFETCH;
6654 s->info = (sinfo) dmalloc (sizeof (*s->info));
6655 s->info->arrayfetch = (ainfo) dmalloc (sizeof (*s->info->arrayfetch));
6656 s->info->arrayfetch->indknown = FALSE;
6657 s->info->arrayfetch->ind = 0;
6658 s->info->arrayfetch->arr = arr;
6660 sRef_setArrayFetchState (s, arr);
6662 s->oaliaskind = s->aliaskind;
6663 s->oexpkind = s->expkind;
6665 if (!context_inProtectVars ())
6667 sRef_addDeriv (arr, s);
6670 if (valueTable_isUndefined (s->state))
6672 s->state = context_createValueTable
6673 (s, stateInfo_makeLoc (g_currentloc, SA_CREATED));
6681 sRef_buildArrayFetchKnown (/*@exposed@*/ sRef arr, int i)
6685 if (!sRef_isReasonable (arr)) {
6686 /*@-nullret@*/ return arr /*@=nullret@*/;
6689 if (ctype_isRealPointer (arr->type))
6691 (void) sRef_buildPointer (arr); /* do this to define arr! */
6694 s = sRef_findDerivedArrayFetch (arr, TRUE, i, FALSE);
6696 if (sRef_isReasonable (s))
6698 /* evans 2001-07-12: this is bogus, clean-up hack */
6699 if (s->info->arrayfetch->arr != arr)
6703 check (sRefSet_delete (arr->deriv, s));
6704 res = sRef_buildArrayFetchKnown (arr, i);
6706 llassert (res->info->arrayfetch->arr == arr);
6707 sRef_copyState (res, s);
6708 llassert (res->info->arrayfetch->arr == arr);
6712 s->expkind = sRef_getExKind (arr);
6713 s->expinfo = stateInfo_copy (arr->expinfo);
6715 llassert (s->info->arrayfetch->arr == arr);
6722 s->kind = SK_ARRAYFETCH;
6723 s->info = (sinfo) dmalloc (sizeof (*s->info));
6724 s->info->arrayfetch = (ainfo) dmalloc (sizeof (*s->info->arrayfetch));
6725 s->info->arrayfetch->arr = arr;
6726 s->info->arrayfetch->indknown = TRUE;
6727 s->info->arrayfetch->ind = i;
6729 sRef_setArrayFetchState (s, arr);
6730 /* evans 2001-08-27 no: can change this - llassert (s->info->arrayfetch->arr == arr); */
6732 s->oaliaskind = s->aliaskind;
6733 s->oexpkind = s->expkind;
6734 sRef_addDeriv (arr, s);
6736 llassert (valueTable_isUndefined (s->state));
6737 s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_CREATED));
6743 ** sets everything except for defstate
6747 sRef_setPartsFromUentry (sRef s, uentry ue)
6749 sRef uref = uentry_getSref (ue);
6751 llassert (sRef_isReasonable (s));
6753 s->aliaskind = alkind_derive (s->aliaskind, uentry_getAliasKind (ue));
6754 s->oaliaskind = s->aliaskind;
6756 if (s->expkind == XO_UNKNOWN)
6758 s->expkind = uentry_getExpKind (ue);
6761 s->oexpkind = s->expkind;
6763 if (sRef_getNullState (s) == NS_UNKNOWN)
6765 DPRINTF (("Set null state: %s / %s", sRef_unparseFull (s), uentry_unparseFull (ue)));
6766 sRef_setNullStateN (s, sRef_getNullState (uentry_getSref (ue)));
6770 DPRINTF (("Skipping null null state!"));
6773 if (s->aliaskind == AK_IMPONLY && (sRef_isExposed (s) || sRef_isObserver (s)))
6775 s->oaliaskind = s->aliaskind = AK_IMPDEPENDENT;
6778 if (sRef_isReasonable (uref))
6780 valueTable utable = uref->state;
6781 valueTable_free (s->state);
6782 s->state = valueTable_copy (utable);
6787 sRef_setStateFromAbstractUentry (sRef s, uentry ue)
6789 llassert (sRef_isReasonable (s));
6790 sRef_checkMutable (s);
6792 sRef_setPartsFromUentry (s, ue);
6794 s->aliaskind = alkind_derive (s->aliaskind, uentry_getAliasKind (ue));
6795 s->oaliaskind = s->aliaskind;
6797 if (s->expkind == XO_UNKNOWN)
6799 s->expkind = uentry_getExpKind (ue);
6802 s->oexpkind = s->expkind;
6806 sRef_setStateFromUentry (sRef s, uentry ue)
6810 sRef_checkMutable (s);
6811 llassert (sRef_isReasonable (s));
6813 sRef_setPartsFromUentry (s, ue);
6815 defstate = uentry_getDefState (ue);
6817 if (sstate_isKnown (defstate))
6819 s->defstate = defstate;
6828 sRef_buildPointer (/*@exposed@*/ sRef t)
6830 DPRINTF (("build pointer: %s", sRef_unparse (t)));
6832 if (sRef_isInvalid (t)) return sRef_undefined;
6834 if (sRef_isAddress (t))
6836 DPRINTF (("Return ref: %s", sRef_unparse (t->info->ref)));
6837 return (t->info->ref);
6841 sRef s = sRef_findDerivedPointer (t);
6843 DPRINTF (("find derived: %s", sRef_unparse (s)));
6845 if (sRef_isReasonable (s))
6847 s->expkind = sRef_getExKind (t);
6848 s->expinfo = stateInfo_copy (t->expinfo);
6850 s->oaliaskind = s->aliaskind;
6851 s->oexpkind = s->expkind;
6857 s = sRef_constructPointerAux (t);
6859 DPRINTF (("construct: %s", sRef_unparse (s)));
6861 if (sRef_isReasonable (s))
6863 sRef_addDeriv (t, s);
6865 s->oaliaskind = s->aliaskind;
6866 s->oexpkind = s->expkind;
6875 sRef_constructPointer (/*@exposed@*/ sRef t)
6878 return sRef_buildPointer (t);
6881 static /*@exposed@*/ sRef sRef_constructDerefAux (sRef t, bool isdead)
6883 if (sRef_isReasonable (t))
6888 ** if there is a derived t[?], return that. Otherwise, *t.
6891 s = sRef_findDerivedArrayFetch (t, FALSE, 0, isdead);
6893 if (sRef_isReasonable (s))
6895 DPRINTF (("Found array fetch: %s", sRef_unparseFull (s)));
6900 sRef ret = sRef_constructPointer (t);
6902 DPRINTF (("Constructed pointer: %s", sRef_unparseFull (ret)));
6909 return sRef_undefined;
6913 sRef sRef_constructDeref (sRef t)
6915 return sRef_constructDerefAux (t, FALSE);
6918 sRef sRef_constructDeadDeref (sRef t)
6920 return sRef_constructDerefAux (t, TRUE);
6924 sRef_constructPointerAux (/*@notnull@*/ /*@exposed@*/ sRef t)
6926 sRef s = sRef_newRef ();
6930 llassert (valueTable_isUndefined (s->state));
6933 s->info = (sinfo) dmalloc (sizeof (*s->info));
6936 if (ctype_isRealAP (rt))
6938 s->type = ctype_baseArrayPtr (rt);
6941 st = ctype_realType (s->type);
6943 if (t->defstate == SS_UNDEFINED)
6945 s->defstate = SS_UNUSEABLE;
6946 s->definfo = stateInfo_copy (t->definfo);
6948 else if ((t->defstate == SS_ALLOCATED) && !ctype_isSU (st))
6950 s->defstate = SS_UNDEFINED;
6951 s->definfo = stateInfo_copy (t->definfo);
6955 s->defstate = t->defstate;
6956 s->definfo = stateInfo_copy (t->definfo);
6959 if (t->aliaskind == AK_LOCAL || t->aliaskind == AK_FRESH)
6961 s->aliaskind = AK_LOCAL;
6965 s->aliaskind = AK_UNKNOWN;
6968 s->expkind = sRef_getExKind (t);
6969 s->expinfo = stateInfo_copy (t->expinfo);
6971 sRef_setTypeState (s);
6973 s->oaliaskind = s->aliaskind;
6974 s->oexpkind = s->expkind;
6976 if (valueTable_isUndefined (s->state))
6978 s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_CREATED));
6981 DPRINTF (("pointer: %s", sRef_unparseFull (s)));
6985 bool sRef_hasDerived (sRef s)
6987 return (sRef_isReasonable (s) && !sRefSet_isEmpty (s->deriv));
6991 sRef_clearDerived (sRef s)
6993 if (sRef_isReasonable (s))
6995 DPRINTF (("Clear derived: [%p] %s", s, sRef_unparseDebug (s)));
6996 sRefSet_clear (s->deriv);
7001 sRef_clearDerivedComplete (sRef s)
7003 if (sRef_isReasonable (s))
7005 sRef base = sRef_getBaseSafe (s);
7007 while (sRef_isReasonable (base))
7009 DPRINTF (("Clear derived: [%p] %s", base, sRef_unparse (base)));
7010 sRefSet_clear (base->deriv);
7011 base = sRef_getBaseSafe (base);
7014 DPRINTF (("Clear derived: [%p] %s", s, sRef_unparse (s)));
7015 sRefSet_clear (s->deriv);
7019 /*@exposed@*/ sRef sRef_makePointer (/*@exposed@*/ sRef s)
7022 sRef res = sRef_buildPointer (s);
7024 DPRINTF (("Res: %s", sRef_unparseFull (res)));
7029 ** &a[] => a (this is for out params)
7033 sRef_makeAnyArrayFetch (/*@exposed@*/ sRef arr)
7035 if (sRef_isAddress (arr))
7037 return (arr->info->ref);
7041 return (sRef_buildArrayFetch (arr));
7046 sRef_makeArrayFetch (/*@exposed@*/ sRef arr)
7048 return (sRef_buildArrayFetch (arr));
7052 sRef_makeArrayFetchKnown (/*@exposed@*/ sRef arr, int i)
7054 return (sRef_buildArrayFetchKnown (arr, i));
7058 sRef_makeField (sRef rec, /*@dependent@*/ cstring f)
7061 ret = sRef_buildField (rec, f);
7066 sRef_makeNCField (/*@exposed@*/ sRef rec, /*@dependent@*/ cstring f)
7068 return (sRef_buildNCField (rec, f));
7072 sRef_unparseKindName (sRef s)
7076 if (s == sRef_undefined) return cstring_makeLiteral ("<invalid>");
7078 s = sRef_fixConj (s);
7083 if (sRef_isLocalVar (s))
7085 result = cstring_makeLiteral ("Variable");
7089 result = cstring_makeLiteral ("Undef global");
7093 result = cstring_makeLiteral ("Out parameter");
7096 if (sRef_isAnyParam (s->info->arrayfetch->arr))
7098 result = cstring_makeLiteral ("Out parameter");
7100 else if (sRef_isIndexKnown (s))
7102 result = cstring_makeLiteral ("Array element");
7106 result = cstring_makeLiteral ("Value");
7110 if (sRef_isAnyParam (s->info->ref))
7112 result = cstring_makeLiteral ("Out parameter");
7116 result = cstring_makeLiteral ("Value");
7120 result = cstring_makeLiteral ("Value");
7123 result = cstring_makeLiteral ("Field");
7126 result = cstring_makeLiteral ("Object");
7128 case SK_UNCONSTRAINED:
7129 result = cstring_makeLiteral ("<anything>");
7138 result = cstring_makeLiteral ("<unknown>");
7141 result = cstring_makeLiteral ("<conj>");
7144 result = cstring_makeLiteral ("Storage");
7152 sRef_unparseKindNamePlain (sRef s)
7156 if (s == sRef_undefined) return cstring_makeLiteral ("<invalid>");
7158 s = sRef_fixConj (s);
7163 if (sRef_isLocalVar (s))
7165 result = cstring_makeLiteral ("Variable");
7169 result = cstring_makeLiteral ("Global");
7173 result = cstring_makeLiteral ("Parameter");
7176 if (sRef_isAnyParam (s->info->arrayfetch->arr))
7178 result = cstring_makeLiteral ("Parameter");
7180 else if (sRef_isIndexKnown (s))
7182 result = cstring_makeLiteral ("Array element");
7186 result = cstring_makeLiteral ("Value");
7190 if (sRef_isAnyParam (s->info->ref))
7192 result = cstring_makeLiteral ("Parameter");
7196 result = cstring_makeLiteral ("Value");
7200 result = cstring_makeLiteral ("Value");
7203 result = cstring_makeLiteral ("Field");
7206 result = cstring_makeLiteral ("Object");
7209 result = cstring_makeLiteral ("Storage");
7211 case SK_UNCONSTRAINED:
7212 result = cstring_makeLiteral ("<anything>");
7221 result = cstring_makeLiteral ("<unknown>");
7224 result = cstring_makeLiteral ("<conj>");
7236 sRef_copyState (sRef s1, sRef s2)
7238 if (sRef_isReasonable (s1) && sRef_isReasonable (s2))
7240 s1->defstate = s2->defstate;
7242 /* start modifications */
7243 s1->bufinfo.bufstate = s2->bufinfo.bufstate;
7244 s1->bufinfo.len = s2->bufinfo.len;
7245 s1->bufinfo.size = s2->bufinfo.size;
7246 /* end modifications */
7248 s1->aliaskind = s2->aliaskind;
7249 s1->aliasinfo = stateInfo_update (s1->aliasinfo, s2->aliasinfo);
7251 s1->expkind = s2->expkind;
7252 s1->expinfo = stateInfo_update (s1->expinfo, s2->expinfo);
7254 s1->nullstate = s2->nullstate;
7255 s1->nullinfo = stateInfo_update (s1->nullinfo, s2->nullinfo);
7257 valueTable_free (s1->state);
7258 s1->state = valueTable_copy (s2->state);
7259 s1->safe = s2->safe;
7264 sRef_makeNew (ctype ct, sRef t, cstring name)
7266 sRef s = sRef_newRef ();
7271 llassert (sRef_isReasonable (t));
7272 s->defstate = t->defstate;
7274 s->aliaskind = t->aliaskind;
7275 s->oaliaskind = s->aliaskind;
7276 s->nullstate = t->nullstate;
7278 s->expkind = t->expkind;
7279 s->oexpkind = s->expkind;
7281 s->info = (sinfo) dmalloc (sizeof (*s->info));
7282 s->info->fname = name;
7284 /* start modifications */
7285 s->bufinfo.bufstate = t->bufinfo.bufstate;
7286 /* end modifications */
7288 llassert (valueTable_isUndefined (s->state));
7289 s->state = valueTable_copy (t->state);
7291 DPRINTF (("==> Copying state: %s", valueTable_unparse (s->state)));
7292 DPRINTF (("==> new: %s", sRef_unparseFull (s)));
7297 sRef_makeType (ctype ct)
7299 sRef s = sRef_newRef ();
7301 sRef_checkMutable (s);
7306 s->defstate = SS_UNKNOWN;
7307 s->aliaskind = AK_UNKNOWN;
7308 sRef_setNullStateN (s, NS_UNKNOWN);
7310 /* start modification */
7311 s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
7312 /* end modification */
7315 if (ctype_isUA (ct))
7317 typeId uid = ctype_typeId (ct);
7318 uentry ue = usymtab_getTypeEntrySafe (uid);
7320 if (uentry_isValid (ue))
7322 sRef_mergeStateQuiet (s, uentry_getSref (ue));
7326 s->oaliaskind = s->aliaskind;
7327 s->oexpkind = s->expkind;
7328 llassert (valueTable_isUndefined (s->state));
7329 s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_CREATED));
7331 DPRINTF (("Create: %s", sRef_unparseFull (s)));
7336 sRef_makeConst (ctype ct)
7338 sRef s = sRef_newRef ();
7343 s->defstate = SS_UNKNOWN;
7344 s->aliaskind = AK_UNKNOWN;
7345 sRef_setNullStateN (s, NS_UNKNOWN);
7347 /* start modification */
7348 s->bufinfo.bufstate = BB_NULLTERMINATED;
7349 /* end modification */
7351 /* evans 2002-04-22: added isManifestBool to avoid errors for -boolfalse initializations */
7352 if (!ctype_isManifestBool (ct) && ctype_isUA (ct))
7354 typeId uid = ctype_typeId (ct);
7355 uentry te = usymtab_getTypeEntrySafe (uid);
7357 if (uentry_isValid (te))
7359 sRef_mergeStateQuiet (s, uentry_getSref (te));
7363 s->oaliaskind = s->aliaskind;
7364 s->oexpkind = s->expkind;
7366 llassert (valueTable_isUndefined (s->state));
7367 s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_CREATED));
7372 bool sRef_hasName (sRef s)
7374 if (sRef_isInvalid (s))
7383 uentry u = usymtab_getRefQuiet (s->info->cvar->lexlevel,
7384 s->info->cvar->index);
7385 return (uentry_hasName (u));
7389 if (s->info->paramno >= 0)
7391 uentry u = uentryList_getN (context_getParams (),
7394 return (uentry_hasName (u));
7398 llassert (s->info->paramno == PARAMUNKNOWN);
7408 sRef_sameName (sRef s1, sRef s2)
7410 if (sRef_isInvalid (s1))
7412 return sRef_isInvalid (s2);
7415 if (sRef_isInvalid (s2))
7423 if (s2->kind == SK_CVAR)
7425 return (s1->info->cvar->lexlevel == s2->info->cvar->lexlevel
7426 && s1->info->cvar->index == s2->info->cvar->index);
7428 else if (s2->kind == SK_PARAM)
7430 if (context_inFunctionLike ())
7432 if (s2->info->paramno != PARAMUNKNOWN)
7434 uentry u1 = usymtab_getRefQuiet (s1->info->cvar->lexlevel,
7435 s1->info->cvar->index);
7436 uentry u2 = uentryList_getN (context_getParams (),
7439 return (cstring_equalFree (uentry_getName (u1),
7440 uentry_getName (u2)));
7444 return s1->info->paramno == PARAMUNKNOWN;
7458 if (s2->kind == SK_PARAM)
7460 return (s1->info->paramno == s2->info->paramno);
7462 else if (s2->kind == SK_CVAR)
7464 if (context_inFunctionLike ())
7466 if (s1->info->paramno == PARAMUNKNOWN)
7472 uentry u1 = uentryList_getN (context_getParams (),
7474 uentry u2 = usymtab_getRefQuiet (s2->info->cvar->lexlevel,
7475 s2->info->cvar->index);
7478 return (cstring_equalFree (uentry_getName (u1),
7479 uentry_getName (u2)));
7493 case SK_UNCONSTRAINED:
7497 if (s2->kind == SK_ARRAYFETCH)
7499 if (bool_equal (s1->info->arrayfetch->indknown,
7500 s2->info->arrayfetch->indknown))
7502 if (!s1->info->arrayfetch->indknown
7503 || (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind))
7505 return sRef_sameName (s1->info->arrayfetch->arr,
7506 s2->info->arrayfetch->arr);
7513 if (s2->kind == SK_FIELD)
7515 if (cstring_equal (s1->info->field->field,
7516 s2->info->field->field))
7518 return sRef_sameName (s1->info->field->rec,
7519 s2->info->field->rec);
7528 if (s2->kind == s1->kind)
7530 return sRef_sameName (s1->info->ref,
7538 return sRef_sameName (sRef_getConjA (s1), s2);
7542 return (s2->kind == SK_UNKNOWN);
7545 if (s2->kind == s1->kind)
7547 return (ctype_equal (s1->type, s2->type));
7552 if (s2->kind == SK_SPECIAL)
7554 return (s1->info->spec == s2->info->spec);
7558 return (s2->kind == SK_RESULT);
7566 sRef_fixOuterRef (/*@returned@*/ sRef s)
7568 sRef root = sRef_getRootBase (s);
7570 if (sRef_isCvar (root))
7572 uentry ue = usymtab_getRefQuiet (root->info->cvar->lexlevel,
7573 root->info->cvar->index);
7575 if (uentry_isValid (ue))
7577 sRef uref = uentry_getSref (ue);
7578 sRef sr = sRef_fixBase (s, uref);
7584 llcontbug (message ("sRef_fixOuterRef: undefined: %q", sRef_unparseDebug (s)));
7593 sRef_storeState (sRef s)
7595 if (sRef_isInvalid (s)) return;
7597 sRef_checkMutable (s);
7598 s->oaliaskind = s->aliaskind;
7599 s->oexpkind = s->expkind;
7602 static void sRef_resetStateAux (sRef s, /*@unused@*/ fileloc loc)
7604 sRef_resetState (s);
7608 sRef_resetState (sRef s)
7610 bool changed = FALSE;
7611 if (sRef_isInvalid (s)) return;
7614 if (s->oaliaskind == AK_KILLREF && !sRef_isParam (s))
7617 ** killref is used in a kludgey way, to save having to add
7618 ** another alias kind (see usymtab_handleParams)
7621 if (s->expkind != s->oexpkind)
7624 s->expkind = s->oexpkind;
7629 if (s->expkind != s->oexpkind)
7632 s->expkind = s->oexpkind;
7635 if (s->aliaskind != s->oaliaskind
7636 && s->aliaskind != AK_REFCOUNTED
7637 && s->aliaskind != AK_REFS)
7640 s->aliaskind = s->oaliaskind;
7646 sRef_clearDerived (s);
7652 sRef_resetStateComplete (sRef s)
7654 sRef_innerAliasSetComplete (sRef_resetStateAux, s, fileloc_undefined);
7658 sRef_fixBase (/*@returned@*/ sRef s, /*@returned@*/ sRef base)
7660 sRef tmp = sRef_undefined;
7663 if (sRef_isInvalid (s)) return s;
7664 if (sRef_isInvalid (base)) return base;
7674 tmp = sRef_fixBase (s->info->arrayfetch->arr, base);
7676 if (s->info->arrayfetch->indknown)
7678 ret = sRef_makeArrayFetchKnown (tmp, s->info->arrayfetch->ind);
7682 ret = sRef_makeArrayFetch (tmp);
7686 tmp = sRef_fixBase (s->info->field->rec, base);
7687 ret = sRef_buildNCField (tmp, s->info->field->field);
7690 tmp = sRef_fixBase (s->info->ref, base);
7691 ret = sRef_makePointer (tmp);
7694 tmp = sRef_fixBase (s->info->ref, base);
7695 ret = sRef_makeAddress (tmp);
7701 tmp = sRef_fixBase (s->info->conj->a, base);
7702 tmpb = sRef_fixBase (s->info->conj->b, base);
7704 ret = sRef_makeConj (tmp, tmpb);
7713 static /*@exposed@*/ sRef
7714 sRef_fixDirectBase (sRef s, sRef base)
7719 if (sRef_isInvalid (s))
7721 return sRef_undefined;
7727 if (s->info->arrayfetch->indknown)
7729 ret = sRef_makeArrayFetchKnown (base, s->info->arrayfetch->ind);
7733 ret = sRef_makeArrayFetch (base);
7737 ret = sRef_buildNCField (base, s->info->field->field);
7740 ret = sRef_makePointer (base);
7743 ret = sRef_makeAddress (base);
7749 tmpa = sRef_fixDirectBase (s->info->conj->a, base);
7750 tmpb = sRef_fixDirectBase (s->info->conj->b, base);
7752 ret = sRef_makeConj (tmpa, tmpb);
7758 sRef_copyState (ret, s);
7763 sRef_isAllocIndexRef (sRef s)
7765 return (sRef_isArrayFetch (s) && !(s->info->arrayfetch->indknown)
7766 && sRef_isAllocated (s->info->arrayfetch->arr));
7770 sRef_showRefLost (sRef s)
7772 if (sRef_hasAliasInfoLoc (s))
7774 llgenindentmsg (cstring_makeLiteral ("Original reference lost"),
7775 sRef_getAliasInfoLoc (s));
7780 sRef_showRefKilled (sRef s)
7782 if (sRef_isValid (s))
7784 DPRINTF (("Killed: %s", sRef_unparseFull (s)));
7785 if (context_getLocIndentSpaces () == 0) {
7786 stateInfo_display (s->definfo, message (" Storage %q", sRef_unparseOpt (s)));
7788 stateInfo_display (s->definfo, message ("Storage %q", sRef_unparseOpt (s)));
7794 sRef_showStateInconsistent (sRef s)
7796 if (sRef_hasStateInfoLoc (s))
7799 (message ("Storage %qbecomes inconsistent (released on one branch)",
7800 sRef_unparseOpt (s)),
7801 sRef_getStateInfoLoc (s));
7806 sRef_showStateInfo (sRef s)
7808 if (sRef_isValid (s)) {
7809 if (context_getLocIndentSpaces () == 0) {
7810 stateInfo_display (s->definfo, message (" Storage %q", sRef_unparseOpt (s)));
7812 stateInfo_display (s->definfo, message ("Storage %q", sRef_unparseOpt (s)));
7818 sRef_showExpInfo (sRef s)
7820 if (sRef_isValid (s)) {
7821 if (context_getLocIndentSpaces () == 0) {
7822 stateInfo_display (s->expinfo, message (" Storage %q", sRef_unparseOpt (s)));
7824 stateInfo_display (s->expinfo, message ("Storage %q", sRef_unparseOpt (s)));
7830 sRef_showMetaStateInfo (sRef s, cstring key)
7833 metaStateInfo minfo = context_lookupMetaStateInfo (key);
7835 llassert (sRef_isReasonable (s));
7836 llassert (valueTable_isDefined (s->state));
7837 llassert (metaStateInfo_isDefined (minfo));
7839 val = valueTable_lookup (s->state, key);
7841 if (stateValue_hasLoc (val))
7844 (message ("%qbecomes %q", sRef_unparseOpt (s),
7845 stateValue_unparseValue (val, minfo)),
7846 stateValue_getLoc (val));
7851 sRef_showNullInfo (sRef s)
7853 DPRINTF (("Show null info: %s", sRef_unparseFull (s)));
7855 if (sRef_hasNullInfoLoc (s) && sRef_isKnown (s))
7857 DPRINTF (("has null info: %s",
7858 fileloc_unparse (sRef_getNullInfoLoc (s))));
7860 switch (sRef_getNullState (s))
7864 fileloc loc = sRef_getNullInfoLoc (s);
7866 if (fileloc_isDefined (loc) && !fileloc_isLib (loc))
7869 (message ("Storage %qbecomes null", sRef_unparseOpt (s)),
7876 fileloc loc = sRef_getNullInfoLoc (s);
7878 if (fileloc_isDefined (loc) && !fileloc_isLib (loc))
7880 llgenindentmsg (message ("Storage %qbecomes null", sRef_unparseOpt (s)),
7888 (message ("Storage %qmay become null", sRef_unparseOpt (s)),
7889 sRef_getNullInfoLoc (s));
7894 (message ("Storage %qbecomes not null", sRef_unparseOpt (s)),
7895 sRef_getNullInfoLoc (s));
7899 (message ("Storage %qnull state becomes unknown",
7900 sRef_unparseOpt (s)),
7901 sRef_getNullInfoLoc (s));
7910 (message ("<error case> Storage %q becomes %s",
7912 nstate_unparse (sRef_getNullState (s))),
7913 sRef_getNullInfoLoc (s));
7921 sRef_showAliasInfo (sRef s)
7923 if (sRef_isValid (s))
7925 if (sRef_isFresh (s))
7927 if (context_getLocIndentSpaces () == 0) {
7928 stateInfo_display (s->aliasinfo, message (" Fresh storage %q", sRef_unparseOpt (s)));
7930 stateInfo_display (s->aliasinfo, message ("Fresh storage %q", sRef_unparseOpt (s)));
7935 if (context_getLocIndentSpaces () == 0) {
7936 stateInfo_display (s->aliasinfo, message (" Storage %q", sRef_unparseOpt (s)));
7938 stateInfo_display (s->aliasinfo, message ("Storage %q", sRef_unparseOpt (s)));
7945 sRef_mergeNullState (sRef s, nstate n)
7947 if (sRef_isReasonable (s))
7951 old = sRef_getNullState (s);
7953 if (n != old && n != NS_UNKNOWN)
7955 sRef_setNullState (s, n, g_currentloc);
7960 llbuglit ("sRef_mergeNullState: invalid");
7965 sRef_possiblyNull (sRef s)
7967 if (sRef_isReasonable (s))
7969 if (sRef_getNullState (s) == NS_ABSNULL)
7971 ctype rct = ctype_realType (s->type);
7973 if (ctype_isAbstract (rct))
7979 if (ctype_isUser (rct))
7981 uentry ue = usymtab_getTypeEntry (ctype_typeId (rct));
7983 return (nstate_possiblyNull
7984 (sRef_getNullState (uentry_getSref (ue))));
7994 return nstate_possiblyNull (sRef_getNullState (s));
8002 sRef_getScopeName (sRef s)
8004 sRef base = sRef_getRootBase (s);
8006 if (sRef_isRealGlobal (base))
8008 return (cstring_makeLiteralTemp ("Global"));
8010 else if (sRef_isFileStatic (base))
8012 return (cstring_makeLiteralTemp ("Static"));
8016 return (cstring_makeLiteralTemp ("Local"));
8021 sRef_unparseScope (sRef s)
8023 sRef base = sRef_getRootBase (s);
8025 if (sRef_isRealGlobal (base))
8027 return (cstring_makeLiteralTemp ("global"));
8029 else if (sRef_isFileStatic (base))
8031 return (cstring_makeLiteralTemp ("file static"));
8040 sRef_getScope (sRef s)
8042 llassert (sRef_isReasonable (s));
8044 if (sRef_isCvar (s))
8046 return s->info->cvar->lexlevel;
8048 else if (sRef_isParam (s))
8059 sRef_isDead (sRef s)
8061 return (sRef_isReasonable (s) && (s)->defstate == SS_DEAD);
8065 sRef_isDeadStorage (sRef s)
8067 if (sRef_isReasonable (s))
8069 if (s->defstate == SS_DEAD
8070 || s->defstate == SS_UNUSEABLE
8071 || s->defstate == SS_UNDEFINED
8072 || s->defstate == SS_UNKNOWN)
8078 return (sRef_isDefinitelyNull (s));
8088 sRef_isPossiblyDead (sRef s)
8090 return (sRef_isReasonable (s) && s->defstate == SS_HOFFA);
8093 bool sRef_isStateLive (sRef s)
8095 if (sRef_isReasonable (s))
8097 sstate ds = s->defstate;
8099 return (!(ds == SS_UNDEFINED
8101 || ds == SS_UNUSEABLE
8102 || ds == SS_HOFFA));
8111 bool sRef_isStateUndefined (sRef s)
8113 return ((sRef_isReasonable(s)) && ((s)->defstate == SS_UNDEFINED));
8116 bool sRef_isJustAllocated (sRef s)
8118 if (sRef_isAllocated (s))
8120 sRefSet_allElements (s->deriv, el)
8122 if (!(sRef_isStateUndefined (el) || sRef_isUnuseable (el)))
8126 } end_sRefSet_allElements ;
8135 sRef_isAllocatedStorage (sRef s)
8137 if (sRef_isReasonable (s) && ynm_toBoolStrict (sRef_isValidLvalue (s)))
8139 return (ctype_isVisiblySharable (sRef_getType (s)));
8148 sRef_isUnuseable (sRef s)
8150 return ((sRef_isValid(s)) && ((s)->defstate == SS_UNUSEABLE));
8154 sRef_perhapsNull (sRef s)
8156 if (sRef_isReasonable (s))
8158 if (sRef_getNullState (s) == NS_ABSNULL)
8160 ctype rct = ctype_realType (s->type);
8162 if (ctype_isAbstract (rct))
8168 if (ctype_isUser (rct))
8170 uentry ue = usymtab_getTypeEntry (ctype_typeId (rct));
8172 return (nstate_perhapsNull
8173 (sRef_getNullState (uentry_getSref (ue))));
8183 return nstate_perhapsNull (sRef_getNullState (s));
8191 ** definitelyNull --- called when TRUE is good
8195 sRef_definitelyNull (sRef s)
8197 return (sRef_isReasonable (s)
8198 && (sRef_getNullState (s) == NS_DEFNULL || sRef_getNullState (s) == NS_CONSTNULL));
8202 ** based on sRef_similar
8206 sRef_setDerivNullState (sRef set, sRef guide, nstate ns)
8208 if (sRef_isReasonable (set))
8210 sRef deriv = sRef_getDeriv (set, guide);
8212 if (sRef_isReasonable (deriv))
8214 sRef_setNullStateN (deriv, ns);
8219 static /*@exposed@*/ sRef
8220 sRef_getDeriv (/*@returned@*/ /*@notnull@*/ sRef set, sRef guide)
8222 llassert (sRef_isReasonable (set));
8223 llassert (sRef_isReasonable (guide));
8225 switch (guide->kind)
8228 llassert (set->kind == SK_CVAR);
8232 llassert (set->kind == guide->kind);
8233 llassert (set->info->paramno == guide->info->paramno);
8238 if (set->kind == SK_ARRAYFETCH
8239 && (sRef_similar (set->info->arrayfetch->arr,
8240 guide->info->arrayfetch->arr)))
8246 return (sRef_makeAnyArrayFetch
8247 (sRef_getDeriv (set, guide->info->arrayfetch->arr)));
8252 if (set->kind == SK_PTR && sRef_similar (set->info->ref, guide->info->ref))
8258 return (sRef_makePointer (sRef_getDeriv (set, guide->info->ref)));
8263 if ((set->kind == SK_FIELD &&
8264 (sRef_similar (set->info->field->rec, guide->info->field->rec) &&
8265 cstring_equal (set->info->field->field, guide->info->field->field))))
8271 return (sRef_makeField (sRef_getDeriv (set, guide->info->field->rec),
8272 guide->info->field->field));
8276 if ((set->kind == SK_ADR) && sRef_similar (set->info->ref, guide->info->ref))
8282 return (sRef_makeAddress (sRef_getDeriv (set, guide->info->ref)));
8287 return sRef_undefined;
8291 case SK_UNCONSTRAINED:
8299 return sRef_undefined;
8306 ** sRef_aliasCheckPred
8308 ** A confusing but spiffy function:
8310 ** Calls predf (s, e, text, <alias>) on s and all of s's aliases
8311 ** (unless checkAliases (s) is FALSE).
8313 ** For alias calls, calls as
8314 ** predf (alias, e, text, s)
8318 sRef_aliasCheckPred (bool (predf) (sRef, exprNode, sRef, exprNode),
8319 /*@null@*/ bool (checkAliases) (sRef),
8320 sRef s, exprNode e, exprNode err)
8322 bool error = (*predf)(s, e, sRef_undefined, err);
8325 if (checkAliases != NULL && !(checkAliases (s)))
8327 /* don't check aliases */
8331 sRefSet aliases = usymtab_allAliases (s);
8333 sRefSet_realElements (aliases, current)
8335 if (sRef_isReasonable (current))
8337 if (sRef_isReasonable (current))
8339 if (!sRef_similar (current, s)
8340 || (error && sRef_sameName (current, s)))
8342 (void) (*predf)(current, e, s, err);
8347 llcontbug (message ("Invalid sRef as alias field of %s", sRef_unparse (s)));
8350 } end_sRefSet_realElements;
8352 sRefSet_free (aliases);
8357 ** return TRUE iff predf (s) is true for s or any alias of s
8361 sRef_aliasCheckSimplePred (sRefTest predf, sRef s)
8372 aliases = usymtab_allAliases (s);
8374 sRefSet_realElements (aliases, current)
8376 if (sRef_isReasonable (current))
8378 sRef cref = sRef_updateSref (current);
8380 /* Whoa! a very kludgey way to make sure the right sref is used
8381 ** where there is a conditional symbol table. I am beginning
8382 ** to think that having a conditional symbol table wasn't such
8388 DPRINTF (("Checking alias: %s", sRef_unparseFull (cref)));
8389 sRefSet_free (aliases);
8393 } end_sRefSet_realElements;
8395 sRefSet_free (aliases);
8401 sRef_aliasCompleteSimplePred (bool (predf) (sRef), sRef s)
8404 bool result = FALSE;
8407 aliases = usymtab_allAliases (s);
8409 if ((*predf)(s)) result = TRUE;
8412 sRefSet_realElements (aliases, current)
8414 if (sRef_isReasonable (current))
8416 current = sRef_updateSref (current);
8417 if ((*predf)(current)) result = TRUE;
8419 } end_sRefSet_realElements;
8421 sRefSet_free (aliases);
8426 sRef_aliasSetComplete (void (predf) (sRef, fileloc), sRef s, fileloc loc)
8430 aliases = usymtab_allAliases (s);
8432 DPRINTF (("All aliases: %s --> %s", sRef_unparseFull (s), sRefSet_unparseFull (aliases)));
8436 sRefSet_realElements (aliases, current)
8438 if (sRef_isReasonable (current))
8440 DPRINTF (("Update: %s", sRef_unparseFull (current)));
8441 current = sRef_updateSref (current);
8442 DPRINTF (("Updated ==> %s", sRef_unparseFull (current)));
8443 ((*predf)(current, loc));
8444 DPRINTF (("Killed: %s", sRef_unparseFull (current)));
8446 } end_sRefSet_realElements;
8448 sRefSet_free (aliases);
8452 sRef_aliasSetCompleteParam (void (predf) (sRef, int, fileloc), sRef s,
8453 int kind, fileloc loc)
8457 if (sRef_isDeep (s))
8459 aliases = usymtab_allAliases (s);
8463 aliases = usymtab_aliasedBy (s);
8466 (*predf)(s, kind, loc);
8468 sRefSet_realElements (aliases, current)
8470 if (sRef_isReasonable (current))
8472 current = sRef_updateSref (current);
8473 ((*predf)(current, kind, loc));
8475 } end_sRefSet_realElements;
8477 sRefSet_free (aliases);
8481 ** Version of aliasSetCompleteParam for alkind parameters
8485 sRef_aliasSetCompleteAlkParam (void (predf) (sRef, alkind, fileloc), sRef s,
8486 alkind kind, fileloc loc)
8490 if (sRef_isDeep (s))
8492 aliases = usymtab_allAliases (s);
8496 aliases = usymtab_aliasedBy (s);
8499 (*predf)(s, kind, loc);
8501 sRefSet_realElements (aliases, current)
8503 if (sRef_isReasonable (current))
8505 current = sRef_updateSref (current);
8506 ((*predf)(current, kind, loc));
8508 } end_sRefSet_realElements;
8510 sRefSet_free (aliases);
8514 sRef_innerAliasSetComplete (void (predf) (sRef, fileloc), sRef s, fileloc loc)
8520 if (!sRef_isReasonable (s)) return;
8523 ** Type equivalence checking is necessary --- there might be casting.
8530 case SK_UNCONSTRAINED:
8535 inner = s->info->ref;
8536 aliases = usymtab_allAliases (inner);
8537 ct = sRef_getType (inner);
8539 sRefSet_realElements (aliases, current)
8541 if (sRef_isReasonable (current))
8543 current = sRef_updateSref (current);
8545 if (ctype_equal (ct, sRef_getType (current)))
8547 sRef ptr = sRef_makePointer (current);
8548 ((*predf)(ptr, loc));
8551 } end_sRefSet_realElements;
8553 sRefSet_free (aliases);
8556 inner = s->info->arrayfetch->arr;
8557 aliases = usymtab_allAliases (inner);
8558 ct = sRef_getType (inner);
8560 DPRINTF (("Array fetch: %s", sRefSet_unparse (aliases)));
8562 sRefSet_realElements (aliases, current)
8564 if (sRef_isReasonable (current))
8566 current = sRef_updateSref (current);
8567 DPRINTF (("Current: %s", sRef_unparseFull (current)));
8569 if (ctype_equal (ct, sRef_getType (current)))
8571 if (s->info->arrayfetch->indknown)
8573 sRef af = sRef_makeArrayFetchKnown (current, s->info->arrayfetch->ind);
8574 DPRINTF (("Defining: %s", sRef_unparseFull (af)));
8575 /* evans 2001-08-27 This isn't true:
8576 llassert (af->info->arrayfetch->arr == current);
8577 see comments in buildArrayFetchKnown
8579 ((*predf)(af, loc));
8583 sRef af = sRef_makeArrayFetch (current);
8584 /* evans 2001-08-27 This isn't true:
8585 llassert (af->info->arrayfetch->arr == current);
8586 see comments in buildArrayFetch
8588 DPRINTF (("Defining: %s", sRef_unparseFull (af)));
8589 ((*predf)(af, loc));
8594 DPRINTF (("Type mismatch: %s / %s",
8596 ctype_unparse (sRef_getType (current))));
8599 } end_sRefSet_realElements;
8601 sRefSet_free (aliases);
8604 inner = s->info->field->rec;
8605 aliases = usymtab_allAliases (inner);
8606 ct = sRef_getType (inner);
8608 sRefSet_realElements (aliases, current)
8610 if (sRef_isReasonable (current))
8612 current = sRef_updateSref (current);
8614 if (ctype_equal (ct, sRef_getType (current)))
8616 sRef f = sRef_makeField (current, s->info->field->field);
8621 } end_sRefSet_realElements;
8623 sRefSet_free (aliases);
8626 sRef_innerAliasSetComplete (predf, s->info->conj->a, loc);
8627 sRef_innerAliasSetComplete (predf, s->info->conj->b, loc);
8644 sRef_innerAliasSetCompleteParam (void (predf) (sRef, sRef), sRef s, sRef t)
8650 if (!sRef_isReasonable (s)) return;
8653 ** Type equivalence checking is necessary --- there might be casting.
8660 case SK_UNCONSTRAINED:
8665 inner = s->info->ref;
8666 aliases = usymtab_allAliases (inner);
8667 ct = sRef_getType (inner);
8669 sRefSet_realElements (aliases, current)
8671 if (sRef_isReasonable (current))
8673 current = sRef_updateSref (current);
8675 if (ctype_equal (ct, sRef_getType (current)))
8677 sRef ptr = sRef_makePointer (current);
8682 } end_sRefSet_realElements;
8684 sRefSet_free (aliases);
8687 inner = s->info->arrayfetch->arr;
8688 aliases = usymtab_allAliases (inner);
8689 ct = sRef_getType (inner);
8691 sRefSet_realElements (aliases, current)
8693 if (sRef_isReasonable (current))
8695 current = sRef_updateSref (current);
8697 if (ctype_equal (ct, sRef_getType (current)))
8700 if (s->info->arrayfetch->indknown)
8702 sRef af = sRef_makeArrayFetchKnown (current, s->info->arrayfetch->ind);
8708 sRef af = sRef_makeArrayFetch (current);
8714 } end_sRefSet_realElements;
8716 sRefSet_free (aliases);
8719 inner = s->info->field->rec;
8720 aliases = usymtab_allAliases (inner);
8721 ct = sRef_getType (inner);
8724 sRefSet_realElements (aliases, current)
8726 if (sRef_isReasonable (current))
8728 current = sRef_updateSref (current);
8730 if (ctype_equal (ct, sRef_getType (current)))
8732 sRef f = sRef_makeField (current, s->info->field->field);
8737 } end_sRefSet_realElements;
8739 sRefSet_free (aliases);
8742 sRef_innerAliasSetCompleteParam (predf, s->info->conj->a, t);
8743 sRef_innerAliasSetCompleteParam (predf, s->info->conj->b, t);
8759 static void sRef_combineExKinds (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other)
8761 exkind a1 = sRef_getExKind (res);
8762 exkind a2 = sRef_getExKind (other);
8764 if (a1 == a2 || a2 == XO_UNKNOWN)
8768 else if (a1 == XO_UNKNOWN)
8770 res->expinfo = stateInfo_update (res->expinfo, other->expinfo);
8775 res->expkind = XO_OBSERVER;
8780 ** Currently, this is a very ad hoc implementation, with lots of fixes to
8781 ** make real code work okay. I need to come up with some more general
8782 ** rules or principles here.
8786 sRef_combineAliasKindsError (/*@notnull@*/ sRef res,
8787 /*@notnull@*/ sRef other,
8788 clause cl, fileloc loc)
8790 bool hasError = FALSE;
8791 alkind ares = sRef_getAliasKind (res);
8792 alkind aother = sRef_getAliasKind (other);
8794 sRef_checkMutable (res);
8796 if (alkind_isDependent (ares))
8798 if (aother == AK_KEPT)
8800 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8801 res->aliaskind = AK_KEPT;
8805 if (aother == AK_LOCAL || aother == AK_STATIC
8806 || alkind_isTemp (aother))
8808 DPRINTF (("Setting dependent: %s", sRef_unparseFull (res)));
8809 res->aliaskind = AK_DEPENDENT;
8813 else if (alkind_isDependent (aother))
8815 if (ares == AK_KEPT)
8817 res->aliaskind = AK_KEPT;
8821 if (ares == AK_LOCAL || ares == AK_STATIC || alkind_isTemp (ares))
8823 DPRINTF (("Setting dependent: %s", sRef_unparseFull (res)));
8824 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8825 res->aliaskind = AK_DEPENDENT;
8829 else if ((ares == AK_LOCAL || ares == AK_UNIQUE
8830 || ares == AK_STATIC || alkind_isTemp (ares))
8831 && sRef_isFresh (other))
8834 ** cases like: if (s == NULL) s = malloc...;
8835 ** don't generate errors
8838 if (usymtab_isAltDefinitelyNullDeep (res))
8840 res->aliaskind = ares;
8847 else if ((aother == AK_LOCAL || aother == AK_UNIQUE
8848 || aother == AK_STATIC || alkind_isTemp (aother))
8849 && sRef_isFresh (res))
8852 ** cases like: if (s == NULL) s = malloc...;
8853 ** don't generate errors
8856 if (usymtab_isDefinitelyNullDeep (other))
8858 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8859 res->aliaskind = aother;
8866 else if (ares == AK_NEWREF && aother == AK_REFCOUNTED
8867 && sRef_isConst (other))
8869 res->aliaskind = AK_NEWREF;
8871 else if (aother == AK_NEWREF && ares == AK_REFCOUNTED
8872 && sRef_isConst (res))
8874 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8875 res->aliaskind = AK_NEWREF;
8877 else if (sRef_isLocalVar (res)
8878 && ((ares == AK_KEPT && aother == AK_LOCAL)
8879 || (aother == AK_KEPT && ares == AK_LOCAL)))
8881 res->aliaskind = AK_KEPT;
8883 else if ((ares == AK_OWNED && aother == AK_ONLY)
8884 || (aother == AK_OWNED && ares == AK_ONLY))
8886 res->aliaskind = AK_OWNED;
8888 if (aother == AK_OWNED)
8890 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8900 if (sRef_isThroughArrayFetch (res))
8903 (FLG_BRANCHSTATE, FLG_STRICTBRANCHSTATE,
8905 ("Clauses exit with %q possibly referencing %s storage %s, "
8908 alkind_unparse (aother),
8909 clause_nameTaken (cl),
8910 alkind_unparse (ares),
8911 clause_nameAlternate (cl)),
8914 sRef_showAliasInfo (res);
8915 sRef_showAliasInfo (other);
8916 res->aliaskind = AK_ERROR;
8920 if (ares == AK_KEPT || aother == AK_KEPT)
8922 sRef_maybeKill (res, loc);
8930 message ("Clauses exit with %q referencing %s storage %s, "
8933 alkind_unparse (aother),
8934 clause_nameTaken (cl),
8935 alkind_unparse (ares),
8936 clause_nameAlternate (cl)),
8939 sRef_showAliasInfo (res);
8940 sRef_showAliasInfo (other);
8942 res->aliaskind = AK_ERROR;
8946 res->aliaskind = (sRef_isLocalVar (res) ? AK_LOCAL : AK_UNKNOWN);
8951 sRef_combineAliasKinds (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other,
8952 clause cl, fileloc loc)
8954 alkind ares = sRef_getAliasKind (res);
8955 alkind aother = sRef_getAliasKind (other);
8957 sRef_checkMutable (res);
8959 DPRINTF (("Combine alias kinds: \n\t%s / \n\t%s",
8960 sRef_unparseFull (res), sRef_unparseFull (other)));
8961 if (alkind_equal (ares, aother)
8962 || aother == AK_UNKNOWN
8963 || aother == AK_ERROR)
8965 ; /* keep current state */
8967 else if (sRef_isDead (res) || sRef_isDead (other))
8969 /* dead error reported (or storage is dead) */
8970 res ->aliaskind = AK_ERROR;
8972 else if (ares == AK_UNKNOWN || ares == AK_ERROR
8973 || sRef_isStateUndefined (res)
8974 || sRef_isDefinitelyNull (res))
8976 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8977 res->aliaskind = aother;
8979 else if (sRef_isStateUndefined (other)
8980 || sRef_isDefinitelyNull (other))
8984 else if (((ares == AK_UNIQUE || alkind_isTemp (ares))
8985 && aother == AK_LOCAL)
8986 || ((aother == AK_UNIQUE || alkind_isTemp (aother))
8987 && ares == AK_LOCAL))
8989 if (ares != AK_LOCAL)
8991 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8994 res->aliaskind = AK_LOCAL;
8996 else if ((ares == AK_OWNED && aother == AK_FRESH)
8997 || (aother == AK_OWNED && ares == AK_FRESH))
8999 if (ares != AK_FRESH)
9001 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
9004 res->aliaskind = AK_FRESH;
9006 else if ((ares == AK_KEEP && aother == AK_FRESH) ||
9007 (aother == AK_KEEP && ares == AK_FRESH))
9009 if (ares != AK_KEEP)
9011 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
9014 res->aliaskind = AK_KEEP;
9016 else if ((ares == AK_LOCAL && aother == AK_STACK) ||
9017 (aother == AK_LOCAL && ares == AK_STACK))
9019 if (ares != AK_STACK)
9021 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
9024 res->aliaskind = AK_STACK;
9026 else if ((ares == AK_LOCAL
9027 && (aother == AK_OWNED && sRef_isLocalVar (other)))
9028 || (aother == AK_LOCAL
9029 && (ares == AK_OWNED && sRef_isLocalVar (res))))
9031 if (ares != AK_LOCAL)
9033 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
9036 res->aliaskind = AK_LOCAL;
9038 else if ((ares == AK_FRESH && alkind_isOnly (aother))
9039 || (aother == AK_FRESH && alkind_isOnly (ares)))
9041 res->aliaskind = AK_FRESH;
9043 else if ((aother == AK_FRESH && sRef_definitelyNull (res))
9044 || (ares == AK_FRESH && sRef_definitelyNull (other)))
9046 if (ares != AK_FRESH)
9048 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
9049 res->aliaskind = AK_FRESH;
9052 else if ((sRef_isFresh (res) && sRef_isConst (other))
9053 || (sRef_isFresh (other) && sRef_isConst (res)))
9056 ** for NULL constantants
9060 if (!sRef_isFresh (res))
9062 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
9065 res->aliaskind = AK_FRESH;
9067 else if ((alkind_isStatic (aother) && sRef_isConst (res))
9068 || (alkind_isStatic (ares) && sRef_isConst (other)))
9070 if (!alkind_isStatic (ares))
9072 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
9073 res->aliaskind = AK_STATIC;
9078 sRef_combineAliasKindsError (res, other, cl, loc);
9082 static void sRef_combineDefState (/*@notnull@*/ sRef res,
9083 /*@notnull@*/ sRef other)
9085 sstate s1 = res->defstate;
9086 sstate s2 = other->defstate;
9089 sRef_checkMutable (res);
9091 if (s1 == s2 || s2 == SS_UNKNOWN)
9095 else if (s1 == SS_UNKNOWN)
9104 if (s2 == SS_DEFINED)
9110 llcontbuglit ("ssfixed: not implemented");
9119 flip = (s2 != SS_DEFINED);
9137 res->definfo = stateInfo_update (res->definfo, other->definfo);
9142 extern /*@notnull@*/ sRef sRef_getConjA (sRef s)
9145 llassert (sRef_isConj (s));
9147 ret = s->info->conj->a;
9148 llassert (ret != NULL);
9152 extern /*@notnull@*/ sRef sRef_getConjB (sRef s)
9155 llassert (sRef_isConj (s));
9157 ret = s->info->conj->b;
9158 llassert (ret != NULL);
9162 extern /*@exposed@*/ sRef sRef_makeArrow (sRef s, /*@dependent@*/ cstring f)
9167 p = sRef_makePointer (s);
9168 ret = sRef_makeField (p, f);
9169 DPRINTF (("Arrow: %s => %s",
9170 sRef_unparseFull (s), sRef_unparseFull (ret)));
9174 extern /*@exposed@*/ sRef sRef_buildArrow (sRef s, cstring f)
9179 p = sRef_buildPointer (s);
9180 ret = sRef_buildField (p, f);
9185 static /*@null@*/ sinfo sinfo_copy (/*@notnull@*/ sRef s)
9192 ret = (sinfo) dmalloc (sizeof (*ret));
9193 ret->cvar = (cref) dmalloc (sizeof (*ret->cvar));
9194 ret->cvar->lexlevel = s->info->cvar->lexlevel;
9195 ret->cvar->index = s->info->cvar->index;
9199 ret = (sinfo) dmalloc (sizeof (*ret));
9200 ret->paramno = s->info->paramno;
9201 llassert (ret->paramno >= -1);
9205 ret = (sinfo) dmalloc (sizeof (*ret));
9206 ret->arrayfetch = (ainfo) dmalloc (sizeof (*ret->arrayfetch));
9207 ret->arrayfetch->indknown = s->info->arrayfetch->indknown;
9208 ret->arrayfetch->ind = s->info->arrayfetch->ind;
9209 ret->arrayfetch->arr = s->info->arrayfetch->arr;
9213 ret = (sinfo) dmalloc (sizeof (*ret));
9214 ret->field = (fldinfo) dmalloc (sizeof (*ret->field));
9215 ret->field->rec = s->info->field->rec;
9216 ret->field->field = s->info->field->field;
9220 ret = (sinfo) dmalloc (sizeof (*ret));
9221 ret->object = s->info->object;
9228 ret = (sinfo) dmalloc (sizeof (*ret));
9229 ret->ref = s->info->ref; /* Ref_copy (s->info->ref); */
9233 ret = (sinfo) dmalloc (sizeof (*ret));
9234 ret->conj = (cjinfo) dmalloc (sizeof (*ret->conj));
9235 ret->conj->a = s->info->conj->a; /* sRef_copy (s->info->conj->a); */
9236 ret->conj->b = s->info->conj->b; /* sRef_copy (s->info->conj->b);*/
9239 ret = (sinfo) dmalloc (sizeof (*ret));
9240 ret->spec = s->info->spec;
9243 case SK_UNCONSTRAINED:
9245 ret = (sinfo) dmalloc (sizeof (*ret));
9246 ret->fname = s->info->fname;
9253 llassertprint (s->info == NULL, ("s = %s", sRef_unparse (s)));
9261 static /*@null@*/ sinfo sinfo_fullCopy (/*@notnull@*/ sRef s)
9266 ** Since its a full copy, only storage is assigned
9267 ** to dependent fields.
9274 ret = (sinfo) dmalloc (sizeof (*ret));
9275 ret->cvar = (cref) dmalloc (sizeof (*ret->cvar));
9276 ret->cvar->lexlevel = s->info->cvar->lexlevel;
9277 ret->cvar->index = s->info->cvar->index;
9281 ret = (sinfo) dmalloc (sizeof (*ret));
9282 ret->paramno = s->info->paramno;
9283 llassert (ret->paramno >= -1);
9287 ret = (sinfo) dmalloc (sizeof (*ret));
9288 ret->arrayfetch = (ainfo) dmalloc (sizeof (*ret->arrayfetch));
9289 ret->arrayfetch->indknown = s->info->arrayfetch->indknown;
9290 ret->arrayfetch->ind = s->info->arrayfetch->ind;
9291 ret->arrayfetch->arr = sRef_saveCopy (s->info->arrayfetch->arr);
9295 ret = (sinfo) dmalloc (sizeof (*ret));
9296 ret->field = (fldinfo) dmalloc (sizeof (*ret->field));
9297 ret->field->rec = sRef_saveCopy (s->info->field->rec);
9298 ret->field->field = s->info->field->field;
9302 ret = (sinfo) dmalloc (sizeof (*ret));
9303 ret->object = s->info->object;
9310 ret = (sinfo) dmalloc (sizeof (*ret));
9311 ret->ref = sRef_saveCopy (s->info->ref);
9315 ret = (sinfo) dmalloc (sizeof (*ret));
9316 ret->conj = (cjinfo) dmalloc (sizeof (*ret->conj));
9317 ret->conj->a = sRef_saveCopy (s->info->conj->a);
9318 ret->conj->b = sRef_saveCopy (s->info->conj->b);
9321 ret = (sinfo) dmalloc (sizeof (*ret));
9322 ret->spec = s->info->spec;
9325 case SK_UNCONSTRAINED:
9326 ret = (sinfo) dmalloc (sizeof (*ret));
9327 ret->fname = s->info->fname;
9333 llassert (s->info == NULL);
9343 sinfo_update (/*@notnull@*/ /*@exposed@*/ sRef res,
9344 /*@notnull@*/ /*@exposed@*/ sRef other)
9346 llassert (res->kind == other->kind);
9351 res->info->cvar->lexlevel = other->info->cvar->lexlevel;
9352 res->info->cvar->index = other->info->cvar->index;
9356 res->info->paramno = other->info->paramno;
9357 llassert (res->info->paramno >= -1);
9361 res->info->arrayfetch->indknown = other->info->arrayfetch->indknown;
9362 res->info->arrayfetch->ind = other->info->arrayfetch->ind;
9363 res->info->arrayfetch->arr = other->info->arrayfetch->arr;
9367 res->info->field->rec = other->info->field->rec;
9368 res->info->field->field = other->info->field->field;
9372 res->info->object = other->info->object;
9379 res->info->ref = other->info->ref;
9383 res->info->conj->a = other->info->conj->a;
9384 res->info->conj->b = other->info->conj->b;
9388 res->info->spec = other->info->spec;
9392 case SK_UNCONSTRAINED:
9393 res->info->fname = other->info->fname;
9400 llassert (res->info == NULL);
9405 static void sinfo_free (/*@special@*/ /*@temp@*/ /*@notnull@*/ sRef s)
9406 /*@uses s->kind, s->info@*/
9407 /*@releases s->info@*/
9412 DPRINTF (("Free sinfo: [%p]", s->info->cvar));
9413 sfree (s->info->cvar);
9420 DPRINTF (("Free sinfo: [%p]", s->info->arrayfetch));
9421 sfree (s->info->arrayfetch);
9425 DPRINTF (("Free sinfo: [%p]", s->info->field));
9426 sfree (s->info->field);
9435 case SK_EXTERNAL: /* is copy now! */
9439 DPRINTF (("Free sinfo: [%p]", s->info->conj));
9440 sfree (s->info->conj);
9443 case SK_UNCONSTRAINED:
9453 if (s->info != NULL) {
9454 DPRINTF (("Free sinfo: [%p]", s->info));
9460 bool sRef_isNSLocalVar (sRef s)
9462 if (sRef_isLocalVar (s))
9464 uentry ue = sRef_getUentry (s);
9466 return (!uentry_isStatic (ue));
9474 bool sRef_isLocalVar (sRef s)
9476 if (sRef_isValid(s))
9478 return (s->kind == SK_CVAR
9479 && (s->info->cvar->lexlevel > fileScope));
9485 bool sRef_isRealLocalVar (sRef s)
9487 if (sRef_isValid(s))
9489 if (s->kind == SK_CVAR)
9491 if (s->info->cvar->lexlevel == functionScope)
9493 uentry ue = sRef_getUentry (s);
9495 if (uentry_isAnyParam (ue)
9496 || uentry_isRefParam (ue))
9507 return (s->info->cvar->lexlevel > functionScope);
9515 bool sRef_isLocalParamVar (sRef s)
9517 if (sRef_isValid(s))
9519 return (s->kind == SK_PARAM
9520 || (s->kind == SK_CVAR
9521 && (s->info->cvar->lexlevel > fileScope)));
9527 static speckind speckind_fromInt (int i)
9530 llassert (i >= SR_NOTHING && i <= SR_SYSTEM);
9533 return ((speckind) i);
9537 static void sRef_updateNullState (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other)
9540 res->nullstate = other->nullstate;
9541 res->nullinfo = stateInfo_update (res->nullinfo, other->nullinfo);
9542 sRef_resetAliasKind (res);
9545 void sRef_combineNullState (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other)
9547 nstate n1 = sRef_getNullState (res);
9548 nstate n2 = sRef_getNullState (other);
9552 if (n1 == n2 || n2 == NS_UNKNOWN)
9558 /* note: n2 is not unknown or defnull */
9562 case NS_ERROR: nn = NS_ERROR; break;
9563 case NS_UNKNOWN: flip = TRUE; nn = n2; break;
9564 case NS_POSNULL: break;
9565 case NS_DEFNULL: nn = NS_POSNULL; break;
9566 case NS_RELNULL: break;
9568 if (n2 == NS_MNOTNULL)
9579 if (n2 == NS_NOTNULL)
9598 res->nullinfo = stateInfo_update (res->nullinfo, other->nullinfo);
9601 res->nullstate = nn;
9602 sRef_resetAliasKind (res);
9605 cstring sRef_nullMessage (sRef s)
9607 llassert (sRef_isReasonable (s));
9609 switch (sRef_getNullState (s))
9613 return (cstring_makeLiteralTemp ("null"));
9615 return (cstring_makeLiteralTemp ("possibly null"));
9620 /*@observer@*/ cstring sRef_ntMessage (sRef s)
9622 llassert (sRef_isReasonable (s));
9624 switch (s->nullstate)
9628 return (cstring_makeLiteralTemp ("not nullterminated"));
9630 return (cstring_makeLiteralTemp ("possibly non-nullterminated"));
9637 sRef sRef_fixResultType (/*@returned@*/ sRef s, ctype typ, uentry ue)
9639 sRef tmp = sRef_undefined;
9642 llassert (sRef_isReasonable (s));
9653 tmp = sRef_fixResultType (s->info->arrayfetch->arr, typ, ue);
9655 ct = ctype_realType (sRef_getType (tmp));
9658 if (ctype_isKnown (ct))
9660 if (ctype_isAP (ct))
9669 ("Special clause indexes non-array (%t): *%q",
9670 ct, sRef_unparse (s->info->arrayfetch->arr)),
9671 uentry_whereLast (ue));
9675 tmp = sRef_fixResultType (s->info->arrayfetch->arr, typ, ue);
9677 if (s->info->arrayfetch->indknown)
9679 ret = sRef_makeArrayFetchKnown (tmp, s->info->arrayfetch->ind);
9683 ret = sRef_makeArrayFetch (tmp);
9689 sRef rec = sRef_fixResultType (s->info->field->rec, typ, ue);
9690 ctype ct = ctype_realType (sRef_getType (rec));
9692 if (ctype_isKnown (ct))
9694 if (ctype_isSU (ct))
9696 if (uentry_isValid (uentryList_lookupField (ctype_getFields (ct),
9697 s->info->field->field)))
9706 ("Special clause accesses non-existent field of result: %q.%s",
9707 sRef_unparse (rec), s->info->field->field),
9708 uentry_whereLast (ue));
9716 ("Special clause accesses field of non-struct or union result (%t): %q.%s",
9717 ct, sRef_unparse (rec), s->info->field->field),
9718 uentry_whereLast (ue));
9722 ret = sRef_makeField (tmp, s->info->field->field);
9728 tmp = sRef_fixResultType (s->info->ref, typ, ue);
9730 ct = ctype_realType (sRef_getType (tmp));
9732 if (ctype_isKnown (ct))
9734 if (ctype_isAP (ct))
9743 ("Special clause dereferences non-pointer (%t): *%q",
9744 ct, sRef_unparse (s->info->ref)),
9745 uentry_whereLast (ue));
9749 ret = sRef_makePointer (tmp);
9756 ("Special clause uses & operator (not allowed): &%q", sRef_unparse (s->info->ref)),
9757 uentry_whereLast (ue));
9766 bool sRef_isOnly (sRef s)
9768 return (sRef_isValid(s) && alkind_isOnly (s->aliaskind));
9771 bool sRef_isDependent (sRef s)
9773 return (sRef_isValid(s) && alkind_isDependent (s->aliaskind));
9776 bool sRef_isOwned (sRef s)
9778 return (sRef_isReasonable (s) && (s->aliaskind == AK_OWNED));
9781 bool sRef_isKeep (sRef s)
9783 return (sRef_isReasonable (s) && (s->aliaskind == AK_KEEP));
9786 bool sRef_isTemp (sRef s)
9788 return (sRef_isReasonable (s) && alkind_isTemp (s->aliaskind));
9791 bool sRef_isLocalState (sRef s)
9793 return (sRef_isReasonable (s) && (s->aliaskind == AK_LOCAL));
9796 bool sRef_isUnique (sRef s)
9798 return (sRef_isReasonable (s) && (s->aliaskind == AK_UNIQUE));
9801 bool sRef_isShared (sRef s)
9803 return (sRef_isReasonable (s) && (s->aliaskind == AK_SHARED));
9806 bool sRef_isExposed (sRef s)
9808 return (sRef_isReasonable (s) && (s->expkind == XO_EXPOSED));
9811 bool sRef_isObserver (sRef s)
9813 return (sRef_isReasonable (s) && (s->expkind == XO_OBSERVER));
9816 bool sRef_isFresh (sRef s)
9818 return (sRef_isReasonable (s) && (s->aliaskind == AK_FRESH));
9821 bool sRef_isDefinitelyNull (sRef s)
9823 return (sRef_isReasonable (s) && (sRef_getNullState (s) == NS_DEFNULL
9824 || sRef_getNullState (s) == NS_CONSTNULL));
9827 bool sRef_isAllocated (sRef s)
9829 return (sRef_isReasonable (s) && (s->defstate == SS_ALLOCATED));
9832 bool sRef_isStack (sRef s)
9834 return (sRef_isReasonable (s) && (s->aliaskind == AK_STACK));
9837 bool sRef_isNotNull (sRef s)
9839 return (sRef_isValid(s) && (sRef_getNullState (s) == NS_MNOTNULL
9840 || sRef_getNullState (s) == NS_NOTNULL));
9843 alkind sRef_getAliasKind (sRef s)
9845 if (sRef_isValid(s)) {
9846 llassert (alkind_isValid (s->aliaskind));
9847 return s->aliaskind;
9853 nstate sRef_getNullState (sRef s)
9855 if (sRef_isReasonable (s)) {
9856 llassert (nstate_isValid (s->nullstate));
9857 return s->nullstate;
9863 void sRef_reflectAnnotation (sRef s, annotationInfo a, fileloc loc)
9865 if (sRef_isReasonable (s))
9867 if (!valueTable_isDefined (s->state))
9869 s->state = valueTable_create (1);
9872 cstring_copy (metaStateInfo_getName (annotationInfo_getState (a))),
9873 stateValue_create (annotationInfo_getValue (a),
9874 stateInfo_makeLoc (loc, SA_DECLARED)));
9878 DPRINTF (("reflect loc: %s", fileloc_unparse (loc)));
9881 metaStateInfo_getName (annotationInfo_getState (a)),
9882 stateValue_create (annotationInfo_getValue (a),
9883 stateInfo_makeLoc (loc, SA_DECLARED)));
9885 DPRINTF (("sref: %s", sRef_unparse (s)));
9886 DPRINTF (("sref: %s", sRef_unparseFull (s)));
9891 void sRef_setMetaStateValueComplete (sRef s, cstring key, int value, fileloc loc)
9893 sRefSet aliases = usymtab_allAliases (s);
9895 sRef_setMetaStateValue (s, key, value, loc);
9897 sRefSet_realElements (aliases, current)
9899 if (sRef_isReasonable (current))
9901 current = sRef_updateSref (current);
9902 sRef_setMetaStateValue (current, key, value, loc);
9904 } end_sRefSet_realElements ;
9906 sRefSet_free (aliases);
9909 void sRef_setMetaStateValue (sRef s, cstring key, int value, fileloc loc)
9911 sRef_checkMutable (s);
9913 if (sRef_isReasonable (s))
9915 if (!valueTable_isDefined (s->state))
9917 DPRINTF (("inserting state: %s: %s %d", sRef_unparse (s), key, value));
9918 s->state = valueTable_create (1);
9919 valueTable_insert (s->state, cstring_copy (key),
9920 stateValue_create (value,
9921 stateInfo_makeLoc (loc, SA_CHANGED)));
9925 DPRINTF (("Updating state: %s: %s %d / %s", sRef_unparse (s), key, value,
9926 fileloc_unparse (loc)));
9927 if (valueTable_contains (s->state, key))
9930 (s->state, key, stateValue_create (value,
9931 stateInfo_makeLoc (loc, SA_CHANGED)));
9936 (s->state, cstring_copy (key),
9937 stateValue_create (value, stateInfo_makeLoc (loc, SA_CHANGED)));
9940 DPRINTF (("After: %s", sRef_unparseFull (s)));
9945 bool sRef_checkMetaStateValue (sRef s, cstring key, int value)
9947 if (sRef_isReasonable (s))
9949 if (valueTable_isDefined (s->state))
9953 DPRINTF (("check state: %s: %s %d", sRef_unparse (s), key, value));
9955 val = valueTable_lookup (s->state, key);
9956 llassert (stateValue_isDefined (val));
9957 return (stateValue_isError (val)
9958 || stateValue_getValue (val) == value);
9971 /*@observer@*/ stateValue sRef_getMetaStateValue (sRef s, cstring key)
9973 if (sRef_isReasonable (s))
9975 if (valueTable_isDefined (s->state))
9979 val = valueTable_lookup (s->state, key);
9980 /* Okay if its not defined, just returns stateValue_undefined */
9985 return stateValue_undefined;
9990 return stateValue_undefined;
9994 /*@observer@*/ valueTable sRef_getValueTable (sRef s)
9996 DPRINTF (("Get value table: %s", sRef_unparse (s)));
9998 if (sRef_isReasonable (s))
10000 llassert (sRef_isReasonable (s));
10001 DPRINTF (("Value table: %s", valueTable_unparse (s->state)));
10006 DPRINTF (("No value table!"));
10007 return valueTable_undefined;
10011 bool sRef_makeStateSpecial (sRef s)
10014 ** Default defined state can be made special.
10017 llassert (sRef_isReasonable (s));
10019 if (s->defstate == SS_UNKNOWN || s->defstate == SS_DEFINED || s->defstate == SS_SPECIAL)
10021 /* s->aliaskind = AK_IMPTEMP; */ /* evans 2001-07-23 shouldn't effect alias state */
10022 s->defstate = SS_SPECIAL;
10023 DPRINTF (("Made special: %s", sRef_unparseFull (s)));
10028 /* s->aliaskind = AK_IMPTEMP; */
10029 s->defstate = SS_SPECIAL;
10034 void sRef_markImmutable (sRef s)
10036 if (sRef_isReasonable (s))
10038 DPRINTF (("Mark immutable: %s", sRef_unparseFull (s)));
10043 bool sRef_definitelyNullContext (sRef s)
10045 return (sRef_definitelyNull (s)
10046 || usymtab_isDefinitelyNullDeep (s));
10049 bool sRef_definitelyNullAltContext (sRef s)
10051 return (sRef_definitelyNull (s)
10052 || usymtab_isAltDefinitelyNullDeep (s));
10056 /* start modifications */
10057 struct s_bbufinfo sRef_getNullTerminatedState (sRef p_s) {
10058 struct s_bbufinfo BUFSTATE_UNKNOWN;
10059 BUFSTATE_UNKNOWN.bufstate = BB_NOTNULLTERMINATED;
10060 BUFSTATE_UNKNOWN.size = 0;
10061 BUFSTATE_UNKNOWN.len = 0;
10063 if (sRef_isValid(p_s))
10064 return p_s->bufinfo;
10065 return BUFSTATE_UNKNOWN;
10068 void sRef_setNullTerminatedState(sRef p_s) {
10069 if(sRef_isReasonable (p_s)) {
10070 p_s->bufinfo.bufstate = BB_NULLTERMINATED;
10072 llfatalbug( message("sRef_setNT passed a invalid sRef\n"));
10077 void sRef_setPossiblyNullTerminatedState(sRef p_s) {
10078 if( sRef_isReasonable (p_s)) {
10079 p_s->bufinfo.bufstate = BB_POSSIBLYNULLTERMINATED;
10081 llfatalbug( message("sRef_setPossNT passed a invalid sRef\n"));
10085 void sRef_setNotNullTerminatedState(sRef p_s) {
10086 if( sRef_isReasonable (p_s)) {
10087 p_s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
10089 llfatalbug( message("sRef_unsetNT passed a invalid sRef\n"));
10093 void sRef_setLen(sRef p_s, int len) {
10094 if (sRef_isReasonable (p_s) && sRef_isNullTerminated(p_s))
10096 p_s->bufinfo.len = len;
10100 llfatalbug( message("sRef_setLen passed an invalid sRef\n"));
10105 void sRef_setSize(sRef p_s, int size) {
10106 if( sRef_isValid(p_s))
10108 p_s->bufinfo.size = size;
10112 llfatalbug( message("sRef_setSize passed a invalid sRef\n"));
10116 void sRef_resetLen(sRef p_s) {
10117 if (sRef_isReasonable (p_s))
10119 p_s->bufinfo.len = 0;
10123 llfatalbug (message ("sRef_setLen passed an invalid sRef\n"));
10127 /*drl7x 11/28/2000 */
10129 bool sRef_isFixedArray (sRef p_s) /*@*/ {
10131 c = sRef_getType (p_s);
10132 return ( ctype_isFixedArray (c) );
10135 size_t sRef_getArraySize (sRef p_s) /*@*/
10138 llassert (sRef_isFixedArray(p_s) );
10139 DPRINTF (( message ("sRef_getArraySize getting array size for %s", sRef_unparse(p_s) ) ));
10141 c = sRef_getType (p_s);
10142 return (ctype_getArraySize (c));
10145 void sRef_setValue (sRef s, multiVal val)
10147 if (!sRef_isReasonable (s))
10149 llcontbuglit ("Unreasonable sRef");
10150 llcontbug (message ("sRef: %s", sRef_unparse (s)));
10154 multiVal_free (s->val);
10158 bool sRef_hasValue (sRef s)
10160 return (sRef_isReasonable (s)
10161 && multiVal_isDefined (s->val));
10164 multiVal sRef_getValue (sRef s)
10166 if (sRef_isReasonable (s))
10171 return multiVal_undefined;