2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2002 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; */
96 static void sRef_checkMutable (/*@unused@*/ sRef s)
99 if (sRef_isValid (s) && s->immut)
101 llcontbug (message ("Modification to sRef marked immutable: %q",
102 sRef_unparseFull (s)));
106 static bool skind_isSimple (skind sk)
110 case SK_PARAM: case SK_CVAR: case SK_CONST:
111 case SK_OBJECT: case SK_UNKNOWN: case SK_NEW:
118 static void sinfo_free (/*@special@*/ /*@temp@*/ /*@notnull@*/ sRef p_s)
119 /*@uses p_s->kind, p_s->info@*/
120 /*@releases p_s->info@*/ ;
122 static /*@null@*/ sinfo sinfo_copy (/*@notnull@*/ sRef p_s) /*@*/ ;
123 static void sRef_setPartsFromUentry (sRef p_s, uentry p_ue)
125 static bool checkDeadState (/*@notnull@*/ sRef p_el, bool p_tbranch, fileloc p_loc);
126 static /*@dependent@*/ sRef sRef_constructPointerAux (/*@notnull@*/ /*@exposed@*/ sRef p_t) /*@*/ ;
129 sRef_combineExKinds (/*@notnull@*/ sRef p_res, /*@notnull@*/ sRef p_other)
130 /*@modifies p_res@*/ ;
133 sRef_combineAliasKinds (/*@notnull@*/ sRef p_res, /*@notnull@*/ sRef p_other,
134 clause p_cl, fileloc p_loc)
135 /*@modifies p_res@*/ ;
138 sRef_combineNullState (/*@notnull@*/ sRef p_res, /*@notnull@*/ sRef p_other)
139 /*@modifies p_res@*/ ;
142 sRef_combineDefState (/*@notnull@*/ sRef p_res, /*@notnull@*/ sRef p_other)
143 /*@modifies p_res@*/ ;
145 static void sRef_setStateFromAbstractUentry (sRef p_s, uentry p_ue)
149 sinfo_update (/*@notnull@*/ /*@exposed@*/ sRef p_res,
150 /*@notnull@*/ /*@exposed@*/ sRef p_other);
151 static void sRef_setDefinedAux (sRef p_s, fileloc p_loc, bool p_clear)
153 static void sRef_setDefinedNoClear (sRef p_s, fileloc p_loc)
155 static void sRef_setStateAux (sRef p_s, sstate p_ss, fileloc p_loc)
158 static /*@exposed@*/ sRef
159 sRef_buildNCField (/*@exposed@*/ sRef p_rec, /*@exposed@*/ cstring p_f);
162 sRef_mergeStateAux (/*@notnull@*/ sRef p_res, /*@notnull@*/ sRef p_other,
163 clause p_cl, bool p_opt, fileloc p_loc,
165 /*@modifies p_res, p_other@*/ ;
167 static /*@null@*/ sinfo sinfo_fullCopy (/*@notnull@*/ sRef p_s);
168 static bool sRef_doModify (sRef p_s, sRefSet p_sl) /*@modifies p_s@*/ ;
169 static bool sRef_doModifyVal (sRef p_s, sRefSet p_sl) /*@modifies p_s@*/;
170 static bool sRef_checkModifyVal (sRef p_s, sRefSet p_sl) /*@*/ ;
172 static /*@only@*/ sRefSet
173 sRef_mergeDerivs (/*@only@*/ sRefSet p_res, sRefSet p_other,
174 bool p_opt, clause p_cl, fileloc p_loc);
176 static /*@only@*/ sRefSet
177 sRef_mergeUnionDerivs (/*@only@*/ sRefSet p_res,
178 /*@exposed@*/ sRefSet p_other,
179 bool p_opt, clause p_cl, fileloc p_loc);
181 static /*@only@*/ sRefSet
182 sRef_mergePdefinedDerivs (/*@only@*/ sRefSet p_res, sRefSet p_other, bool p_opt,
183 clause p_cl, fileloc p_loc);
185 static /*@only@*/ cstring sRef_unparseWithArgs (sRef p_s, uentryList p_args);
186 static /*@only@*/ cstring sRef_unparseNoArgs (sRef p_s);
188 static /*@exposed@*/ sRef sRef_findDerivedPointer (sRef p_s);
189 static /*@exposed@*/ sRef sRef_findDerivedArrayFetch (/*@notnull@*/ sRef, bool, int, bool) ;
190 static /*@exposed@*/ sRef sRef_findDerivedField (/*@notnull@*/ sRef p_rec, cstring p_f);
191 static /*@exposed@*/ sRef
192 sRef_getDeriv (/*@notnull@*/ /*@returned@*/ sRef p_set, sRef p_guide);
194 static bool inFunction = FALSE;
195 static /*@only@*/ sRefTable allRefs;
197 /* # define DEBUGREFS */
201 static totnsrefs = 0;
202 static maxnsrefs = 0;
203 static ntotrefers = 0;
207 static /*@checked@*/ bool protectDerivs = FALSE;
210 ** Result of sRef_alloc is dependent since allRefs may
211 ** reference it. It is only if !inFunction.
214 static /*@dependent@*/ /*@out@*/ /*@notnull@*/ sRef
217 sRef s = (sRef) dmalloc (sizeof (*s));
221 DPRINTF (("Alloc sref: [%p]", s));
225 allRefs = sRefTable_add (allRefs, s);
230 DPRINTF (("Not in function!"));
236 if (nsrefs >= maxnsrefs)
245 /*@-mustfree@*/ /*@-freshtrans@*/
247 /*@=mustfree@*/ /*@=freshtrans@*/
250 static void sRef_checkValidAux (sRef s, sRefSet checkedsofar)
254 if (!sRef_isValid (s)) return;
256 if (sRefSet_containsSameObject (checkedsofar, s))
262 checkedsofar = sRefSet_insert (checkedsofar, s);
263 /*@=temptrans@*/ /* checksofar will be destroyed before checkValid returns */
267 case SK_UNCONSTRAINED:
268 llassert (cstring_length (s->info->fname) < 100);
272 llassert (s->info->cvar->lexlevel >= 0);
273 /* llassert (s->info->cvar->lexlevel <= usymtab_getCurrentDepth ()); */
277 llassert (s->info->paramno >= -1);
278 llassert (s->info->paramno <= 50); /*@i32 bogus...*/
282 sRef_checkValidAux (s->info->arrayfetch->arr, checkedsofar);
286 sRef_checkValidAux (s->info->field->rec, checkedsofar);
287 llassert (cstring_length (s->info->field->field) < 100);
291 sRef_checkValidAux (s->info->ref, checkedsofar);
295 sRef_checkValidAux (s->info->ref, checkedsofar);
299 /* check ctype s->info->object */
303 sRef_checkValidAux (s->info->conj->a, checkedsofar);
304 sRef_checkValidAux (s->info->conj->b, checkedsofar);
308 llassert (cstring_length (s->info->fname) < 100);
312 sRef_checkValidAux (s->info->ref, checkedsofar);
316 sRef_checkValidAux (s->info->ref, checkedsofar);
322 /* check ctyp s->type */
326 llassert (s->info->spec == SR_NOTHING
327 || s->info->spec == SR_INTERNAL
328 || s->info->spec == SR_SPECSTATE
329 || s->info->spec == SR_SYSTEM);
339 sRefSet_elements (s->deriv, el)
341 sRef_checkValidAux (el, checkedsofar);
342 } end_sRefSet_elements ;
345 void sRef_checkValid (/*@unused@*/ sRef s)
349 sRefSet checkedsofar = sRefSet_new ();
350 sRef_checkValidAux (s, checkedsofar);
354 static /*@dependent@*/ /*@notnull@*/ /*@special@*/ sRef
357 /*@ensures isnull result->aliasinfo, result->definfo,
358 result->expinfo, result->info, result->deriv, result->state@*/
360 sRef s = sRef_alloc ();
362 s->kind = SK_UNKNOWN;
366 s->val = multiVal_undefined;
368 s->type = ctype_unknown;
369 s->defstate = SS_UNKNOWN;
371 /* start modifications */
372 s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
373 s->bufinfo.size = -1; /*@i24 unknown@*/
374 s->bufinfo.len = -1; /*@i24 unknown@*/
375 /* end modifications */
377 s->aliaskind = AK_UNKNOWN;
378 s->oaliaskind = AK_UNKNOWN;
380 s->nullstate = NS_UNKNOWN;
382 s->expkind = XO_UNKNOWN;
383 s->oexpkind = XO_UNKNOWN;
385 s->aliasinfo = stateInfo_undefined;
386 s->definfo = stateInfo_undefined;
387 s->nullinfo = stateInfo_undefined;
388 s->expinfo = stateInfo_undefined;
391 s->deriv = sRefSet_undefined;
393 s->state = valueTable_undefined;
398 static /*@dependent@*/ /*@notnull@*/ /*@special@*/ sRef
401 /*@ensures isnull result->aliasinfo, result->definfo,
402 result->expinfo, result->info, result->deriv@*/
404 sRef res = sRef_new ();
406 res->state = valueTable_undefined;
411 void sRef_protectDerivs (void) /*@modifies protectDerivs@*/
413 llassert (!protectDerivs);
414 protectDerivs = TRUE;
417 void sRef_clearProtectDerivs (void) /*@modifies protectDerivs@*/
419 llassert (protectDerivs);
420 protectDerivs = FALSE;
424 ** hmmm...here be kind of a hack. This function mysteriously appeared
425 ** in my code, but I'm sure I didn't write it.
429 sRef_isRecursiveField (sRef s)
431 if (sRef_isField (s))
433 if (sRef_depth (s) > 13)
438 fieldname = sRef_getField (s);
439 base = sRef_getBase (s);
441 while (sRef_isValid (base))
443 if (sRef_isField (base))
445 if (cstring_equal (fieldname, sRef_getField (base)))
451 base = sRef_getBaseSafe (base);
460 sRef_addDeriv (/*@notnull@*/ sRef s, /*@notnull@*/ /*@exposed@*/ sRef t)
462 if (!context_inProtectVars ()
466 && !sRef_isConst (s))
468 int sd = sRef_depth (s);
469 int td = sRef_depth (t);
476 /* This sometimes fails: (evans 2001-07-12)
477 if (sRef_isArrayFetch (t))
479 DPRINTF (("Derived fetch: %s / %s / %s",
480 sRef_unparseFull (s), sRef_unparseFull (t),
481 sRef_unparseFull (t->info->arrayfetch->arr)));
482 llassert (t->info->arrayfetch->arr == s);
486 if (sRef_isFileOrGlobalScope (s))
488 if (context_inFunctionLike ()
489 && ctype_isKnown (sRef_getType (s))
490 && !ctype_isFunction (sRef_getType (s)))
492 globSet g = context_getUsedGlobs ();
494 if (!globSet_member (g, s))
497 ** don't report as a bug
501 (message ("sRef_addDeriv: global variable not in used "
502 "globs: %q / %s / %q",
504 ctype_unparse (sRef_getType (s)),
505 sRefSet_unparse (s->deriv)));
510 s->deriv = sRefSet_insert (s->deriv, t);
516 DPRINTF (("Add deriv: [%p] %s / [%p] %s",
518 t, sRef_unparse (t)));
520 s->deriv = sRefSet_insert (s->deriv, t);
526 sRef_deepPred (bool (predf) (sRef), sRef s)
528 if (sRef_isValid (s))
530 if ((*predf)(s)) return TRUE;
535 return (sRef_deepPred (predf, s->info->ref));
537 return (sRef_deepPred (predf, s->info->arrayfetch->arr));
539 return (sRef_deepPred (predf, s->info->field->rec));
541 return (sRef_deepPred (predf, s->info->conj->a)
542 || sRef_deepPred (predf, s->info->conj->b));
551 bool sRef_modInFunction (void)
556 void sRef_setStateFromType (sRef s, ctype ct)
558 if (sRef_isValid (s))
560 if (ctype_isUser (ct))
562 DPRINTF (("Here we are: %s", sRef_unparseFull (s)));
563 sRef_setStateFromUentry
564 (s, usymtab_getTypeEntry (ctype_typeId (ct)));
566 else if (ctype_isAbstract (ct))
568 DPRINTF (("Here we are: %s", sRef_unparseFull (s)));
569 sRef_setStateFromAbstractUentry
570 (s, usymtab_getTypeEntry (ctype_typeId (ct)));
574 ; /* not a user type */
579 static void sRef_setTypeState (sRef s)
581 if (sRef_isValid (s))
583 sRef_setStateFromType (s, s->type);
588 sRef_hasAliasInfoLoc (sRef s)
590 return (sRef_isValid (s) && (s->aliasinfo != NULL)
591 && (fileloc_isDefined (s->aliasinfo->loc)));
594 static /*@falsewhennull@*/ bool
595 sRef_hasStateInfoLoc (sRef s)
597 return (sRef_isValid (s) && (s->definfo != NULL)
598 && (fileloc_isDefined (s->definfo->loc)));
601 static /*@falsewhennull@*/ bool
602 sRef_hasExpInfoLoc (sRef s)
604 return (sRef_isValid (s)
605 && (s->expinfo != NULL) && (fileloc_isDefined (s->expinfo->loc)));
609 static /*@observer@*/ /*@unused@*/ stateInfo sRef_getInfo (sRef s, cstring key)
613 if (!sRef_isValid (s)) {
614 return stateInfo_undefined;
617 sv = valueTable_lookup (s->state, key);
619 if (stateValue_isDefined (sv))
621 return stateValue_getInfo (sv);
624 return stateInfo_undefined;
629 sRef_hasNullInfoLoc (sRef s)
631 return (sRef_isValid (s) && s->nullinfo != NULL
632 && (fileloc_isDefined (s->nullinfo->loc)));
636 sRef_hasAliasInfoRef (sRef s)
638 return (sRef_isValid (s) && (s->aliasinfo != NULL)
639 && (sRef_isValid (s->aliasinfo->ref)));
642 static /*@observer@*/ fileloc
643 sRef_getAliasInfoLoc (/*@exposed@*/ sRef s)
645 llassert (sRef_isValid (s) && s->aliasinfo != NULL
646 && (fileloc_isDefined (s->aliasinfo->loc)));
647 return (s->aliasinfo->loc);
650 static /*@observer@*/ fileloc
651 sRef_getStateInfoLoc (/*@exposed@*/ sRef s)
653 llassert (sRef_isValid (s) && s->definfo != NULL
654 && (fileloc_isDefined (s->definfo->loc)));
655 return (s->definfo->loc);
658 static /*@observer@*/ fileloc
659 sRef_getExpInfoLoc (/*@exposed@*/ sRef s)
661 llassert (sRef_isValid (s) && s->expinfo != NULL
662 && (fileloc_isDefined (s->expinfo->loc)));
663 return (s->expinfo->loc);
666 static /*@observer@*/ fileloc
667 sRef_getNullInfoLoc (/*@exposed@*/ sRef s)
669 llassert (sRef_isValid (s) && s->nullinfo != NULL
670 && (fileloc_isDefined (s->nullinfo->loc)));
671 return (s->nullinfo->loc);
675 sRef_getAliasInfoRef (/*@temp@*/ sRef s)
677 llassert (sRef_isValid (s) && s->aliasinfo != NULL);
678 return (s->aliasinfo->ref);
681 bool sRef_inGlobalScope ()
687 ** This function should be called before new sRefs are created
688 ** somewhere where they will have a lifetime greater than the
689 ** current function scope.
692 void sRef_setGlobalScope ()
694 llassert (inFunction);
695 DPRINTF (("leave function"));
699 void sRef_clearGlobalScope ()
701 llassert (!inFunction);
702 DPRINTF (("enter function"));
706 static bool oldInFunction = FALSE;
707 static int nestedScope = 0;
709 void sRef_setGlobalScopeSafe ()
711 if (nestedScope == 0)
713 oldInFunction = inFunction;
717 DPRINTF (("leave function safe"));
721 void sRef_clearGlobalScopeSafe ()
724 llassert (nestedScope >= 0);
726 if (nestedScope == 0)
728 inFunction = oldInFunction;
731 DPRINTF (("clear function: %s", bool_unparse (inFunction)));
734 void sRef_enterFunctionScope ()
736 /* evans 2001-09-09 - cleanup if we are in a macro! */
737 if (context_inMacro ())
740 sRef_exitFunctionScope ();
744 llassert (!inFunction);
745 llassert (sRefTable_isEmpty (allRefs));
747 DPRINTF (("enter function"));
750 void sRef_exitFunctionScope ()
754 DPRINTF (("Exit function scope."));
755 sRefTable_clear (allRefs);
760 llbuglit ("sRef_exitFunctionScope: not in function");
764 void sRef_destroyMod () /*@globals killed allRefs;@*/
767 llmsg (message ("Live: %d / %d ", nsrefs, totnsrefs));
770 sRefTable_free (allRefs);
774 static /*@notnull@*/ /*@exposed@*/ sRef
775 sRef_fixConj (/*@notnull@*/ sRef s)
780 s = sRef_getConjA (s);
781 } while (sRef_isConj (s));
783 llassert (sRef_isValid (s));
784 return s; /* don't need to ref */
793 sRef_isExternallyVisibleAux (sRef s)
796 sRef base = sRef_getRootBase (s);
798 if (sRef_isValid (base))
800 res = sRef_isParam (base) || sRef_isFileOrGlobalScope (base) || sRef_isExternal (base);
807 sRef_isExternallyVisible (sRef s)
809 return (sRef_aliasCheckSimplePred (sRef_isExternallyVisibleAux, s));
813 sRef_getBaseUentry (sRef s)
815 sRef base = sRef_getRootBase (s);
816 uentry res = uentry_undefined;
818 if (sRef_isValid (base))
823 res = usymtab_getRefQuiet (paramsScope, base->info->paramno);
827 res = usymtab_getRefQuiet (base->info->cvar->lexlevel,
828 base->info->cvar->index);
840 ** lookup the current uentry corresponding to s, and return the corresponding sRef.
841 ** yuk yuk yuk yuk yuk yuk yuk yuk
845 sRef_updateSref (sRef s)
851 if (!sRef_isValid (s)) return sRef_undefined;
860 case SK_UNCONSTRAINED:
867 sRef r = sRef_updateSref (s->info->ref);
869 if (r != s->info->ref)
871 return sRef_makeExternal (r);
881 uentry ue = sRef_getUentry (s);
883 /* must be raw name! (need the marker) */
884 ue = usymtab_lookupSafe (uentry_rawName (ue));
886 if (uentry_isUndefined (ue))
892 DPRINTF (("Update sref: %s", uentry_unparseFull (ue)));
893 return (uentry_getSref (ue));
897 /* special case if ind known */
898 inner = s->info->arrayfetch->arr;
899 ret = sRef_updateSref (inner);
907 res = sRef_makeArrayFetch (ret);
913 inner = s->info->field->rec;
914 ret = sRef_updateSref (inner);
922 res = (sRef_makeField (ret, s->info->field->field));
927 inner = s->info->ref;
928 ret = sRef_updateSref (inner);
935 res = sRef_makePointer (ret);
941 inner = s->info->ref;
942 ret = sRef_updateSref (inner);
950 res = sRef_makeAddress (ret);
957 sRef innera = s->info->conj->a;
958 sRef innerb = s->info->conj->b;
959 sRef reta = sRef_updateSref (innera);
960 sRef retb = sRef_updateSref (innerb);
962 if (innera == reta && innerb == retb)
968 res = sRef_makeConj (reta, retb);
979 sRef_getUentry (sRef s)
981 llassert (sRef_isValid (s));
986 return (usymtab_getRefQuiet (paramsScope, s->info->paramno));
988 return (usymtab_getRefQuiet (s->info->cvar->lexlevel, s->info->cvar->index));
991 if (sRef_isCvar (s->info->conj->a) || sRef_isParam (s->info->conj->a)
992 || sRef_isConj (s->info->conj->a))
994 return sRef_getUentry (s->info->conj->a);
998 return sRef_getUentry (s->info->conj->b);
1003 return uentry_undefined;
1009 sRef_getParam (sRef s)
1011 llassert (sRef_isValid (s));
1012 llassert (s->kind == SK_PARAM);
1014 return s->info->paramno;
1018 sRef_isModified (sRef s)
1020 return (!sRef_isValid (s) || s->modified);
1023 void sRef_setModified (sRef s)
1025 if (sRef_isValid (s))
1030 if (sRef_isRefsField (s))
1032 sRef base = sRef_getBase (s);
1034 llassert (s->kind == SK_FIELD);
1036 if (sRef_isPointer (base))
1038 base = sRef_getBase (base);
1041 if (sRef_isRefCounted (base))
1043 base->aliaskind = AK_NEWREF;
1050 ** note: this side-effects sRefSet to set modified to TRUE
1051 ** for any sRef similar to s.
1055 sRef_canModifyVal (sRef s, sRefSet sl)
1057 if (context_getFlag (FLG_MUSTMOD))
1059 return (sRef_doModifyVal (s, sl));
1063 return (sRef_checkModifyVal (s, sl));
1068 sRef_canModify (sRef s, sRefSet sl)
1070 if (context_getFlag (FLG_MUSTMOD))
1072 return (sRef_doModify (s, sl));
1076 return (sRef_checkModify (s, sl));
1085 bool sRef_checkModifyVal (sRef s, sRefSet sl)
1087 DPRINTF (("Check modify val: %s", sRef_unparse (s)));
1089 if (sRef_isInvalid (s))
1096 case SK_UNCONSTRAINED:
1100 DPRINTF (("Modify var: %s", sRef_unparse (s)));
1102 if (sRef_isFileOrGlobalScope (s))
1104 if (context_checkGlobMod (s))
1106 return (sRefSet_member (sl, s));
1116 return (sRefSet_member (sl, s)
1117 || alkind_isOnly (sRef_getOrigAliasKind (s)));
1119 /* special case if ind known */
1120 return (sRefSet_member (sl, s) ||
1121 sRef_checkModifyVal (s->info->arrayfetch->arr, sl));
1123 return (sRefSet_member (sl, s) || sRef_checkModifyVal (s->info->field->rec, sl));
1125 return (sRefSet_member (sl, s) || sRef_checkModifyVal (s->info->ref, sl));
1127 return (sRefSet_member (sl, s) || sRef_checkModifyVal (s->info->ref, sl));
1129 return ((sRef_checkModifyVal (s->info->conj->a, sl)) &&
1130 (sRef_checkModifyVal (s->info->conj->b, sl)));
1141 switch (s->info->spec)
1143 case SR_NOTHING: return TRUE;
1145 if (context_getFlag (FLG_INTERNALGLOBS))
1147 return (sRefSet_member (sl, s));
1153 case SR_SPECSTATE: return TRUE;
1154 case SR_SYSTEM: return (sRefSet_member (sl, s));
1155 case SR_GLOBALMARKER: BADBRANCH;
1158 case SK_RESULT: BADBRANCH;
1164 ** this should probably be elsewhere...
1166 ** returns TRUE iff sl indicates that s can be modified
1169 static bool sRef_checkModify (sRef s, sRefSet sl)
1171 llassert (sRef_isValid (s));
1175 case SK_UNCONSTRAINED:
1179 if (sRef_isFileOrGlobalScope (s))
1181 if (context_checkGlobMod (s))
1183 return (sRefSet_member (sl, s));
1195 return (sRefSet_member (sl, s) ||
1196 sRef_checkModifyVal (s->info->arrayfetch->arr, sl));
1199 sRef sr = s->info->field->rec;
1201 if (sr->kind == SK_PARAM)
1202 return TRUE; /* structs are copied on call */
1204 return (sRefSet_member (sl, s) || sRef_checkModifyVal (s->info->field->rec, sl));
1210 sm = sRefSet_member (sl, s);
1215 return (sRef_checkModifyVal (s->info->ref, sl));
1218 return (sRefSet_member (sl, s) || sRef_checkModifyVal (s->info->ref, sl));
1220 return ((sRef_checkModify (s->info->conj->a, sl)) &&
1221 (sRef_checkModify (s->info->conj->b, sl)));
1231 switch (s->info->spec)
1233 case SR_NOTHING: return TRUE;
1235 if (context_getFlag (FLG_INTERNALGLOBS))
1237 return (sRefSet_member (sl, s));
1243 case SR_SPECSTATE: return TRUE;
1244 case SR_SYSTEM: return (sRefSet_member (sl, s));
1245 case SR_GLOBALMARKER: BADBRANCH;
1248 case SK_RESULT: BADBRANCH;
1253 cstring sRef_stateVerb (sRef s)
1255 if (sRef_isDead (s))
1257 return cstring_makeLiteralTemp ("released");
1259 else if (sRef_isKept (s))
1261 return cstring_makeLiteralTemp ("kept");
1263 else if (sRef_isDependent (s))
1265 return cstring_makeLiteralTemp ("dependent");
1273 cstring sRef_stateAltVerb (sRef s)
1275 if (sRef_isDead (s))
1277 return cstring_makeLiteralTemp ("live");
1279 else if (sRef_isKept (s))
1281 return cstring_makeLiteralTemp ("not kept");
1283 else if (sRef_isDependent (s))
1285 return cstring_makeLiteralTemp ("independent");
1294 bool sRef_doModifyVal (sRef s, sRefSet sl)
1296 llassert (sRef_isValid (s));
1301 case SK_UNCONSTRAINED:
1305 if (sRef_isFileOrGlobalScope (s))
1308 if (context_checkGlobMod (s))
1310 return (sRefSet_modifyMember (sl, s));
1314 (void) sRefSet_modifyMember (sl, s);
1324 return (sRefSet_modifyMember (sl, s)
1325 || alkind_isOnly (sRef_getOrigAliasKind (s)));
1327 /* special case if ind known */
1328 /* unconditional OR, need side effect */
1329 return (OR (sRefSet_modifyMember (sl, s),
1330 sRef_doModifyVal (s->info->arrayfetch->arr, sl)));
1332 return (OR (sRefSet_modifyMember (sl, s),
1333 sRef_doModifyVal (s->info->field->rec, sl)));
1335 return (OR (sRefSet_modifyMember (sl, s),
1336 sRef_doModifyVal (s->info->ref, sl)));
1338 return (OR (sRefSet_modifyMember (sl, s),
1339 sRef_doModifyVal (s->info->ref, sl)));
1341 return (AND (sRef_doModifyVal (s->info->conj->a, sl) ,
1342 sRef_doModifyVal (s->info->conj->b, sl)));
1352 switch (s->info->spec)
1354 case SR_NOTHING: return TRUE;
1356 if (context_getFlag (FLG_INTERNALGLOBS))
1358 return (sRefSet_modifyMember (sl, s));
1362 (void) sRefSet_modifyMember (sl, s);
1365 case SR_SPECSTATE: return TRUE;
1366 case SR_SYSTEM: return (sRefSet_modifyMember (sl, s));
1367 case SR_GLOBALMARKER: BADBRANCH;
1371 case SK_RESULT: BADBRANCH;
1377 ** this should probably be elsewhere...
1379 ** returns TRUE iff sl indicates that s can be modified
1383 bool sRef_doModify (sRef s, sRefSet sl)
1385 llassert (sRef_isValid (s));
1389 case SK_UNCONSTRAINED:
1393 if (sRef_isFileOrGlobalScope (s))
1395 if (context_checkGlobMod (s))
1397 return (sRefSet_modifyMember (sl, s));
1401 (void) sRefSet_modifyMember (sl, s);
1413 return (OR (sRefSet_modifyMember (sl, s),
1414 sRef_doModifyVal (s->info->arrayfetch->arr, sl)));
1417 sRef sr = s->info->field->rec;
1419 if (sr->kind == SK_PARAM)
1421 return TRUE; /* structs are shallow-copied on call */
1424 return (OR (sRefSet_modifyMember (sl, s),
1425 sRef_doModifyVal (s->info->field->rec, sl)));
1429 return (OR (sRefSet_modifyMember (sl, s),
1430 sRef_doModifyVal (s->info->ref, sl)));
1433 return (OR (sRefSet_modifyMember (sl, s),
1434 sRef_doModifyVal (s->info->ref, sl)));
1436 return (AND (sRef_doModify (s->info->conj->a, sl),
1437 (sRef_doModify (s->info->conj->b, sl))));
1448 switch (s->info->spec)
1450 case SR_NOTHING: return TRUE;
1451 case SR_INTERNAL: return TRUE;
1452 case SR_SPECSTATE: return TRUE;
1453 case SR_SYSTEM: return (sRefSet_modifyMember (sl, s));
1454 case SR_GLOBALMARKER: BADBRANCH;
1457 case SK_RESULT: BADBRANCH;
1462 static /*@exposed@*/ sRef
1463 sRef_leastCommon (/*@exposed@*/ sRef s1, sRef s2)
1465 llassert (sRef_similar (s1, s2));
1467 if (!sRef_isValid (s1)) return s1;
1468 if (!sRef_isValid (s2)) return s1;
1470 sRef_combineDefState (s1, s2);
1471 sRef_combineNullState (s1, s2);
1472 sRef_combineExKinds (s1, s2);
1474 if (s1->aliaskind != s2->aliaskind)
1476 if (s1->aliaskind == AK_UNKNOWN)
1478 s1->aliaskind = s2->aliaskind;
1480 else if (s2->aliaskind == AK_UNKNOWN)
1486 s1->aliaskind = AK_ERROR;
1493 int sRef_compare (sRef s1, sRef s2)
1495 if (s1 == s2) return 0;
1497 if (sRef_isInvalid (s1)) return -1;
1498 if (sRef_isInvalid (s2)) return 1;
1500 INTCOMPARERETURN (s1->kind, s2->kind);
1501 INTCOMPARERETURN (s1->defstate, s2->defstate);
1502 INTCOMPARERETURN (s1->aliaskind, s2->aliaskind);
1504 DPRINTF (("Compare null state: %s / %s",
1505 sRef_unparseFull (s1),
1506 sRef_unparseFull (s2)));
1508 COMPARERETURN (nstate_compare (sRef_getNullState (s1),
1509 sRef_getNullState (s2)));
1514 return (int_compare (s1->info->paramno, s2->info->paramno));
1517 COMPARERETURN (sRef_compare (s1->info->arrayfetch->arr,
1518 s2->info->arrayfetch->arr));
1520 if (s1->info->arrayfetch->indknown && s2->info->arrayfetch->indknown)
1522 return (int_compare (s1->info->arrayfetch->ind,
1523 s2->info->arrayfetch->ind));
1525 if (!s1->info->arrayfetch->indknown && !s2->info->arrayfetch->indknown)
1532 COMPARERETURN (sRef_compare (s1->info->field->rec, s2->info->field->rec));
1534 if (cstring_equal (s1->info->field->field, s2->info->field->field))
1541 return (sRef_compare (s1->info->ref, s2->info->ref));
1543 COMPARERETURN (sRef_compare (s1->info->conj->a, s2->info->conj->a));
1544 return (sRef_compare (s1->info->conj->b, s2->info->conj->b));
1545 case SK_UNCONSTRAINED:
1546 return (cstring_compare (s1->info->fname, s2->info->fname));
1558 return (generic_compare (s1->info->spec, s2->info->spec));
1563 static bool cref_equal (cref c1, cref c2)
1565 return ((c1->lexlevel == c2->lexlevel) &&
1566 (usymId_equal (c1->index, c2->index)));
1570 ** returns true if s1 could be the same storage as s2.
1571 ** i.e., a[?] ~ a[3]. Note its not symmetric ... s1
1572 ** should be more specific.
1576 ** like similar, but matches objects <-> non-objects
1580 sRef_uniqueReference (sRef s)
1582 return (sRef_isFresh (s) || sRef_isUnique (s)
1583 || sRef_isOnly (s) || sRef_isStack (s)
1584 || sRef_isAddress (s));
1588 sRef_similarRelaxedAux (sRef s1, sRef s2)
1592 if (sRef_isUnknownArrayFetch (s1))
1602 if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
1604 if (sRef_isConj (s2))
1605 return (sRef_similarRelaxedAux (s1, sRef_getConjA (s2)) ||
1606 sRef_similarRelaxedAux (s1, sRef_getConjB (s2)));
1611 return ((s2->kind == SK_CVAR)
1612 && (cref_equal (s1->info->cvar, s2->info->cvar)));
1614 return ((s2->kind == SK_PARAM)
1615 && (s1->info->paramno == s2->info->paramno));
1617 if (s2->kind == SK_ARRAYFETCH)
1619 if (sRef_similarRelaxedAux (s1->info->arrayfetch->arr,
1620 s2->info->arrayfetch->arr))
1622 if (s1->info->arrayfetch->indknown)
1624 if (s2->info->arrayfetch->indknown)
1626 return (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind);
1641 return ((s2->kind == SK_FIELD
1642 && (sRef_similarRelaxedAux (s1->info->field->rec,
1643 s2->info->field->rec)
1644 && cstring_equal (s1->info->field->field,
1645 s2->info->field->field))));
1647 return ((s2->kind == SK_PTR)
1648 && sRef_similarRelaxedAux (s1->info->ref, s2->info->ref));
1650 return ((s2->kind == SK_ADR)
1651 && sRef_similarRelaxedAux (s1->info->ref, s2->info->ref));
1653 return ((sRef_similarRelaxedAux (s1->info->conj->a, s2) ||
1654 (sRef_similarRelaxedAux (s1->info->conj->b, s2))));
1656 return (s1->info->spec == s2->info->spec);
1657 case SK_UNCONSTRAINED:
1658 return (cstring_equal (s1->info->fname, s2->info->fname));
1673 sRef_similarRelaxed (sRef s1, sRef s2)
1679 if (sRef_isThroughArrayFetch (s1))
1689 if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
1691 us1 = sRef_uniqueReference (s1);
1692 us2 = sRef_uniqueReference (s2);
1694 if ((s1->kind == SK_EXTERNAL && (s2->kind != SK_EXTERNAL && !us2))
1695 || (s2->kind == SK_EXTERNAL && (s1->kind != SK_EXTERNAL && !us1)))
1698 ** Previously, also:
1699 ** || (sRef_isExposed (s1) && !us2) || (sRef_isExposed (s2) && !us1)) ????
1701 ** No clue why this was there?!
1705 if (sRef_isExposed (s1) && sRef_isCvar (s1))
1707 uentry ue1 = sRef_getUentry (s1);
1709 if (uentry_isRefParam (ue1))
1711 return sRef_similarRelaxedAux (s1, s2);
1715 if (sRef_isExposed (s2) && sRef_isCvar (s2))
1717 uentry ue2 = sRef_getUentry (s2);
1719 if (uentry_isRefParam (ue2))
1721 return sRef_similarRelaxedAux (s1, s2);
1725 return (ctype_match (s1->type, s2->type));
1729 return sRef_similarRelaxedAux (s1, s2);
1734 sRef_similar (sRef s1, sRef s2)
1736 if (s1 == s2) return TRUE;
1737 if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
1739 if (sRef_isConj (s2))
1741 return (sRef_similar (s1, sRef_getConjA (s2)) ||
1742 sRef_similar (s1, sRef_getConjB (s2)));
1745 if (sRef_isDerived (s2))
1747 return (sRef_includedBy (s1, s2->info->ref));
1753 return ((s2->kind == SK_CVAR)
1754 && (cref_equal (s1->info->cvar, s2->info->cvar)));
1756 return ((s2->kind == SK_PARAM)
1757 && (s1->info->paramno == s2->info->paramno));
1759 if (s2->kind == SK_ARRAYFETCH)
1761 if (sRef_similar (s1->info->arrayfetch->arr,
1762 s2->info->arrayfetch->arr))
1764 if (s1->info->arrayfetch->indknown)
1766 if (s2->info->arrayfetch->indknown)
1768 return (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind);
1783 if (s2->kind == SK_PTR)
1785 if (sRef_similar (s1->info->arrayfetch->arr,
1795 return ((s2->kind == SK_FIELD
1796 && (sRef_similar (s1->info->field->rec,
1797 s2->info->field->rec)
1798 && cstring_equal (s1->info->field->field,
1799 s2->info->field->field))));
1801 if (s2->kind == SK_PTR)
1803 return sRef_similar (s1->info->ref, s2->info->ref);
1807 if (s2->kind == SK_ARRAYFETCH)
1809 if (sRef_similar (s2->info->arrayfetch->arr,
1819 return ((s2->kind == SK_ADR)
1820 && sRef_similar (s1->info->ref, s2->info->ref));
1822 return ((sRef_similar (s1->info->conj->a, s2) ||
1823 (sRef_similar (s1->info->conj->b, s2))));
1825 return (sRef_includedBy (s2, s1->info->ref));
1826 case SK_UNCONSTRAINED:
1827 return (s2->kind == SK_UNCONSTRAINED
1828 && cstring_equal (s1->info->fname, s2->info->fname));
1838 return (s2->kind == SK_SPECIAL
1839 && (s1->info->spec == s2->info->spec));
1842 /*@notreached@*/ DPRINTF (("Fell through for: %s / %s", sRef_unparse (s1), sRef_unparse (s2)));
1847 ** return TRUE iff small can be derived from big.
1849 ** (e.g. x, x.a is includedBy x;
1850 ** x.a is included By x.a;
1854 sRef_includedBy (sRef small, sRef big)
1856 if (small == big) return TRUE;
1857 if (sRef_isInvalid (small) || sRef_isInvalid (big)) return FALSE;
1859 if (sRef_isConj (big))
1860 return (sRef_similar (small, sRef_getConjA (big)) ||
1861 sRef_similar (small, sRef_getConjB (big)));
1863 switch (small->kind)
1867 return (sRef_same (small, big));
1869 if (big->kind == SK_ARRAYFETCH)
1871 if (sRef_same (small->info->arrayfetch->arr, big->info->arrayfetch->arr))
1873 if (small->info->arrayfetch->indknown)
1875 if (big->info->arrayfetch->indknown)
1877 return (small->info->arrayfetch->ind == big->info->arrayfetch->ind);
1890 return (sRef_includedBy (small->info->arrayfetch->arr, big));
1892 if (big->kind == SK_FIELD)
1895 (sRef_same (small->info->field->rec, big->info->field->rec) &&
1896 cstring_equal (small->info->field->field, big->info->field->field));
1900 return (sRef_includedBy (small->info->field->rec, big));
1904 if (big->kind == SK_PTR)
1906 return sRef_same (small->info->ref, big->info->ref);
1910 return (sRef_includedBy (small->info->ref, big));
1914 return ((big->kind == SK_ADR) && sRef_similar (small->info->ref, big->info->ref));
1916 return ((sRef_includedBy (small->info->conj->a, big) ||
1917 (sRef_includedBy (small->info->conj->b, big))));
1919 return (sRef_includedBy (small->info->ref, big));
1920 case SK_UNCONSTRAINED:
1930 switch (small->info->spec)
1932 case SR_NOTHING: return TRUE;
1934 case SR_INTERNAL: return (sRef_isSpecInternalState (big) ||
1935 sRef_isFileStatic (big));
1936 case SR_SYSTEM: return (sRef_isSystemState (big));
1937 case SR_GLOBALMARKER: BADBRANCH;
1944 ** Same is similar to similar, but not quite the same.
1945 ** same and realSame aren't the same, but they are really similar.
1946 ** similarly, same is the same as same. but realSame is
1947 ** not really the same as same, or similar to similar.
1949 ** Similarly to similar, same checks if two sRefs are the same.
1950 ** The similarities end, however, when same compares arrays
1951 ** with unknown indexes. Similar returns false; same returns true.
1953 ** Similarly to similar and same, realSame is the same as same,
1954 ** except they do not behave the same when face with unknown
1955 ** sRefs. Same thinks they are not the same, but realSame thinks
1961 sRef_realSame (sRef s1, sRef s2)
1963 if (s1 == s2) return TRUE;
1964 if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
1969 return ((s2->kind == SK_CVAR) && (cref_equal (s1->info->cvar, s2->info->cvar)));
1971 return ((s2->kind == SK_PARAM) && (s1->info->paramno == s2->info->paramno));
1973 if (s2->kind == SK_ARRAYFETCH)
1975 if (sRef_realSame (s1->info->arrayfetch->arr, s2->info->arrayfetch->arr))
1977 if (s1->info->arrayfetch->indknown && s2->info->arrayfetch->indknown)
1979 return (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind);
1981 if (!s1->info->arrayfetch->indknown && !s2->info->arrayfetch->indknown)
1990 return ((s2->kind == SK_FIELD &&
1991 (sRef_realSame (s1->info->field->rec, s2->info->field->rec) &&
1992 cstring_equal (s1->info->field->field, s2->info->field->field))));
1994 return ((s2->kind == SK_PTR) && sRef_realSame (s1->info->ref, s2->info->ref));
1996 return ((s2->kind == SK_ADR) && sRef_realSame (s1->info->ref, s2->info->ref));
1998 return ((sRef_realSame (s1->info->conj->a, s2) ||
1999 (sRef_realSame (s1->info->conj->b, s2))));
2001 return ((s2->kind == SK_OBJECT)
2002 && ctype_match (s1->info->object, s2->info->object));
2004 return ((s2->kind == SK_EXTERNAL)
2005 && sRef_realSame (s1->info->ref, s2->info->ref));
2007 return ((s2->kind == SK_SPECIAL) && s1->info->spec == s2->info->spec);
2009 return ((s2->kind == SK_DERIVED) && sRef_realSame (s1->info->ref, s2->info->ref));
2010 case SK_UNCONSTRAINED:
2011 return ((s2->kind == SK_UNCONSTRAINED)
2012 && (cstring_equal (s1->info->fname, s2->info->fname)));
2018 return TRUE; /* changed this! was false */
2024 sRef_sameObject (sRef s1, sRef s2)
2030 ** same is similar to similar, but not quite the same.
2032 ** Similarly to similar, same checks is two sRefs are the same.
2033 ** The similarities end, however, when same compares arrays
2034 ** with unknown indexes. Similar returns false; same returns true.
2038 sRef_same (sRef s1, sRef s2)
2040 if (s1 == s2) return TRUE;
2041 if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
2046 return ((s2->kind == SK_CVAR) && (cref_equal (s1->info->cvar, s2->info->cvar)));
2048 return ((s2->kind == SK_PARAM) && (s1->info->paramno == s2->info->paramno));
2050 if (s2->kind == SK_ARRAYFETCH)
2052 llassert (s1->info->field->rec != s1);
2053 if (sRef_same (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);
2065 llassert (s1->info->field->rec != s1);
2066 return ((s2->kind == SK_FIELD &&
2067 (sRef_same (s1->info->field->rec, s2->info->field->rec) &&
2068 cstring_equal (s1->info->field->field, s2->info->field->field))));
2072 llassert (s1->info->ref != s1);
2073 return ((s2->kind == SK_PTR) && sRef_same (s1->info->ref, s2->info->ref));
2077 llassert (s1->info->ref != s1);
2078 return ((s2->kind == SK_ADR) && sRef_same (s1->info->ref, s2->info->ref));
2081 llassert (s1->info->conj->a != s1);
2082 llassert (s1->info->conj->b != s1);
2083 return ((sRef_same (s1->info->conj->a, s2)) && /* or or and? */
2084 (sRef_same (s1->info->conj->b, s2)));
2086 return ((s2->kind == SK_SPECIAL) && s1->info->spec == s2->info->spec);
2088 llassert (s1->info->ref != s1);
2089 return ((s2->kind == SK_DERIVED) && sRef_same (s1->info->ref, s2->info->ref));
2091 case SK_UNCONSTRAINED:
2104 ** sort of similar, for use in def/use
2108 sRef_closeEnough (sRef s1, sRef s2)
2110 if (s1 == s2) return TRUE;
2111 if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
2116 return (((s2->kind == SK_CVAR) &&
2117 (cref_equal (s1->info->cvar, s2->info->cvar))) ||
2118 (s2->kind == SK_UNCONSTRAINED && s1->info->cvar->lexlevel == 0));
2119 case SK_UNCONSTRAINED:
2120 return (s2->kind == SK_UNCONSTRAINED
2121 || ((s2->kind == SK_CVAR) && (s2->info->cvar->lexlevel == 0)));
2123 return ((s2->kind == SK_PARAM)
2124 && (s1->info->paramno == s2->info->paramno));
2126 if (s2->kind == SK_ARRAYFETCH)
2128 if (sRef_closeEnough (s1->info->arrayfetch->arr, s2->info->arrayfetch->arr))
2130 if (s1->info->arrayfetch->indknown && s2->info->arrayfetch->indknown)
2132 return (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind);
2139 return ((s2->kind == SK_FIELD &&
2140 (sRef_closeEnough (s1->info->field->rec, s2->info->field->rec) &&
2141 cstring_equal (s1->info->field->field, s2->info->field->field))));
2143 return ((s2->kind == SK_PTR) && sRef_closeEnough (s1->info->ref, s2->info->ref));
2145 return ((s2->kind == SK_ADR) && sRef_closeEnough (s1->info->ref, s2->info->ref));
2147 return ((s2->kind == SK_DERIVED) && sRef_closeEnough (s1->info->ref, s2->info->ref));
2149 return ((sRef_closeEnough (s1->info->conj->a, s2)) ||
2150 (sRef_closeEnough (s1->info->conj->b, s2)));
2152 return ((s2->kind == SK_SPECIAL) && s1->info->spec == s2->info->spec);
2168 s is an sRef of a formal paramenter in a function call constraint
2169 we trys to return a constraint expression derived from the actual parementer of a function call.
2172 /*@only@*/ constraintExpr sRef_fixConstraintParam (/*@observer@*/ sRef s, /*@observer@*/ /*@temp@*/ exprNodeList args)
2176 if (sRef_isInvalid (s))
2177 llfatalbug((message("Invalid sRef")));
2183 /* s = sRef_saveCopy(s); */ /*@i523@*/
2184 ce = constraintExpr_makeTermsRef (s);
2191 temp = (sRef_makeField (sRef_fixBaseParam (s->info->field->rec, args),
2192 s->info->field->field));
2193 ce = constraintExpr_makeTermsRef (temp);
2199 temp = (sRef_makePointer (sRef_fixBaseParam (s->info->ref, args)));
2200 /* temp = sRef_saveCopy(temp); */ /*@i523@*/
2201 ce = constraintExpr_makeTermsRef (temp);
2208 temp = sRef_saveCopy(s);
2209 temp = sRef_fixBaseParam (temp, args);
2210 ce = constraintExpr_makeTermsRef (temp);
2218 temp = sRef_saveCopy(s);
2219 ce = constraintExpr_makeTermsRef (temp);
2224 llassert(exprNodeList_size (args) > s->info->paramno);
2226 exprNode e = exprNodeList_nth (args, s->info->paramno);
2228 llassert( !(exprNode_isError (e)) );
2229 ce = constraintExpr_makeExprNode (e);
2236 llcontbug (message ("Trying to do fixConstraintParam on nonparam, nonglobal: %q for function with arguments %q",
2237 sRef_unparse (s), exprNodeList_unparse(args)));
2238 temp = sRef_saveCopy(s);
2239 ce = constraintExpr_makeTermsRef (temp);
2248 sRef_fixBaseParam (/*@returned@*/ sRef s, exprNodeList args)
2250 if (sRef_isInvalid (s)) return (sRef_undefined);
2254 case SK_UNCONSTRAINED:
2259 if (exprNodeList_size (args) > s->info->paramno)
2261 exprNode e = exprNodeList_nth (args, s->info->paramno);
2263 if (exprNode_isError (e))
2265 return sRef_makeUnknown ();
2268 return (exprNode_getSref (e));
2272 return sRef_makeUnknown ();
2277 if (s->info->arrayfetch->indknown)
2279 return (sRef_makeArrayFetchKnown
2280 (sRef_fixBaseParam (s->info->arrayfetch->arr, args),
2281 s->info->arrayfetch->ind));
2285 return (sRef_makeArrayFetch
2286 (sRef_fixBaseParam (s->info->arrayfetch->arr, args)));
2291 DPRINTF (("Fix field: %s", sRef_unparseFull (s)));
2292 res = sRef_makeField (sRef_fixBaseParam (s->info->field->rec, args),
2293 s->info->field->field);
2294 DPRINTF (("Returns: %s", sRef_unparseFull (res)));
2298 return (sRef_makePointer (sRef_fixBaseParam (s->info->ref, args)));
2301 return (sRef_makeAddress (sRef_fixBaseParam (s->info->ref, args)));
2304 return (sRef_makeConj (sRef_fixBaseParam (s->info->conj->a, args),
2305 sRef_fixBaseParam (s->info->conj->b, args)));
2321 sRef_undumpGlobal (char **c)
2331 usymId uid = usymId_fromInt (reader_getInt (c));
2336 reader_checkChar (c, '@');
2337 defstate = sstate_fromInt (reader_getInt (c));
2339 reader_checkChar (c, '@');
2340 nullstate = nstate_fromInt (reader_getInt (c));
2342 ret = sRef_makeGlobal (uid, ctype_unknown, stateInfo_currentLoc ());
2343 sRef_setNullStateN (ret, nullstate);
2344 ret->defstate = defstate;
2349 int i = reader_getInt (c);
2350 speckind sk = speckind_fromInt (i);
2354 case SR_NOTHING: return (sRef_makeNothing ());
2355 case SR_INTERNAL: return (sRef_makeInternalState ());
2356 case SR_SPECSTATE: return (sRef_makeSpecState ());
2357 case SR_SYSTEM: return (sRef_makeSystemState ());
2358 case SR_GLOBALMARKER: BADBRANCH;
2363 return sRef_undefined;
2365 return sRef_makeUnknown ();
2367 return sRef_makeUnknown ();
2369 llfatalerror (message ("sRef_undumpGlobal: bad line: %s",
2370 cstring_fromChars (*c)));
2375 static /*@exposed@*/ sRef sRef_undumpBody (char **c)
2384 return (sRef_makeGlobal (usymId_fromInt (reader_getInt (c)), ctype_unknown, stateInfo_currentLoc ()));
2386 return (sRef_makeParam (reader_getInt (c), ctype_unknown, stateInfo_makeLoc (g_currentloc)));
2388 return (sRef_makeResult (ctype_undump (c)));
2391 if ((**c >= '0' && **c <= '9') || **c == '-')
2393 int i = reader_getInt (c);
2394 sRef arr = sRef_undump (c);
2395 sRef ret = sRef_buildArrayFetchKnown (arr, i);
2401 sRef arr = sRef_undump (c);
2402 sRef ret = sRef_buildArrayFetch (arr);
2409 cstring fname = cstring_undefined;
2414 fname = cstring_appendChar (fname, **c);
2419 ret = sRef_buildField (sRef_undump (c), fname);
2420 cstring_markOwned (fname);
2425 int i = reader_getInt (c);
2426 speckind sk = speckind_fromInt (i);
2430 case SR_NOTHING: return (sRef_makeNothing ());
2431 case SR_INTERNAL: return (sRef_makeInternalState ());
2432 case SR_SPECSTATE: return (sRef_makeSpecState ());
2433 case SR_SYSTEM: return (sRef_makeSystemState ());
2434 case SR_GLOBALMARKER: BADBRANCH;
2440 sRef ptr = sRef_undump (c);
2441 sRef ret = sRef_makePointer (ptr);
2447 sRef adr = sRef_undump (c);
2448 sRef ret = sRef_makeAddress (adr);
2454 return (sRef_makeObject (ctype_undump (c)));
2458 sRef s1 = sRef_undump (c);
2459 sRef s2 = ((*c)++, sRef_undump (c));
2460 sRef ret = sRef_makeConj (s1, s2);
2465 return sRef_undefined;
2467 return sRef_makeUnknown ();
2469 return sRef_makeUnknown ();
2471 llfatalerror (message ("sRef_undump: bad line: %s", cstring_fromChars (*c)));
2476 /*@exposed@*/ sRef sRef_undump (char **c)
2478 sRef res = sRef_undumpBody (c);
2480 if (reader_optCheckChar (c, '='))
2482 multiVal mv = multiVal_undump (c);
2483 sRef_setValue (res, mv);
2484 reader_checkChar (c, '=');
2490 static /*@only@*/ cstring sRef_dumpBody (sRef s)
2492 if (sRef_isInvalid (s))
2494 return (cstring_makeLiteral ("-"));
2501 return (message ("p%d", s->info->paramno));
2503 if (s->info->arrayfetch->indknown)
2505 return (message ("a%d%q", s->info->arrayfetch->ind,
2506 sRef_dump (s->info->arrayfetch->arr)));
2510 return (message ("a%q", sRef_dump (s->info->arrayfetch->arr)));
2513 return (message ("f%s.%q", s->info->field->field,
2514 sRef_dump (s->info->field->rec)));
2516 return (message ("t%q", sRef_dump (s->info->ref)));
2518 return (message ("d%q", sRef_dump (s->info->ref)));
2520 return (message ("o%q", ctype_dump (s->info->object)));
2522 return (message ("s%d", (int) s->info->spec));
2524 return (message ("c%q.%q",
2525 sRef_dump (s->info->conj->a),
2526 sRef_dump (s->info->conj->b)));
2528 if (sRef_isFileOrGlobalScope (s))
2530 return (message ("g%d",
2531 usymtab_convertId (s->info->cvar->index)));
2535 llcontbug (message ("Dumping local variable: %q",
2536 sRef_unparseDebug (s)));
2537 return (cstring_makeLiteral ("u"));
2540 return (cstring_makeLiteral ("u"));
2542 return (message ("r%q", ctype_dump (s->type)));
2548 case SK_UNCONSTRAINED:
2549 llcontbug (message ("sRef_dump: bad kind: %q",
2550 sRef_unparseFull (s)));
2551 return (cstring_makeLiteral ("x"));
2558 /*@only@*/ cstring sRef_dump (sRef s)
2560 cstring res = sRef_dumpBody (s);
2562 if (sRef_hasValue (s))
2564 res = message ("%q=%q=", res, multiVal_dump (sRef_getValue (s)));
2570 cstring sRef_dumpGlobal (sRef s)
2572 llassert (!sRef_hasValue (s));
2574 if (sRef_isInvalid (s))
2576 return (cstring_makeLiteral ("-"));
2583 if (sRef_isFileOrGlobalScope (s))
2585 return (message ("g%d@%d@%d",
2586 usymtab_convertId (s->info->cvar->index),
2588 (int) sRef_getNullState (s)));
2592 llcontbug (message ("Dumping local variable: %q",
2593 sRef_unparseDebug (s)));
2594 return (cstring_makeLiteral ("u"));
2597 return (cstring_makeLiteral ("u"));
2599 return (message ("s%d", (int) s->info->spec));
2601 llcontbug (message ("sRef_dumpGlobal: bad kind: %q",
2602 sRef_unparseFull (s)));
2603 return (cstring_makeLiteral ("x"));
2611 sRef_deriveType (sRef s, uentryList cl)
2613 if (sRef_isInvalid (s)) return ctype_unknown;
2618 return (uentry_getType (usymtab_getRefQuiet (s->info->cvar->lexlevel,
2619 s->info->cvar->index)));
2620 case SK_UNCONSTRAINED:
2621 return (ctype_unknown);
2623 if (s->info->paramno >= 0)
2625 return uentry_getType (uentryList_getN (cl, s->info->paramno));
2629 return ctype_unknown;
2633 ctype ca = sRef_deriveType (s->info->arrayfetch->arr, cl);
2635 if (ctype_isArray (ca))
2637 return (ctype_baseArrayPtr (ca));
2639 else if (ctype_isUnknown (ca))
2645 llcontbuglit ("sRef_deriveType: inconsistent array type");
2651 ctype ct = sRef_deriveType (s->info->field->rec, cl);
2653 if (ctype_isStructorUnion (ct))
2655 uentry ue = uentryList_lookupField (ctype_getFields (ct),
2656 s->info->field->field);
2658 if (uentry_isValid (ue))
2660 return (uentry_getType (ue));
2664 llcontbuglit ("sRef_deriveType: bad field");
2665 return ctype_unknown;
2668 else if (ctype_isUnknown (ct))
2674 llcontbuglit ("sRef_deriveType: inconsistent field type");
2680 ctype ct = sRef_deriveType (s->info->ref, cl);
2682 if (ctype_isUnknown (ct)) return ct;
2683 if (ctype_isPointer (ct)) return (ctype_baseArrayPtr (ct));
2686 llcontbuglit ("sRef_deriveType: inconsistent pointer type");
2692 ctype ct = sRef_deriveType (s->info->ref, cl);
2694 if (ctype_isUnknown (ct)) return ct;
2695 return ctype_makePointer (ct);
2699 return sRef_deriveType (s->info->ref, cl);
2703 return (s->info->object);
2707 return (ctype_makeConj (sRef_deriveType (s->info->conj->a, cl),
2708 sRef_deriveType (s->info->conj->b, cl)));
2720 return ctype_unknown;
2726 sRef_getType (sRef s)
2728 if (sRef_isInvalid (s)) return ctype_unknown;
2734 sRef_unparseOpt (sRef s)
2736 sRef rb = sRef_getRootBase (s);
2738 if (sRef_isMeaningful (rb) && !sRef_isConst (rb))
2740 cstring ret = sRef_unparse (s);
2742 llassertprint (!cstring_equalLit (ret, "?"), ("print: %s", sRef_unparseDebug (s)));
2744 if (!cstring_isEmpty (ret))
2746 return (cstring_appendChar (ret, ' '));
2754 return cstring_undefined;
2758 sRef_unparsePreOpt (sRef s)
2760 sRef rb = sRef_getRootBase (s);
2762 if (sRef_isMeaningful (rb) && !sRef_isConst (rb))
2764 cstring ret = sRef_unparse (s);
2766 llassertprint (!cstring_equalLit (ret, "?"), ("print: %s", sRef_unparseDebug (s)));
2767 return (cstring_prependCharO (' ', ret));
2770 return cstring_undefined;
2774 sRef_unparse (sRef s)
2776 if (sRef_isInvalid (s)) return (cstring_makeLiteral ("?"));
2778 if (context_inFunctionLike ())
2780 return (sRef_unparseWithArgs (s, context_getParams ()));
2784 DPRINTF (("Not in function like: %s", context_unparse ()));
2785 return (sRef_unparseNoArgs (s));
2789 static /*@only@*/ cstring
2790 sRef_unparseWithArgs (sRef s, uentryList args)
2792 if (sRef_isInvalid (s))
2794 return (cstring_makeLiteral ("?"));
2800 return (uentry_getName (usymtab_getRefQuiet (s->info->cvar->lexlevel,
2801 s->info->cvar->index)));
2802 case SK_UNCONSTRAINED:
2803 return (cstring_copy (s->info->fname));
2806 if (s->info->paramno < uentryList_size (args)
2807 && s->info->paramno >= 0)
2809 uentry ue = uentryList_getN (args, s->info->paramno);
2811 if (uentry_isValid (ue))
2812 return uentry_getName (ue);
2815 return (message ("parameter %d", s->info->paramno + 1));
2818 if (s->info->arrayfetch->indknown)
2820 return (message ("%q[%d]", sRef_unparseWithArgs (s->info->arrayfetch->arr, args),
2821 s->info->arrayfetch->ind));
2825 return (message ("%q[]", sRef_unparseWithArgs (s->info->arrayfetch->arr, args)));
2828 if (s->info->field->rec->kind == SK_PTR)
2830 sRef ptr = s->info->field->rec;
2832 return (message ("%q->%s", sRef_unparseWithArgs (ptr->info->ref, args),
2833 s->info->field->field));
2835 return (message ("%q.%s", sRef_unparseWithArgs (s->info->field->rec, args),
2836 s->info->field->field));
2840 sRef ref = sRef_fixConj (s->info->ref);
2841 skind sk = ref->kind;
2846 ret = message ("storage pointed to by %q",
2847 sRef_unparseWithArgs (ref, args));
2849 else if (skind_isSimple (sk) || sk == SK_PTR)
2851 ret = message ("*%q", sRef_unparseWithArgs (ref, args));
2855 ret = message ("*(%q)", sRef_unparseWithArgs (ref, args));
2861 return (message ("&%q", sRef_unparseWithArgs (s->info->ref, args)));
2863 return (cstring_copy (ctype_unparse (s->info->object)));
2865 return (sRef_unparseWithArgs (sRef_getConjA (s), args));
2867 if (cstring_isDefined (s->info->fname))
2869 return (message ("[result of %s]", s->info->fname));
2873 return (cstring_makeLiteral ("<new>"));
2876 return (cstring_makeLiteral ("?"));
2878 return (message ("<derived %q>", sRef_unparse (s->info->ref)));
2880 return (message ("<external %q>", sRef_unparse (s->info->ref)));
2882 return (message ("<type %s>", ctype_unparse (s->type)));
2884 return (message ("<const %s>", ctype_unparse (s->type)));
2886 switch (s->info->spec)
2888 case SR_NOTHING: return cstring_makeLiteral ("nothing");
2889 case SR_INTERNAL: return cstring_makeLiteral ("internal state");
2890 case SR_SPECSTATE: return cstring_makeLiteral ("spec state");
2891 case SR_SYSTEM: return cstring_makeLiteral ("file system state");
2892 case SR_GLOBALMARKER: return cstring_makeLiteral ("<global marker>");
2896 return cstring_makeLiteral ("result");
2899 llbug (message ("Bad sref, kind = %d", (int) s->kind));
2907 sRef_unparseDebug (sRef s)
2909 if (sRef_isInvalid (s))
2911 return (cstring_makeLiteral ("<undef>"));
2917 case SK_UNCONSTRAINED:
2918 return (message ("<unconstrained %s>", s->info->fname));
2923 ce = usymtab_getRefQuiet (s->info->cvar->lexlevel, s->info->cvar->index);
2925 if (uentry_isInvalid (ce))
2927 return (message ("<scope: %d.%d *invalid*>",
2928 s->info->cvar->lexlevel,
2929 s->info->cvar->index));
2933 return (message ("<scope: %d.%d *%q*>",
2934 s->info->cvar->lexlevel,
2935 s->info->cvar->index,
2936 uentry_getName (ce)));
2942 return (message ("<parameter %d>", s->info->paramno + 1));
2945 if (s->info->arrayfetch->indknown)
2947 return (message ("%q[%d]", sRef_unparseDebug (s->info->arrayfetch->arr),
2948 s->info->arrayfetch->ind));
2952 return (message ("%q[]", sRef_unparseDebug (s->info->arrayfetch->arr)));
2955 return (message ("%q.%s", sRef_unparseDebug (s->info->field->rec),
2956 s->info->field->field));
2958 if (sRef_isField (s->info->ref))
2960 sRef fld = s->info->ref;
2962 return (message ("%q->%s", sRef_unparseDebug (fld->info->field->rec),
2963 fld->info->field->field));
2967 return (message ("*(%q)", sRef_unparseDebug (s->info->ref)));
2970 return (message ("&%q", sRef_unparseDebug (s->info->ref)));
2972 return (message ("<object type %s>", ctype_unparse (s->info->object)));
2974 return (message ("%q | %q", sRef_unparseDebug (s->info->conj->a),
2975 sRef_unparseDebug (s->info->conj->b)));
2977 return message ("<new: %s>", s->info->fname);
2979 return (message ("<derived %q>", sRef_unparseDebug (s->info->ref)));
2981 return (message ("<external %q>", sRef_unparseDebug (s->info->ref)));
2983 return (message ("<type %s>", ctype_unparse (s->type)));
2985 if (sRef_hasValue (s))
2987 return (message ("<const %s=%q>", ctype_unparse (s->type), multiVal_unparse (sRef_getValue (s))));
2991 return (message ("<const %s>", ctype_unparse (s->type)));
2994 return (message ("<result %s>", ctype_unparse (s->type)));
2996 return (message ("<spec %s>",
2997 cstring_makeLiteralTemp
2998 (s->info->spec == SR_NOTHING ? "nothing"
2999 : s->info->spec == SR_INTERNAL ? "internalState"
3000 : s->info->spec == SR_SPECSTATE ? "spec state"
3001 : s->info->spec == SR_SYSTEM ? "fileSystem"
3004 return cstring_makeLiteral ("<unknown>");
3010 static /*@only@*/ cstring
3011 sRef_unparseNoArgs (sRef s)
3013 if (sRef_isInvalid (s)) return (cstring_makeLiteral ("?"));
3017 case SK_UNCONSTRAINED:
3018 return (cstring_copy (s->info->fname));
3021 uentry ce = usymtab_getRefQuiet (s->info->cvar->lexlevel,
3022 s->info->cvar->index);
3024 if (uentry_isInvalid (ce))
3026 llcontbug (message ("sRef_unparseNoArgs: bad cvar: %q",
3027 sRef_unparseDebug (s)));
3028 return (sRef_unparseDebug (s));
3032 return (uentry_getName (ce));
3036 if (s->info->arrayfetch->indknown)
3038 return (message ("%q[%d]", sRef_unparseNoArgs (s->info->arrayfetch->arr),
3039 s->info->arrayfetch->ind));
3043 return (message ("%q[]", sRef_unparseNoArgs (s->info->arrayfetch->arr)));
3046 return (message ("%q.%s", sRef_unparseNoArgs (s->info->field->rec),
3047 s->info->field->field));
3050 sRef ref = sRef_fixConj (s->info->ref);
3051 skind sk = ref->kind;
3054 if (skind_isSimple (sk) || sk == SK_PTR)
3056 ret = message ("*%q", sRef_unparseNoArgs (ref));
3060 ret = message ("*(%q)", sRef_unparseNoArgs (ref));
3066 return (message ("&%q", sRef_unparseNoArgs (s->info->ref)));
3068 return (cstring_copy (ctype_unparse (s->info->object)));
3070 return (sRef_unparseNoArgs (s->info->conj->a));
3072 return (message ("result of %s", s->info->fname));
3074 return (message ("<der %q>", sRef_unparseNoArgs (s->info->ref)));
3076 return message ("<ext %q>", sRef_unparseNoArgs (s->info->ref));
3078 return (cstring_makeLiteral
3079 (s->info->spec == SR_NOTHING ? "nothing"
3080 : s->info->spec == SR_INTERNAL ? "internal state"
3081 : s->info->spec == SR_SPECSTATE ? "spec state"
3082 : s->info->spec == SR_SYSTEM ? "file system state"
3085 return cstring_makeLiteral ("result");
3089 return cstring_makeLiteral ("?");
3091 /* llcontbug (message ("sRef_unparseNoArgs: bad case: %q", sRef_unparseDebug (s))); */
3092 return (sRef_unparseDebug (s));
3097 /*@dependent@*/ sRef sRef_makeUnconstrained (cstring fname)
3099 sRef s = sRef_new ();
3101 s->kind = SK_UNCONSTRAINED;
3102 s->info = (sinfo) dmalloc (sizeof (*s->info));
3103 s->info->fname = fname;
3108 cstring sRef_unconstrainedName (sRef s)
3110 llassert (sRef_isUnconstrained (s));
3112 return s->info->fname;
3115 bool sRef_isUnconstrained (sRef s)
3117 return (sRef_isValid(s) && s->kind == SK_UNCONSTRAINED);
3120 static /*@dependent@*/ /*@notnull@*/ sRef
3121 sRef_makeCvarAux (int level, usymId index, ctype ct, /*@only@*/ stateInfo stinfo)
3123 sRef s = sRef_newRef ();
3126 s->info = (sinfo) dmalloc (sizeof (*s->info));
3128 s->info->cvar = (cref) dmalloc (sizeof (*s->info->cvar));
3129 s->info->cvar->lexlevel = level;
3130 s->info->cvar->index = index;
3132 /* for now, all globals are defined; all locals, aren't */
3134 if (level <= fileScope)
3136 s->defstate = SS_UNKNOWN;
3140 ctype rct = ctype_realType (ct);
3142 if (level != paramsScope
3143 && (ctype_isStructorUnion (rct) || ctype_isRealArray (rct)))
3145 s->defstate = SS_ALLOCATED;
3146 s->oaliaskind = s->aliaskind = AK_STACK;
3150 s->defstate = SS_UNDEFINED;
3151 s->oaliaskind = s->aliaskind = AK_LOCAL;
3157 llassert (level >= globScope);
3158 llassert (usymId_isValid (index));
3160 DPRINTF (("Made cvar: [%p] %s", s, sRef_unparseDebug (s)));
3161 llassert (valueTable_isUndefined (s->state));
3162 s->state = context_createValueTable (s, stinfo);
3166 /*@dependent@*/ sRef sRef_makeCvar (int level, usymId index, ctype ct, /*@only@*/ stateInfo stinfo)
3168 return (sRef_makeCvarAux (level, index, ct, stinfo));
3171 int sRef_lexLevel (sRef s)
3173 if (sRef_isValid (s))
3177 conj = sRef_fixConj (s);
3178 s = sRef_getRootBase (conj);
3180 if (sRef_isValid (s) && s->kind == SK_CVAR)
3182 return (s->info->cvar->lexlevel);
3190 sRef_makeGlobal (usymId l, ctype ct, /*@only@*/ stateInfo stinfo)
3192 return (sRef_makeCvar (globScope, l, ct, stinfo));
3196 sRef_setParamNo (sRef s, int l)
3198 llassert (sRef_isValid (s) && s->kind == SK_PARAM);
3199 s->info->paramno = l;
3203 /*@dependent@*/ sRef
3204 sRef_makeParam (int l, ctype ct, stateInfo stinfo)
3206 sRef s = sRef_new ();
3211 s->info = (sinfo) dmalloc (sizeof (*s->info));
3212 s->info->paramno = l;
3214 s->defstate = SS_UNKNOWN;
3215 /* (probably defined, unless its an out parameter) */
3217 llassert (valueTable_isUndefined (s->state));
3218 s->state = context_createValueTable (s, stinfo);
3223 sRef_isIndexKnown (sRef arr)
3227 llassert (sRef_isValid (arr));
3228 arr = sRef_fixConj (arr);
3230 llassert (arr->kind == SK_ARRAYFETCH);
3231 res = arr->info->arrayfetch->indknown;
3236 sRef_getIndex (sRef arr)
3240 llassert (sRef_isValid (arr));
3241 arr = sRef_fixConj (arr);
3243 llassert (arr->kind == SK_ARRAYFETCH);
3245 if (!arr->info->arrayfetch->indknown)
3247 llcontbug (message ("sRef_getIndex: unknown: %q", sRef_unparse (arr)));
3252 result = arr->info->arrayfetch->ind;
3258 static bool sRef_isZerothArrayFetch (/*@notnull@*/ sRef s)
3260 return (s->kind == SK_ARRAYFETCH
3261 && s->info->arrayfetch->indknown
3262 && (s->info->arrayfetch->ind == 0));
3265 /*@exposed@*/ sRef sRef_makeAddress (/*@exposed@*/ sRef t)
3268 if (sRef_isInvalid (t)) return sRef_undefined;
3270 if (sRef_isPointer (t))
3272 return (t->info->ref);
3274 else if (sRef_isZerothArrayFetch (t))
3276 return (t->info->arrayfetch->arr);
3280 sRef s = sRef_newRef ();
3283 s->type = ctype_makePointer (t->type);
3284 s->info = (sinfo) dmalloc (sizeof (*s->info));
3285 s->info->ref = t; /* sRef_copy (t); */ /*@i32@*/
3287 if (t->defstate == SS_UNDEFINED)
3288 /* no! it is allocated even still: && !ctype_isPointer (t->type)) */
3290 s->defstate = SS_ALLOCATED;
3294 s->defstate = t->defstate;
3297 if (t->aliaskind == AK_LOCAL)
3299 if (sRef_isLocalVar (t))
3301 s->aliaskind = AK_STACK;
3305 llassert (valueTable_isUndefined (s->state));
3306 s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
3311 cstring sRef_getField (sRef s)
3315 llassert (sRef_isValid (s));
3316 s = sRef_fixConj (s);
3318 llassertprint (sRef_isValid (s) && (s->kind == SK_FIELD),
3319 ("s = %s", sRef_unparseDebug (s)));
3321 res = s->info->field->field;
3325 sRef sRef_getBase (sRef s)
3329 if (sRef_isInvalid (s)) return (sRef_undefined);
3331 s = sRef_fixConj (s);
3342 res = s->info->field->rec;
3346 res = s->info->arrayfetch->arr;
3350 res = sRef_undefined; /* shouldn't need it */
3357 ** same as getBase, except returns invalid
3358 ** (and doesn't use adr's)
3362 sRef_getBaseSafe (sRef s)
3366 if (sRef_isInvalid (s)) { return sRef_undefined; }
3368 s = sRef_fixConj (s);
3376 res = s->info->field->rec; break;
3378 res = s->info->arrayfetch->arr;
3381 res = sRef_undefined; break;
3387 /*@constant int MAXBASEDEPTH;@*/
3388 # define MAXBASEDEPTH 25
3390 static /*@exposed@*/ sRef
3391 sRef_getRootBaseAux (sRef s, int depth)
3393 if (sRef_isInvalid (s)) return sRef_undefined;
3395 if (depth > MAXBASEDEPTH)
3398 ("Warning: reference base limit exceeded for %q. "
3399 "This either means there is a variable with at least "
3400 "%d indirections from this reference, or "
3401 "there is a bug in Splint.",
3406 return sRef_undefined;
3413 return (sRef_getRootBaseAux (s->info->ref, depth + 1));
3415 return (sRef_getRootBaseAux (s->info->field->rec, depth + 1));
3417 return (sRef_getRootBaseAux (s->info->arrayfetch->arr, depth + 1));
3419 return (sRef_getRootBaseAux (sRef_fixConj (s), depth + 1));
3425 sRef sRef_getRootBase (sRef s)
3427 return (sRef_getRootBaseAux (s, 0));
3430 static bool sRef_isDeep (sRef s)
3432 if (sRef_isInvalid (s)) return FALSE;
3442 return (sRef_isDeep (sRef_fixConj (s)));
3448 static int sRef_depth (sRef s)
3450 if (sRef_isInvalid (s)) return 0;
3458 return 1 + sRef_depth (s->info->ref);
3460 return 1 + sRef_depth (s->info->field->rec);
3462 return 1 + sRef_depth (s->info->arrayfetch->arr);
3464 return (sRef_depth (sRef_fixConj (s)));
3471 sRef_makeObject (ctype o)
3473 sRef s = sRef_newRef (); /*@i423 same line is bad...@*/
3475 s->kind = SK_OBJECT;
3476 s->info = (sinfo) dmalloc (sizeof (*s->info));
3477 s->info->object = o;
3478 llassert (valueTable_isUndefined (s->state));
3479 s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
3484 ** This is used to represent storage referenced by a parameter.
3487 sRef sRef_makeExternal (sRef t)
3489 sRef s = sRef_newRef ();
3491 llassert (sRef_isValid (t));
3493 s->kind = SK_EXTERNAL;
3494 s->info = (sinfo) dmalloc (sizeof (*s->info));
3496 s->info->ref = t; /* sRef_copy (t); */ /*@i32 was exposed@*/
3497 llassert (valueTable_isUndefined (s->state));
3498 s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
3502 /*@dependent@*/ sRef sRef_makeDerived (/*@exposed@*/ sRef t)
3504 if (sRef_isValid (t))
3506 sRef s = sRef_newRef ();
3508 s->kind = SK_DERIVED;
3509 s->info = (sinfo) dmalloc (sizeof (*s->info));
3510 s->info->ref = t; /* sRef_copy (t); */ /*@i32@*/
3513 llassert (valueTable_isUndefined (s->state));
3514 s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
3519 return sRef_undefined;
3524 ** definitely NOT symmetric:
3526 ** res fills in unknown state information from other
3530 sRef_mergeStateQuiet (sRef res, sRef other)
3532 llassert (sRef_isValid (res));
3533 llassert (sRef_isValid (other));
3535 res->modified = res->modified || other->modified;
3536 res->safe = res->safe && other->safe;
3538 if (res->defstate == SS_UNKNOWN)
3540 res->defstate = other->defstate;
3541 res->definfo = stateInfo_update (res->definfo, other->definfo);
3544 if (res->aliaskind == AK_UNKNOWN ||
3545 (res->aliaskind == AK_LOCAL && alkind_isKnown (other->aliaskind)))
3547 res->aliaskind = other->aliaskind;
3548 res->oaliaskind = other->oaliaskind;
3549 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
3552 if (res->expkind == XO_UNKNOWN)
3554 res->expkind = other->expkind;
3555 res->oexpkind = other->oexpkind;
3556 res->expinfo = stateInfo_update (res->expinfo, other->expinfo);
3559 /* out takes precedence over implicitly defined */
3560 if (res->defstate == SS_DEFINED && other->defstate != SS_UNKNOWN)
3562 res->defstate = other->defstate;
3563 res->definfo = stateInfo_update (res->definfo, other->definfo);
3566 if (sRef_getNullState (other) == NS_ERROR || sRef_getNullState (res) == NS_ERROR)
3568 sRef_setNullState (res, NS_ERROR, fileloc_undefined);
3572 if (sRef_getNullState (other) != NS_UNKNOWN
3573 && (sRef_getNullState (res) == NS_UNKNOWN || sRef_getNullState (res) == NS_NOTNULL
3574 || sRef_getNullState (res) == NS_MNOTNULL))
3576 sRef_updateNullState (res, other);
3582 ** definitely NOT symmetric:
3584 ** res fills in known state information from other
3588 sRef_mergeStateQuietReverse (/*@dependent@*/ sRef res, /*@dependent@*/ sRef other)
3590 bool changed = FALSE;
3592 llassert (sRef_isValid (res));
3593 llassert (sRef_isValid (other));
3594 sRef_checkMutable (res);
3596 if (res->kind != other->kind)
3602 res->kind = other->kind;
3603 res->type = other->type;
3604 res->info = sinfo_fullCopy (other);
3608 if (!ctype_equal (res->type, other->type))
3611 res->type = other->type;
3614 sinfo_update (res, other);
3617 res->modified = res->modified || other->modified;
3618 res->safe = res->safe && other->safe;
3620 if (res->aliaskind != other->aliaskind
3621 && (res->aliaskind == AK_UNKNOWN
3622 || ((res->aliaskind == AK_LOCAL
3623 || (res->aliaskind == AK_REFCOUNTED
3624 && other->aliaskind != AK_LOCAL))
3625 && other->aliaskind != AK_UNKNOWN)))
3628 res->aliaskind = other->aliaskind;
3629 res->oaliaskind = other->oaliaskind;
3630 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
3633 if (other->expkind != XO_UNKNOWN && other->expkind != res->expkind)
3636 res->expkind = other->expkind;
3637 res->expinfo = stateInfo_update (res->expinfo, other->expinfo);
3640 if (other->oexpkind != XO_UNKNOWN)
3642 res->oexpkind = other->oexpkind;
3645 /* out takes precedence over implicitly defined */
3647 if (res->defstate != other->defstate)
3649 if (other->defstate != SS_UNKNOWN)
3651 res->defstate = other->defstate;
3655 if (sRef_getNullState (other) == NS_ERROR || sRef_getNullState (res) == NS_ERROR)
3657 if (sRef_getNullState (res) != NS_ERROR)
3659 sRef_setNullStateN (res, NS_ERROR);
3665 if (sRef_getNullState (other) != NS_UNKNOWN && sRef_getNullState (other) != sRef_getNullState (res))
3668 sRef_updateNullState (res, other);
3674 sRef_clearDerived (res);
3679 sRef_mergeState (sRef res, sRef other, clause cl, fileloc loc)
3681 if (sRef_isValid (res) && sRef_isValid (other))
3683 sRef_mergeStateAux (res, other, cl, FALSE, loc, TRUE);
3687 if (sRef_isInvalid (res))
3689 llbug (message ("sRef_mergeState: invalid res sRef: %q",
3690 sRef_unparseDebug (other)));
3694 llbug (message ("sRef_mergeState: invalid other sRef: %q",
3695 sRef_unparseDebug (res)));
3701 sRef_mergeOptState (sRef res, sRef other, clause cl, fileloc loc)
3703 if (sRef_isValid (res) && sRef_isValid (other))
3705 sRef_mergeStateAux (res, other, cl, TRUE, loc, TRUE);
3709 if (sRef_isInvalid (res))
3711 llbug (message ("sRef_mergeOptState: invalid res sRef: %q",
3712 sRef_unparseDebug (other)));
3716 llbug (message ("sRef_mergeOptState: invalid other sRef: %q",
3717 sRef_unparseDebug (res)));
3723 sRef_mergeStateAux (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other,
3724 clause cl, bool opt, fileloc loc,
3728 llassertfatal (sRef_isValid (res));
3729 llassertfatal (sRef_isValid (other));
3731 DPRINTF (("Merge aux: %s / %s",
3732 sRef_unparseFull (res),
3733 sRef_unparseFull (other)));
3735 sRef_checkMutable (res);
3736 sRef_checkMutable (other);
3738 res->modified = res->modified || other->modified;
3740 if (res->kind == other->kind
3741 || (other->kind == SK_UNKNOWN || res->kind == SK_UNKNOWN))
3743 sstate odef = other->defstate;
3744 sstate rdef = res->defstate;
3745 nstate onull = sRef_getNullState (other);
3748 ** yucky stuff to handle
3753 if (other->defstate == SS_DEAD
3754 && ((sRef_isOnly (res) && sRef_definitelyNull (res))
3755 || (res->defstate == SS_UNDEFINED
3756 || res->defstate == SS_UNUSEABLE)))
3758 if (res->defstate == SS_UNDEFINED
3759 || res->defstate == SS_UNUSEABLE)
3761 res->defstate = SS_UNUSEABLE;
3765 res->defstate = SS_DEAD;
3768 res->definfo = stateInfo_update (res->definfo, other->definfo);
3769 sRef_clearDerived (other);
3770 sRef_clearDerived (res);
3772 else if (res->defstate == SS_DEAD
3773 && ((sRef_isOnly (other) && sRef_definitelyNull (other))
3774 || (other->defstate == SS_UNDEFINED
3775 || other->defstate == SS_UNUSEABLE)))
3777 if (other->defstate == SS_UNDEFINED
3778 || other->defstate == SS_UNUSEABLE)
3780 res->defstate = SS_UNUSEABLE;
3784 res->defstate = SS_DEAD;
3787 sRef_clearDerived (other);
3788 sRef_clearDerived (res);
3790 else if (res->defstate == SS_DEFINED
3791 && (other->defstate == SS_ALLOCATED
3792 && sRef_definitelyNull (other)))
3794 other->defstate = SS_DEFINED; /* definitely null! */
3796 else if (other->defstate == SS_DEFINED
3797 && (res->defstate == SS_ALLOCATED && sRef_definitelyNull (res)))
3799 res->defstate = SS_DEFINED;
3800 res->definfo = stateInfo_update (res->definfo, other->definfo);
3807 if (res->defstate == SS_DEAD && other->defstate == SS_DEAD)
3809 sRef_clearDerived (other);
3810 sRef_clearDerived (res);
3814 ** only & dead isn't really an only!
3817 if (alkind_isOnly (other->aliaskind) && other->defstate == SS_DEAD)
3819 other->aliaskind = AK_UNKNOWN;
3822 if (alkind_isOnly (res->aliaskind) && res->defstate == SS_DEAD)
3824 res->aliaskind = AK_UNKNOWN;
3828 ** Dead and dependent -> dead
3831 if (alkind_isDependent (other->aliaskind) && res->defstate == SS_DEAD)
3833 other->aliaskind = AK_UNKNOWN;
3834 other->defstate = SS_DEAD;
3835 sRef_clearDerived (res);
3836 sRef_clearDerived (other);
3839 if (alkind_isDependent (res->aliaskind) && other->defstate == SS_DEAD)
3841 res->aliaskind = AK_UNKNOWN;
3842 res->defstate = SS_DEAD;
3843 sRef_clearDerived (res);
3844 sRef_clearDerived (other);
3848 ** must do alias combine first, since it depends on
3849 ** original values of state and null.
3852 sRef_combineAliasKinds (res, other, cl, loc);
3853 sRef_combineDefState (res, other);
3854 sRef_combineNullState (res, other);
3856 if (rdef == SS_ALLOCATED || rdef == SS_SPECIAL)
3858 if (odef == SS_DEFINED)
3860 if (onull == NS_DEFNULL || onull == NS_CONSTNULL)
3862 res->deriv = sRefSet_copyInto (res->deriv, other->deriv);
3863 DPRINTF (("Copy derivs: %s", sRef_unparseFull (res)));
3866 else if (odef == SS_ALLOCATED || odef == SS_SPECIAL)
3871 if (ctype_isUnion (ctype_realType (sRef_getType (res))))
3873 res->deriv = sRef_mergeUnionDerivs (res->deriv,
3876 DPRINTF (("Copy derivs: %s", sRef_unparseFull (res)));
3880 res->deriv = sRef_mergeDerivs (res->deriv, other->deriv,
3882 DPRINTF (("Copy derivs: %s", sRef_unparseFull (res)));
3890 res->deriv = sRef_mergeDerivs (res->deriv, other->deriv,
3892 DPRINTF (("Copy derivs: %s", sRef_unparseFull (res)));
3902 if (rdef == SS_PDEFINED
3903 || (rdef == SS_DEFINED && odef == SS_PDEFINED))
3907 res->deriv = sRef_mergePdefinedDerivs (res->deriv, other->deriv,
3909 DPRINTF (("Copy derivs: %s", sRef_unparseFull (res)));
3914 if ((rdef == SS_DEFINED || rdef == SS_UNKNOWN)
3915 && res->defstate == SS_ALLOCATED)
3917 res->deriv = sRefSet_copyInto (res->deriv, other->deriv);
3923 res->deriv = sRef_mergeDerivs (res->deriv, other->deriv,
3925 DPRINTF (("Copy derivs: %s", sRef_unparseFull (res)));
3932 sRef_combineExKinds (res, other);
3936 if (res->kind == SK_ARRAYFETCH && other->kind == SK_PTR)
3938 sRef nother = sRef_buildArrayFetchKnown (sRef_getBase (other), 0);
3940 sRef_copyState (nother, other);
3941 sRef_mergeStateAux (res, nother, cl, opt, loc, doDerivs);
3943 else if (res->kind == SK_PTR && other->kind == SK_ARRAYFETCH)
3945 sRef nother = sRef_buildPointer (sRef_getBase (other));
3947 if (sRef_isValid (nother))
3949 sRef_copyState (nother, other);
3950 sRef_mergeStateAux (res, nother, cl, opt, loc, doDerivs);
3955 llcontbug (message ("merge conj: %q / %q", sRef_unparseFull (res),
3956 sRef_unparseFull (other)));
3962 ** Merge value table states
3969 ** This doesn't do anything. And its broken too...
3972 valueTable_elements (res->state, key, sv)
3974 stateValue os = valueTable_lookup (other->state, key);
3975 /*@unused@*/ int val;
3976 /*@unused@*/ char *msg;
3978 llassert (stateValue_isDefined (os));
3980 DPRINTF (("Merge state: %s / %s",
3981 cstring_toCharsSafe (stateValue_unparse (sv)),
3982 cstring_toCharsSafe (stateValue_unparse (os))));
3984 val = valueMatix_lookup (key,
3985 stateValue_getValue (os),
3986 stateValue_getValue (sv),
3988 DPRINTF (("Val: %d / %s", val, msg));
3990 } end_valueTable_elements ;
3993 DPRINTF (("Merge aux: %s / %s",
3994 sRef_unparseFull (res),
3995 sRef_unparseFull (other)));
3999 sRef_mergeUnionDerivs (/*@only@*/ sRefSet res,
4000 /*@exposed@*/ sRefSet other, bool opt,
4001 clause cl, fileloc loc)
4003 if (sRefSet_isEmpty (res))
4005 return sRefSet_copyInto (res, other);
4009 sRefSet_allElements (other, el)
4011 if (sRef_isValid (el))
4013 sRef e2 = sRefSet_lookupMember (other, el);
4015 if (sRef_isValid (e2))
4017 sRef_mergeStateAux (el, e2, cl, opt, loc, FALSE);
4021 res = sRefSet_insert (res, el);
4024 } end_sRefSet_allElements ;
4030 static /*@only@*/ sRefSet
4031 sRef_mergeDerivs (/*@only@*/ sRefSet res, sRefSet other,
4032 bool opt, clause cl, fileloc loc)
4034 sRefSet ret = sRefSet_new ();
4036 sRefSet_allElements (res, el)
4038 if (sRef_isValid (el))
4040 sRef e2 = sRefSet_lookupMember (other, el);
4042 if (sRef_isValid (e2))
4044 if (el->defstate == SS_ALLOCATED &&
4045 e2->defstate == SS_PDEFINED)
4047 e2->defstate = SS_ALLOCATED;
4049 else if (e2->defstate == SS_ALLOCATED &&
4050 el->defstate == SS_PDEFINED)
4052 el->defstate = SS_ALLOCATED;
4053 sRef_clearDerived (el);
4055 else if ((el->defstate == SS_DEAD || sRef_isKept (el)) &&
4056 (e2->defstate == SS_DEFINED && !sRef_isKept (e2)))
4059 if (checkDeadState (el, TRUE, loc))
4061 if (sRef_isThroughArrayFetch (el))
4063 sRef_maybeKill (el, loc);
4064 sRef_maybeKill (e2, loc);
4068 else if ((e2->defstate == SS_DEAD || sRef_isKept (e2)) &&
4069 (el->defstate == SS_DEFINED && !sRef_isKept (el)))
4072 if (checkDeadState (e2, FALSE, loc))
4074 if (sRef_isThroughArrayFetch (el))
4076 sRef_maybeKill (el, loc);
4077 sRef_maybeKill (e2, loc);
4081 else if (el->defstate == SS_DEFINED &&
4082 e2->defstate == SS_PDEFINED)
4084 DPRINTF (("set pdefined: %s", sRef_unparseFull (el)));
4085 el->defstate = SS_PDEFINED;
4087 else if (e2->defstate == SS_DEFINED &&
4088 el->defstate == SS_PDEFINED)
4090 DPRINTF (("set pdefined: %s", sRef_unparseFull (e2)));
4091 e2->defstate = SS_PDEFINED;
4098 if (ctype_isUnion (ctype_realType (sRef_getType (el))))
4100 el->deriv = sRef_mergeUnionDerivs (el->deriv, e2->deriv,
4105 el->deriv = sRef_mergeDerivs (el->deriv, e2->deriv, opt, cl, loc);
4108 if (sRef_equivalent (el, e2))
4110 ret = sRefSet_insert (ret, el);
4114 sRef sr = sRef_leastCommon (el, e2);
4116 if (sRef_isValid (sr))
4118 ret = sRefSet_insert (ret, sr);
4126 (void) sRefSet_delete (other, e2);
4128 else /* not defined */
4130 (void) checkDeadState (el, TRUE, loc);
4133 } end_sRefSet_allElements;
4135 sRefSet_allElements (other, el)
4137 if (sRef_isValid (el))
4139 (void) checkDeadState (el, FALSE, loc);
4141 } end_sRefSet_allElements;
4148 ** Returns TRUE is there is an error.
4151 static bool checkDeadState (/*@notnull@*/ sRef el, bool tbranch, fileloc loc)
4154 ** usymtab_isGuarded --- the utab should still be in the
4155 ** state of the alternate branch.
4157 ** tbranch TRUE means el is released in the last branch, e.g.
4158 ** if (x != NULL) { ; } else { sfree (x); }
4159 ** so, if x is null in the other branch no error is reported.
4161 ** tbranch FALSE means this is the other branch:
4162 ** if (x != NULL) { sfree (x); } else { ; }
4163 ** so, if x is null in this branch there is no error.
4167 if ((sRef_isDead (el) || sRef_isKept (el))
4168 && !sRef_isDeepUnionField (el) && !sRef_isThroughArrayFetch (el))
4173 if (usymtab_isDefinitelyNullDeep (el))
4180 if (usymtab_isAltDefinitelyNullDeep (el))
4188 message ("Storage %q is %q in one path, but live in another.",
4190 cstring_makeLiteral (sRef_isKept (el)
4191 ? "kept" : "released")),
4194 if (sRef_isKept (el))
4196 sRef_showAliasInfo (el);
4200 sRef_showStateInfo (el);
4203 /* prevent further errors */
4204 el->defstate = SS_UNKNOWN;
4205 sRef_setAliasKind (el, AK_ERROR, fileloc_undefined);
4215 checkDerivDeadState (/*@notnull@*/ sRef el, bool tbranch, fileloc loc)
4218 if (checkDeadState (el, tbranch, loc))
4220 sRefSet_allElements (el->deriv, t)
4222 if (sRef_isValid (t))
4224 checkDerivDeadState (t, tbranch, loc);
4226 } end_sRefSet_allElements;
4231 sRef_mergePdefinedDerivs (sRefSet res, sRefSet other, bool opt,
4232 clause cl, fileloc loc)
4234 sRefSet ret = sRefSet_new ();
4236 sRefSet_allElements (res, el)
4238 if (sRef_isValid (el))
4240 sRef e2 = sRefSet_lookupMember (other, el);
4242 if (sRef_isValid (e2))
4244 if (sRef_isAllocated (el) && !sRef_isAllocated (e2))
4248 else if (sRef_isAllocated (e2) && !sRef_isAllocated (el))
4250 el->deriv = sRefSet_copyInto (el->deriv, e2->deriv);
4254 el->deriv = sRef_mergePdefinedDerivs (el->deriv, e2->deriv,
4258 sRef_mergeStateAux (el, e2, cl, opt, loc, FALSE);
4260 ret = sRefSet_insert (ret, el);
4261 (void) sRefSet_delete (other, e2);
4267 checkDerivDeadState (el, (cl == FALSECLAUSE), loc);
4270 ret = sRefSet_insert (ret, el);
4273 } end_sRefSet_allElements;
4275 sRefSet_allElements (other, el)
4277 if (sRef_isValid (el))
4279 if (!sRefSet_member (ret, el))
4281 /* was cl == FALSECLAUSE */
4282 checkDerivDeadState (el, FALSE, loc);
4283 ret = sRefSet_insert (ret, el);
4288 ** it's okay --- member is a different equality test
4292 } end_sRefSet_allElements;
4298 sRef sRef_makeConj (/*@exposed@*/ /*@returned@*/ sRef a, /*@exposed@*/ sRef b)
4300 llassert (sRef_isValid (a));
4301 llassert (sRef_isValid (b));
4303 if (!sRef_equivalent (a, b))
4305 sRef s = sRef_newRef ();
4308 s->info = (sinfo) dmalloc (sizeof (*s->info));
4309 s->info->conj = (cjinfo) dmalloc (sizeof (*s->info->conj));
4310 s->info->conj->a = a; /* sRef_copy (a) */ /*@i32*/ ;
4311 s->info->conj->b = b; /* sRef_copy (b);*/ /*@i32@*/ ;
4313 if (ctype_equal (a->type, b->type)) s->type = a->type;
4314 else s->type = ctype_makeConj (a->type, b->type);
4316 if (a->defstate == b->defstate)
4318 s->defstate = a->defstate;
4322 s->defstate = SS_UNKNOWN;
4325 sRef_setNullStateN (s, NS_UNKNOWN);
4327 s->safe = a->safe && b->safe;
4328 s->aliaskind = alkind_resolve (a->aliaskind, b->aliaskind);
4330 llassert (valueTable_isUndefined (s->state));
4331 s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
4336 /*@-exposetrans@*/ return a; /*@=exposetrans@*/
4340 /*@dependent@*/ sRef
4343 sRef s = sRef_new ();
4345 s->kind = SK_UNKNOWN;
4349 static /*@owned@*/ /*@notnull@*/ sRef
4350 sRef_makeSpecial (speckind sk) /*@*/
4352 sRef s = sRef_new ();
4354 s->kind = SK_SPECIAL;
4355 s->info = (sinfo) dmalloc (sizeof (*s->info));
4357 /*@-dependenttrans@*/
4359 /*@=dependenttrans@*/
4362 static /*@owned@*/ sRef srnothing = sRef_undefined;
4363 static /*@owned@*/ sRef srinternal = sRef_undefined;
4364 static /*@owned@*/ sRef srsystem = sRef_undefined;
4365 static /*@owned@*/ sRef srspec = sRef_undefined;
4367 /*@dependent@*/ sRef
4368 sRef_makeNothing (void)
4370 if (sRef_isInvalid (srnothing))
4372 srnothing = sRef_makeSpecial (SR_NOTHING);
4379 sRef_makeInternalState (void)
4381 if (sRef_isInvalid (srinternal))
4383 srinternal = sRef_makeSpecial (SR_INTERNAL);
4390 sRef_makeSpecState (void)
4392 if (sRef_isInvalid (srspec))
4394 srspec = sRef_makeSpecial (SR_SPECSTATE);
4401 sRef_makeSystemState (void)
4403 if (sRef_isInvalid (srsystem))
4405 srsystem = sRef_makeSpecial (SR_SYSTEM);
4412 sRef_makeGlobalMarker (void)
4414 sRef s = sRef_makeSpecial (SR_GLOBALMARKER);
4415 llassert (valueTable_isUndefined (s->state));
4416 s->state = context_createGlobalMarkerValueTable (stateInfo_undefined);
4421 sRef_makeResult (ctype c)
4423 sRef s = sRef_newRef ();
4425 s->kind = SK_RESULT;
4427 s->defstate = SS_UNKNOWN;
4428 s->aliaskind = AK_UNKNOWN;
4429 sRef_setNullStateN (s, NS_UNKNOWN);
4430 llassert (valueTable_isUndefined (s->state));
4431 s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
4433 DPRINTF (("Result: [%p] %s", s, sRef_unparseFull (s)));
4439 sRef_isNothing (sRef s)
4441 return (sRef_isKindSpecial (s) && s->info->spec == SR_NOTHING);
4445 sRef_isInternalState (sRef s)
4447 return (sRef_isKindSpecial (s) && s->info->spec == SR_INTERNAL);
4451 sRef_isSpecInternalState (sRef s)
4453 return (sRef_isKindSpecial (s)
4454 && (s->info->spec == SR_INTERNAL || s->info->spec == SR_SPECSTATE));
4458 sRef_isSpecState (sRef s)
4460 return (sRef_isKindSpecial (s) && s->info->spec == SR_SPECSTATE);
4464 sRef_isResult (sRef s)
4466 return (sRef_isValid (s) && s->kind == SK_RESULT);
4470 sRef_isSystemState (sRef s)
4472 return (sRef_isKindSpecial (s) && s->info->spec == SR_SYSTEM);
4476 sRef_isGlobalMarker (sRef s)
4478 return (sRef_isKindSpecial (s) && s->info->spec == SR_GLOBALMARKER);
4482 sRef_getScopeIndex (sRef s)
4484 llassert (sRef_isValid (s));
4485 llassert (sRef_isCvar (s));
4487 return (s->info->cvar->index);
4491 sRef_makeSafe (sRef s)
4493 if (sRef_isValid (s))
4500 sRef_makeUnsafe (sRef s)
4502 if (sRef_isValid (s))
4509 ** memory state operations
4512 /*@only@*/ cstring sRef_unparseFull (sRef s)
4514 if (sRef_isInvalid (s)) return (cstring_undefined);
4516 return (message ("[%p] %q - %q [%s] { %q } < %q >",
4518 sRef_unparseDebug (s),
4519 sRef_unparseState (s),
4520 exkind_unparse (s->oexpkind),
4521 sRefSet_unparseDebug (s->deriv),
4522 valueTable_unparse (s->state)));
4525 /*@unused@*/ cstring sRef_unparseDeep (sRef s)
4527 cstring st = cstring_undefined;
4529 st = message ("%q:", sRef_unparseFull (s));
4531 if (sRef_isValid (s))
4533 sRefSet_allElements (s->deriv, el)
4535 st = message("%q\n%q", st, sRef_unparseDeep (el));
4536 } end_sRefSet_allElements ;
4542 /*@only@*/ cstring sRef_unparseState (sRef s)
4544 if (sRef_isConj (s))
4546 return (message ("%q | %q",
4547 sRef_unparseState (s->info->conj->a),
4548 sRef_unparseState (s->info->conj->b)));
4551 if (sRef_isInvalid (s))
4553 return (cstring_makeLiteral ("<invalid>"));
4556 return (message ("%s.%s.%s.%s",
4557 alkind_unparse (s->aliaskind),
4558 nstate_unparse (sRef_getNullState (s)),
4559 exkind_unparse (s->expkind),
4560 sstate_unparse (s->defstate)));
4563 bool sRef_isNotUndefined (sRef s)
4565 return (sRef_isInvalid (s)
4566 || (s->defstate != SS_UNDEFINED
4567 && s->defstate != SS_UNUSEABLE
4568 && s->defstate != SS_DEAD));
4571 ynm sRef_isWriteable (sRef s)
4573 if (sRef_isInvalid (s)) return MAYBE;
4575 if (sRef_isConj (s) && s->defstate == SS_UNKNOWN)
4577 if (ynm_toBoolStrict (sRef_isWriteable (sRef_getConjA (s))))
4579 if (ynm_toBoolStrict (sRef_isWriteable (sRef_getConjB (s))))
4587 if (ynm_toBoolStrict (sRef_isWriteable (sRef_getConjB (s))))
4595 return (ynm_fromBool (s->defstate != SS_UNUSEABLE));
4598 bool sRef_hasNoStorage (sRef s)
4600 return (!sRef_isAllocatedStorage (s) || sRef_isDefinitelyNull (s));
4603 bool sRef_isStrictReadable (sRef s)
4605 return (ynm_toBoolStrict (sRef_isValidLvalue (s)));
4609 ** Is this what is does?
4610 ** Returns YES if s can be used as an rvalue,
4611 ** MAYBE if its not clear
4612 ** NO if s cannot be safely used as an rvalue.
4615 ynm sRef_isValidLvalue (sRef s)
4619 if (sRef_isInvalid (s)) return YES;
4623 if (sRef_isConj (s) && s->defstate == SS_UNKNOWN)
4625 if (ynm_toBoolStrict (sRef_isValidLvalue (sRef_getConjA (s))))
4627 if (ynm_toBoolStrict (sRef_isValidLvalue (sRef_getConjB (s))))
4635 if (ynm_toBoolStrict (sRef_isValidLvalue (sRef_getConjB (s))))
4642 else if (ss == SS_HOFFA)
4644 if (context_getFlag (FLG_STRICTUSERELEASED))
4655 return (ynm_fromBool (ss == SS_DEFINED
4658 || ss == SS_PDEFINED
4661 || ss == SS_ALLOCATED
4662 || ss == SS_KILLED /* evans 2001-05-26: added this for killed globals */
4663 || ss == SS_UNKNOWN));
4667 static /*@exposed@*/ sRef whatUndefined (/*@exposed@*/ sRef fref, int depth)
4672 if (depth > MAXDEPTH)
4675 ("Warning: check definition limit exceeded, checking %q. "
4676 "This either means there is a variable with at least "
4677 "%d indirections apparent in the program text, or "
4678 "there is a bug in Splint.",
4679 sRef_unparse (fref),
4683 return sRef_undefined;
4686 if (!sRef_isKnown (fref) || sRef_isAnyDefined (fref))
4688 return sRef_undefined;
4691 if (sRef_isUnuseable (fref) || sRef_isStateUndefined (fref))
4696 ct = ctype_realType (sRef_getType (fref));
4698 if (ctype_isUnknown (ct))
4700 return sRef_undefined;
4702 else if (ctype_isPointer (ct) || ctype_isArray (ct))
4704 if (sRef_isStateUnknown (fref))
4706 return sRef_undefined;
4710 sRef fptr = sRef_constructDeref (fref);
4712 return (whatUndefined (fptr, depth + 1));
4715 else if (ctype_isStruct (ct))
4717 bool hasOneDefined = FALSE;
4719 if (sRef_isStateUnknown (fref))
4724 if (sRef_isPdefined (fref) || sRef_isAnyDefined (fref))
4726 sRefSet_realElements (sRef_derivedFields (fref), sr)
4728 hasOneDefined = TRUE;
4730 if (sRef_isField (sr))
4732 cstring fieldname = sRef_getField (sr);
4733 sRef fldref = sRef_makeField (fref, fieldname);
4734 bool shouldCheck = !sRef_isRecursiveField (fldref);
4738 sRef wdef = whatUndefined (fldref, depth + 1);
4740 if (sRef_isValid (wdef))
4746 } end_sRefSet_realElements;
4748 else if (sRef_isAllocated (fref))
4751 ** for structures, each field must be completely defined
4754 uentryList fields = ctype_getFields (ct);
4756 uentryList_elements (fields, ue)
4758 cstring name = uentry_getRealName (ue);
4759 sRef ffield = sRef_makeField (fref, name);
4760 bool shouldCheck = !sRef_isRecursiveField (ffield);
4762 if (sRef_isRelDef (uentry_getSref (ue)))
4770 sRef wdef = whatUndefined (ffield, depth + 1);
4772 if (sRef_isInvalid (wdef))
4778 } end_uentryList_elements;
4785 else if (ctype_isUnion (ct))
4794 return sRef_undefined;
4797 static bool checkDefined (/*@temp@*/ sRef sr)
4799 /*@-temptrans@*/ /* the result from whatUndefined is lost */
4800 return (sRef_isInvalid (whatUndefined (sr, 0)));
4804 bool sRef_isReallyDefined (sRef s)
4806 if (sRef_isValid (s))
4808 if (sRef_isAnyDefined (s))
4814 if (sRef_isAllocated (s) || sRef_isPdefined (s))
4816 return checkDefined (s);
4830 void sRef_showNotReallyDefined (sRef s)
4832 if (sRef_isValid (s))
4834 if (sRef_isAnyDefined (s))
4840 if (sRef_isAllocated (s) || sRef_isPdefined (s))
4842 /*@-temptrans@*/ /* the result of whatUndefined is lost */
4843 sRef ref = whatUndefined (s, 0);
4845 llassert (sRef_isValid (ref));
4850 (message ("This sub-reference is %s: %q",
4851 sstate_unparse (sRef_getDefState (ref)),
4852 sRef_unparse (ref)));
4867 sstate sRef_getDefState (sRef s)
4869 if (sRef_isInvalid (s)) return (SS_UNKNOWN);
4870 return (s->defstate);
4873 void sRef_setDefState (sRef s, sstate defstate, fileloc loc)
4875 sRef_checkMutable (s);
4876 sRef_setStateAux (s, defstate, loc);
4879 static void sRef_clearAliasStateAux (sRef s, fileloc loc)
4881 sRef_checkMutable (s);
4882 sRef_setAliasKind (s, AK_ERROR, loc);
4885 void sRef_clearAliasState (sRef s, fileloc loc)
4887 sRef_checkMutable (s);
4888 sRef_aliasSetComplete (sRef_clearAliasStateAux, s, loc);
4891 void sRef_setAliasKindComplete (sRef s, alkind kind, fileloc loc)
4893 sRef_checkMutable (s);
4894 sRef_aliasSetCompleteAlkParam (sRef_setAliasKind, s, kind, loc);
4897 void sRef_setAliasKind (sRef s, alkind kind, fileloc loc)
4899 sRef_checkMutable (s);
4901 if (sRef_isValid (s))
4903 sRef_clearDerived (s);
4905 if ((kind != s->aliaskind && kind != s->oaliaskind)
4906 && fileloc_isDefined (loc))
4908 s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, loc);
4911 s->aliaskind = kind;
4915 void sRef_setOrigAliasKind (sRef s, alkind kind)
4917 sRef_checkMutable (s);
4919 if (sRef_isValid (s))
4921 s->oaliaskind = kind;
4925 exkind sRef_getExKind (sRef s)
4927 if (sRef_isValid (s))
4929 return (s->expkind);
4937 exkind sRef_getOrigExKind (sRef s)
4939 if (sRef_isValid (s))
4941 return (s->oexpkind);
4949 static void sRef_clearExKindAux (sRef s, fileloc loc)
4951 sRef_checkMutable (s);
4952 sRef_setExKind (s, XO_UNKNOWN, loc);
4955 void sRef_setObserver (sRef s, fileloc loc)
4957 sRef_checkMutable (s);
4958 sRef_setExKind (s, XO_OBSERVER, loc);
4961 void sRef_setExposed (sRef s, fileloc loc)
4963 sRef_checkMutable (s);
4964 sRef_setExKind (s, XO_EXPOSED, loc);
4967 void sRef_clearExKindComplete (sRef s, fileloc loc)
4969 (void) sRef_aliasSetComplete (sRef_clearExKindAux, s, loc);
4972 void sRef_setExKind (sRef s, exkind exp, fileloc loc)
4974 sRef_checkMutable (s);
4976 if (sRef_isValid (s))
4978 if (s->expkind != exp)
4980 s->expinfo = stateInfo_updateLoc (s->expinfo, loc);
4988 ** s1->derived = s2->derived
4991 static void sRef_copyRealDerived (sRef s1, sRef s2)
4993 DPRINTF (("Copy real: %s / %s", sRef_unparse (s1), sRef_unparse (s2)));
4994 sRef_checkMutable (s1);
4996 if (sRef_isValid (s1) && sRef_isValid (s2))
4998 sRef sb = sRef_getRootBase (s1);
5000 sRefSet_clear (s1->deriv);
5002 sRefSet_allElements (s2->deriv, el)
5004 if (sRef_isValid (el))
5006 sRef rb = sRef_getRootBase (el);
5008 if (!sRef_same (rb, sb))
5010 sRef fb = sRef_fixDirectBase (el, s1);
5012 if (sRef_isValid (fb))
5014 sRef_copyRealDerived (fb, el);
5015 sRef_addDeriv (s1, fb);
5020 sRef_addDeriv (s1, el);
5023 } end_sRefSet_allElements ;
5028 void sRef_copyRealDerivedComplete (sRef s1, sRef s2)
5030 sRef_innerAliasSetCompleteParam (sRef_copyRealDerived, s1, s2);
5033 void sRef_setUndefined (sRef s, fileloc loc)
5035 sRef_checkMutable (s);
5037 if (sRef_isValid (s))
5039 s->defstate = SS_UNDEFINED;
5041 if (fileloc_isDefined (loc))
5043 s->definfo = stateInfo_updateLoc (s->definfo, loc);
5046 sRef_clearDerived (s);
5050 static void sRef_setDefinedAux (sRef s, fileloc loc, bool clear)
5052 sRef_checkMutable (s);
5053 if (sRef_isInvalid (s)) return;
5055 DPRINTF (("Set defined: %s", sRef_unparseFull (s)));
5057 if (s->defstate != SS_DEFINED && fileloc_isDefined (loc))
5059 s->definfo = stateInfo_updateLoc (s->definfo, loc);
5062 s->defstate = SS_DEFINED;
5064 DPRINTF (("Set defined: %s", sRef_unparseFull (s)));
5066 /* e.g., if x is allocated, *x = 3 defines x */
5068 if (s->kind == SK_PTR)
5070 sRef p = s->info->ref;
5073 if (p->defstate == SS_ALLOCATED
5074 || p->defstate == SS_SPECIAL) /* evans 2001-07-12: shouldn't need this */
5076 sRef_setDefinedAux (p, loc, clear);
5080 ** Defines a[0] also:
5083 arr = sRef_findDerivedArrayFetch (p, FALSE, 0, FALSE);
5085 if (sRef_isValid (arr))
5087 sRef_setDefinedAux (arr, loc, clear);
5090 else if (s->kind == SK_ARRAYFETCH)
5092 if (!s->info->arrayfetch->indknown
5093 || (s->info->arrayfetch->ind == 0))
5095 sRef p = s->info->arrayfetch->arr;
5096 sRef ptr = sRef_constructPointer (p);
5098 if (sRef_isValid (ptr))
5100 if (ptr->defstate == SS_ALLOCATED
5101 || ptr->defstate == SS_UNDEFINED
5102 || ptr->defstate == SS_SPECIAL) /* evans 2001-07-12: shouldn't need this */
5104 sRef_setDefinedAux (ptr, loc, clear);
5108 if (p->defstate == SS_RELDEF)
5112 else if (p->defstate == SS_ALLOCATED || p->defstate == SS_PDEFINED
5113 || p->defstate == SS_SPECIAL) /* evans 2001-07-12: shouldn't need this */
5115 p->defstate = SS_DEFINED;
5122 else if (s->kind == SK_FIELD)
5124 sRef parent = s->info->field->rec;
5126 if (sRef_isValid (parent))
5128 if (ctype_isUnion (ctype_realType (parent->type)))
5131 ** Should not clear derived from here.
5134 sRef_setDefinedNoClear (parent, loc);
5138 ; /* Nothing to do for structures. */
5150 sRef_clearDerived (s);
5154 /* evans 2001-07-12: need to define the derived references */
5155 sRefSet_elements (s->deriv, el)
5157 llassert (sRef_isValid (el));
5158 el->defstate = SS_DEFINED;
5159 } end_sRefSet_elements ;
5162 DPRINTF (("Set defined: %s", sRef_unparseFull (s)));
5165 static void sRef_setPartialDefined (sRef s, fileloc loc)
5167 sRef_checkMutable (s);
5169 if (!sRef_isPartial (s))
5171 sRef_setDefined (s, loc);
5175 void sRef_setPartialDefinedComplete (sRef s, fileloc loc)
5177 sRef_innerAliasSetComplete (sRef_setPartialDefined, s, loc);
5180 void sRef_setDefinedComplete (sRef s, fileloc loc)
5182 sRef_innerAliasSetComplete (sRef_setDefined, s, loc);
5185 void sRef_setDefinedCompleteDirect (sRef s, fileloc loc)
5189 aliases = usymtab_allAliases (s);
5190 DPRINTF (("Set defined complete: %s", sRef_unparseFull (s)));
5191 DPRINTF (("All aliases: %s", sRefSet_unparseFull (aliases)));
5193 sRef_setDefined (s, loc);
5195 sRefSet_realElements (aliases, current)
5197 if (sRef_isValid (current))
5199 current = sRef_updateSref (current);
5200 sRef_setDefined (current, loc);
5202 } end_sRefSet_realElements;
5204 sRefSet_free (aliases);
5205 sRef_innerAliasSetComplete (sRef_setDefined, s, loc);
5208 void sRef_setDefined (sRef s, fileloc loc)
5210 sRef_checkMutable (s);
5211 sRef_setDefinedAux (s, loc, TRUE);
5214 static void sRef_setDefinedNoClear (sRef s, fileloc loc)
5216 sRef_checkMutable (s);
5217 DPRINTF (("Defining: %s", sRef_unparseFull (s)));
5218 sRef_setDefinedAux (s, loc, FALSE);
5219 DPRINTF (("==> %s", sRef_unparseFull (s)));
5222 void sRef_setDefinedNCComplete (sRef s, fileloc loc)
5224 sRef_checkMutable (s);
5225 DPRINTF (("Set Defined Complete: %s", sRef_unparseFull (s)));
5226 sRef_innerAliasSetComplete (sRef_setDefinedNoClear, s, loc);
5227 DPRINTF (("==> %s", sRef_unparseFull (s)));
5230 static bool sRef_isDeepUnionField (sRef s)
5232 return (sRef_deepPred (sRef_isUnionField, s));
5235 bool sRef_isUnionField (sRef s)
5237 if (sRef_isValid (s) && s->kind == SK_FIELD)
5240 ** defining one field of a union defines the union
5243 sRef base = s->info->field->rec;
5245 if (sRef_isValid (base))
5247 return (ctype_isUnion (ctype_realType (base->type)));
5254 void sRef_setPdefined (sRef s, fileloc loc)
5256 sRef_checkMutable (s);
5257 if (sRef_isValid (s) && !sRef_isPartial (s))
5259 sRef base = sRef_getBaseSafe (s);
5261 if (s->defstate == SS_ALLOCATED)
5266 if (s->defstate != SS_PDEFINED && fileloc_isDefined (loc))
5268 s->definfo = stateInfo_updateLoc (s->definfo, loc);
5271 DPRINTF (("set pdefined: %s", sRef_unparseFull (s)));
5272 s->defstate = SS_PDEFINED;
5274 /* e.g., if x is allocated, *x = 3 defines x */
5276 while (sRef_isValid (base) && sRef_isKnown (base))
5278 if (base->defstate == SS_DEFINED)
5282 DPRINTF (("set pdefined: %s", sRef_unparseFull (base)));
5283 base->defstate = SS_PDEFINED;
5284 nb = sRef_getBaseSafe (base);
5295 static void sRef_setStateAux (sRef s, sstate ss, fileloc loc)
5297 sRef_checkMutable (s);
5299 if (sRef_isValid (s))
5301 /* if (s->defstate == SS_RELDEF) return; */
5303 if (s->defstate != ss && fileloc_isDefined (loc))
5305 s->definfo = stateInfo_updateLoc (s->definfo, loc);
5309 sRef_clearDerived (s);
5311 if (ss == SS_ALLOCATED)
5313 sRef base = sRef_getBaseSafe (s);
5315 while (sRef_isValid (base) && sRef_isKnown (base))
5317 if (base->defstate == SS_DEFINED)
5321 DPRINTF (("set pdefined: %s", sRef_unparseFull (s)));
5322 base->defstate = SS_PDEFINED;
5323 nb = sRef_getBaseSafe (base);
5335 void sRef_setAllocatedComplete (sRef s, fileloc loc)
5337 sRef_innerAliasSetComplete (sRef_setAllocated, s, loc);
5340 static void sRef_setAllocatedShallow (sRef s, fileloc loc)
5342 sRef_checkMutable (s);
5344 if (sRef_isValid (s))
5346 if (s->defstate == SS_DEAD || s->defstate == SS_UNDEFINED)
5348 s->defstate = SS_ALLOCATED;
5350 if (fileloc_isDefined (loc))
5352 s->definfo = stateInfo_updateLoc (s->definfo, loc);
5358 void sRef_setAllocatedShallowComplete (sRef s, fileloc loc)
5360 sRef_innerAliasSetComplete (sRef_setAllocatedShallow, s, loc);
5363 void sRef_setAllocated (sRef s, fileloc loc)
5365 sRef_checkMutable (s);
5366 sRef_setStateAux (s, SS_ALLOCATED, loc);
5369 void sRef_setPartial (sRef s, fileloc loc)
5371 sRef_checkMutable (s);
5372 sRef_setStateAux (s, SS_PARTIAL, loc);
5375 void sRef_setShared (sRef s, fileloc loc)
5377 sRef_checkMutable (s);
5379 if (sRef_isValid (s))
5381 if (s->aliaskind != AK_SHARED && fileloc_isDefined (loc))
5383 s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, loc);
5386 s->aliaskind = AK_SHARED;
5387 /* don't! sRef_clearDerived (s); */
5391 void sRef_setLastReference (sRef s, /*@exposed@*/ sRef ref, fileloc loc)
5393 sRef_checkMutable (s);
5395 if (sRef_isValid (s))
5397 s->aliaskind = sRef_getAliasKind (ref);
5398 s->aliasinfo = stateInfo_updateRefLoc (s->aliasinfo, ref, loc);
5403 void sRef_setNullStateAux (/*@notnull@*/ sRef s, nstate ns, fileloc loc)
5405 sRef_checkMutable (s);
5407 sRef_resetAliasKind (s);
5409 if (fileloc_isDefined (loc))
5411 s->nullinfo = stateInfo_updateLoc (s->nullinfo, loc);
5415 void sRef_setNotNull (sRef s, fileloc loc)
5417 if (sRef_isValid (s))
5419 sRef_setNullStateAux (s, NS_NOTNULL, loc);
5423 void sRef_setNullStateN (sRef s, nstate n)
5425 if (sRef_isValid (s))
5427 sRef_checkMutable (s);
5429 sRef_resetAliasKind (s);
5433 void sRef_setNullState (sRef s, nstate n, fileloc loc)
5435 if (sRef_isValid (s))
5437 sRef_setNullStateAux (s, n, loc);
5441 void sRef_setNullTerminatedStateInnerComplete (sRef s, struct s_bbufinfo b, /*@unused@*/ fileloc loc)
5443 switch (b.bufstate) {
5444 case BB_NULLTERMINATED:
5445 sRef_setNullTerminatedState (s);
5446 sRef_setLen (s, b.len);
5448 case BB_POSSIBLYNULLTERMINATED:
5449 sRef_setPossiblyNullTerminatedState(s);
5451 case BB_NOTNULLTERMINATED:
5452 sRef_setNotNullTerminatedState (s);
5456 sRef_setSize (s, b.size);
5458 /* PL: TO BE DONE : Aliases are not modified right now, have to be similar to
5459 * setNullStateInnerComplete.
5463 void sRef_setNullStateInnerComplete (sRef s, nstate n, fileloc loc)
5465 DPRINTF (("Set null state: %s", nstate_unparse (n)));
5467 sRef_setNullState (s, n, loc);
5472 sRef_innerAliasSetComplete (sRef_setPosNull, s, loc);
5475 sRef_innerAliasSetComplete (sRef_setDefNull, s, loc);
5478 sRef_innerAliasSetComplete (sRef_setNullUnknown, s, loc);
5481 sRef_innerAliasSetComplete (sRef_setNotNull, s, loc);
5484 sRef_innerAliasSetComplete (sRef_setNotNull, s, loc);
5487 sRef_innerAliasSetComplete (sRef_setNullUnknown, s, loc);
5490 sRef_innerAliasSetComplete (sRef_setDefNull, s, loc);
5493 sRef_innerAliasSetComplete (sRef_setNullUnknown, s, loc);
5496 sRef_innerAliasSetComplete (sRef_setNullErrorLoc, s, loc);
5501 void sRef_setPosNull (sRef s, fileloc loc)
5503 if (sRef_isValid (s))
5505 sRef_setNullStateAux (s, NS_POSNULL, loc);
5509 void sRef_setDefNull (sRef s, fileloc loc)
5511 if (sRef_isValid (s))
5513 sRef_setNullStateAux (s, NS_DEFNULL, loc);
5517 void sRef_setNullUnknown (sRef s, fileloc loc)
5519 if (sRef_isValid (s))
5521 sRef_setNullStateAux (s, NS_UNKNOWN, loc);
5525 void sRef_setNullError (sRef s)
5527 if (sRef_isValid (s))
5529 sRef_setNullStateAux (s, NS_UNKNOWN, fileloc_undefined);
5533 void sRef_setNullErrorLoc (sRef s, /*@unused@*/ fileloc loc)
5535 sRef_setNullError (s);
5538 void sRef_setOnly (sRef s, fileloc loc)
5540 sRef_checkMutable (s);
5542 if (sRef_isValid (s) && s->aliaskind != AK_ONLY)
5544 s->aliaskind = AK_ONLY;
5545 s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, loc);
5549 void sRef_setDependent (sRef s, fileloc loc)
5551 sRef_checkMutable (s);
5553 if (sRef_isValid (s) && !sRef_isConst (s) && (s->aliaskind != AK_DEPENDENT))
5555 DPRINTF (("Setting dependent: %s", sRef_unparseFull (s)));
5556 s->aliaskind = AK_DEPENDENT;
5557 s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, loc);
5561 void sRef_setOwned (sRef s, fileloc loc)
5563 sRef_checkMutable (s);
5565 if (sRef_isValid (s) && !sRef_isConst (s) && (s->aliaskind != AK_OWNED))
5567 s->aliaskind = AK_OWNED;
5568 s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, loc);
5572 void sRef_setKept (sRef s, fileloc loc)
5574 sRef_checkMutable (s);
5576 if (sRef_isValid (s) && !sRef_isConst (s) && (s->aliaskind != AK_KEPT))
5578 sRef base = sRef_getBaseSafe (s);
5580 while (sRef_isValid (base) && sRef_isKnown (base))
5582 if (base->defstate == SS_DEFINED)
5584 base->defstate = SS_PDEFINED;
5585 base = sRef_getBaseSafe (base);
5593 s->aliaskind = AK_KEPT;
5594 s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, loc);
5598 static void sRef_setKeptAux (sRef s, fileloc loc)
5600 if (!sRef_isShared (s))
5602 sRef_setKept (s, loc);
5606 static void sRef_setDependentAux (sRef s, fileloc loc)
5608 if (!sRef_isShared (s))
5610 sRef_setDependent (s, loc);
5614 void sRef_setKeptComplete (sRef s, fileloc loc)
5616 sRef_aliasSetComplete (sRef_setKeptAux, s, loc);
5619 void sRef_setDependentComplete (sRef s, fileloc loc)
5621 sRef_aliasSetComplete (sRef_setDependentAux, s, loc);
5624 void sRef_setFresh (sRef s, fileloc loc)
5626 sRef_checkMutable (s);
5628 if (sRef_isValid (s))
5630 s->aliaskind = AK_FRESH;
5631 s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, loc);
5635 void sRef_kill (sRef s, fileloc loc)
5637 DPRINTF (("Kill: %s", sRef_unparseFull (s)));
5638 sRef_checkMutable (s);
5640 if (sRef_isValid (s) && !sRef_isShared (s) && !sRef_isConst (s))
5642 sRef base = sRef_getBaseSafe (s);
5644 while (sRef_isValid (base) && sRef_isKnown (base))
5646 if (base->defstate == SS_DEFINED)
5648 base->defstate = SS_PDEFINED;
5649 base = sRef_getBaseSafe (base);
5657 s->aliaskind = s->oaliaskind;
5658 s->defstate = SS_DEAD;
5659 s->definfo = stateInfo_updateLoc (s->definfo, loc);
5661 sRef_clearDerived (s);
5665 void sRef_maybeKill (sRef s, fileloc loc)
5667 sRef_checkMutable (s);
5669 if (sRef_isValid (s))
5671 sRef base = sRef_getBaseSafe (s);
5674 while (sRef_isValid (base) && sRef_isKnown (base))
5676 if (base->defstate == SS_DEFINED || base->defstate == SS_RELDEF)
5678 base->defstate = SS_PDEFINED;
5679 base = sRef_getBaseSafe (base);
5688 s->aliaskind = s->oaliaskind;
5689 s->defstate = SS_HOFFA;
5690 s->definfo = stateInfo_updateLoc (s->definfo, loc);
5691 sRef_clearDerived (s);
5697 ** just for type checking...
5700 static void sRef_killAux (sRef s, fileloc loc)
5702 if (sRef_isValid (s) && !sRef_isShared (s))
5704 if (sRef_isUnknownArrayFetch (s))
5706 sRef_maybeKill (s, loc);
5716 ** kills s and all aliases to s
5719 void sRef_killComplete (sRef s, fileloc loc)
5721 DPRINTF (("Kill complete: %s", sRef_unparseFull (s)));
5722 sRef_aliasSetComplete (sRef_killAux, s, loc);
5725 static bool sRef_equivalent (sRef s1, sRef s2)
5727 return (sRef_compare (s1, s2) == 0);
5731 ** returns an sRef that will not be free'd on function exit.
5734 /*@only@*/ sRef sRef_saveCopy (sRef s)
5738 if (sRef_isValid (s))
5740 bool old = inFunction;
5743 ** Exit the function scope, so this sRef is not
5744 ** stored in the deallocation table.
5748 DPRINTF (("Copying sref: %s", sRef_unparseFull(s)));
5749 ret = sRef_copy (s);
5750 DPRINTF (("Copying ===>: %s", sRef_unparseFull(ret)));
5755 ret = sRef_undefined;
5758 /*@-dependenttrans@*/
5760 /*@=dependenttrans@*/
5763 sRef sRef_copy (sRef s)
5765 if (sRef_isKindSpecial (s) && !sRef_isGlobalMarker (s))
5768 return s; /* don't copy specials (except for global markers) */
5772 if (sRef_isValid (s))
5774 sRef t = sRef_alloc ();
5776 DPRINTF (("Copying: [%p] %s", s, sRef_unparse (s)));
5777 DPRINTF (("Full: %s", sRef_unparseFull (s)));
5781 t->modified = s->modified;
5782 t->immut = FALSE; /* Note mutability is not copied. */
5784 t->val = multiVal_copy (s->val);
5786 t->info = sinfo_copy (s);
5787 t->defstate = s->defstate;
5788 t->nullstate = s->nullstate;
5790 /* start modifications */
5791 t->bufinfo.bufstate = s->bufinfo.bufstate;
5792 t->bufinfo.len = s->bufinfo.len;
5793 t->bufinfo.size = s->bufinfo.size;
5794 /* end modifications */
5796 t->aliaskind = s->aliaskind;
5797 t->oaliaskind = s->oaliaskind;
5799 t->expkind = s->expkind;
5800 t->oexpkind = s->oexpkind;
5802 t->nullinfo = stateInfo_copy (s->nullinfo);
5803 t->aliasinfo = stateInfo_copy (s->aliasinfo);
5804 t->definfo = stateInfo_copy (s->definfo);
5805 t->expinfo = stateInfo_copy (s->expinfo);
5807 t->deriv = sRefSet_newDeepCopy (s->deriv);
5808 t->state = valueTable_copy (s->state);
5810 DPRINTF (("Made copy: %s => %s", sRef_unparseFull (s), sRef_unparseFull (t)));
5815 return sRef_undefined;
5820 # define PREDTEST(func,s) \
5821 do { if (sRef_isInvalid (s)) { return FALSE; } \
5822 else { if (sRef_isConj (s)) \
5823 { return (func (sRef_getConjA (s)) \
5824 || func (sRef_getConjB (s))); }}} while (FALSE);
5826 bool sRef_isAddress (sRef s)
5828 PREDTEST (sRef_isAddress, s);
5829 return (s->kind == SK_ADR);
5833 ** pretty weak... maybe a flag should control this.
5836 bool sRef_isThroughArrayFetch (sRef s)
5838 if (sRef_isValid (s))
5846 if (sRef_isArrayFetch (tref))
5851 lt = sRef_getBase (tref);
5853 } while (sRef_isValid (tref));
5859 bool sRef_isArrayFetch (sRef s)
5861 PREDTEST (sRef_isArrayFetch, s);
5862 return (s->kind == SK_ARRAYFETCH);
5865 bool sRef_isMacroParamRef (sRef s)
5867 if (context_inMacro () && sRef_isCvar (s))
5869 uentry ue = sRef_getUentry (s);
5870 cstring pname = makeParam (uentry_rawName (ue));
5871 uentry mac = usymtab_lookupSafe (pname);
5873 cstring_free (pname);
5874 return (uentry_isValid (mac));
5880 bool sRef_isCvar (sRef s)
5882 PREDTEST (sRef_isCvar, s);
5883 return (s->kind == SK_CVAR);
5886 bool sRef_isConst (sRef s)
5888 PREDTEST (sRef_isConst, s);
5889 return (s->kind == SK_CONST);
5892 bool sRef_isObject (sRef s)
5894 PREDTEST (sRef_isObject, s);
5895 return (s->kind == SK_OBJECT);
5898 bool sRef_isExternal (sRef s)
5900 PREDTEST (sRef_isExternal, s);
5901 return (s->kind == SK_EXTERNAL);
5904 static bool sRef_isDerived (sRef s)
5906 PREDTEST (sRef_isDerived, s);
5907 return (s->kind == SK_DERIVED);
5910 bool sRef_isField (sRef s)
5912 PREDTEST (sRef_isField, s);
5913 return (s->kind == SK_FIELD);
5916 static bool sRef_isIndex (sRef s)
5918 PREDTEST (sRef_isIndex, s);
5919 return (s->kind == SK_ARRAYFETCH);
5922 bool sRef_isAnyParam (sRef s)
5924 PREDTEST (sRef_isAnyParam, s);
5925 return (s->kind == SK_PARAM);
5928 bool sRef_isParam (sRef s)
5930 PREDTEST (sRef_isParam, s);
5931 return (s->kind == SK_PARAM);
5934 bool sRef_isDirectParam (sRef s)
5936 PREDTEST (sRef_isDirectParam, s);
5938 return ((s->kind == SK_CVAR) &&
5939 (s->info->cvar->lexlevel == functionScope) &&
5940 (context_inFunction () &&
5941 (s->info->cvar->index <= uentryList_size (context_getParams ()))));
5944 bool sRef_isPointer (sRef s)
5946 PREDTEST (sRef_isPointer, s);
5947 return (s->kind == SK_PTR);
5951 ** returns true if storage referenced by s is visible
5954 bool sRef_isReference (sRef s)
5956 PREDTEST (sRef_isReference, s);
5958 return (sRef_isPointer (s) || sRef_isIndex (s) || sRef_isFileOrGlobalScope (s)
5959 || (sRef_isField (s) && (sRef_isReference (s->info->field->rec))));
5962 bool sRef_isIReference (sRef s)
5964 return (sRef_isPointer (s) || sRef_isAddress (s) || sRef_isIndex (s)
5965 || sRef_isField (s) || sRef_isArrayFetch (s));
5968 bool sRef_isFileOrGlobalScope (sRef s)
5970 return (sRef_isCvar (s) && (s->info->cvar->lexlevel <= fileScope));
5973 bool sRef_isRealGlobal (sRef s)
5975 return (sRef_isCvar (s) && (s->info->cvar->lexlevel == globScope));
5978 bool sRef_isFileStatic (sRef s)
5980 return (sRef_isCvar (s) && (s->info->cvar->lexlevel == fileScope));
5983 bool sRef_isAliasCheckedGlobal (sRef s)
5985 if (sRef_isFileOrGlobalScope (s))
5987 uentry ue = sRef_getUentry (s);
5989 return context_checkAliasGlob (ue);
5997 void sRef_free (/*@only@*/ sRef s)
5999 if (s != sRef_undefined && s->kind != SK_SPECIAL)
6001 DPRINTF (("Free sref: [%p]", s));
6003 sRef_checkValid (s);
6005 stateInfo_free (s->expinfo);
6006 stateInfo_free (s->aliasinfo);
6007 stateInfo_free (s->definfo);
6008 stateInfo_free (s->nullinfo);
6010 sRefSet_free (s->deriv);
6011 s->deriv = sRefSet_undefined;
6013 /*@i43@*/ /* valueTable_free (s->state); */
6017 /* drl added to help locate use after release*/
6018 s->expinfo = stateInfo_undefined;
6019 s->aliasinfo = stateInfo_undefined;
6020 s->definfo = stateInfo_undefined;
6021 s->nullinfo = stateInfo_undefined;
6023 /*@i32@*/ sfree (s);
6027 void sRef_setType (sRef s, ctype t)
6029 sRef_checkMutable (s);
6031 if (sRef_isValid (s))
6037 void sRef_setTypeFull (sRef s, ctype t)
6039 sRef_checkMutable (s);
6041 if (sRef_isValid (s))
6045 sRefSet_allElements (s->deriv, current)
6047 sRef_setTypeFull (current, ctype_unknown);
6048 } end_sRefSet_allElements ;
6053 sRef_buildField (/*@exposed@*/ sRef rec, /*@dependent@*/ cstring f)
6055 return (sRef_buildNCField (rec, f));
6058 static /*@exposed@*/ sRef
6059 sRef_findDerivedField (/*@notnull@*/ sRef rec, cstring f)
6061 sRefSet_allElements (rec->deriv, sr)
6063 if (sRef_isValid (sr))
6065 if (sr->info != NULL)
6067 if (sr->kind == SK_FIELD && cstring_equal (sr->info->field->field, f))
6073 } end_sRefSet_allElements;
6075 return sRef_undefined;
6078 /*@dependent@*/ /*@observer@*/ sRefSet sRef_derivedFields (/*@temp@*/ sRef rec)
6080 if (sRef_isValid (rec))
6088 return (sRefSet_undefined);
6092 static /*@exposed@*/ sRef
6093 sRef_findDerivedPointer (sRef s)
6095 if (sRef_isValid (s))
6097 sRefSet_realElements (s->deriv, sr)
6099 if (sRef_isValid (sr) && sr->kind == SK_PTR)
6103 } end_sRefSet_realElements;
6106 return sRef_undefined;
6110 sRef_isUnknownArrayFetch (sRef s)
6112 return (sRef_isValid (s)
6113 && s->kind == SK_ARRAYFETCH
6114 && !s->info->arrayfetch->indknown);
6117 static /*@exposed@*/ sRef
6118 sRef_findDerivedArrayFetch (/*@notnull@*/ sRef s, bool isknown, int idx, bool dead)
6123 sRefSet_realElements (s->deriv, sr)
6125 if (sRef_isValid (sr)
6126 && sr->kind == SK_ARRAYFETCH
6127 && sr->info->arrayfetch->indknown
6128 && (sr->info->arrayfetch->ind == idx))
6132 } end_sRefSet_realElements;
6136 sRefSet_realElements (s->deriv, sr)
6138 if (sRef_isValid (sr)
6139 && sr->kind == SK_ARRAYFETCH
6140 && (!sr->info->arrayfetch->indknown
6141 || (sr->info->arrayfetch->indknown &&
6142 sr->info->arrayfetch->ind == 0)))
6144 if (sRef_isDead (sr) || sRef_isKept (sr))
6146 if (dead || context_getFlag (FLG_STRICTUSERELEASED))
6156 } end_sRefSet_realElements;
6159 return sRef_undefined;
6162 static /*@exposed@*/ sRef
6163 sRef_buildNCField (/*@exposed@*/ sRef rec, /*@exposed@*/ cstring f)
6167 DPRINTF (("Build nc field: %s / %s",
6168 sRef_unparseFull (rec), f));
6170 if (sRef_isInvalid (rec))
6172 return sRef_undefined;
6176 ** check if the field already has been referenced
6179 s = sRef_findDerivedField (rec, f);
6181 if (sRef_isValid (s))
6187 ctype ct = ctype_realType (rec->type);
6189 DPRINTF (("Field of: %s", sRef_unparse (rec)));
6193 s->info = (sinfo) dmalloc (sizeof (*s->info));
6194 s->info->field = (fldinfo) dmalloc (sizeof (*s->info->field));
6195 s->info->field->rec = rec; /* sRef_copy (rec); */ /*@i32@*/
6196 s->info->field->field = f; /* doesn't copy f */
6198 if (ctype_isKnown (ct) && ctype_isSU (ct))
6200 uentry ue = uentryList_lookupField (ctype_getFields (ct), f);
6202 if (!uentry_isUndefined (ue))
6204 DPRINTF (("lookup: %s for %s", uentry_unparseFull (ue),
6205 ctype_unparse (ct)));
6207 s->type = uentry_getType (ue);
6209 if (ctype_isMutable (s->type)
6210 && rec->aliaskind != AK_STACK
6211 && !alkind_isStatic (rec->aliaskind))
6213 s->aliaskind = rec->aliaskind;
6217 s->aliaskind = AK_UNKNOWN;
6220 if (sRef_isStateDefined (rec) || sRef_isStateUnknown (rec)
6221 || sRef_isPdefined (rec))
6223 sRef_setStateFromUentry (s, ue);
6227 sRef_setPartsFromUentry (s, ue);
6230 s->oaliaskind = s->aliaskind;
6231 s->oexpkind = s->expkind;
6233 DPRINTF (("sref: %s", sRef_unparseFull (s)));
6238 Never report this as an error. It can happen whenever there
6239 is casting involved.
6243 llcontbug (message ("buildNCField --- no field %s: %q / %s",
6244 f, sRef_unparse (s), ctype_unparse (ct)));
6248 return sRef_undefined;
6252 if (rec->defstate == SS_DEFINED
6253 && (s->defstate == SS_UNDEFINED || s->defstate == SS_UNKNOWN))
6255 s->defstate = SS_DEFINED;
6257 else if (rec->defstate == SS_PARTIAL)
6259 s->defstate = SS_PARTIAL;
6261 else if (rec->defstate == SS_ALLOCATED)
6263 if (ctype_isStackAllocated (ct) && ctype_isStackAllocated (s->type))
6265 s->defstate = SS_ALLOCATED;
6269 s->defstate = SS_UNDEFINED;
6272 else if (s->defstate == SS_UNKNOWN)
6274 s->defstate = rec->defstate;
6281 if (s->defstate == SS_UNDEFINED)
6283 ctype rt = ctype_realType (s->type);
6285 if (ctype_isArray (rt) || ctype_isSU (rt))
6287 s->defstate = SS_ALLOCATED;
6291 sRef_addDeriv (rec, s);
6292 DPRINTF (("Add deriv: %s", sRef_unparseFull (rec)));
6294 if (ctype_isInt (s->type) && cstring_equal (f, REFSNAME))
6296 s->aliaskind = AK_REFS;
6297 s->oaliaskind = AK_REFS;
6300 DPRINTF (("Build field ==> %s", sRef_unparseFull (s)));
6306 sRef_isStackAllocated (sRef s)
6308 return (sRef_isValid(s)
6309 && s->defstate == SS_ALLOCATED && ctype_isStackAllocated (s->type));
6313 void sRef_setArrayFetchState (/*@notnull@*/ /*@exposed@*/ sRef s,
6314 /*@notnull@*/ /*@exposed@*/ sRef arr)
6316 sRef_checkMutable (s);
6318 if (ctype_isRealAP (arr->type))
6320 s->type = ctype_baseArrayPtr (arr->type);
6323 /* a hack, methinks... makeArrayFetch (&a[0]) ==> a[] */
6324 /* evans - 2001-08-27: not sure where this was necessary - it
6325 ** causes an assertion in in aliasCheckPred to fail.
6328 if (sRef_isAddress (arr))
6330 sRef t = arr->info->ref;
6332 if (sRef_isArrayFetch (t))
6334 s->info->arrayfetch->arr = t->info->arrayfetch->arr;
6337 else if (ctype_isRealPointer (arr->type))
6339 sRef sp = sRef_findDerivedPointer (arr);
6341 if (sRef_isValid (sp))
6344 if (ctype_isMutable (s->type))
6346 sRef_setExKind (s, sRef_getExKind (sp), fileloc_undefined);
6348 s->aliaskind = sp->aliaskind;
6351 s->defstate = sp->defstate;
6353 if (s->defstate == SS_DEFINED)
6355 if (!context_getFlag (FLG_STRICTDESTROY))
6357 s->defstate = SS_PARTIAL;
6361 DPRINTF (("Set null state: %s / %s", sRef_unparseFull (s), sRef_unparseFull (sp)));
6362 sRef_setNullStateN (s, sRef_getNullState (sp));
6366 if (arr->defstate == SS_UNDEFINED)
6368 s->defstate = SS_UNUSEABLE;
6370 else if ((arr->defstate == SS_ALLOCATED) && !ctype_isSU (s->type))
6372 s->defstate = SS_UNDEFINED;
6376 if (!context_getFlag (FLG_STRICTDESTROY))
6378 s->defstate = SS_PARTIAL;
6382 s->defstate = SS_DEFINED;
6386 ** Very weak checking for array elements.
6388 ** s->defstate = arr->defstate;
6392 sRef_setExKind (s, sRef_getExKind (arr), g_currentloc);
6394 if (arr->aliaskind == AK_LOCAL || arr->aliaskind == AK_FRESH)
6396 s->aliaskind = AK_LOCAL;
6400 s->aliaskind = AK_UNKNOWN;
6403 sRef_setTypeState (s);
6408 if (arr->defstate == SS_DEFINED)
6411 ** Very weak checking for array elements.
6413 ** s->defstate = arr->defstate;
6416 if (context_getFlag (FLG_STRICTDESTROY))
6418 s->defstate = SS_DEFINED;
6422 s->defstate = SS_PARTIAL;
6425 else if (arr->defstate == SS_ALLOCATED)
6427 if (ctype_isRealArray (s->type))
6429 s->defstate = SS_ALLOCATED;
6433 if (!s->info->arrayfetch->indknown)
6436 ** is index is unknown, elements is defined or
6437 ** allocated is any element is!
6440 s->defstate = SS_UNDEFINED;
6442 sRefSet_allElements (arr->deriv, sr)
6444 if (sRef_isValid (sr))
6446 if (sr->defstate == SS_ALLOCATED)
6448 s->defstate = SS_ALLOCATED;
6452 if (sr->defstate == SS_DEFINED)
6454 if (context_getFlag (FLG_STRICTDESTROY))
6456 s->defstate = SS_DEFINED;
6460 s->defstate = SS_PARTIAL;
6467 } end_sRefSet_allElements;
6472 s->defstate = SS_UNDEFINED;
6478 s->defstate = arr->defstate;
6483 ** kludgey way to guess where aliaskind applies
6486 if (ctype_isMutable (s->type)
6487 && !ctype_isPointer (arr->type)
6488 && !alkind_isStatic (arr->aliaskind)
6489 && !alkind_isStack (arr->aliaskind)) /* evs - 2000-06-20: don't pass stack allocation to members */
6491 s->aliaskind = arr->aliaskind;
6495 s->aliaskind = AK_UNKNOWN;
6498 sRef_setTypeState (s);
6501 if (sRef_isObserver (arr))
6503 s->expkind = XO_OBSERVER;
6507 /*@exposed@*/ sRef sRef_buildArrayFetch (/*@exposed@*/ sRef arr)
6511 if (!sRef_isValid (arr)) {
6512 /*@-nullret@*/ return arr /*@=nullret@*/;
6515 if (ctype_isRealPointer (arr->type))
6517 (void) sRef_buildPointer (arr); /* do this to define arr! */
6520 s = sRef_findDerivedArrayFetch (arr, FALSE, 0, FALSE);
6522 if (sRef_isValid (s))
6524 /* evans 2001-07-12: this is bogus, clean-up hack */
6525 if (s->info->arrayfetch->arr != arr)
6528 check (sRefSet_delete (arr->deriv, s));
6529 res = sRef_buildArrayFetch (arr);
6530 sRef_copyState (res, s);
6531 llassert (res->info->arrayfetch->arr == arr);
6535 sRef_setExKind (s, sRef_getExKind (arr), g_currentloc);
6542 s->kind = SK_ARRAYFETCH;
6543 s->info = (sinfo) dmalloc (sizeof (*s->info));
6544 s->info->arrayfetch = (ainfo) dmalloc (sizeof (*s->info->arrayfetch));
6545 s->info->arrayfetch->indknown = FALSE;
6546 s->info->arrayfetch->ind = 0;
6547 s->info->arrayfetch->arr = arr; /* sRef_copy (arr); */ /*@i32@*/
6549 sRef_setArrayFetchState (s, arr);
6551 s->oaliaskind = s->aliaskind;
6552 s->oexpkind = s->expkind;
6554 if (!context_inProtectVars ())
6556 sRef_addDeriv (arr, s);
6559 if (valueTable_isUndefined (s->state))
6561 s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
6569 sRef_buildArrayFetchKnown (/*@exposed@*/ sRef arr, int i)
6573 if (!sRef_isValid (arr)) {
6574 /*@-nullret@*/ return arr /*@=nullret@*/;
6577 if (ctype_isRealPointer (arr->type))
6579 (void) sRef_buildPointer (arr); /* do this to define arr! */
6582 s = sRef_findDerivedArrayFetch (arr, TRUE, i, FALSE);
6584 if (sRef_isValid (s))
6586 /* evans 2001-07-12: this is bogus, clean-up hack */
6587 if (s->info->arrayfetch->arr != arr)
6591 check (sRefSet_delete (arr->deriv, s));
6592 res = sRef_buildArrayFetchKnown (arr, i);
6594 llassert (res->info->arrayfetch->arr == arr);
6595 sRef_copyState (res, s);
6596 llassert (res->info->arrayfetch->arr == arr);
6600 sRef_setExKind (s, sRef_getExKind (arr), g_currentloc);
6601 llassert (s->info->arrayfetch->arr == arr);
6608 s->kind = SK_ARRAYFETCH;
6609 s->info = (sinfo) dmalloc (sizeof (*s->info));
6610 s->info->arrayfetch = (ainfo) dmalloc (sizeof (*s->info->arrayfetch));
6611 s->info->arrayfetch->arr = arr; /* sRef_copy (arr); */ /*@i32@*/
6612 s->info->arrayfetch->indknown = TRUE;
6613 s->info->arrayfetch->ind = i;
6615 sRef_setArrayFetchState (s, arr);
6616 /* evans 2001-08-27 no: can change this - llassert (s->info->arrayfetch->arr == arr); */
6618 s->oaliaskind = s->aliaskind;
6619 s->oexpkind = s->expkind;
6620 sRef_addDeriv (arr, s);
6622 llassert (valueTable_isUndefined (s->state));
6623 s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
6629 ** sets everything except for defstate
6633 sRef_setPartsFromUentry (sRef s, uentry ue)
6635 sRef uref = uentry_getSref (ue);
6637 llassert (sRef_isValid (s));
6639 s->aliaskind = alkind_derive (s->aliaskind, uentry_getAliasKind (ue));
6640 s->oaliaskind = s->aliaskind;
6642 if (s->expkind == XO_UNKNOWN)
6644 s->expkind = uentry_getExpKind (ue);
6647 s->oexpkind = s->expkind;
6649 if (sRef_getNullState (s) == NS_UNKNOWN)
6651 DPRINTF (("Set null state: %s / %s", sRef_unparseFull (s), uentry_unparseFull (ue)));
6652 sRef_setNullStateN (s, sRef_getNullState (uentry_getSref (ue)));
6656 DPRINTF (("Skipping null null state!"));
6659 if (s->aliaskind == AK_IMPONLY && (sRef_isExposed (s) || sRef_isObserver (s)))
6661 s->oaliaskind = s->aliaskind = AK_IMPDEPENDENT;
6664 if (sRef_isValid (uref))
6666 valueTable utable = uref->state;
6667 valueTable_free (s->state);
6668 s->state = valueTable_copy (utable);
6673 sRef_setStateFromAbstractUentry (sRef s, uentry ue)
6675 llassert (sRef_isValid (s));
6676 sRef_checkMutable (s);
6678 sRef_setPartsFromUentry (s, ue);
6680 s->aliaskind = alkind_derive (s->aliaskind, uentry_getAliasKind (ue));
6681 s->oaliaskind = s->aliaskind;
6683 if (s->expkind == XO_UNKNOWN)
6685 s->expkind = uentry_getExpKind (ue);
6688 s->oexpkind = s->expkind;
6692 sRef_setStateFromUentry (sRef s, uentry ue)
6696 sRef_checkMutable (s);
6697 llassert (sRef_isValid (s));
6699 sRef_setPartsFromUentry (s, ue);
6701 defstate = uentry_getDefState (ue);
6703 if (sstate_isKnown (defstate))
6705 s->defstate = defstate;
6714 sRef_buildPointer (/*@exposed@*/ sRef t)
6716 DPRINTF (("build pointer: %s", sRef_unparse (t)));
6718 if (sRef_isInvalid (t)) return sRef_undefined;
6720 if (sRef_isAddress (t))
6722 DPRINTF (("Return ref: %s", sRef_unparse (t->info->ref)));
6723 return (t->info->ref);
6727 sRef s = sRef_findDerivedPointer (t);
6729 DPRINTF (("find derived: %s", sRef_unparse (s)));
6731 if (sRef_isValid (s))
6734 sRef_setExKind (s, sRef_getExKind (t), g_currentloc);
6735 s->oaliaskind = s->aliaskind;
6736 s->oexpkind = s->expkind;
6742 s = sRef_constructPointerAux (t);
6744 DPRINTF (("construct: %s", sRef_unparse (s)));
6746 if (sRef_isValid (s))
6748 sRef_addDeriv (t, s);
6750 s->oaliaskind = s->aliaskind;
6751 s->oexpkind = s->expkind;
6760 sRef_constructPointer (/*@exposed@*/ sRef t)
6763 return sRef_buildPointer (t);
6766 static /*@exposed@*/ sRef sRef_constructDerefAux (sRef t, bool isdead)
6768 if (sRef_isValid (t))
6773 ** if there is a derived t[?], return that. Otherwise, *t.
6776 s = sRef_findDerivedArrayFetch (t, FALSE, 0, isdead);
6778 if (sRef_isValid (s))
6780 DPRINTF (("Found array fetch: %s", sRef_unparseFull (s)));
6785 sRef ret = sRef_constructPointer (t);
6787 DPRINTF (("Constructed pointer: %s", sRef_unparseFull (ret)));
6794 return sRef_undefined;
6798 sRef sRef_constructDeref (sRef t)
6800 return sRef_constructDerefAux (t, FALSE);
6803 sRef sRef_constructDeadDeref (sRef t)
6805 return sRef_constructDerefAux (t, TRUE);
6809 sRef_constructPointerAux (/*@notnull@*/ /*@exposed@*/ sRef t)
6811 sRef s = sRef_newRef ();
6815 llassert (valueTable_isUndefined (s->state));
6818 s->info = (sinfo) dmalloc (sizeof (*s->info));
6819 s->info->ref = t; /* sRef_copy (t); */ /*@i32*/
6821 if (ctype_isRealAP (rt))
6823 s->type = ctype_baseArrayPtr (rt);
6826 st = ctype_realType (s->type);
6828 if (t->defstate == SS_UNDEFINED)
6830 s->defstate = SS_UNUSEABLE;
6832 else if ((t->defstate == SS_ALLOCATED) && !ctype_isSU (st))
6834 s->defstate = SS_UNDEFINED;
6838 s->defstate = t->defstate;
6841 if (t->aliaskind == AK_LOCAL || t->aliaskind == AK_FRESH)
6843 s->aliaskind = AK_LOCAL;
6847 s->aliaskind = AK_UNKNOWN;
6850 sRef_setExKind (s, sRef_getExKind (t), fileloc_undefined);
6851 sRef_setTypeState (s);
6853 s->oaliaskind = s->aliaskind;
6854 s->oexpkind = s->expkind;
6856 if (valueTable_isUndefined (s->state))
6858 s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
6864 bool sRef_hasDerived (sRef s)
6866 return (sRef_isValid (s) && !sRefSet_isEmpty (s->deriv));
6870 sRef_clearDerived (sRef s)
6872 if (sRef_isValid (s))
6874 sRefSet_clear (s->deriv);
6879 sRef_clearDerivedComplete (sRef s)
6882 if (sRef_isValid (s))
6884 sRef base = sRef_getBaseSafe (s);
6886 while (sRef_isValid (base))
6888 sRefSet_clear (base->deriv);
6889 base = sRef_getBaseSafe (base);
6892 sRefSet_clear (s->deriv);
6896 /*@exposed@*/ sRef sRef_makePointer (/*@exposed@*/ sRef s)
6899 sRef res = sRef_buildPointer (s);
6901 DPRINTF (("Res: %s", sRef_unparse (res)));
6906 ** &a[] => a (this is for out params)
6910 sRef_makeAnyArrayFetch (/*@exposed@*/ sRef arr)
6912 if (sRef_isAddress (arr))
6914 return (arr->info->ref);
6918 return (sRef_buildArrayFetch (arr));
6923 sRef_makeArrayFetch (/*@exposed@*/ sRef arr)
6925 return (sRef_buildArrayFetch (arr));
6929 sRef_makeArrayFetchKnown (/*@exposed@*/ sRef arr, int i)
6931 return (sRef_buildArrayFetchKnown (arr, i));
6935 sRef_makeField (sRef rec, /*@dependent@*/ cstring f)
6938 ret = sRef_buildField (rec, f);
6943 sRef_makeNCField (/*@exposed@*/ sRef rec, /*@dependent@*/ cstring f)
6945 return (sRef_buildNCField (rec, f));
6949 sRef_unparseKindName (sRef s)
6953 if (s == sRef_undefined) return cstring_makeLiteral ("<invalid>");
6955 s = sRef_fixConj (s);
6960 if (sRef_isLocalVar (s))
6962 result = cstring_makeLiteral ("Variable");
6966 result = cstring_makeLiteral ("Undef global");
6970 result = cstring_makeLiteral ("Out parameter");
6973 if (sRef_isAnyParam (s->info->arrayfetch->arr))
6975 result = cstring_makeLiteral ("Out parameter");
6977 else if (sRef_isIndexKnown (s))
6979 result = cstring_makeLiteral ("Array element");
6983 result = cstring_makeLiteral ("Value");
6987 if (sRef_isAnyParam (s->info->ref))
6989 result = cstring_makeLiteral ("Out parameter");
6993 result = cstring_makeLiteral ("Value");
6997 result = cstring_makeLiteral ("Value");
7000 result = cstring_makeLiteral ("Field");
7003 result = cstring_makeLiteral ("Object");
7005 case SK_UNCONSTRAINED:
7006 result = cstring_makeLiteral ("<anything>");
7015 result = cstring_makeLiteral ("<unknown>");
7018 result = cstring_makeLiteral ("<conj>");
7021 result = cstring_makeLiteral ("Storage");
7029 sRef_unparseKindNamePlain (sRef s)
7033 if (s == sRef_undefined) return cstring_makeLiteral ("<invalid>");
7035 s = sRef_fixConj (s);
7040 if (sRef_isLocalVar (s))
7042 result = cstring_makeLiteral ("Variable");
7046 result = cstring_makeLiteral ("Global");
7050 result = cstring_makeLiteral ("Parameter");
7053 if (sRef_isAnyParam (s->info->arrayfetch->arr))
7055 result = cstring_makeLiteral ("Parameter");
7057 else if (sRef_isIndexKnown (s))
7059 result = cstring_makeLiteral ("Array element");
7063 result = cstring_makeLiteral ("Value");
7067 if (sRef_isAnyParam (s->info->ref))
7069 result = cstring_makeLiteral ("Parameter");
7073 result = cstring_makeLiteral ("Value");
7077 result = cstring_makeLiteral ("Value");
7080 result = cstring_makeLiteral ("Field");
7083 result = cstring_makeLiteral ("Object");
7086 result = cstring_makeLiteral ("Storage");
7088 case SK_UNCONSTRAINED:
7089 result = cstring_makeLiteral ("<anything>");
7098 result = cstring_makeLiteral ("<unknown>");
7101 result = cstring_makeLiteral ("<conj>");
7113 sRef_copyState (sRef s1, sRef s2)
7115 if (sRef_isValid (s1) && sRef_isValid (s2))
7117 s1->defstate = s2->defstate;
7119 /* start modifications */
7120 s1->bufinfo.bufstate = s2->bufinfo.bufstate;
7121 s1->bufinfo.len = s2->bufinfo.len;
7122 s1->bufinfo.size = s2->bufinfo.size;
7123 /* end modifications */
7125 s1->aliaskind = s2->aliaskind;
7126 s1->aliasinfo = stateInfo_update (s1->aliasinfo, s2->aliasinfo);
7128 s1->expkind = s2->expkind;
7129 s1->expinfo = stateInfo_update (s1->expinfo, s2->expinfo);
7131 s1->nullstate = s2->nullstate;
7132 s1->nullinfo = stateInfo_update (s1->nullinfo, s2->nullinfo);
7135 /*@i834 don't free it: valueTable_free (s1->state); */
7136 /*@i32@*/ s1->state = valueTable_copy (s2->state);
7138 s1->safe = s2->safe;
7143 sRef_makeNew (ctype ct, sRef t, cstring name)
7145 sRef s = sRef_newRef ();
7150 llassert (sRef_isValid (t));
7151 s->defstate = t->defstate;
7153 s->aliaskind = t->aliaskind;
7154 s->oaliaskind = s->aliaskind;
7155 s->nullstate = t->nullstate;
7157 s->expkind = t->expkind;
7158 s->oexpkind = s->expkind;
7160 s->info = (sinfo) dmalloc (sizeof (*s->info));
7161 s->info->fname = name;
7163 /* start modifications */
7164 s->bufinfo.bufstate = t->bufinfo.bufstate;
7165 /* end modifications */
7167 llassert (valueTable_isUndefined (s->state));
7168 s->state = valueTable_copy (t->state);
7170 DPRINTF (("==> Copying state: %s", valueTable_unparse (s->state)));
7171 DPRINTF (("==> new: %s", sRef_unparseFull (s)));
7176 sRef_makeType (ctype ct)
7178 sRef s = sRef_newRef ();
7180 sRef_checkMutable (s);
7185 s->defstate = SS_UNKNOWN;
7186 s->aliaskind = AK_UNKNOWN;
7187 sRef_setNullStateN (s, NS_UNKNOWN);
7189 /* start modification */
7190 s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
7191 /* end modification */
7194 if (ctype_isUA (ct))
7196 typeId uid = ctype_typeId (ct);
7197 uentry ue = usymtab_getTypeEntrySafe (uid);
7199 if (uentry_isValid (ue))
7201 sRef_mergeStateQuiet (s, uentry_getSref (ue));
7205 s->oaliaskind = s->aliaskind;
7206 s->oexpkind = s->expkind;
7207 llassert (valueTable_isUndefined (s->state));
7208 s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
7210 DPRINTF (("Create: %s", sRef_unparseFull (s)));
7215 sRef_makeConst (ctype ct)
7217 sRef s = sRef_newRef ();
7222 s->defstate = SS_UNKNOWN;
7223 s->aliaskind = AK_UNKNOWN;
7224 sRef_setNullStateN (s, NS_UNKNOWN);
7226 /* start modification */
7227 s->bufinfo.bufstate = BB_NULLTERMINATED;
7228 /* end modification */
7229 if (ctype_isUA (ct))
7231 typeId uid = ctype_typeId (ct);
7232 uentry te = usymtab_getTypeEntrySafe (uid);
7234 if (uentry_isValid (te))
7236 sRef_mergeStateQuiet (s, uentry_getSref (te));
7241 s->oaliaskind = s->aliaskind;
7242 s->oexpkind = s->expkind;
7244 llassert (valueTable_isUndefined (s->state));
7245 s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
7250 bool sRef_hasName (sRef s)
7252 if (sRef_isInvalid (s))
7261 uentry u = usymtab_getRefQuiet (s->info->cvar->lexlevel,
7262 s->info->cvar->index);
7263 return (uentry_hasName (u));
7267 if (s->info->paramno >= 0)
7269 uentry u = uentryList_getN (context_getParams (),
7272 return (uentry_hasName (u));
7276 llassert (s->info->paramno == PARAMUNKNOWN);
7286 sRef_sameName (sRef s1, sRef s2)
7288 if (sRef_isInvalid (s1))
7290 return sRef_isInvalid (s2);
7293 if (sRef_isInvalid (s2))
7301 if (s2->kind == SK_CVAR)
7303 return (s1->info->cvar->lexlevel == s2->info->cvar->lexlevel
7304 && s1->info->cvar->index == s2->info->cvar->index);
7306 else if (s2->kind == SK_PARAM)
7308 if (context_inFunctionLike ())
7310 if (s2->info->paramno != PARAMUNKNOWN)
7312 uentry u1 = usymtab_getRefQuiet (s1->info->cvar->lexlevel,
7313 s1->info->cvar->index);
7314 uentry u2 = uentryList_getN (context_getParams (),
7317 return (cstring_equalFree (uentry_getName (u1),
7318 uentry_getName (u2)));
7322 return s1->info->paramno == PARAMUNKNOWN;
7336 if (s2->kind == SK_PARAM)
7338 return (s1->info->paramno == s2->info->paramno);
7340 else if (s2->kind == SK_CVAR)
7342 if (context_inFunctionLike ())
7344 if (s1->info->paramno == PARAMUNKNOWN)
7350 uentry u1 = uentryList_getN (context_getParams (),
7352 uentry u2 = usymtab_getRefQuiet (s2->info->cvar->lexlevel,
7353 s2->info->cvar->index);
7356 return (cstring_equalFree (uentry_getName (u1),
7357 uentry_getName (u2)));
7371 case SK_UNCONSTRAINED:
7375 if (s2->kind == SK_ARRAYFETCH)
7377 if (bool_equal (s1->info->arrayfetch->indknown,
7378 s2->info->arrayfetch->indknown))
7380 if (!s1->info->arrayfetch->indknown
7381 || (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind))
7383 return sRef_sameName (s1->info->arrayfetch->arr,
7384 s2->info->arrayfetch->arr);
7391 if (s2->kind == SK_FIELD)
7393 if (cstring_equal (s1->info->field->field,
7394 s2->info->field->field))
7396 return sRef_sameName (s1->info->field->rec,
7397 s2->info->field->rec);
7406 if (s2->kind == s1->kind)
7408 return sRef_sameName (s1->info->ref,
7416 return sRef_sameName (sRef_getConjA (s1), s2);
7420 return (s2->kind == SK_UNKNOWN);
7423 if (s2->kind == s1->kind)
7425 return (ctype_equal (s1->type, s2->type));
7430 if (s2->kind == SK_SPECIAL)
7432 return (s1->info->spec == s2->info->spec);
7436 return (s2->kind == SK_RESULT);
7444 sRef_fixOuterRef (/*@returned@*/ sRef s)
7446 sRef root = sRef_getRootBase (s);
7448 if (sRef_isCvar (root))
7450 uentry ue = usymtab_getRefQuiet (root->info->cvar->lexlevel,
7451 root->info->cvar->index);
7453 if (uentry_isValid (ue))
7455 sRef uref = uentry_getSref (ue);
7456 sRef sr = sRef_fixBase (s, uref);
7462 llcontbug (message ("sRef_fixOuterRef: undefined: %q", sRef_unparseDebug (s)));
7471 sRef_storeState (sRef s)
7473 if (sRef_isInvalid (s)) return;
7475 sRef_checkMutable (s);
7476 s->oaliaskind = s->aliaskind;
7477 s->oexpkind = s->expkind;
7480 static void sRef_resetStateAux (sRef s, /*@unused@*/ fileloc loc)
7482 sRef_resetState (s);
7486 sRef_resetState (sRef s)
7488 bool changed = FALSE;
7489 if (sRef_isInvalid (s)) return;
7492 if (s->oaliaskind == AK_KILLREF && !sRef_isParam (s))
7495 ** killref is used in a kludgey way, to save having to add
7496 ** another alias kind (see usymtab_handleParams)
7499 if (s->expkind != s->oexpkind)
7502 s->expkind = s->oexpkind;
7507 if (s->expkind != s->oexpkind)
7510 s->expkind = s->oexpkind;
7513 if (s->aliaskind != s->oaliaskind
7514 && s->aliaskind != AK_REFCOUNTED
7515 && s->aliaskind != AK_REFS)
7518 s->aliaskind = s->oaliaskind;
7524 sRef_clearDerived (s);
7530 sRef_resetStateComplete (sRef s)
7532 sRef_innerAliasSetComplete (sRef_resetStateAux, s, fileloc_undefined);
7536 sRef_fixBase (/*@returned@*/ sRef s, /*@returned@*/ sRef base)
7538 sRef tmp = sRef_undefined;
7541 if (sRef_isInvalid (s)) return s;
7542 if (sRef_isInvalid (base)) return base;
7552 tmp = sRef_fixBase (s->info->arrayfetch->arr, base);
7554 if (s->info->arrayfetch->indknown)
7556 ret = sRef_makeArrayFetchKnown (tmp, s->info->arrayfetch->ind);
7560 ret = sRef_makeArrayFetch (tmp);
7564 tmp = sRef_fixBase (s->info->field->rec, base);
7565 ret = sRef_buildNCField (tmp, s->info->field->field);
7568 tmp = sRef_fixBase (s->info->ref, base);
7569 ret = sRef_makePointer (tmp);
7572 tmp = sRef_fixBase (s->info->ref, base);
7573 ret = sRef_makeAddress (tmp);
7579 tmp = sRef_fixBase (s->info->conj->a, base);
7580 tmpb = sRef_fixBase (s->info->conj->b, base);
7582 ret = sRef_makeConj (tmp, tmpb);
7591 static /*@exposed@*/ sRef
7592 sRef_fixDirectBase (sRef s, sRef base)
7597 if (sRef_isInvalid (s))
7599 return sRef_undefined;
7605 if (s->info->arrayfetch->indknown)
7607 ret = sRef_makeArrayFetchKnown (base, s->info->arrayfetch->ind);
7611 ret = sRef_makeArrayFetch (base);
7615 ret = sRef_buildNCField (base, s->info->field->field);
7618 ret = sRef_makePointer (base);
7621 ret = sRef_makeAddress (base);
7627 tmpa = sRef_fixDirectBase (s->info->conj->a, base);
7628 tmpb = sRef_fixDirectBase (s->info->conj->b, base);
7630 ret = sRef_makeConj (tmpa, tmpb);
7636 sRef_copyState (ret, s);
7641 sRef_isAllocIndexRef (sRef s)
7643 return (sRef_isArrayFetch (s) && !(s->info->arrayfetch->indknown)
7644 && sRef_isAllocated (s->info->arrayfetch->arr));
7648 sRef_showRefLost (sRef s)
7650 if (sRef_hasAliasInfoLoc (s))
7652 llgenindentmsg (cstring_makeLiteral ("Original reference lost"),
7653 sRef_getAliasInfoLoc (s));
7658 sRef_showRefKilled (sRef s)
7660 if (sRef_hasStateInfoLoc (s))
7662 llgenindentmsg (message ("Storage %q released",
7663 sRef_unparse (s)), sRef_getStateInfoLoc (s));
7668 sRef_showStateInconsistent (sRef s)
7670 if (sRef_hasStateInfoLoc (s))
7673 (message ("Storage %qbecomes inconsistent (released on one branch)",
7674 sRef_unparseOpt (s)),
7675 sRef_getStateInfoLoc (s));
7680 sRef_showStateInfo (sRef s)
7682 if (sRef_hasStateInfoLoc (s))
7684 if (s->defstate == SS_DEAD)
7687 (message ("Storage %qis released", sRef_unparseOpt (s)),
7688 sRef_getStateInfoLoc (s));
7690 else if (s->defstate == SS_ALLOCATED || s->defstate == SS_DEFINED)
7693 (message ("Storage %qis %s", sRef_unparseOpt (s),
7694 sstate_unparse (s->defstate)),
7695 sRef_getStateInfoLoc (s));
7697 else if (s->defstate == SS_UNUSEABLE)
7700 (message ("Storage %qbecomes inconsistent (clauses merge with"
7701 "%qreleased on one branch)",
7702 sRef_unparseOpt (s),
7703 sRef_unparseOpt (s)),
7704 sRef_getStateInfoLoc (s));
7708 llgenindentmsg (message ("Storage %qbecomes %s",
7709 sRef_unparseOpt (s),
7710 sstate_unparse (s->defstate)),
7711 sRef_getStateInfoLoc (s));
7717 sRef_showExpInfo (sRef s)
7719 if (sRef_hasExpInfoLoc (s))
7721 llgenindentmsg (message ("Storage %qbecomes %s", sRef_unparseOpt (s),
7722 exkind_unparse (s->expkind)),
7723 sRef_getExpInfoLoc (s));
7728 sRef_showMetaStateInfo (sRef s, cstring key)
7731 metaStateInfo minfo = context_lookupMetaStateInfo (key);
7733 llassert (sRef_isValid (s));
7734 llassert (valueTable_isDefined (s->state));
7735 llassert (metaStateInfo_isDefined (minfo));
7737 val = valueTable_lookup (s->state, key);
7739 if (stateValue_hasLoc (val))
7742 (message ("%qbecomes %q", sRef_unparseOpt (s),
7743 stateValue_unparseValue (val, minfo)),
7744 stateValue_getLoc (val));
7749 sRef_showNullInfo (sRef s)
7751 DPRINTF (("Show null info: %s", sRef_unparseFull (s)));
7753 if (sRef_hasNullInfoLoc (s) && sRef_isKnown (s))
7755 DPRINTF (("has null info: %s",
7756 fileloc_unparse (sRef_getNullInfoLoc (s))));
7758 switch (sRef_getNullState (s))
7762 fileloc loc = sRef_getNullInfoLoc (s);
7764 if (fileloc_isDefined (loc) && !fileloc_isLib (loc))
7767 (message ("Storage %qbecomes null", sRef_unparseOpt (s)),
7774 fileloc loc = sRef_getNullInfoLoc (s);
7776 if (fileloc_isDefined (loc) && !fileloc_isLib (loc))
7778 llgenindentmsg (message ("Storage %qbecomes null", sRef_unparseOpt (s)),
7786 (message ("Storage %qmay become null", sRef_unparseOpt (s)),
7787 sRef_getNullInfoLoc (s));
7792 (message ("Storage %qbecomes not null", sRef_unparseOpt (s)),
7793 sRef_getNullInfoLoc (s));
7797 (message ("Storage %qnull state becomes unknown",
7798 sRef_unparseOpt (s)),
7799 sRef_getNullInfoLoc (s));
7808 (message ("<error case> Storage %q becomes %s",
7810 nstate_unparse (sRef_getNullState (s))),
7811 sRef_getNullInfoLoc (s));
7819 sRef_showAliasInfo (sRef s)
7821 if (sRef_hasAliasInfoLoc (s))
7823 if (sRef_isFresh (s))
7826 (message ("Fresh storage %qallocated", sRef_unparseOpt (s)),
7827 sRef_getAliasInfoLoc (s));
7831 if (!sRef_isRefCounted (s))
7834 (message ("Storage %qbecomes %s",
7835 sRef_unparseOpt (s),
7836 alkind_unparse (sRef_getAliasKind (s))),
7837 sRef_getAliasInfoLoc (s));
7844 sRef_mergeNullState (sRef s, nstate n)
7846 if (sRef_isValid (s))
7850 old = sRef_getNullState (s);
7852 if (n != old && n != NS_UNKNOWN)
7854 sRef_setNullState (s, n, g_currentloc);
7859 llbuglit ("sRef_mergeNullState: invalid");
7864 sRef_possiblyNull (sRef s)
7866 if (sRef_isValid (s))
7868 if (sRef_getNullState (s) == NS_ABSNULL)
7870 ctype rct = ctype_realType (s->type);
7872 if (ctype_isAbstract (rct))
7878 if (ctype_isUser (rct))
7880 uentry ue = usymtab_getTypeEntry (ctype_typeId (rct));
7882 return (nstate_possiblyNull
7883 (sRef_getNullState (uentry_getSref (ue))));
7893 return nstate_possiblyNull (sRef_getNullState (s));
7901 sRef_getScopeName (sRef s)
7903 sRef base = sRef_getRootBase (s);
7905 if (sRef_isRealGlobal (base))
7907 return (cstring_makeLiteralTemp ("Global"));
7909 else if (sRef_isFileStatic (base))
7911 return (cstring_makeLiteralTemp ("Static"));
7915 return (cstring_makeLiteralTemp ("Local"));
7920 sRef_unparseScope (sRef s)
7922 sRef base = sRef_getRootBase (s);
7924 if (sRef_isRealGlobal (base))
7926 return (cstring_makeLiteralTemp ("global"));
7928 else if (sRef_isFileStatic (base))
7930 return (cstring_makeLiteralTemp ("file static"));
7939 sRef_getScope (sRef s)
7941 llassert (sRef_isValid (s));
7943 if (sRef_isCvar (s))
7945 return s->info->cvar->lexlevel;
7947 else if (sRef_isParam (s))
7958 sRef_isDead (sRef s)
7960 return (sRef_isValid (s) && (s)->defstate == SS_DEAD);
7964 sRef_isDeadStorage (sRef s)
7966 if (sRef_isValid (s))
7968 if (s->defstate == SS_DEAD
7969 || s->defstate == SS_UNUSEABLE
7970 || s->defstate == SS_UNDEFINED
7971 || s->defstate == SS_UNKNOWN)
7977 return (sRef_isDefinitelyNull (s));
7987 sRef_isPossiblyDead (sRef s)
7989 return (sRef_isValid (s) && s->defstate == SS_HOFFA);
7992 bool sRef_isStateLive (sRef s)
7994 if (sRef_isValid (s))
7996 sstate ds = s->defstate;
7998 return (!(ds == SS_UNDEFINED
8000 || ds == SS_UNUSEABLE
8001 || ds == SS_HOFFA));
8010 bool sRef_isStateUndefined (sRef s)
8012 return ((sRef_isValid(s)) && ((s)->defstate == SS_UNDEFINED));
8015 bool sRef_isJustAllocated (sRef s)
8017 if (sRef_isAllocated (s))
8019 sRefSet_allElements (s->deriv, el)
8021 if (!(sRef_isStateUndefined (el) || sRef_isUnuseable (el)))
8025 } end_sRefSet_allElements ;
8034 sRef_isAllocatedStorage (sRef s)
8036 if (sRef_isValid (s) && ynm_toBoolStrict (sRef_isValidLvalue (s)))
8038 return (ctype_isVisiblySharable (sRef_getType (s)));
8047 sRef_isUnuseable (sRef s)
8049 return ((sRef_isValid(s)) && ((s)->defstate == SS_UNUSEABLE));
8053 sRef_perhapsNull (sRef s)
8055 if (sRef_isValid (s))
8057 if (sRef_getNullState (s) == NS_ABSNULL)
8059 ctype rct = ctype_realType (s->type);
8061 if (ctype_isAbstract (rct))
8067 if (ctype_isUser (rct))
8069 uentry ue = usymtab_getTypeEntry (ctype_typeId (rct));
8071 return (nstate_perhapsNull
8072 (sRef_getNullState (uentry_getSref (ue))));
8082 return nstate_perhapsNull (sRef_getNullState (s));
8090 ** definitelyNull --- called when TRUE is good
8094 sRef_definitelyNull (sRef s)
8096 return (sRef_isValid (s)
8097 && (sRef_getNullState (s) == NS_DEFNULL || sRef_getNullState (s) == NS_CONSTNULL));
8101 ** based on sRef_similar
8105 sRef_setDerivNullState (sRef set, sRef guide, nstate ns)
8107 if (sRef_isValid (set))
8109 sRef deriv = sRef_getDeriv (set, guide);
8111 if (sRef_isValid (deriv))
8113 sRef_setNullStateN (deriv, ns);
8118 static /*@exposed@*/ sRef
8119 sRef_getDeriv (/*@returned@*/ /*@notnull@*/ sRef set, sRef guide)
8121 llassert (sRef_isValid (set));
8122 llassert (sRef_isValid (guide));
8124 switch (guide->kind)
8127 llassert (set->kind == SK_CVAR);
8132 llassert (set->kind == guide->kind);
8133 llassert (set->info->paramno == guide->info->paramno);
8139 if (set->kind == SK_ARRAYFETCH
8140 && (sRef_similar (set->info->arrayfetch->arr,
8141 guide->info->arrayfetch->arr)))
8147 return (sRef_makeAnyArrayFetch
8148 (sRef_getDeriv (set, guide->info->arrayfetch->arr)));
8153 if (set->kind == SK_PTR && sRef_similar (set->info->ref, guide->info->ref))
8159 return (sRef_makePointer (sRef_getDeriv (set, guide->info->ref)));
8164 if ((set->kind == SK_FIELD &&
8165 (sRef_similar (set->info->field->rec, guide->info->field->rec) &&
8166 cstring_equal (set->info->field->field, guide->info->field->field))))
8172 return (sRef_makeField (sRef_getDeriv (set, guide->info->field->rec),
8173 guide->info->field->field));
8177 if ((set->kind == SK_ADR) && sRef_similar (set->info->ref, guide->info->ref))
8183 return (sRef_makeAddress (sRef_getDeriv (set, guide->info->ref)));
8188 return sRef_undefined;
8192 case SK_UNCONSTRAINED:
8200 return sRef_undefined;
8207 ** sRef_aliasCheckPred
8209 ** A confusing but spiffy function:
8211 ** Calls predf (s, e, text, <alias>) on s and all of s's aliases
8212 ** (unless checkAliases (s) is FALSE).
8214 ** For alias calls, calls as
8215 ** predf (alias, e, text, s)
8219 sRef_aliasCheckPred (bool (predf) (sRef, exprNode, sRef, exprNode),
8220 /*@null@*/ bool (checkAliases) (sRef),
8221 sRef s, exprNode e, exprNode err)
8223 bool error = (*predf)(s, e, sRef_undefined, err);
8226 if (checkAliases != NULL && !(checkAliases (s)))
8228 /* don't check aliases */
8232 sRefSet aliases = usymtab_allAliases (s);
8234 sRefSet_realElements (aliases, current)
8236 if (sRef_isValid (current))
8238 if (!sRef_similar (current, s)
8239 || (error && sRef_sameName (current, s)))
8241 (void) (*predf)(current, e, s, err);
8244 } end_sRefSet_realElements;
8246 sRefSet_free (aliases);
8251 ** return TRUE iff predf (s) is true for s or any alias of s
8255 sRef_aliasCheckSimplePred (sRefTest predf, sRef s)
8266 aliases = usymtab_allAliases (s);
8268 sRefSet_realElements (aliases, current)
8270 if (sRef_isValid (current))
8272 sRef cref = sRef_updateSref (current);
8274 /* Whoa! a very kludgey way to make sure the right sref is used
8275 ** where there is a conditional symbol table. I am beginning
8276 ** to think that having a conditional symbol table wasn't such
8282 DPRINTF (("Checking alias: %s", sRef_unparseFull (cref)));
8283 sRefSet_free (aliases);
8287 } end_sRefSet_realElements;
8289 sRefSet_free (aliases);
8295 sRef_aliasCompleteSimplePred (bool (predf) (sRef), sRef s)
8298 bool result = FALSE;
8301 aliases = usymtab_allAliases (s);
8303 if ((*predf)(s)) result = TRUE;
8306 sRefSet_realElements (aliases, current)
8308 if (sRef_isValid (current))
8310 current = sRef_updateSref (current);
8311 if ((*predf)(current)) result = TRUE;
8313 } end_sRefSet_realElements;
8315 sRefSet_free (aliases);
8320 sRef_aliasSetComplete (void (predf) (sRef, fileloc), sRef s, fileloc loc)
8324 aliases = usymtab_allAliases (s);
8326 DPRINTF (("All aliases: %s", sRefSet_unparseFull (aliases)));
8330 sRefSet_realElements (aliases, current)
8332 if (sRef_isValid (current))
8334 current = sRef_updateSref (current);
8335 ((*predf)(current, loc));
8336 DPRINTF (("Killed: %s", sRef_unparseFull (current)));
8338 } end_sRefSet_realElements;
8340 sRefSet_free (aliases);
8344 sRef_aliasSetCompleteParam (void (predf) (sRef, int, fileloc), sRef s,
8345 int kind, fileloc loc)
8349 if (sRef_isDeep (s))
8351 aliases = usymtab_allAliases (s);
8355 aliases = usymtab_aliasedBy (s);
8358 (*predf)(s, kind, loc);
8360 sRefSet_realElements (aliases, current)
8362 if (sRef_isValid (current))
8364 current = sRef_updateSref (current);
8365 ((*predf)(current, kind, loc));
8367 } end_sRefSet_realElements;
8369 sRefSet_free (aliases);
8373 ** Version of aliasSetCompleteParam for alkind parameters
8377 sRef_aliasSetCompleteAlkParam (void (predf) (sRef, alkind, fileloc), sRef s,
8378 alkind kind, fileloc loc)
8382 if (sRef_isDeep (s))
8384 aliases = usymtab_allAliases (s);
8388 aliases = usymtab_aliasedBy (s);
8391 (*predf)(s, kind, loc);
8393 sRefSet_realElements (aliases, current)
8395 if (sRef_isValid (current))
8397 current = sRef_updateSref (current);
8398 ((*predf)(current, kind, loc));
8400 } end_sRefSet_realElements;
8402 sRefSet_free (aliases);
8406 sRef_innerAliasSetComplete (void (predf) (sRef, fileloc), sRef s, fileloc loc)
8412 if (!sRef_isValid (s)) return;
8415 ** Type equivalence checking is necessary --- there might be casting.
8422 case SK_UNCONSTRAINED:
8427 inner = s->info->ref;
8428 aliases = usymtab_allAliases (inner);
8429 ct = sRef_getType (inner);
8431 sRefSet_realElements (aliases, current)
8433 if (sRef_isValid (current))
8435 current = sRef_updateSref (current);
8437 if (ctype_equal (ct, sRef_getType (current)))
8439 sRef ptr = sRef_makePointer (current);
8440 ((*predf)(ptr, loc));
8443 } end_sRefSet_realElements;
8445 sRefSet_free (aliases);
8448 inner = s->info->arrayfetch->arr;
8449 aliases = usymtab_allAliases (inner);
8450 ct = sRef_getType (inner);
8452 DPRINTF (("Array fetch: %s", sRefSet_unparse (aliases)));
8454 sRefSet_realElements (aliases, current)
8456 if (sRef_isValid (current))
8458 current = sRef_updateSref (current);
8459 DPRINTF (("Current: %s", sRef_unparseFull (current)));
8461 if (ctype_equal (ct, sRef_getType (current)))
8463 if (s->info->arrayfetch->indknown)
8465 sRef af = sRef_makeArrayFetchKnown (current, s->info->arrayfetch->ind);
8466 DPRINTF (("Defining: %s", sRef_unparseFull (af)));
8467 /* evans 2001-08-27 This isn't true:
8468 llassert (af->info->arrayfetch->arr == current);
8469 see comments in buildArrayFetchKnown
8471 ((*predf)(af, loc));
8475 sRef af = sRef_makeArrayFetch (current);
8476 /* evans 2001-08-27 This isn't true:
8477 llassert (af->info->arrayfetch->arr == current);
8478 see comments in buildArrayFetch
8480 DPRINTF (("Defining: %s", sRef_unparseFull (af)));
8481 ((*predf)(af, loc));
8486 DPRINTF (("Type mismatch: %s / %s",
8488 ctype_unparse (sRef_getType (current))));
8491 } end_sRefSet_realElements;
8493 sRefSet_free (aliases);
8496 inner = s->info->field->rec;
8497 aliases = usymtab_allAliases (inner);
8498 ct = sRef_getType (inner);
8500 sRefSet_realElements (aliases, current)
8502 if (sRef_isValid (current))
8504 current = sRef_updateSref (current);
8506 if (ctype_equal (ct, sRef_getType (current)))
8508 sRef f = sRef_makeField (current, s->info->field->field);
8513 } end_sRefSet_realElements;
8515 sRefSet_free (aliases);
8518 sRef_innerAliasSetComplete (predf, s->info->conj->a, loc);
8519 sRef_innerAliasSetComplete (predf, s->info->conj->b, loc);
8536 sRef_innerAliasSetCompleteParam (void (predf) (sRef, sRef), sRef s, sRef t)
8542 if (!sRef_isValid (s)) return;
8545 ** Type equivalence checking is necessary --- there might be casting.
8552 case SK_UNCONSTRAINED:
8557 inner = s->info->ref;
8558 aliases = usymtab_allAliases (inner);
8559 ct = sRef_getType (inner);
8561 sRefSet_realElements (aliases, current)
8563 if (sRef_isValid (current))
8565 current = sRef_updateSref (current);
8567 if (ctype_equal (ct, sRef_getType (current)))
8569 sRef ptr = sRef_makePointer (current);
8574 } end_sRefSet_realElements;
8576 sRefSet_free (aliases);
8579 inner = s->info->arrayfetch->arr;
8580 aliases = usymtab_allAliases (inner);
8581 ct = sRef_getType (inner);
8583 sRefSet_realElements (aliases, current)
8585 if (sRef_isValid (current))
8587 current = sRef_updateSref (current);
8589 if (ctype_equal (ct, sRef_getType (current)))
8592 if (s->info->arrayfetch->indknown)
8594 sRef af = sRef_makeArrayFetchKnown (current, s->info->arrayfetch->ind);
8600 sRef af = sRef_makeArrayFetch (current);
8606 } end_sRefSet_realElements;
8608 sRefSet_free (aliases);
8611 inner = s->info->field->rec;
8612 aliases = usymtab_allAliases (inner);
8613 ct = sRef_getType (inner);
8616 sRefSet_realElements (aliases, current)
8618 if (sRef_isValid (current))
8620 current = sRef_updateSref (current);
8622 if (ctype_equal (ct, sRef_getType (current)))
8624 sRef f = sRef_makeField (current, s->info->field->field);
8629 } end_sRefSet_realElements;
8631 sRefSet_free (aliases);
8634 sRef_innerAliasSetCompleteParam (predf, s->info->conj->a, t);
8635 sRef_innerAliasSetCompleteParam (predf, s->info->conj->b, t);
8651 static void sRef_combineExKinds (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other)
8653 exkind a1 = sRef_getExKind (res);
8654 exkind a2 = sRef_getExKind (other);
8656 if (a1 == a2 || a2 == XO_UNKNOWN)
8660 else if (a1 == XO_UNKNOWN)
8662 res->expinfo = stateInfo_update (res->expinfo, other->expinfo);
8667 res->expkind = XO_OBSERVER;
8672 ** Currently, this is a very ad hoc implementation, with lots of fixes to
8673 ** make real code work okay. I need to come up with some more general
8674 ** rules or principles here.
8678 sRef_combineAliasKindsError (/*@notnull@*/ sRef res,
8679 /*@notnull@*/ sRef other,
8680 clause cl, fileloc loc)
8682 bool hasError = FALSE;
8683 alkind ares = sRef_getAliasKind (res);
8684 alkind aother = sRef_getAliasKind (other);
8686 sRef_checkMutable (res);
8688 if (alkind_isDependent (ares))
8690 if (aother == AK_KEPT)
8692 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8693 res->aliaskind = AK_KEPT;
8697 if (aother == AK_LOCAL || aother == AK_STATIC
8698 || alkind_isTemp (aother))
8700 DPRINTF (("Setting dependent: %s", sRef_unparseFull (res)));
8701 res->aliaskind = AK_DEPENDENT;
8705 else if (alkind_isDependent (aother))
8707 if (ares == AK_KEPT)
8709 res->aliaskind = AK_KEPT;
8713 if (ares == AK_LOCAL || ares == AK_STATIC || alkind_isTemp (ares))
8715 DPRINTF (("Setting dependent: %s", sRef_unparseFull (res)));
8716 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8717 res->aliaskind = AK_DEPENDENT;
8721 else if ((ares == AK_LOCAL || ares == AK_UNIQUE
8722 || ares == AK_STATIC || alkind_isTemp (ares))
8723 && sRef_isFresh (other))
8726 ** cases like: if (s == NULL) s = malloc...;
8727 ** don't generate errors
8730 if (usymtab_isAltDefinitelyNullDeep (res))
8732 res->aliaskind = ares;
8739 else if ((aother == AK_LOCAL || aother == AK_UNIQUE
8740 || aother == AK_STATIC || alkind_isTemp (aother))
8741 && sRef_isFresh (res))
8744 ** cases like: if (s == NULL) s = malloc...;
8745 ** don't generate errors
8748 if (usymtab_isDefinitelyNullDeep (other))
8750 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8751 res->aliaskind = aother;
8758 else if (ares == AK_NEWREF && aother == AK_REFCOUNTED
8759 && sRef_isConst (other))
8761 res->aliaskind = AK_NEWREF;
8763 else if (aother == AK_NEWREF && ares == AK_REFCOUNTED
8764 && sRef_isConst (res))
8766 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8767 res->aliaskind = AK_NEWREF;
8769 else if (sRef_isLocalVar (res)
8770 && ((ares == AK_KEPT && aother == AK_LOCAL)
8771 || (aother == AK_KEPT && ares == AK_LOCAL)))
8773 res->aliaskind = AK_KEPT;
8782 if (sRef_isThroughArrayFetch (res))
8785 (FLG_BRANCHSTATE, FLG_STRICTBRANCHSTATE,
8787 ("Clauses exit with %q possibly referencing %s storage %s, "
8790 alkind_unparse (aother),
8791 clause_nameTaken (cl),
8792 alkind_unparse (ares),
8793 clause_nameAlternate (cl)),
8796 sRef_showAliasInfo (res);
8797 sRef_showAliasInfo (other);
8798 res->aliaskind = AK_ERROR;
8802 if (ares == AK_KEPT || aother == AK_KEPT)
8804 sRef_maybeKill (res, loc);
8812 message ("Clauses exit with %q referencing %s storage %s, "
8815 alkind_unparse (aother),
8816 clause_nameTaken (cl),
8817 alkind_unparse (ares),
8818 clause_nameAlternate (cl)),
8821 sRef_showAliasInfo (res);
8822 sRef_showAliasInfo (other);
8824 res->aliaskind = AK_ERROR;
8828 res->aliaskind = (sRef_isLocalVar (res) ? AK_LOCAL : AK_UNKNOWN);
8833 sRef_combineAliasKinds (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other,
8834 clause cl, fileloc loc)
8836 alkind ares = sRef_getAliasKind (res);
8837 alkind aother = sRef_getAliasKind (other);
8839 sRef_checkMutable (res);
8841 DPRINTF (("Combine alias kinds: \n\t%s / \n\t%s",
8842 sRef_unparseFull (res), sRef_unparseFull (other)));
8843 if (alkind_equal (ares, aother)
8844 || aother == AK_UNKNOWN
8845 || aother == AK_ERROR)
8847 ; /* keep current state */
8849 else if (sRef_isDead (res) || sRef_isDead (other))
8851 /* dead error reported (or storage is dead) */
8852 res ->aliaskind = AK_ERROR;
8854 else if (ares == AK_UNKNOWN || ares == AK_ERROR
8855 || sRef_isStateUndefined (res)
8856 || sRef_isDefinitelyNull (res))
8858 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8859 res->aliaskind = aother;
8861 else if (sRef_isStateUndefined (other)
8862 || sRef_isDefinitelyNull (other))
8866 else if (((ares == AK_UNIQUE || alkind_isTemp (ares))
8867 && aother == AK_LOCAL)
8868 || ((aother == AK_UNIQUE || alkind_isTemp (aother))
8869 && ares == AK_LOCAL))
8871 if (ares != AK_LOCAL)
8873 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8876 res->aliaskind = AK_LOCAL;
8878 else if ((ares == AK_OWNED && aother == AK_FRESH)
8879 || (aother == AK_OWNED && ares == AK_FRESH))
8881 if (ares != AK_FRESH)
8883 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8886 res->aliaskind = AK_FRESH;
8888 else if ((ares == AK_KEEP && aother == AK_FRESH) ||
8889 (aother == AK_KEEP && ares == AK_FRESH))
8891 if (ares != AK_KEEP)
8893 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8896 res->aliaskind = AK_KEEP;
8898 else if ((ares == AK_LOCAL && aother == AK_STACK) ||
8899 (aother == AK_LOCAL && ares == AK_STACK))
8901 if (ares != AK_STACK)
8903 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8906 res->aliaskind = AK_STACK;
8908 else if ((ares == AK_LOCAL
8909 && (aother == AK_OWNED && sRef_isLocalVar (other)))
8910 || (aother == AK_LOCAL
8911 && (ares == AK_OWNED && sRef_isLocalVar (res))))
8913 if (ares != AK_LOCAL)
8915 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8918 res->aliaskind = AK_LOCAL;
8920 else if ((ares == AK_FRESH && alkind_isOnly (aother))
8921 || (aother == AK_FRESH && alkind_isOnly (ares)))
8923 res->aliaskind = AK_FRESH;
8925 else if ((aother == AK_FRESH && sRef_definitelyNull (res))
8926 || (ares == AK_FRESH && sRef_definitelyNull (other)))
8928 if (ares != AK_FRESH)
8930 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8931 res->aliaskind = AK_FRESH;
8934 else if ((sRef_isFresh (res) && sRef_isConst (other))
8935 || (sRef_isFresh (other) && sRef_isConst (res)))
8938 ** for NULL constantants
8942 if (!sRef_isFresh (res))
8944 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8947 res->aliaskind = AK_FRESH;
8949 else if ((alkind_isStatic (aother) && sRef_isConst (res))
8950 || (alkind_isStatic (ares) && sRef_isConst (other)))
8952 if (!alkind_isStatic (ares))
8954 res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8955 res->aliaskind = AK_STATIC;
8960 sRef_combineAliasKindsError (res, other, cl, loc);
8964 static void sRef_combineDefState (/*@notnull@*/ sRef res,
8965 /*@notnull@*/ sRef other)
8967 sstate s1 = res->defstate;
8968 sstate s2 = other->defstate;
8971 sRef_checkMutable (res);
8973 if (s1 == s2 || s2 == SS_UNKNOWN)
8977 else if (s1 == SS_UNKNOWN)
8986 if (s2 == SS_DEFINED)
8992 llcontbuglit ("ssfixed: not implemented");
9001 flip = (s2 != SS_DEFINED);
9019 res->definfo = stateInfo_update (res->definfo, other->definfo);
9024 extern /*@notnull@*/ sRef sRef_getConjA (sRef s)
9027 llassert (sRef_isConj (s));
9029 ret = s->info->conj->a;
9030 llassert (ret != NULL);
9034 extern /*@notnull@*/ sRef sRef_getConjB (sRef s)
9037 llassert (sRef_isConj (s));
9039 ret = s->info->conj->b;
9040 llassert (ret != NULL);
9044 extern /*@exposed@*/ sRef sRef_makeArrow (sRef s, /*@dependent@*/ cstring f)
9049 p = sRef_makePointer (s);
9050 ret = sRef_makeField (p, f);
9051 DPRINTF (("Arrow: %s => %s",
9052 sRef_unparseFull (s), sRef_unparseFull (ret)));
9056 extern /*@exposed@*/ sRef sRef_buildArrow (sRef s, cstring f)
9061 p = sRef_buildPointer (s);
9062 ret = sRef_buildField (p, f);
9067 static /*@null@*/ sinfo sinfo_copy (/*@notnull@*/ sRef s)
9074 ret = (sinfo) dmalloc (sizeof (*ret));
9075 ret->cvar = (cref) dmalloc (sizeof (*ret->cvar));
9076 ret->cvar->lexlevel = s->info->cvar->lexlevel;
9077 ret->cvar->index = s->info->cvar->index;
9081 ret = (sinfo) dmalloc (sizeof (*ret));
9082 ret->paramno = s->info->paramno;
9083 llassert (ret->paramno >= -1);
9087 ret = (sinfo) dmalloc (sizeof (*ret));
9088 ret->arrayfetch = (ainfo) dmalloc (sizeof (*ret->arrayfetch));
9089 ret->arrayfetch->indknown = s->info->arrayfetch->indknown;
9090 ret->arrayfetch->ind = s->info->arrayfetch->ind;
9091 ret->arrayfetch->arr = s->info->arrayfetch->arr; /* sRef_copy (s->info->arrayfetch->arr); */ /*@i32@*/
9095 ret = (sinfo) dmalloc (sizeof (*ret));
9096 ret->field = (fldinfo) dmalloc (sizeof (*ret->field));
9097 ret->field->rec = s->info->field->rec; /* sRef_copy (s->info->field->rec); */ /*@i32@*/
9098 ret->field->field = s->info->field->field;
9102 ret = (sinfo) dmalloc (sizeof (*ret));
9103 ret->object = s->info->object;
9110 ret = (sinfo) dmalloc (sizeof (*ret));
9111 ret->ref = s->info->ref; /* Ref_copy (s->info->ref); */
9115 ret = (sinfo) dmalloc (sizeof (*ret));
9116 ret->conj = (cjinfo) dmalloc (sizeof (*ret->conj));
9117 ret->conj->a = s->info->conj->a; /* sRef_copy (s->info->conj->a); */
9118 ret->conj->b = s->info->conj->b; /* sRef_copy (s->info->conj->b);*/
9121 ret = (sinfo) dmalloc (sizeof (*ret));
9122 ret->spec = s->info->spec;
9124 case SK_UNCONSTRAINED:
9126 ret = (sinfo) dmalloc (sizeof (*ret));
9127 ret->fname = s->info->fname;
9133 llassertprint (s->info == NULL, ("s = %s", sRef_unparse (s)));
9141 static /*@null@*/ sinfo sinfo_fullCopy (/*@notnull@*/ sRef s)
9146 ** Since its a full copy, only storage is assigned
9147 ** to dependent fields.
9154 ret = (sinfo) dmalloc (sizeof (*ret));
9155 ret->cvar = (cref) dmalloc (sizeof (*ret->cvar));
9156 ret->cvar->lexlevel = s->info->cvar->lexlevel;
9157 ret->cvar->index = s->info->cvar->index;
9161 ret = (sinfo) dmalloc (sizeof (*ret));
9162 ret->paramno = s->info->paramno;
9163 llassert (ret->paramno >= -1);
9167 ret = (sinfo) dmalloc (sizeof (*ret));
9168 ret->arrayfetch = (ainfo) dmalloc (sizeof (*ret->arrayfetch));
9169 ret->arrayfetch->indknown = s->info->arrayfetch->indknown;
9170 ret->arrayfetch->ind = s->info->arrayfetch->ind;
9171 ret->arrayfetch->arr = sRef_saveCopy (s->info->arrayfetch->arr);
9175 ret = (sinfo) dmalloc (sizeof (*ret));
9176 ret->field = (fldinfo) dmalloc (sizeof (*ret->field));
9177 ret->field->rec = sRef_saveCopy (s->info->field->rec);
9178 ret->field->field = s->info->field->field;
9182 ret = (sinfo) dmalloc (sizeof (*ret));
9183 ret->object = s->info->object;
9190 ret = (sinfo) dmalloc (sizeof (*ret));
9191 ret->ref = sRef_saveCopy (s->info->ref);
9195 ret = (sinfo) dmalloc (sizeof (*ret));
9196 ret->conj = (cjinfo) dmalloc (sizeof (*ret->conj));
9197 ret->conj->a = sRef_saveCopy (s->info->conj->a);
9198 ret->conj->b = sRef_saveCopy (s->info->conj->b);
9201 ret = (sinfo) dmalloc (sizeof (*ret));
9202 ret->spec = s->info->spec;
9205 case SK_UNCONSTRAINED:
9206 ret = (sinfo) dmalloc (sizeof (*ret));
9207 ret->fname = s->info->fname;
9213 llassert (s->info == NULL);
9223 sinfo_update (/*@notnull@*/ /*@exposed@*/ sRef res,
9224 /*@notnull@*/ /*@exposed@*/ sRef other)
9226 llassert (res->kind == other->kind);
9231 res->info->cvar->lexlevel = other->info->cvar->lexlevel;
9232 res->info->cvar->index = other->info->cvar->index;
9236 res->info->paramno = other->info->paramno;
9237 llassert (res->info->paramno >= -1);
9241 res->info->arrayfetch->indknown = other->info->arrayfetch->indknown;
9242 res->info->arrayfetch->ind = other->info->arrayfetch->ind;
9243 res->info->arrayfetch->arr = other->info->arrayfetch->arr;
9247 res->info->field->rec = other->info->field->rec;
9248 res->info->field->field = other->info->field->field;
9252 res->info->object = other->info->object;
9259 res->info->ref = other->info->ref;
9263 res->info->conj->a = other->info->conj->a;
9264 res->info->conj->b = other->info->conj->b;
9268 res->info->spec = other->info->spec;
9272 case SK_UNCONSTRAINED:
9273 res->info->fname = other->info->fname;
9280 llassert (res->info == NULL);
9285 static void sinfo_free (/*@special@*/ /*@temp@*/ /*@notnull@*/ sRef s)
9286 /*@uses s->kind, s->info@*/
9287 /*@releases s->info@*/
9292 DPRINTF (("Free sinfo: [%p]", s->info->cvar));
9293 sfree (s->info->cvar);
9300 DPRINTF (("Free sinfo: [%p]", s->info->arrayfetch));
9301 sfree (s->info->arrayfetch);
9305 DPRINTF (("Free sinfo: [%p]", s->info->field));
9306 sfree (s->info->field);
9315 case SK_EXTERNAL: /*@i32 is copy now! */
9319 DPRINTF (("Free sinfo: [%p]", s->info->conj));
9320 sfree (s->info->conj);
9323 case SK_UNCONSTRAINED:
9333 if (s->info != NULL) {
9334 DPRINTF (("Free sinfo: [%p]", s->info));
9340 bool sRef_isNSLocalVar (sRef s)
9342 if (sRef_isLocalVar (s))
9344 uentry ue = sRef_getUentry (s);
9346 return (!uentry_isStatic (ue));
9354 bool sRef_isLocalVar (sRef s)
9356 if (sRef_isValid(s))
9358 return (s->kind == SK_CVAR
9359 && (s->info->cvar->lexlevel > fileScope));
9365 bool sRef_isRealLocalVar (sRef s)
9367 if (sRef_isValid(s))
9369 if (s->kind == SK_CVAR)
9371 if (s->info->cvar->lexlevel == functionScope)
9373 uentry ue = sRef_getUentry (s);
9375 if (uentry_isAnyParam (ue)
9376 || uentry_isRefParam (ue))
9387 return (s->info->cvar->lexlevel > functionScope);
9395 bool sRef_isLocalParamVar (sRef s)
9397 if (sRef_isValid(s))
9399 return (s->kind == SK_PARAM
9400 || (s->kind == SK_CVAR
9401 && (s->info->cvar->lexlevel > fileScope)));
9407 static speckind speckind_fromInt (int i)
9410 llassert (i >= SR_NOTHING && i <= SR_SYSTEM);
9413 return ((speckind) i);
9417 static void sRef_updateNullState (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other)
9420 res->nullstate = other->nullstate;
9421 res->nullinfo = stateInfo_update (res->nullinfo, other->nullinfo);
9422 sRef_resetAliasKind (res);
9425 void sRef_combineNullState (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other)
9427 nstate n1 = sRef_getNullState (res);
9428 nstate n2 = sRef_getNullState (other);
9432 if (n1 == n2 || n2 == NS_UNKNOWN)
9438 /* note: n2 is not unknown or defnull */
9442 case NS_ERROR: nn = NS_ERROR; break;
9443 case NS_UNKNOWN: flip = TRUE; nn = n2; break;
9444 case NS_POSNULL: break;
9445 case NS_DEFNULL: nn = NS_POSNULL; break;
9446 case NS_RELNULL: break;
9448 if (n2 == NS_MNOTNULL)
9459 if (n2 == NS_NOTNULL)
9478 res->nullinfo = stateInfo_update (res->nullinfo, other->nullinfo);
9481 res->nullstate = nn;
9482 sRef_resetAliasKind (res);
9485 cstring sRef_nullMessage (sRef s)
9487 llassert (sRef_isValid (s));
9489 switch (sRef_getNullState (s))
9493 return (cstring_makeLiteralTemp ("null"));
9495 return (cstring_makeLiteralTemp ("possibly null"));
9500 /*@observer@*/ cstring sRef_ntMessage (sRef s)
9502 llassert (sRef_isValid (s));
9504 switch (s->nullstate)
9508 return (cstring_makeLiteralTemp ("not nullterminated"));
9510 return (cstring_makeLiteralTemp ("possibly non-nullterminated"));
9517 sRef sRef_fixResultType (/*@returned@*/ sRef s, ctype typ, uentry ue)
9519 sRef tmp = sRef_undefined;
9522 llassert (sRef_isValid (s));
9533 tmp = sRef_fixResultType (s->info->arrayfetch->arr, typ, ue);
9535 ct = ctype_realType (sRef_getType (tmp));
9538 if (ctype_isKnown (ct))
9540 if (ctype_isAP (ct))
9549 ("Special clause indexes non-array (%t): *%q",
9550 ct, sRef_unparse (s->info->arrayfetch->arr)),
9551 uentry_whereLast (ue));
9555 tmp = sRef_fixResultType (s->info->arrayfetch->arr, typ, ue);
9557 if (s->info->arrayfetch->indknown)
9559 ret = sRef_makeArrayFetchKnown (tmp, s->info->arrayfetch->ind);
9563 ret = sRef_makeArrayFetch (tmp);
9569 sRef rec = sRef_fixResultType (s->info->field->rec, typ, ue);
9570 ctype ct = ctype_realType (sRef_getType (rec));
9572 if (ctype_isKnown (ct))
9574 if (ctype_isSU (ct))
9576 if (uentry_isValid (uentryList_lookupField (ctype_getFields (ct),
9577 s->info->field->field)))
9586 ("Special clause accesses non-existent field of result: %q.%s",
9587 sRef_unparse (rec), s->info->field->field),
9588 uentry_whereLast (ue));
9596 ("Special clause accesses field of non-struct or union result (%t): %q.%s",
9597 ct, sRef_unparse (rec), s->info->field->field),
9598 uentry_whereLast (ue));
9602 ret = sRef_makeField (tmp, s->info->field->field);
9608 tmp = sRef_fixResultType (s->info->ref, typ, ue);
9610 ct = ctype_realType (sRef_getType (tmp));
9612 if (ctype_isKnown (ct))
9614 if (ctype_isAP (ct))
9623 ("Special clause dereferences non-pointer (%t): *%q",
9624 ct, sRef_unparse (s->info->ref)),
9625 uentry_whereLast (ue));
9629 ret = sRef_makePointer (tmp);
9636 ("Special clause uses & operator (not allowed): &%q", sRef_unparse (s->info->ref)),
9637 uentry_whereLast (ue));
9646 bool sRef_isOnly (sRef s)
9648 return (sRef_isValid(s) && alkind_isOnly (s->aliaskind));
9651 bool sRef_isDependent (sRef s)
9653 return (sRef_isValid(s) && alkind_isDependent (s->aliaskind));
9656 bool sRef_isOwned (sRef s)
9658 return (sRef_isValid (s) && (s->aliaskind == AK_OWNED));
9661 bool sRef_isKeep (sRef s)
9663 return (sRef_isValid (s) && (s->aliaskind == AK_KEEP));
9666 bool sRef_isTemp (sRef s)
9668 return (sRef_isValid (s) && alkind_isTemp (s->aliaskind));
9671 bool sRef_isLocalState (sRef s)
9673 return (sRef_isValid (s) && (s->aliaskind == AK_LOCAL));
9676 bool sRef_isUnique (sRef s)
9678 return (sRef_isValid (s) && (s->aliaskind == AK_UNIQUE));
9681 bool sRef_isShared (sRef s)
9683 return (sRef_isValid (s) && (s->aliaskind == AK_SHARED));
9686 bool sRef_isExposed (sRef s)
9688 return (sRef_isValid (s) && (s->expkind == XO_EXPOSED));
9691 bool sRef_isObserver (sRef s)
9693 return (sRef_isValid (s) && (s->expkind == XO_OBSERVER));
9696 bool sRef_isFresh (sRef s)
9698 return (sRef_isValid (s) && (s->aliaskind == AK_FRESH));
9701 bool sRef_isDefinitelyNull (sRef s)
9703 return (sRef_isValid (s) && (sRef_getNullState (s) == NS_DEFNULL
9704 || sRef_getNullState (s) == NS_CONSTNULL));
9707 bool sRef_isAllocated (sRef s)
9709 return (sRef_isValid (s) && (s->defstate == SS_ALLOCATED));
9712 bool sRef_isStack (sRef s)
9714 return (sRef_isValid (s) && (s->aliaskind == AK_STACK));
9717 bool sRef_isNotNull (sRef s)
9719 return (sRef_isValid(s) && (sRef_getNullState (s) == NS_MNOTNULL
9720 || sRef_getNullState (s) == NS_NOTNULL));
9723 alkind sRef_getAliasKind (sRef s)
9725 if (sRef_isValid(s)) {
9726 llassert (alkind_isValid (s->aliaskind));
9727 return s->aliaskind;
9733 nstate sRef_getNullState (sRef s)
9735 if (sRef_isValid (s)) {
9736 llassert (nstate_isValid (s->nullstate));
9737 return s->nullstate;
9743 void sRef_reflectAnnotation (sRef s, annotationInfo a, fileloc loc)
9745 if (sRef_isValid (s))
9747 if (!valueTable_isDefined (s->state))
9749 s->state = valueTable_create (1);
9750 valueTable_insert (s->state,
9751 cstring_copy (metaStateInfo_getName (annotationInfo_getState (a))),
9752 stateValue_create (annotationInfo_getValue (a), stateInfo_makeLoc (loc)));
9756 DPRINTF (("reflect loc: %s", fileloc_unparse (loc)));
9759 metaStateInfo_getName (annotationInfo_getState (a)),
9760 stateValue_create (annotationInfo_getValue (a), stateInfo_makeLoc (loc)));
9761 DPRINTF (("state info: %s", stateInfo_unparse (stateInfo_makeLoc (loc))));
9762 DPRINTF (("sref: %s", sRef_unparse (s)));
9763 DPRINTF (("sref: %s", sRef_unparseFull (s)));
9768 void sRef_setMetaStateValueComplete (sRef s, cstring key, int value, fileloc loc)
9770 sRefSet aliases = usymtab_allAliases (s);
9772 sRef_setMetaStateValue (s, key, value, loc);
9774 sRefSet_realElements (aliases, current)
9776 if (sRef_isValid (current))
9778 current = sRef_updateSref (current);
9779 sRef_setMetaStateValue (current, key, value, loc);
9781 } end_sRefSet_realElements ;
9783 sRefSet_free (aliases);
9786 void sRef_setMetaStateValue (sRef s, cstring key, int value, fileloc loc)
9788 sRef_checkMutable (s);
9790 if (sRef_isValid (s))
9792 if (!valueTable_isDefined (s->state))
9794 DPRINTF (("inserting state: %s: %s %d", sRef_unparse (s), key, value));
9795 s->state = valueTable_create (1);
9796 valueTable_insert (s->state, cstring_copy (key),
9797 stateValue_create (value, stateInfo_makeLoc (loc)));
9801 DPRINTF (("Updating state: %s: %s %d / %s", sRef_unparse (s), key, value,
9802 fileloc_unparse (loc)));
9803 if (valueTable_contains (s->state, key))
9806 (s->state, key, stateValue_create (value, stateInfo_makeLoc (loc)));
9811 (s->state, cstring_copy (key), stateValue_create (value, stateInfo_makeLoc (loc)));
9814 DPRINTF (("After: %s", sRef_unparseFull (s)));
9819 bool sRef_checkMetaStateValue (sRef s, cstring key, int value)
9821 if (sRef_isValid (s))
9823 if (valueTable_isDefined (s->state))
9827 DPRINTF (("check state: %s: %s %d", sRef_unparse (s), key, value));
9829 val = valueTable_lookup (s->state, key);
9830 llassert (stateValue_isDefined (val));
9831 return (stateValue_isError (val)
9832 || stateValue_getValue (val) == value);
9845 /*@observer@*/ stateValue sRef_getMetaStateValue (sRef s, cstring key)
9847 if (sRef_isValid (s))
9849 if (valueTable_isDefined (s->state))
9853 val = valueTable_lookup (s->state, key);
9854 /* Okay if its not defined, just returns stateValue_undefined */
9859 return stateValue_undefined;
9864 return stateValue_undefined;
9868 /*@observer@*/ valueTable sRef_getValueTable (sRef s)
9870 DPRINTF (("Get value table: %s", sRef_unparse (s)));
9872 if (sRef_isValid (s))
9874 llassert (sRef_isValid (s));
9875 DPRINTF (("Value table: %s", valueTable_unparse (s->state)));
9880 DPRINTF (("No value table!"));
9881 return valueTable_undefined;
9885 bool sRef_makeStateSpecial (sRef s)
9888 ** Default defined state can be made special.
9891 llassert (sRef_isValid (s)); /*@i523 why doesn't null-checking work!??? */
9893 if (s->defstate == SS_UNKNOWN || s->defstate == SS_DEFINED || s->defstate == SS_SPECIAL)
9895 /* s->aliaskind = AK_IMPTEMP; */ /* evans 2001-07-23 shouldn't effect alias state */
9896 s->defstate = SS_SPECIAL;
9897 DPRINTF (("Made special: %s", sRef_unparseFull (s)));
9902 /* s->aliaskind = AK_IMPTEMP; */
9903 s->defstate = SS_SPECIAL;
9908 void sRef_markImmutable (sRef s)
9910 if (sRef_isValid (s))
9912 DPRINTF (("Mark immutable: %s", sRef_unparseFull (s)));
9917 bool sRef_definitelyNullContext (sRef s)
9919 return (sRef_definitelyNull (s)
9920 || usymtab_isDefinitelyNullDeep (s));
9923 bool sRef_definitelyNullAltContext (sRef s)
9925 return (sRef_definitelyNull (s)
9926 || usymtab_isAltDefinitelyNullDeep (s));
9930 /* start modifications */
9931 struct s_bbufinfo sRef_getNullTerminatedState (sRef p_s) {
9932 struct s_bbufinfo BUFSTATE_UNKNOWN;
9933 BUFSTATE_UNKNOWN.bufstate = BB_NOTNULLTERMINATED;
9934 BUFSTATE_UNKNOWN.size = 0;
9935 BUFSTATE_UNKNOWN.len = 0;
9937 if (sRef_isValid(p_s))
9938 return p_s->bufinfo;
9939 return BUFSTATE_UNKNOWN;
9942 void sRef_setNullTerminatedState(sRef p_s) {
9943 if(sRef_isValid (p_s)) {
9944 p_s->bufinfo.bufstate = BB_NULLTERMINATED;
9946 llfatalbug( message("sRef_setNT passed a invalid sRef\n"));
9951 void sRef_setPossiblyNullTerminatedState(sRef p_s) {
9952 if( sRef_isValid (p_s)) {
9953 p_s->bufinfo.bufstate = BB_POSSIBLYNULLTERMINATED;
9955 llfatalbug( message("sRef_setPossNT passed a invalid sRef\n"));
9959 void sRef_setNotNullTerminatedState(sRef p_s) {
9960 if( sRef_isValid (p_s)) {
9961 p_s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
9963 llfatalbug( message("sRef_unsetNT passed a invalid sRef\n"));
9967 void sRef_setLen(sRef p_s, int len) {
9968 if( sRef_isValid (p_s) && sRef_isNullTerminated(p_s)) {
9969 p_s->bufinfo.len = len;
9971 llfatalbug( message("sRef_setLen passed a invalid sRef\n"));
9976 void sRef_setSize(sRef p_s, int size) {
9977 if( sRef_isValid(p_s)) {
9978 p_s->bufinfo.size = size;
9980 llfatalbug( message("sRef_setSize passed a invalid sRef\n"));
9984 void sRef_resetLen(sRef p_s) {
9985 if (sRef_isValid (p_s)) {
9986 p_s->bufinfo.len = 0;
9988 llfatalbug (message ("sRef_setLen passed an invalid sRef\n"));
9992 /*drl7x 11/28/2000 */
9994 bool sRef_isFixedArray (sRef p_s) /*@*/ {
9996 c = sRef_getType (p_s);
9997 return ( ctype_isFixedArray (c) );
10000 long int sRef_getArraySize (sRef p_s) /*@*/ {
10002 llassert (sRef_isFixedArray(p_s) );
10003 DPRINTF (( message ("sRef_getArraySize getting array size for %s", sRef_unparse(p_s) ) ));
10005 c = sRef_getType (p_s);
10007 return (ctype_getArraySize (c) );
10010 void sRef_setValue (sRef s, multiVal val)
10012 llassert (sRef_isValid (s));
10013 multiVal_free (s->val);
10017 bool sRef_hasValue (sRef s)
10019 return (sRef_isValid (s)
10020 && multiVal_isDefined (s->val));
10023 multiVal sRef_getValue (sRef s)
10025 if (sRef_isValid (s))
10030 return multiVal_undefined;