2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 University of Virginia,
4 ** Massachusetts Institute of Technology
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
28 ** storeRef's are kept in allRefs for each function scope, and all are
29 ** free'd at the end of the function. This relies on the constraint that
30 ** no storeRef created while checking a function is used outside that
33 ** storeRefs in the file and global scopes are free'd by the uentry.
37 # include "splintMacros.nf"
39 # include "sRefTable.h"
40 # include "structNames.h"
43 ** Predicate functions that evaluate both arguments in order.
47 # define OR(a,b) (a ? (b, TRUE) : b)
50 # define AND(a,b) (a ? b : (b, FALSE))
52 static bool sRef_isDerived (sRef p_s
) /*@*/ ;
54 static /*@exposed@*/ sRef
sRef_fixDirectBase (sRef p_s
, sRef p_base
)
55 /*@modifies p_base@*/ ;
57 static void sRef_updateNullState (sRef p_res
, sRef p_other
) /*@modifies p_res@*/ ;
59 static bool sRef_isAllocatedStorage (sRef p_s
) /*@*/ ;
60 static void sRef_setNullErrorLoc (sRef p_s
, fileloc
) /*@*/ ;
61 static void sRef_setNullStateN (sRef p_s
, nstate p_n
) /*@modifies p_s@*/ ;
63 static int sRef_depth (sRef p_s
) /*@*/ ;
66 sRef_innerAliasSetComplete (void (p_predf
) (sRef
, fileloc
), sRef p_s
,
71 sRef_innerAliasSetCompleteParam (void (p_predf
) (sRef
, sRef
), sRef p_s
, sRef p_t
)
74 static speckind
speckind_fromInt (int p_i
);
75 static bool sRef_equivalent (sRef p_s1
, sRef p_s2
);
76 static bool sRef_isDeepUnionField (sRef p_s
);
77 static void sRef_addDeriv (/*@notnull@*/ sRef p_s
, /*@notnull@*/ /*@exposed@*/ sRef p_t
);
78 static bool sRef_checkModify (sRef p_s
, sRefSet p_sl
) /*@*/ ;
81 ** If s is definitely null, it has no memory state.
84 static void sRef_resetAliasKind (/*@notnull@*/ sRef s
) /*@modifies s->aliaskind@*/
86 if (s
->nullstate
== NS_DEFNULL
)
88 /* s->aliaskind = AK_ERROR; */
93 extern void sRef_checkCompletelyReasonable (sRef s
) /*@*/
95 DPRINTF (("Check sRef: [%p] %s / %s", s
, sRef_unparse (s
),
96 sRefSet_unparse (sRef_derivedFields (s
))));
98 if (sRef_isReasonable (s
))
100 sRefSet_elements (s
->deriv
, el
)
103 sRef_checkCompletelyReasonable (el
);
104 } end_sRefSet_elements
;
109 static /*@falsewhennull@*/ bool sRef_isReasonable (sRef s
) /*@*/
111 if (sRef_isValid (s
))
114 if (!bool_isReasonable (s
->safe
)
115 || !bool_isReasonable (s
->modified
)
116 || !bool_isReasonable (s
->immut
))
118 llcontbug (message ("Unreasonable sRef [%p]", s
));
122 if (!sstate_isValid (s
->defstate
))
124 llcontbug (message ("Unreasonable sRef [%p]", s
));
128 if (!nstate_isValid (s
->nullstate
))
130 llcontbug (message ("Unreasonable sRef [%p]", s
));
134 if (!alkind_isValid (s
->aliaskind
)
135 || !alkind_isValid (s
->oaliaskind
))
137 llcontbug (message ("Unreasonable sRef [%p]", s
));
141 if (!exkind_isValid (s
->expkind
)
142 || !exkind_isValid (s
->oexpkind
))
144 llcontbug (message ("Unreasonable sRef [%p]", s
));
155 static /*@nullwhentrue@*/ bool sRef_isUnreasonable (sRef s
) /*@*/
157 return (!sRef_isReasonable (s
));
160 static void sRef_checkMutable (/*@unused@*/ sRef s
)
162 if (sRef_isReasonable (s
) && s
->immut
)
164 llcontbug (message ("Modification to sRef marked immutable: %q",
165 sRef_unparseFull (s
)));
169 static bool skind_isSimple (skind sk
)
173 case SK_PARAM
: case SK_CVAR
: case SK_CONST
:
174 case SK_OBJECT
: case SK_UNKNOWN
: case SK_NEW
:
181 static void sinfo_free (/*@special@*/ /*@temp@*/ /*@notnull@*/ sRef p_s
)
182 /*@uses p_s->kind, p_s->info@*/
183 /*@releases p_s->info@*/ ;
185 static /*@null@*/ sinfo
sinfo_copy (/*@notnull@*/ sRef p_s
) /*@*/ ;
186 static void sRef_setPartsFromUentry (sRef p_s
, uentry p_ue
)
188 static bool checkDeadState (/*@notnull@*/ sRef p_el
, /*@null@*/ sRef p_e2
,
189 bool p_tbranch
, fileloc p_loc
);
190 static /*@dependent@*/ sRef
sRef_constructPointerAux (/*@notnull@*/ /*@exposed@*/ sRef p_t
) /*@*/ ;
193 sRef_combineExKinds (/*@notnull@*/ sRef p_res
, /*@notnull@*/ sRef p_other
)
194 /*@modifies p_res@*/ ;
197 sRef_combineAliasKinds (/*@notnull@*/ sRef p_res
, /*@notnull@*/ sRef p_other
,
198 clause p_cl
, fileloc p_loc
)
199 /*@modifies p_res@*/ ;
202 sRef_combineNullState (/*@notnull@*/ sRef p_res
, /*@notnull@*/ sRef p_other
)
203 /*@modifies p_res@*/ ;
206 sRef_combineDefState (/*@notnull@*/ sRef p_res
, /*@notnull@*/ sRef p_other
)
207 /*@modifies p_res@*/ ;
209 static void sRef_setStateFromAbstractUentry (sRef p_s
, uentry p_ue
)
213 sinfo_update (/*@notnull@*/ /*@exposed@*/ sRef p_res
,
214 /*@notnull@*/ /*@exposed@*/ sRef p_other
);
215 static void sRef_setDefinedAux (sRef p_s
, fileloc p_loc
, bool p_clear
)
217 static void sRef_setDefinedNoClear (sRef p_s
, fileloc p_loc
)
219 static void sRef_setStateAux (sRef p_s
, sstate p_ss
, fileloc p_loc
)
222 static /*@exposed@*/ sRef
223 sRef_buildNCField (/*@exposed@*/ sRef p_rec
, /*@exposed@*/ cstring p_f
);
226 sRef_mergeStateAux (/*@notnull@*/ sRef p_res
, /*@notnull@*/ sRef p_other
,
227 clause p_cl
, bool p_opt
, fileloc p_loc
,
229 /*@modifies p_res, p_other@*/ ;
231 static /*@null@*/ sinfo
sinfo_fullCopy (/*@notnull@*/ sRef p_s
);
232 static bool sRef_doModify (sRef p_s
, sRefSet p_sl
) /*@modifies p_s@*/ ;
233 static bool sRef_doModifyVal (sRef p_s
, sRefSet p_sl
) /*@modifies p_s@*/;
234 static bool sRef_checkModifyVal (sRef p_s
, sRefSet p_sl
) /*@*/ ;
236 static /*@only@*/ sRefSet
237 sRef_mergeDerivs (/*@only@*/ sRefSet p_res
, sRefSet p_other
,
238 bool p_opt
, clause p_cl
, fileloc p_loc
);
240 static /*@only@*/ sRefSet
241 sRef_mergeUnionDerivs (/*@only@*/ sRefSet p_res
,
242 /*@exposed@*/ sRefSet p_other
,
243 bool p_opt
, clause p_cl
, fileloc p_loc
);
245 static /*@only@*/ sRefSet
246 sRef_mergePdefinedDerivs (/*@only@*/ sRefSet p_res
, sRefSet p_other
, bool p_opt
,
247 clause p_cl
, fileloc p_loc
);
249 static /*@only@*/ cstring
sRef_unparseWithArgs (sRef p_s
, uentryList p_args
);
250 static /*@only@*/ cstring
sRef_unparseNoArgs (sRef p_s
);
252 static /*@exposed@*/ sRef
sRef_findDerivedPointer (sRef p_s
);
253 static /*@exposed@*/ sRef
sRef_findDerivedArrayFetch (/*@notnull@*/ sRef
, bool, int, bool) ;
254 static /*@exposed@*/ sRef
sRef_findDerivedField (/*@notnull@*/ sRef p_rec
, cstring p_f
);
255 static /*@exposed@*/ sRef
256 sRef_getDeriv (/*@notnull@*/ /*@returned@*/ sRef p_set
, sRef p_guide
);
258 static bool inFunction
= FALSE
;
259 static /*@only@*/ sRefTable allRefs
;
261 /* # define DEBUGREFS */
265 static totnsrefs
= 0;
266 static maxnsrefs
= 0;
267 static ntotrefers
= 0;
271 static /*@checked@*/ bool protectDerivs
= FALSE
;
274 ** Result of sRef_alloc is dependent since allRefs may
275 ** reference it. It is only if !inFunction.
278 static /*@dependent@*/ /*@out@*/ /*@notnull@*/ sRef
281 sRef s
= (sRef
) dmalloc (sizeof (*s
));
285 DPRINTF (("Alloc sref: [%p]", s
));
289 allRefs
= sRefTable_add (allRefs
, s
);
294 DPRINTF (("Not in function!"));
300 if (nsrefs
>= maxnsrefs
)
309 /*@-mustfree@*/ /*@-freshtrans@*/
311 /*@=mustfree@*/ /*@=freshtrans@*/
315 static void sRef_checkValidAux (sRef s
, sRefSet checkedsofar
)
319 if (!sRef_isReasonable (s
)) return;
321 if (sRefSet_containsSameObject (checkedsofar
, s
))
327 checkedsofar
= sRefSet_insert (checkedsofar
, s
);
328 /*@=temptrans@*/ /* checksofar will be destroyed before checkValid returns */
332 case SK_UNCONSTRAINED
:
333 llassert (cstring_length (s
->info
->fname
) < 100);
337 llassert (s
->info
->cvar
->lexlevel
>= 0);
339 llassert (s
->info
->cvar
->lexlevel
<= usymtab_getCurrentDepth ());
344 llassert (s
->info
->paramno
>= -1);
345 llassert (s
->info
->paramno
<= 999); /* sanity check */
349 sRef_checkValidAux (s
->info
->arrayfetch
->arr
, checkedsofar
);
353 sRef_checkValidAux (s
->info
->field
->rec
, checkedsofar
);
354 llassert (cstring_length (s
->info
->field
->field
) < 100);
358 sRef_checkValidAux (s
->info
->ref
, checkedsofar
);
362 sRef_checkValidAux (s
->info
->ref
, checkedsofar
);
366 /* check ctype s->info->object */
370 sRef_checkValidAux (s
->info
->conj
->a
, checkedsofar
);
371 sRef_checkValidAux (s
->info
->conj
->b
, checkedsofar
);
375 llassert (cstring_length (s
->info
->fname
) < 100);
379 sRef_checkValidAux (s
->info
->ref
, checkedsofar
);
383 sRef_checkValidAux (s
->info
->ref
, checkedsofar
);
389 /* check ctyp s->type */
393 llassert (s
->info
->spec
== SR_NOTHING
394 || s
->info
->spec
== SR_INTERNAL
395 || s
->info
->spec
== SR_SPECSTATE
396 || s
->info
->spec
== SR_SYSTEM
);
406 sRefSet_elements (s
->deriv
, el
)
408 sRef_checkValidAux (el
, checkedsofar
);
409 } end_sRefSet_elements
;
414 static /*@maynotreturn@*/ void sRef_checkValid (/*@temp@*/ sRef s
) /*@modifies stderr@*/
416 sRefSet checkedsofar
= sRefSet_new ();
417 sRef_checkValidAux (s
, checkedsofar
);
421 static /*@dependent@*/ /*@notnull@*/ /*@special@*/ sRef
424 /*@ensures isnull result->aliasinfo, result->definfo,
425 result->expinfo, result->info, result->deriv, result->state@*/
427 sRef s
= sRef_alloc ();
429 s
->kind
= SK_UNKNOWN
;
433 s
->val
= multiVal_undefined
;
435 s
->type
= ctype_unknown
;
436 s
->defstate
= SS_UNKNOWN
;
438 /* start modifications */
439 s
->bufinfo
.bufstate
= BB_NOTNULLTERMINATED
;
440 s
->bufinfo
.size
= -1;
442 /* end modifications */
444 s
->aliaskind
= AK_UNKNOWN
;
445 s
->oaliaskind
= AK_UNKNOWN
;
447 s
->nullstate
= NS_UNKNOWN
;
449 s
->expkind
= XO_UNKNOWN
;
450 s
->oexpkind
= XO_UNKNOWN
;
452 s
->aliasinfo
= stateInfo_undefined
;
453 s
->definfo
= stateInfo_undefined
;
454 s
->nullinfo
= stateInfo_undefined
;
455 s
->expinfo
= stateInfo_undefined
;
458 s
->deriv
= sRefSet_undefined
;
460 s
->state
= valueTable_undefined
;
465 static /*@dependent@*/ /*@notnull@*/ /*@special@*/ sRef
468 /*@ensures isnull result->aliasinfo, result->definfo,
469 result->expinfo, result->info, result->deriv@*/
471 sRef res
= sRef_new ();
473 res
->state
= valueTable_undefined
;
478 void sRef_protectDerivs (void) /*@modifies protectDerivs@*/
480 llassert (!protectDerivs
);
481 protectDerivs
= TRUE
;
484 void sRef_clearProtectDerivs (void) /*@modifies protectDerivs@*/
486 llassert (protectDerivs
);
487 protectDerivs
= FALSE
;
491 ** hmmm...here be kind of a hack. This function mysteriously appeared
492 ** in my code, but I'm sure I didn't write it.
496 sRef_isRecursiveField (sRef s
)
498 if (sRef_isField (s
))
500 if (sRef_depth (s
) > 13)
505 fieldname
= sRef_getField (s
);
506 base
= sRef_getBase (s
);
508 while (sRef_isReasonable (base
))
510 if (sRef_isField (base
))
512 if (cstring_equal (fieldname
, sRef_getField (base
)))
518 base
= sRef_getBaseSafe (base
);
527 sRef_addDeriv (/*@notnull@*/ sRef s
, /*@notnull@*/ /*@exposed@*/ sRef t
)
529 if (!context_inProtectVars ()
531 && sRef_isReasonable (s
)
532 && sRef_isReasonable (t
)
533 && !sRef_isConst (s
))
535 int sd
= sRef_depth (s
);
536 int td
= sRef_depth (t
);
543 /* This sometimes fails: (evans 2001-07-12)
544 if (sRef_isArrayFetch (t))
546 DPRINTF (("Derived fetch: %s / %s / %s",
547 sRef_unparseFull (s), sRef_unparseFull (t),
548 sRef_unparseFull (t->info->arrayfetch->arr)));
549 llassert (t->info->arrayfetch->arr == s);
553 if (sRef_isFileOrGlobalScope (s
))
555 if (context_inFunctionLike ()
556 && ctype_isKnown (sRef_getType (s
))
557 && !ctype_isFunction (sRef_getType (s
)))
559 globSet g
= context_getUsedGlobs ();
561 if (!globSet_member (g
, s
))
564 ** don't report as a bug
568 (message ("sRef_addDeriv: global variable not in used "
569 "globs: %q / %s / %q",
571 ctype_unparse (sRef_getType (s)),
572 sRefSet_unparse (s->deriv)));
577 DPRINTF (("Add deriv: [%p] %s / [%p] %s",
579 t
, sRef_unparse (t
)));
581 s
->deriv
= sRefSet_insert (s
->deriv
, t
);
587 DPRINTF (("Add deriv: [%p] %s / [%p] %s",
589 t
, sRef_unparse (t
)));
591 s
->deriv
= sRefSet_insert (s
->deriv
, t
);
597 sRef_deepPred (bool (predf
) (sRef
), sRef s
)
599 if (sRef_isReasonable (s
))
601 if ((*predf
)(s
)) return TRUE
;
606 return (sRef_deepPred (predf
, s
->info
->ref
));
608 return (sRef_deepPred (predf
, s
->info
->arrayfetch
->arr
));
610 return (sRef_deepPred (predf
, s
->info
->field
->rec
));
612 return (sRef_deepPred (predf
, s
->info
->conj
->a
)
613 || sRef_deepPred (predf
, s
->info
->conj
->b
));
622 bool sRef_modInFunction (void)
627 void sRef_setStateFromType (sRef s
, ctype ct
)
629 if (sRef_isReasonable (s
))
631 if (ctype_isUser (ct
))
633 DPRINTF (("Here we are: %s", sRef_unparseFull (s
)));
634 sRef_setStateFromUentry
635 (s
, usymtab_getTypeEntry (ctype_typeId (ct
)));
637 else if (ctype_isAbstract (ct
))
639 DPRINTF (("Here we are: %s", sRef_unparseFull (s
)));
640 sRef_setStateFromAbstractUentry
641 (s
, usymtab_getTypeEntry (ctype_typeId (ct
)));
645 ; /* not a user type */
650 static void sRef_setTypeState (sRef s
)
652 if (sRef_isReasonable (s
))
654 sRef_setStateFromType (s
, s
->type
);
658 bool sRef_hasAliasInfoLoc (sRef s
)
660 return (sRef_isReasonable (s
) && (s
->aliasinfo
!= NULL
)
661 && (fileloc_isDefined (s
->aliasinfo
->loc
)));
664 /*@falsewhennull@*/ bool sRef_hasStateInfoLoc (sRef s
)
666 return (sRef_isReasonable (s
) && (s
->definfo
!= NULL
)
667 && (fileloc_isDefined (s
->definfo
->loc
)));
671 /*@falsewhennull@*/ bool sRef_hasExpInfoLoc (sRef s
)
673 return (sRef_isReasonable (s
)
674 && (s
->expinfo
!= NULL
) && (fileloc_isDefined (s
->expinfo
->loc
)));
676 # endif /* DEADCODE */
679 static /*@observer@*/ /*@unused@*/ stateInfo
sRef_getInfo (sRef s
, cstring key
)
683 if (!sRef_isReasonable (s
)) {
684 return stateInfo_undefined
;
687 sv
= valueTable_lookup (s
->state
, key
);
689 if (stateValue_isDefined (sv
))
691 return stateValue_getInfo (sv
);
694 return stateInfo_undefined
;
699 sRef_hasNullInfoLoc (sRef s
)
701 return (sRef_isReasonable (s
) && s
->nullinfo
!= NULL
702 && (fileloc_isDefined (s
->nullinfo
->loc
)));
706 sRef_hasAliasInfoRef (sRef s
)
708 return (sRef_isReasonable (s
) && (s
->aliasinfo
!= NULL
)
709 && (sRef_isReasonable (s
->aliasinfo
->ref
)));
712 static /*@observer@*/ fileloc
713 sRef_getAliasInfoLoc (/*@exposed@*/ sRef s
)
715 llassert (sRef_isReasonable (s
) && s
->aliasinfo
!= NULL
716 && (fileloc_isDefined (s
->aliasinfo
->loc
)));
717 return (s
->aliasinfo
->loc
);
720 static /*@observer@*/ fileloc
721 sRef_getStateInfoLoc (/*@exposed@*/ sRef s
)
723 llassert (sRef_isReasonable (s
) && s
->definfo
!= NULL
724 && (fileloc_isDefined (s
->definfo
->loc
)));
725 return (s
->definfo
->loc
);
729 static /*@observer@*/ fileloc
730 sRef_getExpInfoLoc (/*@exposed@*/ sRef s
)
732 llassert (sRef_isReasonable (s
) && s
->expinfo
!= NULL
733 && (fileloc_isDefined (s
->expinfo
->loc
)));
734 return (s
->expinfo
->loc
);
738 static /*@observer@*/ fileloc
739 sRef_getNullInfoLoc (/*@exposed@*/ sRef s
)
741 llassert (sRef_isReasonable (s
) && s
->nullinfo
!= NULL
742 && (fileloc_isDefined (s
->nullinfo
->loc
)));
743 return (s
->nullinfo
->loc
);
747 sRef_getAliasInfoRef (/*@temp@*/ sRef s
)
749 llassert (sRef_isReasonable (s
) && s
->aliasinfo
!= NULL
);
750 return (s
->aliasinfo
->ref
);
753 bool sRef_inGlobalScope (void)
759 ** This function should be called before new sRefs are created
760 ** somewhere where they will have a lifetime greater than the
761 ** current function scope.
764 void sRef_setGlobalScope (void)
766 llassert (inFunction
);
767 DPRINTF (("leave function"));
771 void sRef_clearGlobalScope (void)
773 llassert (!inFunction
);
774 DPRINTF (("enter function"));
778 static bool oldInFunction
= FALSE
;
779 static int nestedScope
= 0;
781 void sRef_setGlobalScopeSafe (void)
783 if (nestedScope
== 0)
785 oldInFunction
= inFunction
;
789 DPRINTF (("leave function safe"));
793 void sRef_clearGlobalScopeSafe (void)
796 llassert (nestedScope
>= 0);
798 if (nestedScope
== 0)
800 inFunction
= oldInFunction
;
803 DPRINTF (("clear function: %s", bool_unparse (inFunction
)));
806 void sRef_enterFunctionScope (void)
808 /* evans 2001-09-09 - cleanup if we are in a macro! */
809 if (context_inMacro ())
812 sRef_exitFunctionScope ();
816 llassert (!inFunction
);
817 llassert (sRefTable_isEmpty (allRefs
));
819 DPRINTF (("enter function"));
822 void sRef_exitFunctionScope (void)
826 DPRINTF (("Exit function scope."));
827 sRefTable_clear (allRefs
);
828 DPRINTF (("Exit function scope done."));
833 llbuglit ("sRef_exitFunctionScope: not in function");
837 void sRef_destroyMod (void) /*@globals killed allRefs;@*/
840 llmsg (message ("Live: %d / %d ", nsrefs
, totnsrefs
));
843 sRefTable_free (allRefs
);
847 static /*@notnull@*/ /*@exposed@*/ sRef
848 sRef_fixConj (/*@notnull@*/ sRef s
)
853 s
= sRef_getConjA (s
);
854 } while (sRef_isConj (s
));
856 llassert (sRef_isReasonable (s
));
857 return s
; /* don't need to ref */
866 sRef_isExternallyVisibleAux (sRef s
)
869 sRef base
= sRef_getRootBase (s
);
871 if (sRef_isReasonable (base
))
873 res
= sRef_isParam (base
) || sRef_isFileOrGlobalScope (base
) || sRef_isExternal (base
);
880 sRef_isExternallyVisible (sRef s
)
882 return (sRef_aliasCheckSimplePred (sRef_isExternallyVisibleAux
, s
));
886 sRef_getBaseUentry (sRef s
)
888 sRef base
= sRef_getRootBase (s
);
889 uentry res
= uentry_undefined
;
891 if (sRef_isReasonable (base
))
896 res
= usymtab_getRefQuiet (paramsScope
, usymId_fromInt (base
->info
->paramno
));
900 res
= usymtab_getRefQuiet (base
->info
->cvar
->lexlevel
,
901 base
->info
->cvar
->index
);
913 ** lookup the current uentry corresponding to s, and return the corresponding sRef.
914 ** yuk yuk yuk yuk yuk yuk yuk yuk
918 sRef_updateSref (sRef s
)
924 if (!sRef_isReasonable (s
)) return sRef_undefined
;
933 case SK_UNCONSTRAINED
:
940 sRef r
= sRef_updateSref (s
->info
->ref
);
942 if (r
!= s
->info
->ref
)
944 return sRef_makeExternal (r
);
954 uentry ue
= sRef_getUentry (s
);
956 /* must be raw name! (need the marker) */
957 /* Must be in the correct scope! */
959 ue
= usymtab_lookupSafeScope (uentry_rawName (ue
), sRef_lexLevel (s
));
961 if (uentry_isUndefined (ue
))
967 DPRINTF (("Update sref: %s", uentry_unparseFull (ue
)));
968 return (uentry_getSref (ue
));
972 /* special case if ind known */
973 inner
= s
->info
->arrayfetch
->arr
;
974 ret
= sRef_updateSref (inner
);
982 res
= sRef_makeArrayFetch (ret
);
988 inner
= s
->info
->field
->rec
;
989 ret
= sRef_updateSref (inner
);
997 res
= (sRef_makeField (ret
, s
->info
->field
->field
));
1002 inner
= s
->info
->ref
;
1003 ret
= sRef_updateSref (inner
);
1010 res
= sRef_makePointer (ret
);
1016 inner
= s
->info
->ref
;
1017 ret
= sRef_updateSref (inner
);
1025 res
= sRef_makeAddress (ret
);
1032 sRef innera
= s
->info
->conj
->a
;
1033 sRef innerb
= s
->info
->conj
->b
;
1034 sRef reta
= sRef_updateSref (innera
);
1035 sRef retb
= sRef_updateSref (innerb
);
1037 if (innera
== reta
&& innerb
== retb
)
1043 res
= sRef_makeConj (reta
, retb
);
1054 sRef_getUentry (sRef s
)
1056 llassert (sRef_isReasonable (s
));
1061 return (usymtab_getRefQuiet (paramsScope
, usymId_fromInt (s
->info
->paramno
)));
1063 return (usymtab_getRefQuiet (s
->info
->cvar
->lexlevel
, s
->info
->cvar
->index
));
1066 if (sRef_isCvar (s
->info
->conj
->a
) || sRef_isParam (s
->info
->conj
->a
)
1067 || sRef_isConj (s
->info
->conj
->a
))
1069 return sRef_getUentry (s
->info
->conj
->a
);
1073 return sRef_getUentry (s
->info
->conj
->b
);
1076 case SK_FIELD
: /* evans 2002-07-17: added case for SK_FIELD */
1079 return uentry_undefined
;
1085 sRef_getParam (sRef s
)
1087 llassert (sRef_isReasonable (s
));
1088 llassert (s
->kind
== SK_PARAM
);
1090 return s
->info
->paramno
;
1094 sRef_isModified (sRef s
)
1096 return (!sRef_isReasonable (s
) || s
->modified
);
1099 void sRef_setModified (sRef s
)
1101 if (sRef_isReasonable (s
))
1106 if (sRef_isRefsField (s
))
1108 sRef base
= sRef_getBase (s
);
1110 llassert (s
->kind
== SK_FIELD
);
1112 if (sRef_isPointer (base
))
1114 base
= sRef_getBase (base
);
1117 if (sRef_isRefCounted (base
))
1119 base
->aliaskind
= AK_NEWREF
;
1126 ** note: this side-effects sRefSet to set modified to TRUE
1127 ** for any sRef similar to s.
1131 sRef_canModifyVal (sRef s
, sRefSet sl
)
1133 if (context_getFlag (FLG_MUSTMOD
))
1135 return (sRef_doModifyVal (s
, sl
));
1139 return (sRef_checkModifyVal (s
, sl
));
1144 sRef_canModify (sRef s
, sRefSet sl
)
1146 if (context_getFlag (FLG_MUSTMOD
))
1148 return (sRef_doModify (s
, sl
));
1152 return (sRef_checkModify (s
, sl
));
1161 bool sRef_checkModifyVal (sRef s
, sRefSet sl
)
1163 DPRINTF (("Check modify val: %s", sRef_unparse (s
)));
1165 if (sRef_isInvalid (s
))
1172 case SK_UNCONSTRAINED
:
1176 DPRINTF (("Modify var: %s", sRef_unparse (s
)));
1178 if (sRef_isFileOrGlobalScope (s
))
1180 if (context_checkGlobMod (s
))
1182 return (sRefSet_member (sl
, s
));
1192 return (sRefSet_member (sl
, s
)
1193 || alkind_isOnly (sRef_getOrigAliasKind (s
)));
1195 /* special case if ind known */
1196 return (sRefSet_member (sl
, s
) ||
1197 sRef_checkModifyVal (s
->info
->arrayfetch
->arr
, sl
));
1199 return (sRefSet_member (sl
, s
) || sRef_checkModifyVal (s
->info
->field
->rec
, sl
));
1201 return (sRefSet_member (sl
, s
) || sRef_checkModifyVal (s
->info
->ref
, sl
));
1203 return (sRefSet_member (sl
, s
) || sRef_checkModifyVal (s
->info
->ref
, sl
));
1205 return ((sRef_checkModifyVal (s
->info
->conj
->a
, sl
)) &&
1206 (sRef_checkModifyVal (s
->info
->conj
->b
, sl
)));
1217 switch (s
->info
->spec
)
1219 case SR_NOTHING
: return TRUE
;
1221 if (context_getFlag (FLG_INTERNALGLOBS
))
1223 return (sRefSet_member (sl
, s
));
1229 case SR_SPECSTATE
: return TRUE
;
1230 case SR_SYSTEM
: return (sRefSet_member (sl
, s
));
1231 case SR_GLOBALMARKER
: BADBRANCH
;
1234 case SK_RESULT
: BADBRANCH
;
1240 ** this should probably be elsewhere...
1242 ** returns TRUE iff sl indicates that s can be modified
1245 static bool sRef_checkModify (sRef s
, sRefSet sl
)
1247 llassert (sRef_isReasonable (s
));
1251 case SK_UNCONSTRAINED
:
1255 if (sRef_isFileOrGlobalScope (s
))
1257 if (context_checkGlobMod (s
))
1259 return (sRefSet_member (sl
, s
));
1271 return (sRefSet_member (sl
, s
) ||
1272 sRef_checkModifyVal (s
->info
->arrayfetch
->arr
, sl
));
1275 sRef sr
= s
->info
->field
->rec
;
1277 if (sr
->kind
== SK_PARAM
)
1278 return TRUE
; /* structs are copied on call */
1280 return (sRefSet_member (sl
, s
) || sRef_checkModifyVal (s
->info
->field
->rec
, sl
));
1286 sm
= sRefSet_member (sl
, s
);
1291 return (sRef_checkModifyVal (s
->info
->ref
, sl
));
1294 return (sRefSet_member (sl
, s
) || sRef_checkModifyVal (s
->info
->ref
, sl
));
1296 return ((sRef_checkModify (s
->info
->conj
->a
, sl
)) &&
1297 (sRef_checkModify (s
->info
->conj
->b
, sl
)));
1307 switch (s
->info
->spec
)
1309 case SR_NOTHING
: return TRUE
;
1311 if (context_getFlag (FLG_INTERNALGLOBS
))
1313 return (sRefSet_member (sl
, s
));
1319 case SR_SPECSTATE
: return TRUE
;
1320 case SR_SYSTEM
: return (sRefSet_member (sl
, s
));
1321 case SR_GLOBALMARKER
: BADBRANCH
;
1324 case SK_RESULT
: BADBRANCH
;
1329 cstring
sRef_stateVerb (sRef s
)
1331 if (sRef_isDead (s
))
1333 return cstring_makeLiteralTemp ("released");
1335 else if (sRef_isKept (s
))
1337 return cstring_makeLiteralTemp ("kept");
1339 else if (sRef_isDependent (s
))
1341 return cstring_makeLiteralTemp ("dependent");
1349 cstring
sRef_stateAltVerb (sRef s
)
1351 if (sRef_isDead (s
))
1353 return cstring_makeLiteralTemp ("live");
1355 else if (sRef_isKept (s
))
1357 return cstring_makeLiteralTemp ("not kept");
1359 else if (sRef_isDependent (s
))
1361 return cstring_makeLiteralTemp ("independent");
1370 bool sRef_doModifyVal (sRef s
, sRefSet sl
)
1372 llassert (sRef_isReasonable (s
));
1377 case SK_UNCONSTRAINED
:
1381 if (sRef_isFileOrGlobalScope (s
))
1384 if (context_checkGlobMod (s
))
1386 return (sRefSet_modifyMember (sl
, s
));
1390 (void) sRefSet_modifyMember (sl
, s
);
1400 return (sRefSet_modifyMember (sl
, s
)
1401 || alkind_isOnly (sRef_getOrigAliasKind (s
)));
1403 /* special case if ind known */
1404 /* unconditional OR, need side effect */
1405 return (OR (sRefSet_modifyMember (sl
, s
),
1406 sRef_doModifyVal (s
->info
->arrayfetch
->arr
, sl
)));
1408 return (OR (sRefSet_modifyMember (sl
, s
),
1409 sRef_doModifyVal (s
->info
->field
->rec
, sl
)));
1411 return (OR (sRefSet_modifyMember (sl
, s
),
1412 sRef_doModifyVal (s
->info
->ref
, sl
)));
1414 return (OR (sRefSet_modifyMember (sl
, s
),
1415 sRef_doModifyVal (s
->info
->ref
, sl
)));
1417 return (AND (sRef_doModifyVal (s
->info
->conj
->a
, sl
) ,
1418 sRef_doModifyVal (s
->info
->conj
->b
, sl
)));
1428 switch (s
->info
->spec
)
1430 case SR_NOTHING
: return TRUE
;
1432 if (context_getFlag (FLG_INTERNALGLOBS
))
1434 return (sRefSet_modifyMember (sl
, s
));
1438 (void) sRefSet_modifyMember (sl
, s
);
1441 case SR_SPECSTATE
: return TRUE
;
1442 case SR_SYSTEM
: return (sRefSet_modifyMember (sl
, s
));
1443 case SR_GLOBALMARKER
: BADBRANCH
;
1447 case SK_RESULT
: BADBRANCH
;
1453 ** this should probably be elsewhere...
1455 ** returns TRUE iff sl indicates that s can be modified
1459 bool sRef_doModify (sRef s
, sRefSet sl
)
1461 llassert (sRef_isReasonable (s
));
1465 case SK_UNCONSTRAINED
:
1469 if (sRef_isFileOrGlobalScope (s
))
1471 if (context_checkGlobMod (s
))
1473 return (sRefSet_modifyMember (sl
, s
));
1477 (void) sRefSet_modifyMember (sl
, s
);
1489 return (OR (sRefSet_modifyMember (sl
, s
),
1490 sRef_doModifyVal (s
->info
->arrayfetch
->arr
, sl
)));
1493 sRef sr
= s
->info
->field
->rec
;
1495 if (sr
->kind
== SK_PARAM
)
1497 return TRUE
; /* structs are shallow-copied on call */
1500 return (OR (sRefSet_modifyMember (sl
, s
),
1501 sRef_doModifyVal (s
->info
->field
->rec
, sl
)));
1505 return (OR (sRefSet_modifyMember (sl
, s
),
1506 sRef_doModifyVal (s
->info
->ref
, sl
)));
1509 return (OR (sRefSet_modifyMember (sl
, s
),
1510 sRef_doModifyVal (s
->info
->ref
, sl
)));
1512 return (AND (sRef_doModify (s
->info
->conj
->a
, sl
),
1513 (sRef_doModify (s
->info
->conj
->b
, sl
))));
1524 switch (s
->info
->spec
)
1526 case SR_NOTHING
: return TRUE
;
1527 case SR_INTERNAL
: return TRUE
;
1528 case SR_SPECSTATE
: return TRUE
;
1529 case SR_SYSTEM
: return (sRefSet_modifyMember (sl
, s
));
1530 case SR_GLOBALMARKER
: BADBRANCH
;
1533 case SK_RESULT
: BADBRANCH
;
1538 static /*@exposed@*/ sRef
1539 sRef_leastCommon (/*@exposed@*/ sRef s1
, sRef s2
)
1541 llassert (sRef_similar (s1
, s2
));
1543 if (!sRef_isReasonable (s1
)) return s1
;
1544 if (!sRef_isReasonable (s2
)) return s1
;
1546 sRef_combineDefState (s1
, s2
);
1547 sRef_combineNullState (s1
, s2
);
1548 sRef_combineExKinds (s1
, s2
);
1550 if (s1
->aliaskind
!= s2
->aliaskind
)
1552 if (s1
->aliaskind
== AK_UNKNOWN
)
1554 s1
->aliaskind
= s2
->aliaskind
;
1556 else if (s2
->aliaskind
== AK_UNKNOWN
)
1562 s1
->aliaskind
= AK_ERROR
;
1569 int sRef_compare (sRef s1
, sRef s2
)
1571 if (s1
== s2
) return 0;
1573 if (sRef_isInvalid (s1
)) return -1;
1574 if (sRef_isInvalid (s2
)) return 1;
1576 INTCOMPARERETURN (s1
->kind
, s2
->kind
);
1577 INTCOMPARERETURN (s1
->defstate
, s2
->defstate
);
1578 INTCOMPARERETURN (s1
->aliaskind
, s2
->aliaskind
);
1580 DPRINTF (("Compare null state: %s / %s",
1581 sRef_unparseFull (s1
),
1582 sRef_unparseFull (s2
)));
1584 COMPARERETURN (nstate_compare (sRef_getNullState (s1
),
1585 sRef_getNullState (s2
)));
1590 return (int_compare (s1
->info
->paramno
, s2
->info
->paramno
));
1593 COMPARERETURN (sRef_compare (s1
->info
->arrayfetch
->arr
,
1594 s2
->info
->arrayfetch
->arr
));
1596 if (s1
->info
->arrayfetch
->indknown
&& s2
->info
->arrayfetch
->indknown
)
1598 return (int_compare (s1
->info
->arrayfetch
->ind
,
1599 s2
->info
->arrayfetch
->ind
));
1601 if (!s1
->info
->arrayfetch
->indknown
&& !s2
->info
->arrayfetch
->indknown
)
1608 COMPARERETURN (sRef_compare (s1
->info
->field
->rec
, s2
->info
->field
->rec
));
1610 if (cstring_equal (s1
->info
->field
->field
, s2
->info
->field
->field
))
1617 return (sRef_compare (s1
->info
->ref
, s2
->info
->ref
));
1619 COMPARERETURN (sRef_compare (s1
->info
->conj
->a
, s2
->info
->conj
->a
));
1620 return (sRef_compare (s1
->info
->conj
->b
, s2
->info
->conj
->b
));
1621 case SK_UNCONSTRAINED
:
1622 return (cstring_compare (s1
->info
->fname
, s2
->info
->fname
));
1634 return (generic_compare (s1
->info
->spec
, s2
->info
->spec
));
1639 static bool cref_equal (cref c1
, cref c2
)
1641 return ((c1
->lexlevel
== c2
->lexlevel
) &&
1642 (usymId_equal (c1
->index
, c2
->index
)));
1646 ** returns true if s1 could be the same storage as s2.
1647 ** i.e., a[?] ~ a[3]. Note its not symmetric ... s1
1648 ** should be more specific.
1652 ** like similar, but matches objects <-> non-objects
1656 sRef_uniqueReference (sRef s
)
1658 return (sRef_isFresh (s
) || sRef_isUnique (s
)
1659 || sRef_isOnly (s
) || sRef_isStack (s
)
1660 || sRef_isAddress (s
));
1664 sRef_similarRelaxedAux (sRef s1
, sRef s2
)
1668 if (sRef_isUnknownArrayFetch (s1
))
1678 if (sRef_isInvalid (s1
) || sRef_isInvalid (s2
)) return FALSE
;
1680 if (sRef_isConj (s2
))
1681 return (sRef_similarRelaxedAux (s1
, sRef_getConjA (s2
)) ||
1682 sRef_similarRelaxedAux (s1
, sRef_getConjB (s2
)));
1687 return ((s2
->kind
== SK_CVAR
)
1688 && (cref_equal (s1
->info
->cvar
, s2
->info
->cvar
)));
1690 return ((s2
->kind
== SK_PARAM
)
1691 && (s1
->info
->paramno
== s2
->info
->paramno
));
1693 if (s2
->kind
== SK_ARRAYFETCH
)
1695 if (sRef_similarRelaxedAux (s1
->info
->arrayfetch
->arr
,
1696 s2
->info
->arrayfetch
->arr
))
1698 if (s1
->info
->arrayfetch
->indknown
)
1700 if (s2
->info
->arrayfetch
->indknown
)
1702 return (s1
->info
->arrayfetch
->ind
== s2
->info
->arrayfetch
->ind
);
1717 return ((s2
->kind
== SK_FIELD
1718 && (sRef_similarRelaxedAux (s1
->info
->field
->rec
,
1719 s2
->info
->field
->rec
)
1720 && cstring_equal (s1
->info
->field
->field
,
1721 s2
->info
->field
->field
))));
1723 return ((s2
->kind
== SK_PTR
)
1724 && sRef_similarRelaxedAux (s1
->info
->ref
, s2
->info
->ref
));
1726 return ((s2
->kind
== SK_ADR
)
1727 && sRef_similarRelaxedAux (s1
->info
->ref
, s2
->info
->ref
));
1729 return ((sRef_similarRelaxedAux (s1
->info
->conj
->a
, s2
) ||
1730 (sRef_similarRelaxedAux (s1
->info
->conj
->b
, s2
))));
1732 return (s1
->info
->spec
== s2
->info
->spec
);
1733 case SK_UNCONSTRAINED
:
1734 return (cstring_equal (s1
->info
->fname
, s2
->info
->fname
));
1749 sRef_similarRelaxed (sRef s1
, sRef s2
)
1755 if (sRef_isThroughArrayFetch (s1
))
1765 if (sRef_isInvalid (s1
) || sRef_isInvalid (s2
)) return FALSE
;
1767 us1
= sRef_uniqueReference (s1
);
1768 us2
= sRef_uniqueReference (s2
);
1770 if ((s1
->kind
== SK_EXTERNAL
&& (s2
->kind
!= SK_EXTERNAL
&& !us2
))
1771 || (s2
->kind
== SK_EXTERNAL
&& (s1
->kind
!= SK_EXTERNAL
&& !us1
)))
1774 ** Previously, also:
1775 ** || (sRef_isExposed (s1) && !us2) || (sRef_isExposed (s2) && !us1)) ????
1777 ** No clue why this was there?!
1781 if (sRef_isExposed (s1
) && sRef_isCvar (s1
))
1783 uentry ue1
= sRef_getUentry (s1
);
1785 if (uentry_isRefParam (ue1
))
1787 return sRef_similarRelaxedAux (s1
, s2
);
1791 if (sRef_isExposed (s2
) && sRef_isCvar (s2
))
1793 uentry ue2
= sRef_getUentry (s2
);
1795 if (uentry_isRefParam (ue2
))
1797 return sRef_similarRelaxedAux (s1
, s2
);
1801 return (ctype_match (s1
->type
, s2
->type
));
1805 return sRef_similarRelaxedAux (s1
, s2
);
1810 sRef_similar (sRef s1
, sRef s2
)
1812 if (s1
== s2
) return TRUE
;
1813 if (sRef_isInvalid (s1
) || sRef_isInvalid (s2
)) return FALSE
;
1815 if (sRef_isConj (s2
))
1817 return (sRef_similar (s1
, sRef_getConjA (s2
)) ||
1818 sRef_similar (s1
, sRef_getConjB (s2
)));
1821 if (sRef_isDerived (s2
))
1823 return (sRef_includedBy (s1
, s2
->info
->ref
));
1829 return ((s2
->kind
== SK_CVAR
)
1830 && (cref_equal (s1
->info
->cvar
, s2
->info
->cvar
)));
1832 return ((s2
->kind
== SK_PARAM
)
1833 && (s1
->info
->paramno
== s2
->info
->paramno
));
1835 if (s2
->kind
== SK_ARRAYFETCH
)
1837 if (sRef_similar (s1
->info
->arrayfetch
->arr
,
1838 s2
->info
->arrayfetch
->arr
))
1840 if (s1
->info
->arrayfetch
->indknown
)
1842 if (s2
->info
->arrayfetch
->indknown
)
1844 return (s1
->info
->arrayfetch
->ind
== s2
->info
->arrayfetch
->ind
);
1859 if (s2
->kind
== SK_PTR
)
1861 if (sRef_similar (s1
->info
->arrayfetch
->arr
,
1871 return ((s2
->kind
== SK_FIELD
1872 && (sRef_similar (s1
->info
->field
->rec
,
1873 s2
->info
->field
->rec
)
1874 && cstring_equal (s1
->info
->field
->field
,
1875 s2
->info
->field
->field
))));
1877 if (s2
->kind
== SK_PTR
)
1879 return sRef_similar (s1
->info
->ref
, s2
->info
->ref
);
1883 if (s2
->kind
== SK_ARRAYFETCH
)
1885 if (sRef_similar (s2
->info
->arrayfetch
->arr
,
1895 return ((s2
->kind
== SK_ADR
)
1896 && sRef_similar (s1
->info
->ref
, s2
->info
->ref
));
1898 return ((sRef_similar (s1
->info
->conj
->a
, s2
) ||
1899 (sRef_similar (s1
->info
->conj
->b
, s2
))));
1901 return (sRef_includedBy (s2
, s1
->info
->ref
));
1902 case SK_UNCONSTRAINED
:
1903 return (s2
->kind
== SK_UNCONSTRAINED
1904 && cstring_equal (s1
->info
->fname
, s2
->info
->fname
));
1914 return (s2
->kind
== SK_SPECIAL
1915 && (s1
->info
->spec
== s2
->info
->spec
));
1918 /*@notreached@*/ DPRINTF (("Fell through for: %s / %s", sRef_unparse (s1
), sRef_unparse (s2
)));
1923 ** return TRUE iff small can be derived from big.
1925 ** (e.g. x, x.a is includedBy x;
1926 ** x.a is included By x.a;
1930 sRef_includedBy (sRef small
, sRef big
)
1932 if (small
== big
) return TRUE
;
1933 if (sRef_isInvalid (small
) || sRef_isInvalid (big
)) return FALSE
;
1935 if (sRef_isConj (big
))
1936 return (sRef_similar (small
, sRef_getConjA (big
)) ||
1937 sRef_similar (small
, sRef_getConjB (big
)));
1939 switch (small
->kind
)
1943 return (sRef_same (small
, big
));
1945 if (big
->kind
== SK_ARRAYFETCH
)
1947 if (sRef_same (small
->info
->arrayfetch
->arr
, big
->info
->arrayfetch
->arr
))
1949 if (small
->info
->arrayfetch
->indknown
)
1951 if (big
->info
->arrayfetch
->indknown
)
1953 return (small
->info
->arrayfetch
->ind
== big
->info
->arrayfetch
->ind
);
1966 return (sRef_includedBy (small
->info
->arrayfetch
->arr
, big
));
1968 if (big
->kind
== SK_FIELD
)
1971 (sRef_same (small
->info
->field
->rec
, big
->info
->field
->rec
) &&
1972 cstring_equal (small
->info
->field
->field
, big
->info
->field
->field
));
1976 return (sRef_includedBy (small
->info
->field
->rec
, big
));
1980 if (big
->kind
== SK_PTR
)
1982 return sRef_same (small
->info
->ref
, big
->info
->ref
);
1986 return (sRef_includedBy (small
->info
->ref
, big
));
1990 return ((big
->kind
== SK_ADR
) && sRef_similar (small
->info
->ref
, big
->info
->ref
));
1992 return ((sRef_includedBy (small
->info
->conj
->a
, big
) ||
1993 (sRef_includedBy (small
->info
->conj
->b
, big
))));
1995 return (sRef_includedBy (small
->info
->ref
, big
));
1996 case SK_UNCONSTRAINED
:
2006 switch (small
->info
->spec
)
2008 case SR_NOTHING
: return TRUE
;
2010 case SR_INTERNAL
: return (sRef_isSpecInternalState (big
) ||
2011 sRef_isFileStatic (big
));
2012 case SR_SYSTEM
: return (sRef_isSystemState (big
));
2013 case SR_GLOBALMARKER
: BADBRANCH
;
2020 ** Same is similar to similar, but not quite the same.
2021 ** same and realSame aren't the same, but they are really similar.
2022 ** similarly, same is the same as same. but realSame is
2023 ** not really the same as same, or similar to similar.
2025 ** Similarly to similar, same checks if two sRefs are the same.
2026 ** The similarities end, however, when same compares arrays
2027 ** with unknown indexes. Similar returns false; same returns true.
2029 ** Similarly to similar and same, realSame is the same as same,
2030 ** except they do not behave the same when face with unknown
2031 ** sRefs. Same thinks they are not the same, but realSame thinks
2037 sRef_realSame (sRef s1
, sRef s2
)
2039 if (s1
== s2
) return TRUE
;
2041 if (sRef_isUnreasonable (s1
)
2042 || sRef_isUnreasonable (s2
))
2050 return ((s2
->kind
== SK_CVAR
) && (cref_equal (s1
->info
->cvar
, s2
->info
->cvar
)));
2052 return ((s2
->kind
== SK_PARAM
) && (s1
->info
->paramno
== s2
->info
->paramno
));
2054 if (s2
->kind
== SK_ARRAYFETCH
)
2056 if (sRef_realSame (s1
->info
->arrayfetch
->arr
, s2
->info
->arrayfetch
->arr
))
2058 if (s1
->info
->arrayfetch
->indknown
&& s2
->info
->arrayfetch
->indknown
)
2060 return (s1
->info
->arrayfetch
->ind
== s2
->info
->arrayfetch
->ind
);
2062 if (!s1
->info
->arrayfetch
->indknown
&& !s2
->info
->arrayfetch
->indknown
)
2071 return ((s2
->kind
== SK_FIELD
&&
2072 (sRef_realSame (s1
->info
->field
->rec
, s2
->info
->field
->rec
) &&
2073 cstring_equal (s1
->info
->field
->field
, s2
->info
->field
->field
))));
2075 return ((s2
->kind
== SK_PTR
) && sRef_realSame (s1
->info
->ref
, s2
->info
->ref
));
2077 return ((s2
->kind
== SK_ADR
) && sRef_realSame (s1
->info
->ref
, s2
->info
->ref
));
2079 return ((sRef_realSame (s1
->info
->conj
->a
, s2
) ||
2080 (sRef_realSame (s1
->info
->conj
->b
, s2
))));
2082 return ((s2
->kind
== SK_OBJECT
)
2083 && ctype_match (s1
->info
->object
, s2
->info
->object
));
2085 return ((s2
->kind
== SK_EXTERNAL
)
2086 && sRef_realSame (s1
->info
->ref
, s2
->info
->ref
));
2088 return ((s2
->kind
== SK_SPECIAL
) && s1
->info
->spec
== s2
->info
->spec
);
2090 return ((s2
->kind
== SK_DERIVED
) && sRef_realSame (s1
->info
->ref
, s2
->info
->ref
));
2091 case SK_UNCONSTRAINED
:
2092 return ((s2
->kind
== SK_UNCONSTRAINED
)
2093 && (cstring_equal (s1
->info
->fname
, s2
->info
->fname
)));
2099 return TRUE
; /* changed this! was false */
2106 sRef_sameObject (sRef s1
, sRef s2
)
2113 ** same is similar to similar, but not quite the same.
2115 ** Similarly to similar, same checks is two sRefs are the same.
2116 ** The similarities end, however, when same compares arrays
2117 ** with unknown indexes. Similar returns false; same returns true.
2121 sRef_same (sRef s1
, sRef s2
)
2123 if (s1
== s2
) return TRUE
;
2124 if (sRef_isInvalid (s1
) || sRef_isInvalid (s2
)) return FALSE
;
2129 return ((s2
->kind
== SK_CVAR
) && (cref_equal (s1
->info
->cvar
, s2
->info
->cvar
)));
2131 return ((s2
->kind
== SK_PARAM
) && (s1
->info
->paramno
== s2
->info
->paramno
));
2133 if (s2
->kind
== SK_ARRAYFETCH
)
2135 llassert (s1
->info
->field
->rec
!= s1
);
2136 if (sRef_same (s1
->info
->arrayfetch
->arr
, s2
->info
->arrayfetch
->arr
))
2138 if (s1
->info
->arrayfetch
->indknown
&& s2
->info
->arrayfetch
->indknown
)
2140 return (s1
->info
->arrayfetch
->ind
== s2
->info
->arrayfetch
->ind
);
2148 llassert (s1
->info
->field
->rec
!= s1
);
2149 return ((s2
->kind
== SK_FIELD
&&
2150 (sRef_same (s1
->info
->field
->rec
, s2
->info
->field
->rec
) &&
2151 cstring_equal (s1
->info
->field
->field
, s2
->info
->field
->field
))));
2155 llassert (s1
->info
->ref
!= s1
);
2156 return ((s2
->kind
== SK_PTR
) && sRef_same (s1
->info
->ref
, s2
->info
->ref
));
2160 llassert (s1
->info
->ref
!= s1
);
2161 return ((s2
->kind
== SK_ADR
) && sRef_same (s1
->info
->ref
, s2
->info
->ref
));
2164 llassert (s1
->info
->conj
->a
!= s1
);
2165 llassert (s1
->info
->conj
->b
!= s1
);
2166 return ((sRef_same (s1
->info
->conj
->a
, s2
)) && /* or or and? */
2167 (sRef_same (s1
->info
->conj
->b
, s2
)));
2169 return ((s2
->kind
== SK_SPECIAL
) && s1
->info
->spec
== s2
->info
->spec
);
2171 llassert (s1
->info
->ref
!= s1
);
2172 return ((s2
->kind
== SK_DERIVED
) && sRef_same (s1
->info
->ref
, s2
->info
->ref
));
2174 case SK_UNCONSTRAINED
:
2188 ** sort of similar, for use in def/use
2192 sRef_closeEnough (sRef s1
, sRef s2
)
2194 if (s1
== s2
) return TRUE
;
2195 if (sRef_isInvalid (s1
) || sRef_isInvalid (s2
)) return FALSE
;
2200 return (((s2
->kind
== SK_CVAR
) &&
2201 (cref_equal (s1
->info
->cvar
, s2
->info
->cvar
))) ||
2202 (s2
->kind
== SK_UNCONSTRAINED
&& s1
->info
->cvar
->lexlevel
== 0));
2203 case SK_UNCONSTRAINED
:
2204 return (s2
->kind
== SK_UNCONSTRAINED
2205 || ((s2
->kind
== SK_CVAR
) && (s2
->info
->cvar
->lexlevel
== 0)));
2207 return ((s2
->kind
== SK_PARAM
)
2208 && (s1
->info
->paramno
== s2
->info
->paramno
));
2210 if (s2
->kind
== SK_ARRAYFETCH
)
2212 if (sRef_closeEnough (s1
->info
->arrayfetch
->arr
, s2
->info
->arrayfetch
->arr
))
2214 if (s1
->info
->arrayfetch
->indknown
&& s2
->info
->arrayfetch
->indknown
)
2216 return (s1
->info
->arrayfetch
->ind
== s2
->info
->arrayfetch
->ind
);
2223 return ((s2
->kind
== SK_FIELD
&&
2224 (sRef_closeEnough (s1
->info
->field
->rec
, s2
->info
->field
->rec
) &&
2225 cstring_equal (s1
->info
->field
->field
, s2
->info
->field
->field
))));
2227 return ((s2
->kind
== SK_PTR
) && sRef_closeEnough (s1
->info
->ref
, s2
->info
->ref
));
2229 return ((s2
->kind
== SK_ADR
) && sRef_closeEnough (s1
->info
->ref
, s2
->info
->ref
));
2231 return ((s2
->kind
== SK_DERIVED
) && sRef_closeEnough (s1
->info
->ref
, s2
->info
->ref
));
2233 return ((sRef_closeEnough (s1
->info
->conj
->a
, s2
)) ||
2234 (sRef_closeEnough (s1
->info
->conj
->b
, s2
)));
2236 return ((s2
->kind
== SK_SPECIAL
) && s1
->info
->spec
== s2
->info
->spec
);
2253 s is an sRef of a formal paramenter in a function call constraint
2254 we trys to return a constraint expression derived from the actual parementer of a function call.
2257 /*@only@*/ constraintExpr
sRef_fixConstraintParam (/*@observer@*/ sRef s
, /*@observer@*/ /*@temp@*/ exprNodeList args
)
2261 if (sRef_isInvalid (s
))
2262 llfatalbug((message("Invalid sRef")));
2268 ce
= constraintExpr_makeTermsRef (s
);
2275 temp
= (sRef_makeField (sRef_fixBaseParam (s
->info
->field
->rec
, args
),
2276 s
->info
->field
->field
));
2277 ce
= constraintExpr_makeTermsRef (temp
);
2283 temp
= (sRef_makePointer (sRef_fixBaseParam (s
->info
->ref
, args
)));
2284 ce
= constraintExpr_makeTermsRef (temp
);
2291 temp
= sRef_saveCopy(s
);
2292 temp
= sRef_fixBaseParam (temp
, args
);
2293 ce
= constraintExpr_makeTermsRef (temp
);
2301 temp
= sRef_saveCopy(s
);
2302 ce
= constraintExpr_makeTermsRef (temp
);
2309 llassert (exprNodeList_size (args
) > s
->info
->paramno
);
2310 e
= exprNodeList_nth (args
, s
->info
->paramno
);
2312 llassert (!(exprNode_isError (e
)));
2313 ce
= constraintExpr_makeExprNode (e
);
2320 llcontbug (message ("Trying to do fixConstraintParam on nonparam, nonglobal: %q for function with arguments %q",
2321 sRef_unparse (s
), exprNodeList_unparse(args
)));
2322 temp
= sRef_saveCopy(s
);
2323 ce
= constraintExpr_makeTermsRef (temp
);
2332 sRef_fixBaseParam (/*@returned@*/ sRef s
, exprNodeList args
)
2334 if (sRef_isInvalid (s
)) return (sRef_undefined
);
2338 case SK_UNCONSTRAINED
:
2343 if (exprNodeList_size (args
) > s
->info
->paramno
)
2345 exprNode e
= exprNodeList_nth (args
, s
->info
->paramno
);
2347 if (exprNode_isError (e
))
2349 return sRef_makeUnknown ();
2352 return (exprNode_getSref (e
));
2356 return sRef_makeUnknown ();
2361 if (s
->info
->arrayfetch
->indknown
)
2363 return (sRef_makeArrayFetchKnown
2364 (sRef_fixBaseParam (s
->info
->arrayfetch
->arr
, args
),
2365 s
->info
->arrayfetch
->ind
));
2369 return (sRef_makeArrayFetch
2370 (sRef_fixBaseParam (s
->info
->arrayfetch
->arr
, args
)));
2375 DPRINTF (("Fix field: %s", sRef_unparseFull (s
)));
2376 res
= sRef_makeField (sRef_fixBaseParam (s
->info
->field
->rec
, args
),
2377 s
->info
->field
->field
);
2378 DPRINTF (("Returns: %s", sRef_unparseFull (res
)));
2382 return (sRef_makePointer (sRef_fixBaseParam (s
->info
->ref
, args
)));
2385 return (sRef_makeAddress (sRef_fixBaseParam (s
->info
->ref
, args
)));
2388 return (sRef_makeConj (sRef_fixBaseParam (s
->info
->conj
->a
, args
),
2389 sRef_fixBaseParam (s
->info
->conj
->b
, args
)));
2405 sRef_undumpGlobal (char **c
)
2415 usymId uid
= usymId_fromInt (reader_getInt (c
));
2420 reader_checkChar (c
, '@');
2421 defstate
= sstate_fromInt (reader_getInt (c
));
2423 reader_checkChar (c
, '@');
2424 nullstate
= nstate_fromInt (reader_getInt (c
));
2426 ret
= sRef_makeGlobal (uid
, ctype_unknown
, stateInfo_currentLoc ());
2427 sRef_setNullStateN (ret
, nullstate
);
2428 ret
->defstate
= defstate
;
2433 int i
= reader_getInt (c
);
2434 speckind sk
= speckind_fromInt (i
);
2438 case SR_NOTHING
: return (sRef_makeNothing ());
2439 case SR_INTERNAL
: return (sRef_makeInternalState ());
2440 case SR_SPECSTATE
: return (sRef_makeSpecState ());
2441 case SR_SYSTEM
: return (sRef_makeSystemState ());
2442 case SR_GLOBALMARKER
: BADBRANCH
;
2447 return sRef_undefined
;
2449 return sRef_makeUnknown ();
2451 return sRef_makeUnknown ();
2453 llfatalerror (message ("sRef_undumpGlobal: bad line: %s",
2454 cstring_fromChars (*c
)));
2459 static /*@exposed@*/ sRef
sRef_undumpBody (char **c
)
2468 return (sRef_makeGlobal (usymId_fromInt (reader_getInt (c
)),
2469 ctype_unknown
, stateInfo_currentLoc ()));
2471 return (sRef_makeParam (reader_getInt (c
), ctype_unknown
,
2472 stateInfo_makeLoc (g_currentloc
, SA_DECLARED
)));
2474 return (sRef_makeResult (ctype_undump (c
)));
2477 if ((**c
>= '0' && **c
<= '9') || **c
== '-')
2479 int i
= reader_getInt (c
);
2480 sRef arr
= sRef_undump (c
);
2481 sRef ret
= sRef_buildArrayFetchKnown (arr
, i
);
2487 sRef arr
= sRef_undump (c
);
2488 sRef ret
= sRef_buildArrayFetch (arr
);
2495 cstring fname
= cstring_undefined
;
2500 fname
= cstring_appendChar (fname
, **c
);
2505 ret
= sRef_buildField (sRef_undump (c
), fname
);
2506 cstring_markOwned (fname
);
2511 int i
= reader_getInt (c
);
2512 speckind sk
= speckind_fromInt (i
);
2516 case SR_NOTHING
: return (sRef_makeNothing ());
2517 case SR_INTERNAL
: return (sRef_makeInternalState ());
2518 case SR_SPECSTATE
: return (sRef_makeSpecState ());
2519 case SR_SYSTEM
: return (sRef_makeSystemState ());
2520 case SR_GLOBALMARKER
: BADBRANCH
;
2526 sRef ptr
= sRef_undump (c
);
2527 sRef ret
= sRef_makePointer (ptr
);
2533 sRef adr
= sRef_undump (c
);
2534 sRef ret
= sRef_makeAddress (adr
);
2540 return (sRef_makeObject (ctype_undump (c
)));
2544 sRef s1
= sRef_undump (c
);
2545 sRef s2
= ((*c
)++, sRef_undump (c
));
2546 sRef ret
= sRef_makeConj (s1
, s2
);
2551 return sRef_undefined
;
2553 return sRef_makeUnknown ();
2555 return sRef_makeUnknown ();
2557 llfatalerror (message ("sRef_undump: bad line: %s", cstring_fromChars (*c
)));
2562 /*@exposed@*/ sRef
sRef_undump (char **c
)
2564 sRef res
= sRef_undumpBody (c
);
2566 if (reader_optCheckChar (c
, '='))
2568 multiVal mv
= multiVal_undump (c
);
2569 sRef_setValue (res
, mv
);
2570 reader_checkChar (c
, '=');
2576 static /*@only@*/ cstring
sRef_dumpBody (sRef s
)
2578 if (sRef_isInvalid (s
))
2580 return (cstring_makeLiteral ("-"));
2587 return (message ("p%d", s
->info
->paramno
));
2589 if (s
->info
->arrayfetch
->indknown
)
2591 return (message ("a%d%q", s
->info
->arrayfetch
->ind
,
2592 sRef_dump (s
->info
->arrayfetch
->arr
)));
2596 return (message ("a%q", sRef_dump (s
->info
->arrayfetch
->arr
)));
2599 return (message ("f%s.%q", s
->info
->field
->field
,
2600 sRef_dump (s
->info
->field
->rec
)));
2602 return (message ("t%q", sRef_dump (s
->info
->ref
)));
2604 return (message ("d%q", sRef_dump (s
->info
->ref
)));
2606 return (message ("o%q", ctype_dump (s
->info
->object
)));
2608 return (message ("s%d", (int) s
->info
->spec
));
2610 return (message ("c%q.%q",
2611 sRef_dump (s
->info
->conj
->a
),
2612 sRef_dump (s
->info
->conj
->b
)));
2614 if (sRef_isFileOrGlobalScope (s
))
2616 return (message ("g%d",
2617 usymtab_convertId (s
->info
->cvar
->index
)));
2621 llcontbug (message ("Dumping local variable: %q",
2622 sRef_unparseDebug (s
)));
2623 return (cstring_makeLiteral ("u"));
2626 return (cstring_makeLiteral ("u"));
2628 return (message ("r%q", ctype_dump (s
->type
)));
2634 case SK_UNCONSTRAINED
:
2635 llcontbug (message ("sRef_dump: bad kind: %q",
2636 sRef_unparseFull (s
)));
2637 return (cstring_makeLiteral ("x"));
2644 /*@only@*/ cstring
sRef_dump (sRef s
)
2646 cstring res
= sRef_dumpBody (s
);
2648 if (sRef_hasValue (s
))
2650 res
= message ("%q=%q=", res
, multiVal_dump (sRef_getValue (s
)));
2656 cstring
sRef_dumpGlobal (sRef s
)
2658 llassert (!sRef_hasValue (s
));
2660 if (sRef_isInvalid (s
))
2662 return (cstring_makeLiteral ("-"));
2669 if (sRef_isFileOrGlobalScope (s
))
2671 return (message ("g%d@%d@%d",
2672 usymtab_convertId (s
->info
->cvar
->index
),
2674 (int) sRef_getNullState (s
)));
2678 llcontbug (message ("Dumping local variable: %q",
2679 sRef_unparseDebug (s
)));
2680 return (cstring_makeLiteral ("u"));
2683 return (cstring_makeLiteral ("u"));
2685 return (message ("s%d", (int) s
->info
->spec
));
2687 llcontbug (message ("sRef_dumpGlobal: bad kind: %q",
2688 sRef_unparseFull (s
)));
2689 return (cstring_makeLiteral ("x"));
2697 sRef_deriveType (sRef s
, uentryList cl
)
2699 if (sRef_isInvalid (s
)) return ctype_unknown
;
2704 return (uentry_getType (usymtab_getRefQuiet (s
->info
->cvar
->lexlevel
,
2705 s
->info
->cvar
->index
)));
2706 case SK_UNCONSTRAINED
:
2707 return (ctype_unknown
);
2709 if (s
->info
->paramno
>= 0)
2711 return uentry_getType (uentryList_getN (cl
, s
->info
->paramno
));
2715 return ctype_unknown
;
2719 ctype ca
= sRef_deriveType (s
->info
->arrayfetch
->arr
, cl
);
2721 if (ctype_isArray (ca
))
2723 return (ctype_baseArrayPtr (ca
));
2725 else if (ctype_isUnknown (ca
))
2731 llcontbuglit ("sRef_deriveType: inconsistent array type");
2737 ctype ct
= sRef_deriveType (s
->info
->field
->rec
, cl
);
2739 if (ctype_isStructorUnion (ct
))
2741 uentry ue
= uentryList_lookupField (ctype_getFields (ct
),
2742 s
->info
->field
->field
);
2744 if (uentry_isValid (ue
))
2746 return (uentry_getType (ue
));
2750 llcontbuglit ("sRef_deriveType: bad field");
2751 return ctype_unknown
;
2754 else if (ctype_isUnknown (ct
))
2760 llcontbuglit ("sRef_deriveType: inconsistent field type");
2766 ctype ct
= sRef_deriveType (s
->info
->ref
, cl
);
2768 if (ctype_isUnknown (ct
)) return ct
;
2769 if (ctype_isPointer (ct
)) return (ctype_baseArrayPtr (ct
));
2772 llcontbuglit ("sRef_deriveType: inconsistent pointer type");
2778 ctype ct
= sRef_deriveType (s
->info
->ref
, cl
);
2780 if (ctype_isUnknown (ct
)) return ct
;
2781 return ctype_makePointer (ct
);
2785 return sRef_deriveType (s
->info
->ref
, cl
);
2789 return (s
->info
->object
);
2793 return (ctype_makeConj (sRef_deriveType (s
->info
->conj
->a
, cl
),
2794 sRef_deriveType (s
->info
->conj
->b
, cl
)));
2806 return ctype_unknown
;
2812 sRef_getType (sRef s
)
2814 if (sRef_isInvalid (s
)) return ctype_unknown
;
2820 sRef_unparseOpt (sRef s
)
2822 sRef rb
= sRef_getRootBase (s
);
2824 if (sRef_isMeaningful (rb
) && !sRef_isConst (rb
))
2826 cstring ret
= sRef_unparse (s
);
2828 llassertprint (!cstring_equalLit (ret
, "?"), ("print: %s", sRef_unparseDebug (s
)));
2830 if (!cstring_isEmpty (ret
))
2832 return (cstring_appendChar (ret
, ' '));
2840 return cstring_undefined
;
2844 sRef_unparsePreOpt (sRef s
)
2846 sRef rb
= sRef_getRootBase (s
);
2848 if (sRef_isMeaningful (rb
) && !sRef_isConst (rb
))
2850 cstring ret
= sRef_unparse (s
);
2852 llassertprint (!cstring_equalLit (ret
, "?"), ("print: %s", sRef_unparseDebug (s
)));
2853 return (cstring_prependCharO (' ', ret
));
2856 return cstring_undefined
;
2860 sRef_unparse (sRef s
)
2862 if (sRef_isInvalid (s
)) return (cstring_makeLiteral ("?"));
2864 if (context_inFunctionLike ())
2866 return (sRef_unparseWithArgs (s
, context_getParams ()));
2870 DPRINTF (("Not in function like: %s", context_unparse ()));
2871 return (sRef_unparseNoArgs (s
));
2875 static /*@only@*/ cstring
2876 sRef_unparseWithArgs (sRef s
, uentryList args
)
2878 if (sRef_isInvalid (s
))
2880 return (cstring_makeLiteral ("?"));
2886 return (uentry_getName (usymtab_getRefQuiet (s
->info
->cvar
->lexlevel
,
2887 s
->info
->cvar
->index
)));
2888 case SK_UNCONSTRAINED
:
2889 return (cstring_copy (s
->info
->fname
));
2892 if (s
->info
->paramno
< uentryList_size (args
)
2893 && s
->info
->paramno
>= 0)
2895 uentry ue
= uentryList_getN (args
, s
->info
->paramno
);
2897 if (uentry_isValid (ue
))
2898 return uentry_getName (ue
);
2901 return (message ("parameter %d", s
->info
->paramno
+ 1));
2904 if (s
->info
->arrayfetch
->indknown
)
2906 return (message ("%q[%d]", sRef_unparseWithArgs (s
->info
->arrayfetch
->arr
, args
),
2907 s
->info
->arrayfetch
->ind
));
2911 return (message ("%q[]", sRef_unparseWithArgs (s
->info
->arrayfetch
->arr
, args
)));
2914 if (s
->info
->field
->rec
->kind
== SK_PTR
)
2916 sRef ptr
= s
->info
->field
->rec
;
2918 return (message ("%q->%s", sRef_unparseWithArgs (ptr
->info
->ref
, args
),
2919 s
->info
->field
->field
));
2921 return (message ("%q.%s", sRef_unparseWithArgs (s
->info
->field
->rec
, args
),
2922 s
->info
->field
->field
));
2926 sRef ref
= sRef_fixConj (s
->info
->ref
);
2927 skind sk
= ref
->kind
;
2932 ret
= message ("storage pointed to by %q",
2933 sRef_unparseWithArgs (ref
, args
));
2935 else if (skind_isSimple (sk
) || sk
== SK_PTR
)
2937 ret
= message ("*%q", sRef_unparseWithArgs (ref
, args
));
2941 ret
= message ("*(%q)", sRef_unparseWithArgs (ref
, args
));
2947 return (message ("&%q", sRef_unparseWithArgs (s
->info
->ref
, args
)));
2949 return (cstring_copy (ctype_unparse (s
->info
->object
)));
2951 return (sRef_unparseWithArgs (sRef_getConjA (s
), args
));
2953 if (cstring_isDefined (s
->info
->fname
))
2955 return (message ("[result of %s]", s
->info
->fname
));
2959 return (cstring_makeLiteral ("<new>"));
2962 return (cstring_makeLiteral ("?"));
2964 return (message ("<derived %q>", sRef_unparse (s
->info
->ref
)));
2966 return (message ("<external %q>", sRef_unparse (s
->info
->ref
)));
2968 return (message ("<type %s>", ctype_unparse (s
->type
)));
2970 return (message ("<const %s>", ctype_unparse (s
->type
)));
2972 switch (s
->info
->spec
)
2974 case SR_NOTHING
: return cstring_makeLiteral ("nothing");
2975 case SR_INTERNAL
: return cstring_makeLiteral ("internal state");
2976 case SR_SPECSTATE
: return cstring_makeLiteral ("spec state");
2977 case SR_SYSTEM
: return cstring_makeLiteral ("file system state");
2978 case SR_GLOBALMARKER
: return cstring_makeLiteral ("<global marker>");
2982 return cstring_makeLiteral ("result");
2985 llbug (message ("Bad sref, kind = %d", (int) s
->kind
));
2993 sRef_unparseDebug (sRef s
)
2995 if (sRef_isInvalid (s
))
2997 return (cstring_makeLiteral ("<undef>"));
3003 case SK_UNCONSTRAINED
:
3004 return (message ("<unconstrained %s>", s
->info
->fname
));
3009 ce
= usymtab_getRefQuiet (s
->info
->cvar
->lexlevel
, s
->info
->cvar
->index
);
3011 if (uentry_isInvalid (ce
))
3013 return (message ("<scope: %d.%d *invalid*>",
3014 s
->info
->cvar
->lexlevel
,
3015 s
->info
->cvar
->index
));
3019 return (message ("<scope: %d.%d *%q*>",
3020 s
->info
->cvar
->lexlevel
,
3021 s
->info
->cvar
->index
,
3022 uentry_getName (ce
)));
3028 return (message ("<parameter %d>", s
->info
->paramno
+ 1));
3031 if (s
->info
->arrayfetch
->indknown
)
3033 return (message ("%q[%d]", sRef_unparseDebug (s
->info
->arrayfetch
->arr
),
3034 s
->info
->arrayfetch
->ind
));
3038 return (message ("%q[]", sRef_unparseDebug (s
->info
->arrayfetch
->arr
)));
3041 return (message ("%q.%s", sRef_unparseDebug (s
->info
->field
->rec
),
3042 s
->info
->field
->field
));
3044 if (sRef_isField (s
->info
->ref
))
3046 sRef fld
= s
->info
->ref
;
3048 return (message ("%q->%s", sRef_unparseDebug (fld
->info
->field
->rec
),
3049 fld
->info
->field
->field
));
3053 return (message ("*(%q)", sRef_unparseDebug (s
->info
->ref
)));
3056 return (message ("&%q", sRef_unparseDebug (s
->info
->ref
)));
3058 return (message ("<object type %s>", ctype_unparse (s
->info
->object
)));
3060 return (message ("%q | %q", sRef_unparseDebug (s
->info
->conj
->a
),
3061 sRef_unparseDebug (s
->info
->conj
->b
)));
3063 return message ("<new: %s>", s
->info
->fname
);
3065 return (message ("<derived %q>", sRef_unparseDebug (s
->info
->ref
)));
3067 return (message ("<external %q>", sRef_unparseDebug (s
->info
->ref
)));
3069 return (message ("<type %s>", ctype_unparse (s
->type
)));
3071 if (sRef_hasValue (s
))
3073 return (message ("<const %s=%q>", ctype_unparse (s
->type
), multiVal_unparse (sRef_getValue (s
))));
3077 return (message ("<const %s>", ctype_unparse (s
->type
)));
3080 return (message ("<result %s>", ctype_unparse (s
->type
)));
3082 return (message ("<spec %s>",
3083 cstring_makeLiteralTemp
3084 (s
->info
->spec
== SR_NOTHING
? "nothing"
3085 : s
->info
->spec
== SR_INTERNAL
? "internalState"
3086 : s
->info
->spec
== SR_SPECSTATE
? "spec state"
3087 : s
->info
->spec
== SR_SYSTEM
? "fileSystem"
3090 return cstring_makeLiteral ("<unknown>");
3096 static /*@only@*/ cstring
3097 sRef_unparseNoArgs (sRef s
)
3099 if (sRef_isInvalid (s
)) return (cstring_makeLiteral ("?"));
3103 case SK_UNCONSTRAINED
:
3104 return (cstring_copy (s
->info
->fname
));
3107 uentry ce
= usymtab_getRefQuiet (s
->info
->cvar
->lexlevel
,
3108 s
->info
->cvar
->index
);
3110 if (uentry_isInvalid (ce
))
3112 llcontbug (message ("sRef_unparseNoArgs: bad cvar: %q",
3113 sRef_unparseDebug (s
)));
3114 return (sRef_unparseDebug (s
));
3118 return (uentry_getName (ce
));
3122 if (s
->info
->arrayfetch
->indknown
)
3124 return (message ("%q[%d]", sRef_unparseNoArgs (s
->info
->arrayfetch
->arr
),
3125 s
->info
->arrayfetch
->ind
));
3129 return (message ("%q[]", sRef_unparseNoArgs (s
->info
->arrayfetch
->arr
)));
3132 return (message ("%q.%s", sRef_unparseNoArgs (s
->info
->field
->rec
),
3133 s
->info
->field
->field
));
3136 sRef ref
= sRef_fixConj (s
->info
->ref
);
3137 skind sk
= ref
->kind
;
3140 if (skind_isSimple (sk
) || sk
== SK_PTR
)
3142 ret
= message ("*%q", sRef_unparseNoArgs (ref
));
3146 ret
= message ("*(%q)", sRef_unparseNoArgs (ref
));
3152 return (message ("&%q", sRef_unparseNoArgs (s
->info
->ref
)));
3154 return (cstring_copy (ctype_unparse (s
->info
->object
)));
3156 return (sRef_unparseNoArgs (s
->info
->conj
->a
));
3158 return (message ("result of %s", s
->info
->fname
));
3160 return (message ("<der %q>", sRef_unparseNoArgs (s
->info
->ref
)));
3162 return message ("<ext %q>", sRef_unparseNoArgs (s
->info
->ref
));
3164 return (cstring_makeLiteral
3165 (s
->info
->spec
== SR_NOTHING
? "nothing"
3166 : s
->info
->spec
== SR_INTERNAL
? "internal state"
3167 : s
->info
->spec
== SR_SPECSTATE
? "spec state"
3168 : s
->info
->spec
== SR_SYSTEM
? "file system state"
3171 return cstring_makeLiteral ("result");
3175 return cstring_makeLiteral ("?");
3177 /* llcontbug (message ("sRef_unparseNoArgs: bad case: %q", sRef_unparseDebug (s))); */
3178 return (sRef_unparseDebug (s
));
3183 /*@dependent@*/ sRef
sRef_makeUnconstrained (cstring fname
)
3185 sRef s
= sRef_new ();
3187 s
->kind
= SK_UNCONSTRAINED
;
3188 s
->info
= (sinfo
) dmalloc (sizeof (*s
->info
));
3189 s
->info
->fname
= cstring_copy (fname
); /* evans 2002-07-12: this was exposed, causing memory errors */
3194 cstring
sRef_unconstrainedName (sRef s
)
3196 llassert (sRef_isUnconstrained (s
));
3198 return s
->info
->fname
;
3201 bool sRef_isUnconstrained (sRef s
)
3203 return (sRef_isReasonable(s
) && s
->kind
== SK_UNCONSTRAINED
);
3206 static /*@dependent@*/ /*@notnull@*/ sRef
3207 sRef_makeCvarAux (int level
, usymId index
, ctype ct
, /*@only@*/ stateInfo stinfo
)
3209 sRef s
= sRef_newRef ();
3212 s
->info
= (sinfo
) dmalloc (sizeof (*s
->info
));
3214 s
->info
->cvar
= (cref
) dmalloc (sizeof (*s
->info
->cvar
));
3215 s
->info
->cvar
->lexlevel
= level
;
3216 s
->info
->cvar
->index
= index
;
3218 /* for now, all globals are defined; all locals, aren't */
3220 if (level
<= fileScope
)
3222 s
->defstate
= SS_UNKNOWN
;
3226 ctype rct
= ctype_realType (ct
);
3228 if (level
!= paramsScope
3229 && (ctype_isStructorUnion (rct
) || ctype_isRealArray (rct
)))
3231 s
->defstate
= SS_ALLOCATED
;
3232 s
->oaliaskind
= s
->aliaskind
= AK_STACK
;
3236 s
->defstate
= SS_UNDEFINED
;
3237 s
->oaliaskind
= s
->aliaskind
= AK_LOCAL
;
3243 llassert (level
>= globScope
);
3244 llassert (usymId_isValid (index
));
3246 DPRINTF (("Made cvar: [%p] %s", s
, sRef_unparseDebug (s
)));
3247 llassert (valueTable_isUndefined (s
->state
));
3248 s
->state
= context_createValueTable (s
, stinfo
);
3252 /*@dependent@*/ sRef
sRef_makeCvar (int level
, usymId index
, ctype ct
, /*@only@*/ stateInfo stinfo
)
3254 return (sRef_makeCvarAux (level
, index
, ct
, stinfo
));
3257 int sRef_lexLevel (sRef s
)
3259 if (sRef_isReasonable (s
))
3263 conj
= sRef_fixConj (s
);
3264 s
= sRef_getRootBase (conj
);
3266 if (sRef_isReasonable (s
) && s
->kind
== SK_CVAR
)
3268 return (s
->info
->cvar
->lexlevel
);
3276 sRef_makeGlobal (usymId l
, ctype ct
, /*@only@*/ stateInfo stinfo
)
3278 return (sRef_makeCvar (globScope
, l
, ct
, stinfo
));
3282 sRef_setParamNo (sRef s
, int l
)
3284 llassert (sRef_isReasonable (s
) && s
->kind
== SK_PARAM
);
3285 s
->info
->paramno
= l
;
3289 /*@dependent@*/ sRef
3290 sRef_makeParam (int l
, ctype ct
, stateInfo stinfo
)
3292 sRef s
= sRef_new ();
3297 s
->info
= (sinfo
) dmalloc (sizeof (*s
->info
));
3298 s
->info
->paramno
= l
;
3300 s
->defstate
= SS_UNKNOWN
;
3301 /* (probably defined, unless its an out parameter) */
3303 llassert (valueTable_isUndefined (s
->state
));
3304 s
->state
= context_createValueTable (s
, stinfo
);
3309 sRef_isIndexKnown (sRef arr
)
3313 llassert (sRef_isReasonable (arr
));
3314 arr
= sRef_fixConj (arr
);
3316 llassert (arr
->kind
== SK_ARRAYFETCH
);
3317 res
= arr
->info
->arrayfetch
->indknown
;
3322 sRef_getIndex (sRef arr
)
3326 llassert (sRef_isReasonable (arr
));
3327 arr
= sRef_fixConj (arr
);
3329 llassert (arr
->kind
== SK_ARRAYFETCH
);
3331 if (!arr
->info
->arrayfetch
->indknown
)
3333 llcontbug (message ("sRef_getIndex: unknown: %q", sRef_unparse (arr
)));
3338 result
= arr
->info
->arrayfetch
->ind
;
3344 static bool sRef_isZerothArrayFetch (/*@notnull@*/ sRef s
)
3346 return (s
->kind
== SK_ARRAYFETCH
3347 && s
->info
->arrayfetch
->indknown
3348 && (s
->info
->arrayfetch
->ind
== 0));
3351 /*@exposed@*/ sRef
sRef_makeAddress (/*@exposed@*/ sRef t
)
3354 if (sRef_isInvalid (t
)) return sRef_undefined
;
3356 if (sRef_isPointer (t
))
3358 return (t
->info
->ref
);
3360 else if (sRef_isZerothArrayFetch (t
))
3362 return (t
->info
->arrayfetch
->arr
);
3366 sRef s
= sRef_newRef ();
3369 s
->type
= ctype_makePointer (t
->type
);
3370 s
->info
= (sinfo
) dmalloc (sizeof (*s
->info
));
3373 if (t
->defstate
== SS_UNDEFINED
)
3374 /* no! it is allocated even still: && !ctype_isPointer (t->type)) */
3376 s
->defstate
= SS_ALLOCATED
;
3380 s
->defstate
= t
->defstate
;
3383 if (t
->aliaskind
== AK_LOCAL
)
3385 if (sRef_isLocalVar (t
))
3387 s
->aliaskind
= AK_STACK
;
3391 llassert (valueTable_isUndefined (s
->state
));
3392 s
->state
= context_createValueTable (s
,
3393 stateInfo_makeLoc (g_currentloc
, SA_CREATED
));
3398 cstring
sRef_getField (sRef s
)
3402 llassert (sRef_isReasonable (s
));
3403 s
= sRef_fixConj (s
);
3405 llassertprint (sRef_isReasonable (s
) && (s
->kind
== SK_FIELD
),
3406 ("s = %s", sRef_unparseDebug (s
)));
3408 res
= s
->info
->field
->field
;
3412 sRef
sRef_getBase (sRef s
)
3416 if (sRef_isInvalid (s
)) return (sRef_undefined
);
3418 s
= sRef_fixConj (s
);
3429 res
= s
->info
->field
->rec
;
3433 res
= s
->info
->arrayfetch
->arr
;
3437 res
= sRef_undefined
; /* shouldn't need it */
3444 ** same as getBase, except returns invalid
3445 ** (and doesn't use adr's)
3449 sRef_getBaseSafe (sRef s
)
3453 if (sRef_isInvalid (s
)) { return sRef_undefined
; }
3455 s
= sRef_fixConj (s
);
3463 res
= s
->info
->field
->rec
; break;
3465 res
= s
->info
->arrayfetch
->arr
;
3468 res
= sRef_undefined
; break;
3474 /*@constant int MAXBASEDEPTH;@*/
3475 # define MAXBASEDEPTH 25
3477 static /*@exposed@*/ sRef
3478 sRef_getRootBaseAux (sRef s
, int depth
)
3480 if (sRef_isInvalid (s
)) return sRef_undefined
;
3482 if (depth
> MAXBASEDEPTH
)
3485 ("Warning: reference base limit exceeded for %q. "
3486 "This either means there is a variable with at least "
3487 "%d indirections from this reference, or "
3488 "there is a bug in Splint.",
3493 return sRef_undefined
;
3500 return (sRef_getRootBaseAux (s
->info
->ref
, depth
+ 1));
3502 return (sRef_getRootBaseAux (s
->info
->field
->rec
, depth
+ 1));
3504 return (sRef_getRootBaseAux (s
->info
->arrayfetch
->arr
, depth
+ 1));
3506 return (sRef_getRootBaseAux (sRef_fixConj (s
), depth
+ 1));
3512 sRef
sRef_getRootBase (sRef s
)
3514 return (sRef_getRootBaseAux (s
, 0));
3517 static bool sRef_isDeep (sRef s
)
3519 if (sRef_isInvalid (s
)) return FALSE
;
3529 return (sRef_isDeep (sRef_fixConj (s
)));
3535 static int sRef_depth (sRef s
)
3537 if (sRef_isInvalid (s
)) return 0;
3545 return 1 + sRef_depth (s
->info
->ref
);
3547 return 1 + sRef_depth (s
->info
->field
->rec
);
3549 return 1 + sRef_depth (s
->info
->arrayfetch
->arr
);
3551 return (sRef_depth (sRef_fixConj (s
)));
3558 sRef_makeObject (ctype o
)
3560 sRef s
= sRef_newRef ();
3562 s
->kind
= SK_OBJECT
;
3563 s
->info
= (sinfo
) dmalloc (sizeof (*s
->info
));
3564 s
->info
->object
= o
;
3565 llassert (valueTable_isUndefined (s
->state
));
3566 s
->state
= context_createValueTable (s
, stateInfo_makeLoc (g_currentloc
, SA_CREATED
));
3571 ** This is used to represent storage referenced by a parameter.
3574 sRef
sRef_makeExternal (sRef t
)
3576 sRef s
= sRef_newRef ();
3578 llassert (sRef_isReasonable (t
));
3580 s
->kind
= SK_EXTERNAL
;
3581 s
->info
= (sinfo
) dmalloc (sizeof (*s
->info
));
3584 llassert (valueTable_isUndefined (s
->state
));
3585 s
->state
= context_createValueTable (s
, stateInfo_makeLoc (g_currentloc
, SA_DECLARED
));
3589 /*@dependent@*/ sRef
sRef_makeDerived (/*@exposed@*/ sRef t
)
3591 if (sRef_isReasonable (t
))
3593 sRef s
= sRef_newRef ();
3595 s
->kind
= SK_DERIVED
;
3596 s
->info
= (sinfo
) dmalloc (sizeof (*s
->info
));
3600 llassert (valueTable_isUndefined (s
->state
));
3601 s
->state
= context_createValueTable (s
, stateInfo_makeLoc (g_currentloc
, SA_CREATED
));
3606 return sRef_undefined
;
3611 ** definitely NOT symmetric:
3613 ** res fills in unknown state information from other
3617 sRef_mergeStateQuiet (sRef res
, sRef other
)
3619 llassert (sRef_isReasonable (res
));
3620 llassert (sRef_isReasonable (other
));
3622 res
->modified
= res
->modified
|| other
->modified
;
3623 res
->safe
= res
->safe
&& other
->safe
;
3625 if (res
->defstate
== SS_UNKNOWN
)
3627 res
->defstate
= other
->defstate
;
3628 res
->definfo
= stateInfo_update (res
->definfo
, other
->definfo
);
3631 if (res
->aliaskind
== AK_UNKNOWN
||
3632 (res
->aliaskind
== AK_LOCAL
&& alkind_isKnown (other
->aliaskind
)))
3634 res
->aliaskind
= other
->aliaskind
;
3635 res
->oaliaskind
= other
->oaliaskind
;
3636 res
->aliasinfo
= stateInfo_update (res
->aliasinfo
, other
->aliasinfo
);
3639 if (res
->expkind
== XO_UNKNOWN
)
3641 res
->expkind
= other
->expkind
;
3642 res
->oexpkind
= other
->oexpkind
;
3643 res
->expinfo
= stateInfo_update (res
->expinfo
, other
->expinfo
);
3646 /* out takes precedence over implicitly defined */
3647 if (res
->defstate
== SS_DEFINED
&& other
->defstate
!= SS_UNKNOWN
)
3649 res
->defstate
= other
->defstate
;
3650 res
->definfo
= stateInfo_update (res
->definfo
, other
->definfo
);
3653 if (sRef_getNullState (other
) == NS_ERROR
|| sRef_getNullState (res
) == NS_ERROR
)
3655 sRef_setNullState (res
, NS_ERROR
, fileloc_undefined
);
3659 if (sRef_getNullState (other
) != NS_UNKNOWN
3660 && (sRef_getNullState (res
) == NS_UNKNOWN
|| sRef_getNullState (res
) == NS_NOTNULL
3661 || sRef_getNullState (res
) == NS_MNOTNULL
))
3663 sRef_updateNullState (res
, other
);
3669 ** definitely NOT symmetric:
3671 ** res fills in known state information from other
3675 sRef_mergeStateQuietReverse (/*@dependent@*/ sRef res
, /*@dependent@*/ sRef other
)
3677 bool changed
= FALSE
;
3679 llassert (sRef_isReasonable (res
));
3680 llassert (sRef_isReasonable (other
));
3681 sRef_checkMutable (res
);
3683 if (res
->kind
!= other
->kind
)
3689 res
->kind
= other
->kind
;
3690 res
->type
= other
->type
;
3691 res
->info
= sinfo_fullCopy (other
);
3695 if (!ctype_equal (res
->type
, other
->type
))
3698 res
->type
= other
->type
;
3701 sinfo_update (res
, other
);
3704 res
->modified
= res
->modified
|| other
->modified
;
3705 res
->safe
= res
->safe
&& other
->safe
;
3707 if (res
->aliaskind
!= other
->aliaskind
3708 && (res
->aliaskind
== AK_UNKNOWN
3709 || ((res
->aliaskind
== AK_LOCAL
3710 || (res
->aliaskind
== AK_REFCOUNTED
3711 && other
->aliaskind
!= AK_LOCAL
))
3712 && other
->aliaskind
!= AK_UNKNOWN
)))
3715 res
->aliaskind
= other
->aliaskind
;
3716 res
->oaliaskind
= other
->oaliaskind
;
3717 res
->aliasinfo
= stateInfo_update (res
->aliasinfo
, other
->aliasinfo
);
3720 if (other
->expkind
!= XO_UNKNOWN
&& other
->expkind
!= res
->expkind
)
3723 res
->expkind
= other
->expkind
;
3724 res
->expinfo
= stateInfo_update (res
->expinfo
, other
->expinfo
);
3727 if (other
->oexpkind
!= XO_UNKNOWN
)
3729 res
->oexpkind
= other
->oexpkind
;
3732 /* out takes precedence over implicitly defined */
3734 if (res
->defstate
!= other
->defstate
)
3736 if (other
->defstate
!= SS_UNKNOWN
)
3738 res
->defstate
= other
->defstate
;
3739 res
->definfo
= stateInfo_update (res
->definfo
, other
->definfo
);
3743 if (sRef_getNullState (other
) == NS_ERROR
|| sRef_getNullState (res
) == NS_ERROR
)
3745 if (sRef_getNullState (res
) != NS_ERROR
)
3747 sRef_setNullStateN (res
, NS_ERROR
);
3753 if (sRef_getNullState (other
) != NS_UNKNOWN
3754 && sRef_getNullState (other
) != sRef_getNullState (res
))
3757 sRef_updateNullState (res
, other
);
3763 sRef_clearDerived (res
);
3768 sRef_mergeState (sRef res
, sRef other
, clause cl
, fileloc loc
)
3770 if (sRef_isReasonable (res
) && sRef_isReasonable (other
))
3772 sRef_mergeStateAux (res
, other
, cl
, FALSE
, loc
, TRUE
);
3776 if (sRef_isInvalid (res
))
3778 llbug (message ("sRef_mergeState: invalid res sRef: %q",
3779 sRef_unparseDebug (other
)));
3783 llbug (message ("sRef_mergeState: invalid other sRef: %q",
3784 sRef_unparseDebug (res
)));
3790 sRef_mergeOptState (sRef res
, sRef other
, clause cl
, fileloc loc
)
3792 if (sRef_isReasonable (res
) && sRef_isReasonable (other
))
3794 sRef_mergeStateAux (res
, other
, cl
, TRUE
, loc
, TRUE
);
3798 if (sRef_isInvalid (res
))
3800 llbug (message ("sRef_mergeOptState: invalid res sRef: %q",
3801 sRef_unparseDebug (other
)));
3805 llbug (message ("sRef_mergeOptState: invalid other sRef: %q",
3806 sRef_unparseDebug (res
)));
3812 sRef_mergeStateAux (/*@notnull@*/ sRef res
, /*@notnull@*/ sRef other
,
3813 clause cl
, bool opt
, fileloc loc
,
3817 llassertfatal (sRef_isReasonable (res
));
3818 llassertfatal (sRef_isReasonable (other
));
3820 DPRINTF (("Merge aux: %s / %s",
3821 sRef_unparseFull (res
),
3822 sRef_unparseFull (other
)));
3824 sRef_checkMutable (res
);
3825 sRef_checkMutable (other
);
3827 res
->modified
= res
->modified
|| other
->modified
;
3829 if (res
->kind
== other
->kind
3830 || (other
->kind
== SK_UNKNOWN
|| res
->kind
== SK_UNKNOWN
))
3832 sstate odef
= other
->defstate
;
3833 sstate rdef
= res
->defstate
;
3834 nstate onull
= sRef_getNullState (other
);
3837 ** yucky stuff to handle
3842 if (other
->defstate
== SS_DEAD
3843 && ((sRef_isOnly (res
) && sRef_definitelyNull (res
))
3844 || (res
->defstate
== SS_UNDEFINED
3845 || res
->defstate
== SS_UNUSEABLE
)))
3847 if (res
->defstate
== SS_UNDEFINED
3848 || res
->defstate
== SS_UNUSEABLE
)
3850 res
->defstate
= SS_UNUSEABLE
;
3854 res
->defstate
= SS_DEAD
;
3857 res
->definfo
= stateInfo_update (res
->definfo
, other
->definfo
);
3858 sRef_clearDerived (other
);
3859 sRef_clearDerived (res
);
3861 else if (res
->defstate
== SS_DEAD
3862 && ((sRef_isOnly (other
) && sRef_definitelyNull (other
))
3863 || (other
->defstate
== SS_UNDEFINED
3864 || other
->defstate
== SS_UNUSEABLE
)))
3866 if (other
->defstate
== SS_UNDEFINED
3867 || other
->defstate
== SS_UNUSEABLE
)
3869 res
->defstate
= SS_UNUSEABLE
;
3873 res
->defstate
= SS_DEAD
;
3876 res
->definfo
= stateInfo_update (res
->definfo
, other
->definfo
);
3877 sRef_clearDerived (other
);
3878 sRef_clearDerived (res
);
3880 else if (res
->defstate
== SS_DEFINED
3881 && (other
->defstate
== SS_ALLOCATED
3882 && sRef_definitelyNull (other
)))
3884 other
->defstate
= SS_DEFINED
; /* definitely null! */
3886 else if (other
->defstate
== SS_DEFINED
3887 && (res
->defstate
== SS_ALLOCATED
&& sRef_definitelyNull (res
)))
3889 res
->defstate
= SS_DEFINED
;
3890 res
->definfo
= stateInfo_update (res
->definfo
, other
->definfo
);
3897 if (res
->defstate
== SS_DEAD
&& other
->defstate
== SS_DEAD
)
3899 sRef_clearDerived (other
);
3900 sRef_clearDerived (res
);
3904 ** only & dead isn't really an only!
3907 if (alkind_isOnly (other
->aliaskind
) && other
->defstate
== SS_DEAD
)
3909 other
->aliaskind
= AK_UNKNOWN
;
3912 if (alkind_isOnly (res
->aliaskind
) && res
->defstate
== SS_DEAD
)
3914 res
->aliaskind
= AK_UNKNOWN
;
3918 ** Dead and dependent -> dead
3921 if (alkind_isDependent (other
->aliaskind
) && res
->defstate
== SS_DEAD
)
3923 other
->aliaskind
= AK_UNKNOWN
;
3924 other
->defstate
= SS_DEAD
;
3925 sRef_clearDerived (res
);
3926 sRef_clearDerived (other
);
3929 if (alkind_isDependent (res
->aliaskind
) && other
->defstate
== SS_DEAD
)
3931 res
->aliaskind
= AK_UNKNOWN
;
3932 res
->defstate
= SS_DEAD
;
3933 sRef_clearDerived (res
);
3934 sRef_clearDerived (other
);
3938 ** must do alias combine first, since it depends on
3939 ** original values of state and null.
3942 sRef_combineAliasKinds (res
, other
, cl
, loc
);
3943 sRef_combineDefState (res
, other
);
3944 sRef_combineNullState (res
, other
);
3946 if (rdef
== SS_ALLOCATED
|| rdef
== SS_SPECIAL
)
3948 if (odef
== SS_DEFINED
)
3950 if (onull
== NS_DEFNULL
|| onull
== NS_CONSTNULL
)
3952 res
->deriv
= sRefSet_copyInto (res
->deriv
, other
->deriv
);
3953 DPRINTF (("Copy derivs: %s", sRef_unparseFull (res
)));
3956 else if (odef
== SS_ALLOCATED
|| odef
== SS_SPECIAL
)
3961 if (ctype_isUnion (ctype_realType (sRef_getType (res
))))
3963 res
->deriv
= sRef_mergeUnionDerivs (res
->deriv
,
3966 DPRINTF (("Copy derivs: %s", sRef_unparseFull (res
)));
3970 res
->deriv
= sRef_mergeDerivs (res
->deriv
, other
->deriv
,
3972 DPRINTF (("Copy derivs: %s", sRef_unparseFull (res
)));
3980 res
->deriv
= sRef_mergeDerivs (res
->deriv
, other
->deriv
,
3982 DPRINTF (("Copy derivs: %s", sRef_unparseFull (res
)));
3992 if (rdef
== SS_PDEFINED
3993 || (rdef
== SS_DEFINED
&& odef
== SS_PDEFINED
))
3997 res
->deriv
= sRef_mergePdefinedDerivs (res
->deriv
, other
->deriv
,
3999 DPRINTF (("Copy derivs: %s", sRef_unparseFull (res
)));
4004 if ((rdef
== SS_DEFINED
|| rdef
== SS_UNKNOWN
)
4005 && res
->defstate
== SS_ALLOCATED
)
4007 res
->deriv
= sRefSet_copyInto (res
->deriv
, other
->deriv
);
4013 res
->deriv
= sRef_mergeDerivs (res
->deriv
, other
->deriv
,
4015 DPRINTF (("Copy derivs: %s", sRef_unparseFull (res
)));
4022 sRef_combineExKinds (res
, other
);
4026 if (res
->kind
== SK_ARRAYFETCH
&& other
->kind
== SK_PTR
)
4028 sRef nother
= sRef_buildArrayFetchKnown (sRef_getBase (other
), 0);
4030 sRef_copyState (nother
, other
);
4031 sRef_mergeStateAux (res
, nother
, cl
, opt
, loc
, doDerivs
);
4033 else if (res
->kind
== SK_PTR
&& other
->kind
== SK_ARRAYFETCH
)
4035 sRef nother
= sRef_buildPointer (sRef_getBase (other
));
4037 if (sRef_isReasonable (nother
))
4039 sRef_copyState (nother
, other
);
4040 sRef_mergeStateAux (res
, nother
, cl
, opt
, loc
, doDerivs
);
4045 llcontbug (message ("merge conj: %q / %q", sRef_unparseFull (res
),
4046 sRef_unparseFull (other
)));
4052 ** Merge value table states
4057 ** This doesn't do anything. And its broken too...
4060 valueTable_elements (res
->state
, key
, sv
)
4062 stateValue os
= valueTable_lookup (other
->state
, key
);
4063 /*@unused@*/ int val
;
4064 /*@unused@*/ char *msg
;
4066 llassert (stateValue_isDefined (os
));
4068 DPRINTF (("Merge state: %s / %s",
4069 cstring_toCharsSafe (stateValue_unparse (sv
)),
4070 cstring_toCharsSafe (stateValue_unparse (os
))));
4072 val = valueMatix_lookup (key,
4073 stateValue_getValue (os),
4074 stateValue_getValue (sv),
4076 DPRINTF (("Val: %d / %s", val, msg));
4078 } end_valueTable_elements
;
4081 DPRINTF (("Merge aux: %s / %s",
4082 sRef_unparseFull (res
),
4083 sRef_unparseFull (other
)));
4087 sRef_mergeUnionDerivs (/*@only@*/ sRefSet res
,
4088 /*@exposed@*/ sRefSet other
, bool opt
,
4089 clause cl
, fileloc loc
)
4091 if (sRefSet_isEmpty (res
))
4093 return sRefSet_copyInto (res
, other
);
4097 sRefSet_allElements (other
, el
)
4099 if (sRef_isReasonable (el
))
4101 sRef e2
= sRefSet_lookupMember (other
, el
);
4103 if (sRef_isReasonable (e2
))
4105 sRef_mergeStateAux (el
, e2
, cl
, opt
, loc
, FALSE
);
4109 res
= sRefSet_insert (res
, el
);
4112 } end_sRefSet_allElements
;
4118 static /*@only@*/ sRefSet
4119 sRef_mergeDerivs (/*@only@*/ sRefSet res
, sRefSet other
,
4120 bool opt
, clause cl
, fileloc loc
)
4122 sRefSet ret
= sRefSet_new ();
4124 sRefSet_allElements (res
, el
)
4126 if (sRef_isReasonable (el
))
4128 sRef e2
= sRefSet_lookupMember (other
, el
);
4130 if (sRef_isReasonable (e2
))
4132 if (el
->defstate
== SS_ALLOCATED
&&
4133 e2
->defstate
== SS_PDEFINED
)
4135 e2
->defstate
= SS_ALLOCATED
;
4137 else if (e2
->defstate
== SS_ALLOCATED
&&
4138 el
->defstate
== SS_PDEFINED
)
4140 el
->defstate
= SS_ALLOCATED
;
4141 el
->definfo
= stateInfo_update (el
->definfo
, e2
->definfo
);
4142 sRef_clearDerived (el
);
4144 else if ((el
->defstate
== SS_DEAD
|| sRef_isKept (el
)) &&
4145 (e2
->defstate
== SS_DEFINED
&& !sRef_isKept (e2
)))
4147 DPRINTF (("Checking dead: %s / %s", sRef_unparseFull (el
),
4148 sRef_unparseFull (e2
)));
4150 if (checkDeadState (el
, e2
, TRUE
, loc
))
4152 if (sRef_isThroughArrayFetch (el
))
4154 sRef_maybeKill (el
, loc
);
4155 sRef_maybeKill (e2
, loc
);
4159 else if ((e2
->defstate
== SS_DEAD
|| sRef_isKept (e2
)) &&
4160 (el
->defstate
== SS_DEFINED
&& !sRef_isKept (el
)))
4162 DPRINTF (("Checking dead: %s / %s", sRef_unparseFull (el
),
4163 sRef_unparseFull (e2
)));
4165 if (checkDeadState (e2
, el
, FALSE
, loc
))
4167 if (sRef_isThroughArrayFetch (el
))
4169 sRef_maybeKill (el
, loc
);
4170 sRef_maybeKill (e2
, loc
);
4174 else if (el
->defstate
== SS_DEFINED
&&
4175 e2
->defstate
== SS_PDEFINED
)
4177 DPRINTF (("set pdefined: %s", sRef_unparseFull (el
)));
4178 el
->defstate
= SS_PDEFINED
;
4179 el
->definfo
= stateInfo_update (el
->definfo
, e2
->definfo
);
4181 else if (e2
->defstate
== SS_DEFINED
&&
4182 el
->defstate
== SS_PDEFINED
)
4184 DPRINTF (("set pdefined: %s", sRef_unparseFull (e2
)));
4185 e2
->defstate
= SS_PDEFINED
;
4186 e2
->definfo
= stateInfo_update (e2
->definfo
, el
->definfo
);
4193 if (ctype_isUnion (ctype_realType (sRef_getType (el
))))
4195 el
->deriv
= sRef_mergeUnionDerivs (el
->deriv
, e2
->deriv
,
4200 el
->deriv
= sRef_mergeDerivs (el
->deriv
, e2
->deriv
, opt
, cl
, loc
);
4203 if (sRef_equivalent (el
, e2
))
4205 ret
= sRefSet_insert (ret
, el
);
4209 sRef sr
= sRef_leastCommon (el
, e2
);
4211 if (sRef_isReasonable (sr
))
4213 ret
= sRefSet_insert (ret
, sr
);
4221 (void) sRefSet_delete (other
, e2
);
4223 else /* not defined */
4225 DPRINTF (("Checking dead: %s", sRef_unparseFull (el
)));
4226 (void) checkDeadState (el
, e2
, TRUE
, loc
);
4229 } end_sRefSet_allElements
;
4231 sRefSet_allElements (other
, el
)
4233 if (sRef_isReasonable (el
))
4235 DPRINTF (("Checking dead: %s", sRef_unparseFull (el
)));
4236 (void) checkDeadState (el
, sRef_undefined
, FALSE
, loc
);
4238 } end_sRefSet_allElements
;
4245 ** Returns TRUE is there is an error.
4248 static bool checkDeadState (/*@notnull@*/ sRef el
, sRef e2
, bool tbranch
, fileloc loc
)
4251 ** usymtab_isGuarded --- the utab should still be in the
4252 ** state of the alternate branch.
4254 ** tbranch TRUE means el is released in the last branch, e.g.
4255 ** if (x != NULL) { ; } else { sfree (x); }
4256 ** so, if x is null in the other branch no error is reported.
4258 ** tbranch FALSE means this is the other branch:
4259 ** if (x != NULL) { sfree (x); } else { ; }
4260 ** so, if x is null in this branch there is no error.
4264 if ((sRef_isDead (el
) || sRef_isKept (el
))
4265 && !sRef_isDeepUnionField (el
)
4266 && !sRef_isThroughArrayFetch (el
))
4271 if (usymtab_isDefinitelyNullDeep (el
))
4278 if (usymtab_isAltDefinitelyNullDeep (el
))
4286 message ("Storage %q is %q in one path, but live in another.",
4288 cstring_makeLiteral (sRef_isKept (el
)
4289 ? "kept" : "released")),
4292 if (sRef_isKept (el
))
4294 sRef_showAliasInfo (el
);
4298 sRef_showStateInfo (el
);
4301 if (sRef_isValid (e2
))
4303 if (sRef_isKept (e2
))
4305 sRef_showAliasInfo (e2
);
4309 sRef_showStateInfo (e2
);
4313 /* prevent further errors */
4314 el
->defstate
= SS_UNKNOWN
;
4315 sRef_setAliasKind (el
, AK_ERROR
, fileloc_undefined
);
4324 checkDerivDeadState (/*@notnull@*/ sRef el
, bool tbranch
, fileloc loc
)
4326 if (checkDeadState (el
, sRef_undefined
, tbranch
, loc
))
4328 sRefSet_allElements (el
->deriv
, t
)
4330 if (sRef_isReasonable (t
))
4332 checkDerivDeadState (t
, tbranch
, loc
);
4334 } end_sRefSet_allElements
;
4339 sRef_mergePdefinedDerivs (sRefSet res
, sRefSet other
, bool opt
,
4340 clause cl
, fileloc loc
)
4342 sRefSet ret
= sRefSet_new ();
4344 sRefSet_allElements (res
, el
)
4346 if (sRef_isReasonable (el
))
4348 sRef e2
= sRefSet_lookupMember (other
, el
);
4350 if (sRef_isReasonable (e2
))
4352 if (sRef_isAllocated (el
) && !sRef_isAllocated (e2
))
4356 else if (sRef_isAllocated (e2
) && !sRef_isAllocated (el
))
4358 el
->deriv
= sRefSet_copyInto (el
->deriv
, e2
->deriv
);
4362 el
->deriv
= sRef_mergePdefinedDerivs (el
->deriv
, e2
->deriv
,
4366 sRef_mergeStateAux (el
, e2
, cl
, opt
, loc
, FALSE
);
4368 ret
= sRefSet_insert (ret
, el
);
4369 (void) sRefSet_delete (other
, e2
);
4375 checkDerivDeadState (el
, (cl
== FALSECLAUSE
), loc
);
4378 ret
= sRefSet_insert (ret
, el
);
4381 } end_sRefSet_allElements
;
4383 sRefSet_allElements (other
, el
)
4385 if (sRef_isReasonable (el
))
4387 if (!sRefSet_member (ret
, el
))
4389 /* was cl == FALSECLAUSE */
4390 checkDerivDeadState (el
, FALSE
, loc
);
4391 ret
= sRefSet_insert (ret
, el
);
4396 ** it's okay --- member is a different equality test
4400 } end_sRefSet_allElements
;
4406 sRef
sRef_makeConj (/*@exposed@*/ /*@returned@*/ sRef a
, /*@exposed@*/ sRef b
)
4408 llassert (sRef_isReasonable (a
));
4409 llassert (sRef_isReasonable (b
));
4411 if (!sRef_equivalent (a
, b
))
4413 sRef s
= sRef_newRef ();
4416 s
->info
= (sinfo
) dmalloc (sizeof (*s
->info
));
4417 s
->info
->conj
= (cjinfo
) dmalloc (sizeof (*s
->info
->conj
));
4418 s
->info
->conj
->a
= a
;
4419 s
->info
->conj
->b
= b
;
4421 if (ctype_equal (a
->type
, b
->type
)) s
->type
= a
->type
;
4422 else s
->type
= ctype_makeConj (a
->type
, b
->type
);
4424 if (a
->defstate
== b
->defstate
)
4426 s
->defstate
= a
->defstate
;
4427 s
->definfo
= stateInfo_update (s
->definfo
, a
->definfo
);
4428 s
->definfo
= stateInfo_update (s
->definfo
, b
->definfo
);
4432 s
->defstate
= SS_UNKNOWN
;
4435 sRef_setNullStateN (s
, NS_UNKNOWN
);
4437 s
->safe
= a
->safe
&& b
->safe
;
4438 s
->aliaskind
= alkind_resolve (a
->aliaskind
, b
->aliaskind
);
4440 llassert (valueTable_isUndefined (s
->state
));
4441 s
->state
= context_createValueTable (s
, stateInfo_makeLoc (g_currentloc
, SA_MERGED
));
4446 /*@-exposetrans@*/ return a
; /*@=exposetrans@*/
4450 /*@dependent@*/ sRef
4451 sRef_makeUnknown (void)
4453 sRef s
= sRef_new ();
4455 s
->kind
= SK_UNKNOWN
;
4459 static /*@owned@*/ /*@notnull@*/ sRef
4460 sRef_makeSpecial (speckind sk
) /*@*/
4462 sRef s
= sRef_new ();
4464 s
->kind
= SK_SPECIAL
;
4465 s
->info
= (sinfo
) dmalloc (sizeof (*s
->info
));
4467 /*@-dependenttrans@*/
4469 /*@=dependenttrans@*/
4472 static /*@owned@*/ sRef srnothing
= sRef_undefined
;
4473 static /*@owned@*/ sRef srinternal
= sRef_undefined
;
4474 static /*@owned@*/ sRef srsystem
= sRef_undefined
;
4475 static /*@owned@*/ sRef srspec
= sRef_undefined
;
4477 /*@dependent@*/ sRef
4478 sRef_makeNothing (void)
4480 if (sRef_isInvalid (srnothing
))
4482 srnothing
= sRef_makeSpecial (SR_NOTHING
);
4489 sRef_makeInternalState (void)
4491 if (sRef_isInvalid (srinternal
))
4493 srinternal
= sRef_makeSpecial (SR_INTERNAL
);
4500 sRef_makeSpecState (void)
4502 if (sRef_isInvalid (srspec
))
4504 srspec
= sRef_makeSpecial (SR_SPECSTATE
);
4511 sRef_makeSystemState (void)
4513 if (sRef_isInvalid (srsystem
))
4515 srsystem
= sRef_makeSpecial (SR_SYSTEM
);
4522 sRef_makeGlobalMarker (void)
4524 sRef s
= sRef_makeSpecial (SR_GLOBALMARKER
);
4525 llassert (valueTable_isUndefined (s
->state
));
4526 s
->state
= context_createGlobalMarkerValueTable (stateInfo_undefined
);
4531 sRef_makeResult (ctype c
)
4533 sRef s
= sRef_newRef ();
4535 s
->kind
= SK_RESULT
;
4537 s
->defstate
= SS_UNKNOWN
;
4538 s
->aliaskind
= AK_UNKNOWN
;
4539 sRef_setNullStateN (s
, NS_UNKNOWN
);
4540 llassert (valueTable_isUndefined (s
->state
));
4541 s
->state
= context_createValueTable (s
, stateInfo_makeLoc (g_currentloc
, SA_DECLARED
));
4543 DPRINTF (("Result: [%p] %s", s
, sRef_unparseFull (s
)));
4549 sRef_isNothing (sRef s
)
4551 return (sRef_isKindSpecial (s
) && s
->info
->spec
== SR_NOTHING
);
4555 sRef_isInternalState (sRef s
)
4557 return (sRef_isKindSpecial (s
) && s
->info
->spec
== SR_INTERNAL
);
4561 sRef_isSpecInternalState (sRef s
)
4563 return (sRef_isKindSpecial (s
)
4564 && (s
->info
->spec
== SR_INTERNAL
|| s
->info
->spec
== SR_SPECSTATE
));
4568 sRef_isSpecState (sRef s
)
4570 return (sRef_isKindSpecial (s
) && s
->info
->spec
== SR_SPECSTATE
);
4574 sRef_isResult (sRef s
)
4576 return (sRef_isReasonable (s
) && s
->kind
== SK_RESULT
);
4580 sRef_isSystemState (sRef s
)
4582 return (sRef_isKindSpecial (s
) && s
->info
->spec
== SR_SYSTEM
);
4586 sRef_isGlobalMarker (sRef s
)
4588 return (sRef_isKindSpecial (s
) && s
->info
->spec
== SR_GLOBALMARKER
);
4592 sRef_getScopeIndex (sRef s
)
4594 llassert (sRef_isReasonable (s
));
4595 llassert (sRef_isCvar (s
));
4597 return (s
->info
->cvar
->index
);
4601 sRef_makeSafe (sRef s
)
4603 if (sRef_isReasonable (s
))
4610 sRef_makeUnsafe (sRef s
)
4612 if (sRef_isReasonable (s
))
4619 ** memory state operations
4622 /*@only@*/ cstring
sRef_unparseFull (sRef s
)
4624 if (sRef_isInvalid (s
)) return (cstring_undefined
);
4626 return (message ("[%p] %q - %q { %q } [%s] { %q } < %q >",
4628 sRef_unparseDebug (s
),
4629 sRef_unparseState (s
),
4630 stateInfo_unparse (s
->definfo
),
4631 exkind_unparse (s
->oexpkind
),
4632 sRefSet_unparseDebug (s
->deriv
),
4633 valueTable_unparse (s
->state
)));
4637 cstring
sRef_unparseDeep (sRef s
)
4639 cstring st
= cstring_undefined
;
4641 st
= message ("%q:", sRef_unparseFull (s
));
4643 if (sRef_isReasonable (s
))
4645 sRefSet_allElements (s
->deriv
, el
)
4647 st
= message("%q\n%q", st
, sRef_unparseDeep (el
));
4648 } end_sRefSet_allElements
;
4655 /*@only@*/ cstring
sRef_unparseState (sRef s
)
4657 if (sRef_isConj (s
))
4659 return (message ("%q | %q",
4660 sRef_unparseState (s
->info
->conj
->a
),
4661 sRef_unparseState (s
->info
->conj
->b
)));
4664 if (sRef_isInvalid (s
))
4666 return (cstring_makeLiteral ("<invalid>"));
4669 return (message ("%s.%s.%s.%s",
4670 alkind_unparse (s
->aliaskind
),
4671 nstate_unparse (sRef_getNullState (s
)),
4672 exkind_unparse (s
->expkind
),
4673 sstate_unparse (s
->defstate
)));
4676 bool sRef_isNotUndefined (sRef s
)
4678 return (sRef_isInvalid (s
)
4679 || (s
->defstate
!= SS_UNDEFINED
4680 && s
->defstate
!= SS_UNUSEABLE
4681 && s
->defstate
!= SS_DEAD
));
4684 ynm
sRef_isWriteable (sRef s
)
4686 if (sRef_isInvalid (s
)) return MAYBE
;
4688 if (sRef_isConj (s
) && s
->defstate
== SS_UNKNOWN
)
4690 if (ynm_toBoolStrict (sRef_isWriteable (sRef_getConjA (s
))))
4692 if (ynm_toBoolStrict (sRef_isWriteable (sRef_getConjB (s
))))
4700 if (ynm_toBoolStrict (sRef_isWriteable (sRef_getConjB (s
))))
4708 return (ynm_fromBool (s
->defstate
!= SS_UNUSEABLE
));
4711 bool sRef_hasNoStorage (sRef s
)
4713 return (!sRef_isAllocatedStorage (s
) || sRef_isDefinitelyNull (s
));
4716 bool sRef_isStrictReadable (sRef s
)
4718 return (ynm_toBoolStrict (sRef_isValidLvalue (s
)));
4722 ** Is this what is does?
4723 ** Returns YES if s can be used as an rvalue,
4724 ** MAYBE if its not clear
4725 ** NO if s cannot be safely used as an rvalue.
4728 ynm
sRef_isValidLvalue (sRef s
)
4732 if (sRef_isInvalid (s
)) return YES
;
4736 if (sRef_isConj (s
) && s
->defstate
== SS_UNKNOWN
)
4738 if (ynm_toBoolStrict (sRef_isValidLvalue (sRef_getConjA (s
))))
4740 if (ynm_toBoolStrict (sRef_isValidLvalue (sRef_getConjB (s
))))
4748 if (ynm_toBoolStrict (sRef_isValidLvalue (sRef_getConjB (s
))))
4755 else if (ss
== SS_HOFFA
)
4757 if (context_getFlag (FLG_STRICTUSERELEASED
))
4768 return (ynm_fromBool (ss
== SS_DEFINED
4771 || ss
== SS_PDEFINED
4774 || ss
== SS_ALLOCATED
4775 || ss
== SS_KILLED
/* evans 2001-05-26: added this for killed globals */
4776 || ss
== SS_UNKNOWN
));
4780 static /*@exposed@*/ sRef
whatUndefined (/*@exposed@*/ sRef fref
, int depth
)
4785 if (depth
> MAXDEPTH
)
4788 ("Warning: check definition limit exceeded, checking %q. "
4789 "This either means there is a variable with at least "
4790 "%d indirections apparent in the program text, or "
4791 "there is a bug in Splint.",
4792 sRef_unparse (fref
),
4796 return sRef_undefined
;
4799 if (!sRef_isKnown (fref
) || sRef_isAnyDefined (fref
))
4801 return sRef_undefined
;
4804 if (sRef_isUnuseable (fref
) || sRef_isStateUndefined (fref
))
4809 ct
= ctype_realType (sRef_getType (fref
));
4811 if (ctype_isUnknown (ct
))
4813 return sRef_undefined
;
4815 else if (ctype_isPointer (ct
) || ctype_isArray (ct
))
4817 if (sRef_isStateUnknown (fref
))
4819 return sRef_undefined
;
4823 sRef fptr
= sRef_constructDeref (fref
);
4825 return (whatUndefined (fptr
, depth
+ 1));
4828 else if (ctype_isStruct (ct
))
4830 if (sRef_isStateUnknown (fref
))
4835 if (sRef_isPdefined (fref
) || sRef_isAnyDefined (fref
))
4837 sRefSet_realElements (sRef_derivedFields (fref
), sr
)
4839 if (sRef_isField (sr
))
4841 cstring fieldname
= sRef_getField (sr
);
4842 sRef fldref
= sRef_makeField (fref
, fieldname
);
4843 bool shouldCheck
= !sRef_isRecursiveField (fldref
);
4847 sRef wdef
= whatUndefined (fldref
, depth
+ 1);
4849 if (sRef_isReasonable (wdef
))
4855 } end_sRefSet_realElements
;
4857 else if (sRef_isAllocated (fref
))
4860 ** for structures, each field must be completely defined
4863 uentryList fields
= ctype_getFields (ct
);
4865 uentryList_elements (fields
, ue
)
4867 cstring name
= uentry_getRealName (ue
);
4868 sRef ffield
= sRef_makeField (fref
, name
);
4869 bool shouldCheck
= !sRef_isRecursiveField (ffield
);
4871 if (sRef_isRelDef (uentry_getSref (ue
)))
4879 sRef wdef
= whatUndefined (ffield
, depth
+ 1);
4881 if (sRef_isInvalid (wdef
))
4887 } end_uentryList_elements
;
4894 else if (ctype_isUnion (ct
))
4903 return sRef_undefined
;
4906 static bool checkDefined (/*@temp@*/ sRef sr
)
4908 /*@-temptrans@*/ /* the result from whatUndefined is lost */
4909 return (sRef_isInvalid (whatUndefined (sr
, 0)));
4913 bool sRef_isReallyDefined (sRef s
)
4915 if (sRef_isReasonable (s
))
4917 if (sRef_isAnyDefined (s
))
4923 if (sRef_isAllocated (s
) || sRef_isPdefined (s
))
4925 return checkDefined (s
);
4939 void sRef_showNotReallyDefined (sRef s
)
4941 if (sRef_isReasonable (s
))
4943 if (sRef_isAnyDefined (s
))
4949 if (sRef_isAllocated (s
) || sRef_isPdefined (s
))
4951 /*@-temptrans@*/ /* the result of whatUndefined is lost */
4952 sRef ref
= whatUndefined (s
, 0);
4954 llassert (sRef_isReasonable (ref
));
4959 (message ("This sub-reference is %s: %q",
4960 sstate_unparse (sRef_getDefState (ref
)),
4961 sRef_unparse (ref
)));
4976 sstate
sRef_getDefState (sRef s
)
4978 if (sRef_isInvalid (s
)) return (SS_UNKNOWN
);
4979 return (s
->defstate
);
4982 void sRef_setDefState (sRef s
, sstate defstate
, fileloc loc
)
4984 sRef_checkMutable (s
);
4985 sRef_setStateAux (s
, defstate
, loc
);
4988 static void sRef_clearAliasStateAux (sRef s
, fileloc loc
)
4990 sRef_checkMutable (s
);
4991 sRef_setAliasKind (s
, AK_ERROR
, loc
);
4994 void sRef_clearAliasState (sRef s
, fileloc loc
)
4996 sRef_checkMutable (s
);
4997 sRef_aliasSetComplete (sRef_clearAliasStateAux
, s
, loc
);
5000 void sRef_setAliasKindComplete (sRef s
, alkind kind
, fileloc loc
)
5002 sRef_checkMutable (s
);
5003 sRef_aliasSetCompleteAlkParam (sRef_setAliasKind
, s
, kind
, loc
);
5006 void sRef_setAliasKind (sRef s
, alkind kind
, fileloc loc
)
5008 sRef_checkMutable (s
);
5010 if (sRef_isReasonable (s
))
5012 sRef_clearDerived (s
);
5014 if ((kind
!= s
->aliaskind
&& kind
!= s
->oaliaskind
)
5015 && fileloc_isDefined (loc
))
5017 s
->aliasinfo
= stateInfo_updateLoc (s
->aliasinfo
, stateAction_fromAlkind (kind
), loc
);
5020 s
->aliaskind
= kind
;
5024 void sRef_setOrigAliasKind (sRef s
, alkind kind
)
5026 sRef_checkMutable (s
);
5028 if (sRef_isReasonable (s
))
5030 s
->oaliaskind
= kind
;
5034 exkind
sRef_getExKind (sRef s
)
5036 if (sRef_isReasonable (s
))
5038 return (s
->expkind
);
5046 exkind
sRef_getOrigExKind (sRef s
)
5048 if (sRef_isReasonable (s
))
5050 return (s
->oexpkind
);
5058 static void sRef_clearExKindAux (sRef s
, fileloc loc
)
5060 sRef_checkMutable (s
);
5061 sRef_setExKind (s
, XO_UNKNOWN
, loc
);
5064 void sRef_setObserver (sRef s
, fileloc loc
)
5066 sRef_checkMutable (s
);
5067 sRef_setExKind (s
, XO_OBSERVER
, loc
);
5070 void sRef_setExposed (sRef s
, fileloc loc
)
5072 sRef_checkMutable (s
);
5073 sRef_setExKind (s
, XO_EXPOSED
, loc
);
5076 void sRef_clearExKindComplete (sRef s
, fileloc loc
)
5078 (void) sRef_aliasSetComplete (sRef_clearExKindAux
, s
, loc
);
5081 void sRef_setExKind (sRef s
, exkind exp
, fileloc loc
)
5083 sRef_checkMutable (s
);
5085 if (sRef_isReasonable (s
))
5087 if (s
->expkind
!= exp
)
5089 s
->expinfo
= stateInfo_updateLoc (s
->expinfo
, stateAction_fromExkind (exp
), loc
);
5097 ** s1->derived = s2->derived
5100 static void sRef_copyRealDerived (sRef s1
, sRef s2
)
5102 DPRINTF (("Copy real: %s / %s", sRef_unparse (s1
), sRef_unparse (s2
)));
5103 sRef_checkMutable (s1
);
5105 if (sRef_isReasonable (s1
) && sRef_isReasonable (s2
))
5107 sRef sb
= sRef_getRootBase (s1
);
5109 sRefSet_clear (s1
->deriv
);
5111 sRefSet_allElements (s2
->deriv
, el
)
5113 if (sRef_isReasonable (el
))
5115 sRef rb
= sRef_getRootBase (el
);
5117 if (!sRef_same (rb
, sb
))
5119 sRef fb
= sRef_fixDirectBase (el
, s1
);
5121 if (sRef_isReasonable (fb
))
5123 sRef_copyRealDerived (fb
, el
);
5124 sRef_addDeriv (s1
, fb
);
5129 sRef_addDeriv (s1
, el
);
5132 } end_sRefSet_allElements
;
5137 void sRef_copyRealDerivedComplete (sRef s1
, sRef s2
)
5139 sRef_innerAliasSetCompleteParam (sRef_copyRealDerived
, s1
, s2
);
5142 void sRef_setUndefined (sRef s
, fileloc loc
)
5144 sRef_checkMutable (s
);
5146 if (sRef_isReasonable (s
))
5148 s
->defstate
= SS_UNDEFINED
;
5149 s
->definfo
= stateInfo_updateLoc (s
->definfo
, SA_UNDEFINED
, loc
);
5151 sRef_clearDerived (s
);
5155 static void sRef_setDefinedAux (sRef s
, fileloc loc
, bool clear
)
5157 sRef_checkMutable (s
);
5158 if (sRef_isInvalid (s
)) return;
5160 DPRINTF (("Set defined: %s", sRef_unparseFull (s
)));
5162 s
->definfo
= stateInfo_updateLoc (s
->definfo
, SA_DEFINED
, loc
);
5163 s
->defstate
= SS_DEFINED
;
5165 DPRINTF (("Set defined: %s", sRef_unparseFull (s
)));
5167 /* e.g., if x is allocated, *x = 3 defines x */
5169 if (s
->kind
== SK_PTR
)
5171 sRef p
= s
->info
->ref
;
5174 if (p
->defstate
== SS_ALLOCATED
5175 || p
->defstate
== SS_SPECIAL
) /* evans 2001-07-12: shouldn't need this */
5177 sRef_setDefinedAux (p
, loc
, clear
);
5181 ** Defines a[0] also:
5184 arr
= sRef_findDerivedArrayFetch (p
, FALSE
, 0, FALSE
);
5186 if (sRef_isReasonable (arr
))
5188 sRef_setDefinedAux (arr
, loc
, clear
);
5191 else if (s
->kind
== SK_ARRAYFETCH
)
5193 if (!s
->info
->arrayfetch
->indknown
5194 || (s
->info
->arrayfetch
->ind
== 0))
5196 sRef p
= s
->info
->arrayfetch
->arr
;
5197 sRef ptr
= sRef_constructPointer (p
);
5199 if (sRef_isReasonable (ptr
))
5201 if (ptr
->defstate
== SS_ALLOCATED
5202 || ptr
->defstate
== SS_UNDEFINED
5203 || ptr
->defstate
== SS_SPECIAL
) /* evans 2001-07-12: shouldn't need this */
5205 sRef_setDefinedAux (ptr
, loc
, clear
);
5209 if (p
->defstate
== SS_RELDEF
)
5213 else if (p
->defstate
== SS_ALLOCATED
|| p
->defstate
== SS_PDEFINED
5214 || p
->defstate
== SS_SPECIAL
) /* evans 2001-07-12: shouldn't need this */
5216 p
->defstate
= SS_DEFINED
;
5223 else if (s
->kind
== SK_FIELD
)
5225 sRef parent
= s
->info
->field
->rec
;
5227 if (sRef_isReasonable (parent
))
5229 if (ctype_isUnion (ctype_realType (parent
->type
)))
5232 ** Should not clear derived from here.
5235 sRef_setDefinedNoClear (parent
, loc
);
5239 ; /* Nothing to do for structures. */
5251 sRef_clearDerived (s
);
5255 /* evans 2001-07-12: need to define the derived references */
5256 sRefSet_elements (s
->deriv
, el
)
5258 llassert (sRef_isReasonable (el
));
5259 el
->defstate
= SS_DEFINED
;
5260 } end_sRefSet_elements
;
5263 DPRINTF (("Set defined: %s", sRef_unparseFull (s
)));
5266 static void sRef_setPartialDefined (sRef s
, fileloc loc
)
5268 sRef_checkMutable (s
);
5270 if (!sRef_isPartial (s
))
5272 sRef_setDefined (s
, loc
);
5276 void sRef_setPartialDefinedComplete (sRef s
, fileloc loc
)
5278 sRef_innerAliasSetComplete (sRef_setPartialDefined
, s
, loc
);
5281 void sRef_setDefinedComplete (sRef s
, fileloc loc
)
5283 sRef_innerAliasSetComplete (sRef_setDefined
, s
, loc
);
5286 void sRef_setDefinedCompleteDirect (sRef s
, fileloc loc
)
5290 aliases
= usymtab_allAliases (s
);
5291 DPRINTF (("Set defined complete: %s", sRef_unparseFull (s
)));
5292 DPRINTF (("All aliases: %s", sRefSet_unparseFull (aliases
)));
5294 sRef_setDefined (s
, loc
);
5296 sRefSet_realElements (aliases
, current
)
5298 if (sRef_isReasonable (current
))
5300 current
= sRef_updateSref (current
);
5301 sRef_setDefined (current
, loc
);
5303 } end_sRefSet_realElements
;
5305 sRefSet_free (aliases
);
5306 sRef_innerAliasSetComplete (sRef_setDefined
, s
, loc
);
5309 void sRef_setDefined (sRef s
, fileloc loc
)
5311 sRef_checkMutable (s
);
5312 sRef_setDefinedAux (s
, loc
, TRUE
);
5315 static void sRef_setDefinedNoClear (sRef s
, fileloc loc
)
5317 sRef_checkMutable (s
);
5318 DPRINTF (("Defining: %s", sRef_unparseFull (s
)));
5319 sRef_setDefinedAux (s
, loc
, FALSE
);
5320 DPRINTF (("==> %s", sRef_unparseFull (s
)));
5323 void sRef_setDefinedNCComplete (sRef s
, fileloc loc
)
5325 sRef_checkMutable (s
);
5326 DPRINTF (("Set Defined Complete: %s", sRef_unparseFull (s
)));
5327 sRef_innerAliasSetComplete (sRef_setDefinedNoClear
, s
, loc
);
5328 DPRINTF (("==> %s", sRef_unparseFull (s
)));
5331 static bool sRef_isDeepUnionField (sRef s
)
5333 return (sRef_deepPred (sRef_isUnionField
, s
));
5336 bool sRef_isUnionField (sRef s
)
5338 if (sRef_isReasonable (s
) && s
->kind
== SK_FIELD
)
5341 ** defining one field of a union defines the union
5344 sRef base
= s
->info
->field
->rec
;
5346 if (sRef_isReasonable (base
))
5348 return (ctype_isUnion (ctype_realType (base
->type
)));
5355 void sRef_setPdefined (sRef s
, fileloc loc
)
5357 sRef_checkMutable (s
);
5358 if (sRef_isReasonable (s
) && !sRef_isPartial (s
))
5360 sRef base
= sRef_getBaseSafe (s
);
5362 if (s
->defstate
== SS_ALLOCATED
)
5367 s
->definfo
= stateInfo_updateLoc (s
->definfo
, SA_PDEFINED
, loc
);
5368 s
->defstate
= SS_PDEFINED
;
5370 /* e.g., if x is allocated, *x = 3 defines x */
5372 while (sRef_isReasonable (base
) && sRef_isKnown (base
))
5374 if (base
->defstate
== SS_DEFINED
)
5378 DPRINTF (("set pdefined: %s", sRef_unparseFull (base
)));
5379 base
->defstate
= SS_PDEFINED
;
5380 nb
= sRef_getBaseSafe (base
);
5391 static void sRef_setStateAux (sRef s
, sstate ss
, fileloc loc
)
5393 sRef_checkMutable (s
);
5395 DPRINTF (("Set state: %s => %s", sRef_unparseFull (s
), sstate_unparse (ss
)));
5397 if (sRef_isReasonable (s
))
5399 /* if (s->defstate == SS_RELDEF) return; */
5401 if (s
->defstate
!= ss
&& fileloc_isDefined (loc
))
5403 s
->definfo
= stateInfo_updateLoc (s
->definfo
,
5404 stateAction_fromSState (ss
), loc
);
5408 sRef_clearDerived (s
);
5410 if (ss
== SS_ALLOCATED
)
5412 sRef base
= sRef_getBaseSafe (s
);
5414 while (sRef_isReasonable (base
) && sRef_isKnown (base
))
5416 if (base
->defstate
== SS_DEFINED
)
5420 DPRINTF (("set pdefined: %s", sRef_unparseFull (s
)));
5421 base
->defstate
= SS_PDEFINED
;
5422 nb
= sRef_getBaseSafe (base
);
5434 void sRef_setAllocatedComplete (sRef s
, fileloc loc
)
5436 sRef_innerAliasSetComplete (sRef_setAllocated
, s
, loc
);
5439 static void sRef_setAllocatedShallow (sRef s
, fileloc loc
)
5441 sRef_checkMutable (s
);
5443 if (sRef_isReasonable (s
))
5445 if (s
->defstate
== SS_DEAD
|| s
->defstate
== SS_UNDEFINED
)
5447 s
->defstate
= SS_ALLOCATED
;
5448 s
->definfo
= stateInfo_updateLoc (s
->definfo
, SA_ALLOCATED
, loc
);
5453 void sRef_setAllocatedShallowComplete (sRef s
, fileloc loc
)
5455 sRef_innerAliasSetComplete (sRef_setAllocatedShallow
, s
, loc
);
5458 void sRef_setAllocated (sRef s
, fileloc loc
)
5460 sRef_checkMutable (s
);
5461 sRef_setStateAux (s
, SS_ALLOCATED
, loc
);
5464 void sRef_setPartial (sRef s
, fileloc loc
)
5466 sRef_checkMutable (s
);
5467 sRef_setStateAux (s
, SS_PARTIAL
, loc
);
5470 void sRef_setShared (sRef s
, fileloc loc
)
5472 sRef_checkMutable (s
);
5474 if (sRef_isReasonable (s
))
5476 if (s
->aliaskind
!= AK_SHARED
&& fileloc_isDefined (loc
))
5478 s
->aliasinfo
= stateInfo_updateLoc (s
->aliasinfo
, SA_SHARED
, loc
);
5481 s
->aliaskind
= AK_SHARED
;
5482 /* don't! sRef_clearDerived (s); */
5486 void sRef_setLastReference (sRef s
, /*@exposed@*/ sRef ref
, fileloc loc
)
5488 sRef_checkMutable (s
);
5490 if (sRef_isReasonable (s
))
5492 s
->aliaskind
= sRef_getAliasKind (ref
);
5493 s
->aliasinfo
= stateInfo_updateRefLoc (s
->aliasinfo
, ref
, stateAction_fromAlkind (s
->aliaskind
), loc
);
5498 void sRef_setNullStateAux (/*@notnull@*/ sRef s
, nstate ns
, fileloc loc
)
5500 sRef_checkMutable (s
);
5502 sRef_resetAliasKind (s
);
5504 if (fileloc_isDefined (loc
))
5506 s
->nullinfo
= stateInfo_updateLoc (s
->nullinfo
, stateAction_fromNState (ns
), loc
);
5510 void sRef_setNotNull (sRef s
, fileloc loc
)
5512 if (sRef_isReasonable (s
))
5514 sRef_setNullStateAux (s
, NS_NOTNULL
, loc
);
5518 void sRef_setNullStateN (sRef s
, nstate n
)
5520 if (sRef_isReasonable (s
))
5522 sRef_checkMutable (s
);
5524 DPRINTF (("Set null state ==> %s", sRef_unparseFull (s
)));
5525 sRef_resetAliasKind (s
);
5529 void sRef_setNullState (sRef s
, nstate n
, fileloc loc
)
5531 if (sRef_isReasonable (s
))
5533 sRef_setNullStateAux (s
, n
, loc
);
5538 void sRef_setNullTerminatedStateInnerComplete (sRef s
, struct s_bbufinfo b
, /*@unused@*/ fileloc loc
)
5540 switch (b
.bufstate
) {
5541 case BB_NULLTERMINATED
:
5542 sRef_setNullTerminatedState (s
);
5543 sRef_setLen (s
, b
.len
);
5545 case BB_POSSIBLYNULLTERMINATED
:
5546 sRef_setPossiblyNullTerminatedState(s
);
5548 case BB_NOTNULLTERMINATED
:
5549 sRef_setNotNullTerminatedState (s
);
5553 sRef_setSize (s
, b
.size
);
5555 /* PL: TO BE DONE : Aliases are not modified right now, have to be similar to
5556 * setNullStateInnerComplete.
5559 # endif /* DEADCODE */
5561 void sRef_setNullStateInnerComplete (sRef s
, nstate n
, fileloc loc
)
5563 DPRINTF (("Set null state: %s", nstate_unparse (n
)));
5565 sRef_setNullState (s
, n
, loc
);
5570 sRef_innerAliasSetComplete (sRef_setPosNull
, s
, loc
);
5573 sRef_innerAliasSetComplete (sRef_setDefNull
, s
, loc
);
5576 sRef_innerAliasSetComplete (sRef_setNullUnknown
, s
, loc
);
5579 sRef_innerAliasSetComplete (sRef_setNotNull
, s
, loc
);
5582 sRef_innerAliasSetComplete (sRef_setNotNull
, s
, loc
);
5585 sRef_innerAliasSetComplete (sRef_setNullUnknown
, s
, loc
);
5588 sRef_innerAliasSetComplete (sRef_setDefNull
, s
, loc
);
5591 sRef_innerAliasSetComplete (sRef_setNullUnknown
, s
, loc
);
5594 sRef_innerAliasSetComplete (sRef_setNullErrorLoc
, s
, loc
);
5599 void sRef_setPosNull (sRef s
, fileloc loc
)
5601 if (sRef_isReasonable (s
))
5603 sRef_setNullStateAux (s
, NS_POSNULL
, loc
);
5607 void sRef_setDefNull (sRef s
, fileloc loc
)
5609 if (sRef_isReasonable (s
))
5611 sRef_setNullStateAux (s
, NS_DEFNULL
, loc
);
5615 void sRef_setNullUnknown (sRef s
, fileloc loc
)
5617 if (sRef_isReasonable (s
))
5619 sRef_setNullStateAux (s
, NS_UNKNOWN
, loc
);
5623 void sRef_setNullError (sRef s
)
5625 if (sRef_isReasonable (s
) && !sRef_isConst (s
))
5627 sRef_setNullStateAux (s
, NS_UNKNOWN
, fileloc_undefined
);
5631 void sRef_setNullErrorLoc (sRef s
, fileloc loc
)
5633 if (sRef_isReasonable (s
) && !sRef_isConst (s
))
5635 sRef_setNullStateAux (s
, NS_UNKNOWN
, loc
);
5639 void sRef_setOnly (sRef s
, fileloc loc
)
5641 if (sRef_isReasonable (s
) && s
->aliaskind
!= AK_ONLY
)
5643 sRef_checkMutable (s
);
5644 s
->aliaskind
= AK_ONLY
;
5645 s
->aliasinfo
= stateInfo_updateLoc (s
->aliasinfo
, SA_ONLY
, loc
);
5649 void sRef_setDependent (sRef s
, fileloc loc
)
5651 if (sRef_isReasonable (s
) && !sRef_isConst (s
) && (s
->aliaskind
!= AK_DEPENDENT
))
5653 sRef_checkMutable (s
);
5654 DPRINTF (("Setting dependent: %s", sRef_unparseFull (s
)));
5655 s
->aliaskind
= AK_DEPENDENT
;
5656 s
->aliasinfo
= stateInfo_updateLoc (s
->aliasinfo
, SA_DEPENDENT
, loc
);
5660 void sRef_setOwned (sRef s
, fileloc loc
)
5662 if (sRef_isReasonable (s
) && !sRef_isConst (s
) && (s
->aliaskind
!= AK_OWNED
))
5664 sRef_checkMutable (s
);
5665 s
->aliaskind
= AK_OWNED
;
5666 s
->aliasinfo
= stateInfo_updateLoc (s
->aliasinfo
, SA_OWNED
, loc
);
5670 void sRef_setKept (sRef s
, fileloc loc
)
5672 if (sRef_isReasonable (s
) && !sRef_isConst (s
) && (s
->aliaskind
!= AK_KEPT
))
5674 sRef base
= sRef_getBaseSafe (s
);
5676 while (sRef_isReasonable (base
) && sRef_isKnown (base
))
5678 if (base
->defstate
== SS_DEFINED
)
5680 sRef_checkMutable (base
);
5681 base
->defstate
= SS_PDEFINED
;
5682 base
= sRef_getBaseSafe (base
);
5690 sRef_checkMutable (s
);
5691 s
->aliaskind
= AK_KEPT
;
5692 s
->aliasinfo
= stateInfo_updateLoc (s
->aliasinfo
, SA_KEPT
, loc
);
5696 static void sRef_setKeptAux (sRef s
, fileloc loc
)
5698 if (!sRef_isShared (s
))
5700 sRef_setKept (s
, loc
);
5704 static void sRef_setDependentAux (sRef s
, fileloc loc
)
5706 if (!sRef_isShared (s
))
5708 sRef_setDependent (s
, loc
);
5712 void sRef_setKeptComplete (sRef s
, fileloc loc
)
5714 sRef_aliasSetComplete (sRef_setKeptAux
, s
, loc
);
5717 void sRef_setDependentComplete (sRef s
, fileloc loc
)
5719 sRef_aliasSetComplete (sRef_setDependentAux
, s
, loc
);
5722 void sRef_setFresh (sRef s
, fileloc loc
)
5724 if (sRef_isReasonable (s
) && !sRef_isConst (s
))
5726 sRef_checkMutable (s
);
5727 s
->aliaskind
= AK_FRESH
;
5728 s
->aliasinfo
= stateInfo_updateLoc (s
->aliasinfo
, SA_CREATED
, loc
);
5729 DPRINTF (("SetFresh: %s", sRef_unparseFull (s
)));
5733 void sRef_kill (sRef s
, fileloc loc
)
5735 DPRINTF (("Kill: %s", sRef_unparseFull (s
)));
5737 if (sRef_isReasonable (s
) && !sRef_isShared (s
) && !sRef_isConst (s
))
5739 sRef base
= sRef_getBaseSafe (s
);
5740 sRef_checkMutable (s
);
5742 while (sRef_isReasonable (base
) && sRef_isKnown (base
))
5744 if (base
->defstate
== SS_DEFINED
)
5746 sRef_checkMutable (base
);
5747 base
->defstate
= SS_PDEFINED
;
5748 base
= sRef_getBaseSafe (base
);
5756 s
->aliaskind
= s
->oaliaskind
;
5757 s
->defstate
= SS_DEAD
;
5758 s
->definfo
= stateInfo_updateLoc (s
->definfo
, SA_KILLED
, loc
);
5759 DPRINTF (("State info: %s", stateInfo_unparse (s
->definfo
)));
5760 sRef_clearDerived (s
);
5764 void sRef_maybeKill (sRef s
, fileloc loc
)
5766 if (sRef_isReasonable (s
))
5768 sRef base
= sRef_getBaseSafe (s
);
5769 sRef_checkMutable (s
);
5771 while (sRef_isReasonable (base
) && sRef_isKnown (base
))
5773 if (base
->defstate
== SS_DEFINED
|| base
->defstate
== SS_RELDEF
)
5775 sRef_checkMutable (base
);
5776 base
->defstate
= SS_PDEFINED
;
5777 base
= sRef_getBaseSafe (base
);
5786 s
->aliaskind
= s
->oaliaskind
;
5787 s
->defstate
= SS_HOFFA
;
5788 s
->definfo
= stateInfo_updateLoc (s
->definfo
, SA_PKILLED
, loc
);
5789 DPRINTF (("State info: %s / %s", sRef_unparse (s
),
5790 stateInfo_unparse (s
->definfo
)));
5791 sRef_clearDerived (s
);
5797 ** just for type checking...
5800 static void sRef_killAux (sRef s
, fileloc loc
)
5802 if (sRef_isReasonable (s
) && !sRef_isShared (s
))
5804 if (sRef_isUnknownArrayFetch (s
))
5806 sRef_maybeKill (s
, loc
);
5816 ** kills s and all aliases to s
5819 void sRef_killComplete (sRef s
, fileloc loc
)
5821 DPRINTF (("Kill complete: %s", sRef_unparseFull (s
)));
5822 sRef_aliasSetComplete (sRef_killAux
, s
, loc
);
5825 static bool sRef_equivalent (sRef s1
, sRef s2
)
5827 return (sRef_compare (s1
, s2
) == 0);
5831 ** returns an sRef that will not be free'd on function exit.
5834 /*@only@*/ sRef
sRef_saveCopy (sRef s
)
5838 if (sRef_isReasonable (s
))
5840 bool old
= inFunction
;
5843 ** Exit the function scope, so this sRef is not
5844 ** stored in the deallocation table.
5848 DPRINTF (("Copying sref: %s", sRef_unparseFull(s
)));
5849 ret
= sRef_copy (s
);
5850 DPRINTF (("Copying ===>: %s", sRef_unparseFull(ret
)));
5855 ret
= sRef_undefined
;
5858 /*@-dependenttrans@*/
5860 /*@=dependenttrans@*/
5863 sRef
sRef_copy (sRef s
)
5865 if (sRef_isKindSpecial (s
) && !sRef_isGlobalMarker (s
))
5868 return s
; /* don't copy specials (except for global markers) */
5872 if (sRef_isReasonable (s
))
5874 sRef t
= sRef_alloc ();
5876 DPRINTF (("Copying: [%p] %s", s
, sRef_unparse (s
)));
5877 DPRINTF (("Full: %s", sRef_unparseFull (s
)));
5881 t
->modified
= s
->modified
;
5882 t
->immut
= FALSE
; /* Note mutability is not copied. */
5884 t
->val
= multiVal_copy (s
->val
);
5886 t
->info
= sinfo_copy (s
);
5887 t
->defstate
= s
->defstate
;
5888 t
->nullstate
= s
->nullstate
;
5889 DPRINTF (("Set null state==> %s", sRef_unparseFull (t
)));
5892 /* start modifications */
5893 t
->bufinfo
.bufstate
= s
->bufinfo
.bufstate
;
5894 t
->bufinfo
.len
= s
->bufinfo
.len
;
5895 t
->bufinfo
.size
= s
->bufinfo
.size
;
5896 /* end modifications */
5898 t
->aliaskind
= s
->aliaskind
;
5899 t
->oaliaskind
= s
->oaliaskind
;
5901 t
->expkind
= s
->expkind
;
5902 t
->oexpkind
= s
->oexpkind
;
5904 t
->nullinfo
= stateInfo_copy (s
->nullinfo
);
5905 t
->aliasinfo
= stateInfo_copy (s
->aliasinfo
);
5906 t
->definfo
= stateInfo_copy (s
->definfo
);
5907 t
->expinfo
= stateInfo_copy (s
->expinfo
);
5909 t
->deriv
= sRefSet_newDeepCopy (s
->deriv
);
5910 t
->state
= valueTable_copy (s
->state
);
5912 DPRINTF (("Made copy: %s => %s", sRef_unparseFull (s
), sRef_unparseFull (t
)));
5917 return sRef_undefined
;
5922 # define PREDTEST(func,s) \
5923 do { if (sRef_isInvalid (s)) { return FALSE; } \
5924 else { if (sRef_isConj (s)) \
5925 { return (func (sRef_getConjA (s)) \
5926 || func (sRef_getConjB (s))); }}} while (FALSE);
5928 bool sRef_isAddress (sRef s
)
5930 PREDTEST (sRef_isAddress
, s
);
5931 return (s
->kind
== SK_ADR
);
5935 ** pretty weak... maybe a flag should control this.
5938 bool sRef_isThroughArrayFetch (sRef s
)
5940 if (sRef_isReasonable (s
))
5948 if (sRef_isArrayFetch (tref
))
5953 lt
= sRef_getBase (tref
);
5955 } while (sRef_isReasonable (tref
));
5961 bool sRef_isArrayFetch (sRef s
)
5963 PREDTEST (sRef_isArrayFetch
, s
);
5964 return (s
->kind
== SK_ARRAYFETCH
);
5967 bool sRef_isMacroParamRef (sRef s
)
5969 if (context_inMacro () && sRef_isCvar (s
))
5971 uentry ue
= sRef_getUentry (s
);
5972 cstring pname
= makeParam (uentry_rawName (ue
));
5973 uentry mac
= usymtab_lookupSafe (pname
);
5975 cstring_free (pname
);
5976 return (uentry_isValid (mac
));
5982 bool sRef_isCvar (sRef s
)
5984 PREDTEST (sRef_isCvar
, s
);
5985 return (s
->kind
== SK_CVAR
);
5988 bool sRef_isConst (sRef s
)
5990 PREDTEST (sRef_isConst
, s
);
5991 return (s
->kind
== SK_CONST
);
5995 bool sRef_isObject (sRef s
)
5997 PREDTEST (sRef_isObject
, s
);
5998 return (s
->kind
== SK_OBJECT
);
6000 # endif /* DEADCODE */
6002 bool sRef_isExternal (sRef s
)
6004 PREDTEST (sRef_isExternal
, s
);
6005 return (s
->kind
== SK_EXTERNAL
);
6008 static bool sRef_isDerived (sRef s
)
6010 PREDTEST (sRef_isDerived
, s
);
6011 return (s
->kind
== SK_DERIVED
);
6014 bool sRef_isField (sRef s
)
6016 PREDTEST (sRef_isField
, s
);
6017 return (s
->kind
== SK_FIELD
);
6020 static bool sRef_isIndex (sRef s
)
6022 PREDTEST (sRef_isIndex
, s
);
6023 return (s
->kind
== SK_ARRAYFETCH
);
6026 bool sRef_isAnyParam (sRef s
)
6028 PREDTEST (sRef_isAnyParam
, s
);
6029 return (s
->kind
== SK_PARAM
);
6032 bool sRef_isParam (sRef s
)
6034 PREDTEST (sRef_isParam
, s
);
6035 return (s
->kind
== SK_PARAM
);
6038 bool sRef_isDirectParam (sRef s
)
6040 PREDTEST (sRef_isDirectParam
, s
);
6042 return ((s
->kind
== SK_CVAR
) &&
6043 (s
->info
->cvar
->lexlevel
== functionScope
) &&
6044 (context_inFunction () &&
6045 (s
->info
->cvar
->index
<= usymId_fromInt (uentryList_size (context_getParams ())))));
6048 bool sRef_isPointer (sRef s
)
6050 PREDTEST (sRef_isPointer
, s
);
6051 return (s
->kind
== SK_PTR
);
6055 ** returns true if storage referenced by s is visible
6058 bool sRef_isReference (sRef s
)
6060 PREDTEST (sRef_isReference
, s
);
6062 return (sRef_isPointer (s
) || sRef_isIndex (s
) || sRef_isFileOrGlobalScope (s
)
6063 || (sRef_isField (s
) && (sRef_isReference (s
->info
->field
->rec
))));
6066 bool sRef_isIReference (sRef s
)
6068 return (sRef_isPointer (s
) || sRef_isAddress (s
) || sRef_isIndex (s
)
6069 || sRef_isField (s
) || sRef_isArrayFetch (s
));
6072 bool sRef_isFileOrGlobalScope (sRef s
)
6074 return (sRef_isCvar (s
) && (s
->info
->cvar
->lexlevel
<= fileScope
));
6077 bool sRef_isRealGlobal (sRef s
)
6079 return (sRef_isCvar (s
) && (s
->info
->cvar
->lexlevel
== globScope
));
6082 bool sRef_isFileStatic (sRef s
)
6084 return (sRef_isCvar (s
) && (s
->info
->cvar
->lexlevel
== fileScope
));
6087 bool sRef_isAliasCheckedGlobal (sRef s
)
6089 if (sRef_isFileOrGlobalScope (s
))
6091 uentry ue
= sRef_getUentry (s
);
6093 return context_checkAliasGlob (ue
);
6101 void sRef_free (/*@only@*/ sRef s
)
6103 if (s
!= sRef_undefined
&& s
->kind
!= SK_SPECIAL
)
6105 DPRINTF (("Free sref: [%p]", s
));
6108 sRef_checkValid (s
);
6111 multiVal_free (s
->val
); /* evans 2002-07-12 */
6113 stateInfo_free (s
->expinfo
);
6114 stateInfo_free (s
->aliasinfo
);
6115 stateInfo_free (s
->definfo
);
6116 stateInfo_free (s
->nullinfo
);
6118 sRefSet_free (s
->deriv
);
6119 s
->deriv
= sRefSet_undefined
;
6121 valueTable_free (s
->state
);
6125 /* drl added to help locate use after release*/
6126 s
->expinfo
= stateInfo_undefined
;
6127 s
->aliasinfo
= stateInfo_undefined
;
6128 s
->definfo
= stateInfo_undefined
;
6129 s
->nullinfo
= stateInfo_undefined
;
6135 void sRef_setType (sRef s
, ctype t
)
6137 if (sRef_isReasonable (s
))
6139 sRef_checkMutable (s
);
6144 void sRef_setTypeFull (sRef s
, ctype t
)
6146 if (sRef_isReasonable (s
))
6148 sRef_checkMutable (s
);
6151 sRefSet_allElements (s
->deriv
, current
)
6153 sRef_setTypeFull (current
, ctype_unknown
);
6154 } end_sRefSet_allElements
;
6159 sRef_buildField (/*@exposed@*/ sRef rec
, /*@dependent@*/ cstring f
)
6161 return (sRef_buildNCField (rec
, f
));
6164 static /*@exposed@*/ sRef
6165 sRef_findDerivedField (/*@notnull@*/ sRef rec
, cstring f
)
6167 sRefSet_allElements (sRef_derivedFields (rec
), sr
)
6169 if (sRef_isReasonable (sr
))
6171 if (sRef_isReasonable (sr
))
6173 if (sr
->info
!= NULL
)
6175 if (sr
->kind
== SK_FIELD
&& cstring_equal (sr
->info
->field
->field
, f
))
6183 llcontbug (message ("Invalid sRef as derived field of %s", sRef_unparse (rec
)));
6186 } end_sRefSet_allElements
;
6188 return sRef_undefined
;
6191 /*@dependent@*/ /*@observer@*/ sRefSet
sRef_derivedFields (/*@temp@*/ sRef rec
)
6193 if (sRef_isReasonable (rec
))
6201 return (sRefSet_undefined
);
6205 static /*@exposed@*/ sRef
6206 sRef_findDerivedPointer (sRef s
)
6208 if (sRef_isReasonable (s
))
6210 sRefSet_realElements (s
->deriv
, sr
)
6212 if (sRef_isReasonable (sr
) && sr
->kind
== SK_PTR
)
6216 } end_sRefSet_realElements
;
6219 return sRef_undefined
;
6223 sRef_isUnknownArrayFetch (sRef s
)
6225 return (sRef_isReasonable (s
)
6226 && s
->kind
== SK_ARRAYFETCH
6227 && !s
->info
->arrayfetch
->indknown
);
6230 static /*@exposed@*/ sRef
6231 sRef_findDerivedArrayFetch (/*@notnull@*/ sRef s
, bool isknown
, int idx
, bool dead
)
6236 sRefSet_realElements (s
->deriv
, sr
)
6238 if (sRef_isReasonable (sr
)
6239 && sr
->kind
== SK_ARRAYFETCH
6240 && sr
->info
->arrayfetch
->indknown
6241 && (sr
->info
->arrayfetch
->ind
== idx
))
6245 } end_sRefSet_realElements
;
6249 sRefSet_realElements (s
->deriv
, sr
)
6251 if (sRef_isReasonable (sr
)
6252 && sr
->kind
== SK_ARRAYFETCH
6253 && (!sr
->info
->arrayfetch
->indknown
6254 || (sr
->info
->arrayfetch
->indknown
&&
6255 sr
->info
->arrayfetch
->ind
== 0)))
6257 if (sRef_isDead (sr
) || sRef_isKept (sr
))
6259 if (dead
|| context_getFlag (FLG_STRICTUSERELEASED
))
6269 } end_sRefSet_realElements
;
6272 return sRef_undefined
;
6275 static /*@exposed@*/ sRef
6276 sRef_buildNCField (/*@exposed@*/ sRef rec
, /*@exposed@*/ cstring f
)
6280 DPRINTF (("Build nc field: %s / %s",
6281 sRef_unparseFull (rec
), f
));
6283 if (sRef_isInvalid (rec
))
6285 return sRef_undefined
;
6289 ** check if the field already has been referenced
6292 s
= sRef_findDerivedField (rec
, f
);
6294 if (sRef_isReasonable (s
))
6300 ctype ct
= ctype_realType (rec
->type
);
6302 DPRINTF (("Field of: %s", sRef_unparse (rec
)));
6306 s
->info
= (sinfo
) dmalloc (sizeof (*s
->info
));
6307 s
->info
->field
= (fldinfo
) dmalloc (sizeof (*s
->info
->field
));
6308 s
->info
->field
->rec
= rec
;
6309 s
->info
->field
->field
= f
; /* doesn't copy f */
6311 if (ctype_isKnown (ct
) && ctype_isSU (ct
))
6313 uentry ue
= uentryList_lookupField (ctype_getFields (ct
), f
);
6315 if (!uentry_isUndefined (ue
))
6317 DPRINTF (("lookup: %s for %s", uentry_unparseFull (ue
),
6318 ctype_unparse (ct
)));
6320 s
->type
= uentry_getType (ue
);
6322 if (ctype_isMutable (s
->type
)
6323 && rec
->aliaskind
!= AK_STACK
6324 && !alkind_isStatic (rec
->aliaskind
))
6326 s
->aliaskind
= rec
->aliaskind
;
6330 s
->aliaskind
= AK_UNKNOWN
;
6333 if (sRef_isStateDefined (rec
) || sRef_isStateUnknown (rec
)
6334 || sRef_isPdefined (rec
))
6336 sRef_setStateFromUentry (s
, ue
);
6340 sRef_setPartsFromUentry (s
, ue
);
6343 s
->oaliaskind
= s
->aliaskind
;
6344 s
->oexpkind
= s
->expkind
;
6346 DPRINTF (("sref: %s", sRef_unparseFull (s
)));
6351 Never report this as an error. It can happen whenever there
6352 is casting involved.
6356 llcontbug (message ("buildNCField --- no field %s: %q / %s",
6357 f, sRef_unparse (s), ctype_unparse (ct)));
6361 return sRef_undefined
;
6365 if (rec
->defstate
== SS_DEFINED
6366 && (s
->defstate
== SS_UNDEFINED
|| s
->defstate
== SS_UNKNOWN
))
6368 s
->defstate
= SS_DEFINED
;
6370 else if (rec
->defstate
== SS_PARTIAL
)
6372 s
->defstate
= SS_PARTIAL
;
6374 else if (rec
->defstate
== SS_ALLOCATED
)
6376 if (ctype_isStackAllocated (ct
) && ctype_isStackAllocated (s
->type
))
6378 s
->defstate
= SS_ALLOCATED
;
6382 s
->defstate
= SS_UNDEFINED
;
6385 else if (s
->defstate
== SS_UNKNOWN
)
6387 s
->defstate
= rec
->defstate
;
6394 if (s
->defstate
== SS_UNDEFINED
)
6396 ctype rt
= ctype_realType (s
->type
);
6398 if (ctype_isArray (rt
) || ctype_isSU (rt
))
6400 s
->defstate
= SS_ALLOCATED
;
6404 sRef_addDeriv (rec
, s
);
6405 DPRINTF (("Add deriv: %s", sRef_unparseFull (rec
)));
6407 if (ctype_isInt (s
->type
) && cstring_equal (f
, REFSNAME
))
6409 s
->aliaskind
= AK_REFS
;
6410 s
->oaliaskind
= AK_REFS
;
6413 DPRINTF (("Build field ==> %s", sRef_unparseFull (s
)));
6419 sRef_isStackAllocated (sRef s
)
6421 return (sRef_isReasonable(s
)
6422 && s
->defstate
== SS_ALLOCATED
&& ctype_isStackAllocated (s
->type
));
6426 void sRef_setArrayFetchState (/*@notnull@*/ /*@exposed@*/ sRef s
,
6427 /*@notnull@*/ /*@exposed@*/ sRef arr
)
6429 sRef_checkMutable (s
);
6431 if (ctype_isRealAP (arr
->type
))
6433 s
->type
= ctype_baseArrayPtr (arr
->type
);
6436 /* a hack, methinks... makeArrayFetch (&a[0]) ==> a[] */
6437 /* evans - 2001-08-27: not sure where this was necessary - it
6438 ** causes an assertion in in aliasCheckPred to fail.
6441 if (sRef_isAddress (arr
))
6443 sRef t
= arr
->info
->ref
;
6445 if (sRef_isArrayFetch (t
))
6447 s
->info
->arrayfetch
->arr
= t
->info
->arrayfetch
->arr
;
6450 else if (ctype_isRealPointer (arr
->type
))
6452 sRef sp
= sRef_findDerivedPointer (arr
);
6454 if (sRef_isReasonable (sp
))
6457 if (ctype_isMutable (s
->type
))
6459 s
->expkind
= sRef_getExKind (sp
);
6460 s
->expinfo
= stateInfo_copy (sp
->expinfo
);
6462 s
->aliaskind
= sp
->aliaskind
;
6463 s
->aliasinfo
= stateInfo_copy (sp
->aliasinfo
);
6466 s
->defstate
= sp
->defstate
;
6468 if (s
->defstate
== SS_DEFINED
)
6470 if (!context_getFlag (FLG_STRICTDESTROY
))
6472 s
->defstate
= SS_PARTIAL
;
6476 DPRINTF (("Set null state: %s / %s", sRef_unparseFull (s
), sRef_unparseFull (sp
)));
6477 sRef_setNullStateN (s
, sRef_getNullState (sp
));
6481 if (arr
->defstate
== SS_UNDEFINED
)
6483 s
->defstate
= SS_UNUSEABLE
;
6485 else if ((arr
->defstate
== SS_ALLOCATED
) && !ctype_isSU (s
->type
))
6487 s
->defstate
= SS_UNDEFINED
;
6491 if (!context_getFlag (FLG_STRICTDESTROY
))
6493 s
->defstate
= SS_PARTIAL
;
6497 s
->defstate
= SS_DEFINED
;
6501 ** Very weak checking for array elements.
6503 ** s->defstate = arr->defstate;
6507 s
->expkind
= sRef_getExKind (arr
);
6508 s
->expinfo
= stateInfo_copy (arr
->expinfo
);
6510 if (arr
->aliaskind
== AK_LOCAL
|| arr
->aliaskind
== AK_FRESH
)
6512 s
->aliaskind
= AK_LOCAL
;
6516 s
->aliaskind
= AK_UNKNOWN
;
6519 sRef_setTypeState (s
);
6524 if (arr
->defstate
== SS_DEFINED
)
6527 ** Very weak checking for array elements.
6529 ** s->defstate = arr->defstate;
6532 if (context_getFlag (FLG_STRICTDESTROY
))
6534 s
->defstate
= SS_DEFINED
;
6538 s
->defstate
= SS_PARTIAL
;
6541 else if (arr
->defstate
== SS_ALLOCATED
)
6543 if (ctype_isRealArray (s
->type
))
6545 s
->defstate
= SS_ALLOCATED
;
6549 if (!s
->info
->arrayfetch
->indknown
)
6552 ** is index is unknown, elements is defined or
6553 ** allocated is any element is!
6556 s
->defstate
= SS_UNDEFINED
;
6558 sRefSet_allElements (arr
->deriv
, sr
)
6560 if (sRef_isReasonable (sr
))
6562 if (sRef_isReasonable (sr
))
6564 if (sr
->defstate
== SS_ALLOCATED
)
6566 s
->defstate
= SS_ALLOCATED
;
6570 if (sr
->defstate
== SS_DEFINED
)
6572 if (context_getFlag (FLG_STRICTDESTROY
))
6574 s
->defstate
= SS_DEFINED
;
6578 s
->defstate
= SS_PARTIAL
;
6587 llcontbug (message ("Invalid sRef as derived element of %s", sRef_unparse (arr
)));
6590 } end_sRefSet_allElements
;
6594 s
->defstate
= SS_UNDEFINED
;
6600 s
->defstate
= arr
->defstate
;
6605 ** kludgey way to guess where aliaskind applies
6608 if (ctype_isMutable (s
->type
)
6609 && !ctype_isPointer (arr
->type
)
6610 && !alkind_isStatic (arr
->aliaskind
)
6611 && !alkind_isStack (arr
->aliaskind
)) /* evs - 2000-06-20: don't pass stack allocation to members */
6613 s
->aliaskind
= arr
->aliaskind
;
6617 s
->aliaskind
= AK_UNKNOWN
;
6620 sRef_setTypeState (s
);
6623 if (sRef_isObserver (arr
))
6625 s
->expkind
= XO_OBSERVER
;
6626 s
->expinfo
= stateInfo_copy (arr
->expinfo
);
6630 /*@exposed@*/ sRef
sRef_buildArrayFetch (/*@exposed@*/ sRef arr
)
6634 if (!sRef_isReasonable (arr
)) {
6635 /*@-nullret@*/ return arr
/*@=nullret@*/;
6638 if (ctype_isRealPointer (arr
->type
))
6640 (void) sRef_buildPointer (arr
); /* do this to define arr! */
6643 s
= sRef_findDerivedArrayFetch (arr
, FALSE
, 0, FALSE
);
6645 if (sRef_isReasonable (s
))
6647 /* evans 2001-07-12: this is bogus, clean-up hack */
6648 if (s
->info
->arrayfetch
->arr
!= arr
)
6651 check (sRefSet_delete (arr
->deriv
, s
));
6652 res
= sRef_buildArrayFetch (arr
);
6653 sRef_copyState (res
, s
);
6654 llassert (res
->info
->arrayfetch
->arr
== arr
);
6658 s
->expkind
= sRef_getExKind (arr
);
6659 s
->expinfo
= stateInfo_copy (arr
->expinfo
);
6667 s
->kind
= SK_ARRAYFETCH
;
6668 s
->info
= (sinfo
) dmalloc (sizeof (*s
->info
));
6669 s
->info
->arrayfetch
= (ainfo
) dmalloc (sizeof (*s
->info
->arrayfetch
));
6670 s
->info
->arrayfetch
->indknown
= FALSE
;
6671 s
->info
->arrayfetch
->ind
= 0;
6672 s
->info
->arrayfetch
->arr
= arr
;
6674 sRef_setArrayFetchState (s
, arr
);
6676 s
->oaliaskind
= s
->aliaskind
;
6677 s
->oexpkind
= s
->expkind
;
6679 if (!context_inProtectVars ())
6681 sRef_addDeriv (arr
, s
);
6684 if (valueTable_isUndefined (s
->state
))
6686 s
->state
= context_createValueTable
6687 (s
, stateInfo_makeLoc (g_currentloc
, SA_CREATED
));
6695 sRef_buildArrayFetchKnown (/*@exposed@*/ sRef arr
, int i
)
6699 if (!sRef_isReasonable (arr
)) {
6700 /*@-nullret@*/ return arr
/*@=nullret@*/;
6703 if (ctype_isRealPointer (arr
->type
))
6705 (void) sRef_buildPointer (arr
); /* do this to define arr! */
6708 s
= sRef_findDerivedArrayFetch (arr
, TRUE
, i
, FALSE
);
6710 if (sRef_isReasonable (s
))
6712 /* evans 2001-07-12: this is bogus, clean-up hack */
6713 if (s
->info
->arrayfetch
->arr
!= arr
)
6717 check (sRefSet_delete (arr
->deriv
, s
));
6718 res
= sRef_buildArrayFetchKnown (arr
, i
);
6720 llassert (res
->info
->arrayfetch
->arr
== arr
);
6721 sRef_copyState (res
, s
);
6722 llassert (res
->info
->arrayfetch
->arr
== arr
);
6726 s
->expkind
= sRef_getExKind (arr
);
6727 s
->expinfo
= stateInfo_copy (arr
->expinfo
);
6729 llassert (s
->info
->arrayfetch
->arr
== arr
);
6736 s
->kind
= SK_ARRAYFETCH
;
6737 s
->info
= (sinfo
) dmalloc (sizeof (*s
->info
));
6738 s
->info
->arrayfetch
= (ainfo
) dmalloc (sizeof (*s
->info
->arrayfetch
));
6739 s
->info
->arrayfetch
->arr
= arr
;
6740 s
->info
->arrayfetch
->indknown
= TRUE
;
6741 s
->info
->arrayfetch
->ind
= i
;
6743 sRef_setArrayFetchState (s
, arr
);
6744 /* evans 2001-08-27 no: can change this - llassert (s->info->arrayfetch->arr == arr); */
6746 s
->oaliaskind
= s
->aliaskind
;
6747 s
->oexpkind
= s
->expkind
;
6748 sRef_addDeriv (arr
, s
);
6750 llassert (valueTable_isUndefined (s
->state
));
6751 s
->state
= context_createValueTable (s
, stateInfo_makeLoc (g_currentloc
, SA_CREATED
));
6757 ** sets everything except for defstate
6761 sRef_setPartsFromUentry (sRef s
, uentry ue
)
6763 sRef uref
= uentry_getSref (ue
);
6765 llassert (sRef_isReasonable (s
));
6767 s
->aliaskind
= alkind_derive (s
->aliaskind
, uentry_getAliasKind (ue
));
6768 s
->oaliaskind
= s
->aliaskind
;
6770 if (s
->expkind
== XO_UNKNOWN
)
6772 s
->expkind
= uentry_getExpKind (ue
);
6775 s
->oexpkind
= s
->expkind
;
6777 if (sRef_getNullState (s
) == NS_UNKNOWN
)
6779 DPRINTF (("Set null state: %s / %s", sRef_unparseFull (s
), uentry_unparseFull (ue
)));
6780 sRef_setNullStateN (s
, sRef_getNullState (uentry_getSref (ue
)));
6784 DPRINTF (("Skipping null null state!"));
6787 if (s
->aliaskind
== AK_IMPONLY
&& (sRef_isExposed (s
) || sRef_isObserver (s
)))
6789 s
->oaliaskind
= s
->aliaskind
= AK_IMPDEPENDENT
;
6792 if (sRef_isReasonable (uref
))
6794 valueTable utable
= uref
->state
;
6795 valueTable_free (s
->state
);
6796 s
->state
= valueTable_copy (utable
);
6801 sRef_setStateFromAbstractUentry (sRef s
, uentry ue
)
6803 llassert (sRef_isReasonable (s
));
6804 sRef_checkMutable (s
);
6806 sRef_setPartsFromUentry (s
, ue
);
6808 s
->aliaskind
= alkind_derive (s
->aliaskind
, uentry_getAliasKind (ue
));
6809 s
->oaliaskind
= s
->aliaskind
;
6811 if (s
->expkind
== XO_UNKNOWN
)
6813 s
->expkind
= uentry_getExpKind (ue
);
6816 s
->oexpkind
= s
->expkind
;
6820 sRef_setStateFromUentry (sRef s
, uentry ue
)
6824 sRef_checkMutable (s
);
6825 llassert (sRef_isReasonable (s
));
6827 sRef_setPartsFromUentry (s
, ue
);
6829 defstate
= uentry_getDefState (ue
);
6831 if (sstate_isKnown (defstate
))
6833 s
->defstate
= defstate
;
6842 sRef_buildPointer (/*@exposed@*/ sRef t
)
6844 DPRINTF (("build pointer: %s", sRef_unparse (t
)));
6846 if (sRef_isInvalid (t
)) return sRef_undefined
;
6848 if (sRef_isAddress (t
))
6850 DPRINTF (("Return ref: %s", sRef_unparse (t
->info
->ref
)));
6851 return (t
->info
->ref
);
6855 sRef s
= sRef_findDerivedPointer (t
);
6857 DPRINTF (("find derived: %s", sRef_unparse (s
)));
6859 if (sRef_isReasonable (s
))
6861 s
->expkind
= sRef_getExKind (t
);
6862 s
->expinfo
= stateInfo_copy (t
->expinfo
);
6864 s
->oaliaskind
= s
->aliaskind
;
6865 s
->oexpkind
= s
->expkind
;
6871 s
= sRef_constructPointerAux (t
);
6873 DPRINTF (("construct: %s", sRef_unparse (s
)));
6875 if (sRef_isReasonable (s
))
6877 sRef_addDeriv (t
, s
);
6879 s
->oaliaskind
= s
->aliaskind
;
6880 s
->oexpkind
= s
->expkind
;
6889 sRef_constructPointer (/*@exposed@*/ sRef t
)
6892 return sRef_buildPointer (t
);
6895 static /*@exposed@*/ sRef
sRef_constructDerefAux (sRef t
, bool isdead
)
6897 if (sRef_isReasonable (t
))
6902 ** if there is a derived t[?], return that. Otherwise, *t.
6905 s
= sRef_findDerivedArrayFetch (t
, FALSE
, 0, isdead
);
6907 if (sRef_isReasonable (s
))
6909 DPRINTF (("Found array fetch: %s", sRef_unparseFull (s
)));
6914 sRef ret
= sRef_constructPointer (t
);
6916 DPRINTF (("Constructed pointer: %s", sRef_unparseFull (ret
)));
6923 return sRef_undefined
;
6927 sRef
sRef_constructDeref (sRef t
)
6929 return sRef_constructDerefAux (t
, FALSE
);
6932 sRef
sRef_constructDeadDeref (sRef t
)
6934 return sRef_constructDerefAux (t
, TRUE
);
6938 sRef_constructPointerAux (/*@notnull@*/ /*@exposed@*/ sRef t
)
6940 sRef s
= sRef_newRef ();
6944 llassert (valueTable_isUndefined (s
->state
));
6947 s
->info
= (sinfo
) dmalloc (sizeof (*s
->info
));
6950 if (ctype_isRealAP (rt
))
6952 s
->type
= ctype_baseArrayPtr (rt
);
6955 st
= ctype_realType (s
->type
);
6957 if (t
->defstate
== SS_UNDEFINED
)
6959 s
->defstate
= SS_UNUSEABLE
;
6960 s
->definfo
= stateInfo_copy (t
->definfo
);
6962 else if ((t
->defstate
== SS_ALLOCATED
) && !ctype_isSU (st
))
6964 s
->defstate
= SS_UNDEFINED
;
6965 s
->definfo
= stateInfo_copy (t
->definfo
);
6969 s
->defstate
= t
->defstate
;
6970 s
->definfo
= stateInfo_copy (t
->definfo
);
6973 if (t
->aliaskind
== AK_LOCAL
|| t
->aliaskind
== AK_FRESH
)
6975 s
->aliaskind
= AK_LOCAL
;
6979 s
->aliaskind
= AK_UNKNOWN
;
6982 s
->expkind
= sRef_getExKind (t
);
6983 s
->expinfo
= stateInfo_copy (t
->expinfo
);
6985 sRef_setTypeState (s
);
6987 s
->oaliaskind
= s
->aliaskind
;
6988 s
->oexpkind
= s
->expkind
;
6990 if (valueTable_isUndefined (s
->state
))
6992 s
->state
= context_createValueTable (s
, stateInfo_makeLoc (g_currentloc
, SA_CREATED
));
6995 DPRINTF (("pointer: %s", sRef_unparseFull (s
)));
6999 bool sRef_hasDerived (sRef s
)
7001 return (sRef_isReasonable (s
) && !sRefSet_isEmpty (s
->deriv
));
7005 sRef_clearDerived (sRef s
)
7007 if (sRef_isReasonable (s
))
7009 DPRINTF (("Clear derived: [%p] %s", s
, sRef_unparseDebug (s
)));
7010 sRefSet_clear (s
->deriv
);
7015 sRef_clearDerivedComplete (sRef s
)
7017 if (sRef_isReasonable (s
))
7019 sRef base
= sRef_getBaseSafe (s
);
7021 while (sRef_isReasonable (base
))
7023 DPRINTF (("Clear derived: [%p] %s", base
, sRef_unparse (base
)));
7024 sRefSet_clear (base
->deriv
);
7025 base
= sRef_getBaseSafe (base
);
7028 DPRINTF (("Clear derived: [%p] %s", s
, sRef_unparse (s
)));
7029 sRefSet_clear (s
->deriv
);
7033 /*@exposed@*/ sRef
sRef_makePointer (/*@exposed@*/ sRef s
)
7036 sRef res
= sRef_buildPointer (s
);
7038 DPRINTF (("Res: %s", sRef_unparseFull (res
)));
7043 ** &a[] => a (this is for out params)
7047 sRef_makeAnyArrayFetch (/*@exposed@*/ sRef arr
)
7049 if (sRef_isAddress (arr
))
7051 return (arr
->info
->ref
);
7055 return (sRef_buildArrayFetch (arr
));
7060 sRef_makeArrayFetch (/*@exposed@*/ sRef arr
)
7062 return (sRef_buildArrayFetch (arr
));
7066 sRef_makeArrayFetchKnown (/*@exposed@*/ sRef arr
, int i
)
7068 return (sRef_buildArrayFetchKnown (arr
, i
));
7072 sRef_makeField (sRef rec
, /*@dependent@*/ cstring f
)
7075 ret
= sRef_buildField (rec
, f
);
7080 sRef_makeNCField (/*@exposed@*/ sRef rec
, /*@dependent@*/ cstring f
)
7082 return (sRef_buildNCField (rec
, f
));
7086 sRef_unparseKindName (sRef s
)
7090 if (s
== sRef_undefined
) return cstring_makeLiteral ("<invalid>");
7092 s
= sRef_fixConj (s
);
7097 if (sRef_isLocalVar (s
))
7099 result
= cstring_makeLiteral ("Variable");
7103 result
= cstring_makeLiteral ("Undef global");
7107 result
= cstring_makeLiteral ("Out parameter");
7110 if (sRef_isAnyParam (s
->info
->arrayfetch
->arr
))
7112 result
= cstring_makeLiteral ("Out parameter");
7114 else if (sRef_isIndexKnown (s
))
7116 result
= cstring_makeLiteral ("Array element");
7120 result
= cstring_makeLiteral ("Value");
7124 if (sRef_isAnyParam (s
->info
->ref
))
7126 result
= cstring_makeLiteral ("Out parameter");
7130 result
= cstring_makeLiteral ("Value");
7134 result
= cstring_makeLiteral ("Value");
7137 result
= cstring_makeLiteral ("Field");
7140 result
= cstring_makeLiteral ("Object");
7142 case SK_UNCONSTRAINED
:
7143 result
= cstring_makeLiteral ("<anything>");
7152 result
= cstring_makeLiteral ("<unknown>");
7155 result
= cstring_makeLiteral ("<conj>");
7158 result
= cstring_makeLiteral ("Storage");
7166 sRef_unparseKindNamePlain (sRef s
)
7170 if (s
== sRef_undefined
) return cstring_makeLiteral ("<invalid>");
7172 s
= sRef_fixConj (s
);
7177 if (sRef_isLocalVar (s
))
7179 result
= cstring_makeLiteral ("Variable");
7183 result
= cstring_makeLiteral ("Global");
7187 result
= cstring_makeLiteral ("Parameter");
7190 if (sRef_isAnyParam (s
->info
->arrayfetch
->arr
))
7192 result
= cstring_makeLiteral ("Parameter");
7194 else if (sRef_isIndexKnown (s
))
7196 result
= cstring_makeLiteral ("Array element");
7200 result
= cstring_makeLiteral ("Value");
7204 if (sRef_isAnyParam (s
->info
->ref
))
7206 result
= cstring_makeLiteral ("Parameter");
7210 result
= cstring_makeLiteral ("Value");
7214 result
= cstring_makeLiteral ("Value");
7217 result
= cstring_makeLiteral ("Field");
7220 result
= cstring_makeLiteral ("Object");
7223 result
= cstring_makeLiteral ("Storage");
7225 case SK_UNCONSTRAINED
:
7226 result
= cstring_makeLiteral ("<anything>");
7235 result
= cstring_makeLiteral ("<unknown>");
7238 result
= cstring_makeLiteral ("<conj>");
7250 sRef_copyState (sRef s1
, sRef s2
)
7252 if (sRef_isReasonable (s1
) && sRef_isReasonable (s2
))
7254 s1
->defstate
= s2
->defstate
;
7256 /* start modifications */
7257 s1
->bufinfo
.bufstate
= s2
->bufinfo
.bufstate
;
7258 s1
->bufinfo
.len
= s2
->bufinfo
.len
;
7259 s1
->bufinfo
.size
= s2
->bufinfo
.size
;
7260 /* end modifications */
7262 s1
->aliaskind
= s2
->aliaskind
;
7263 s1
->aliasinfo
= stateInfo_update (s1
->aliasinfo
, s2
->aliasinfo
);
7265 s1
->expkind
= s2
->expkind
;
7266 s1
->expinfo
= stateInfo_update (s1
->expinfo
, s2
->expinfo
);
7268 s1
->nullstate
= s2
->nullstate
;
7269 DPRINTF (("Set null state==> %s", sRef_unparseFull (s1
)));
7270 s1
->nullinfo
= stateInfo_update (s1
->nullinfo
, s2
->nullinfo
);
7272 valueTable_free (s1
->state
);
7273 s1
->state
= valueTable_copy (s2
->state
);
7274 s1
->safe
= s2
->safe
;
7279 sRef_makeNew (ctype ct
, sRef t
, cstring name
)
7281 sRef s
= sRef_newRef ();
7286 llassert (sRef_isReasonable (t
));
7287 s
->defstate
= t
->defstate
;
7289 s
->aliaskind
= t
->aliaskind
;
7290 s
->oaliaskind
= s
->aliaskind
;
7291 s
->nullstate
= t
->nullstate
;
7293 s
->expkind
= t
->expkind
;
7294 s
->oexpkind
= s
->expkind
;
7296 s
->info
= (sinfo
) dmalloc (sizeof (*s
->info
));
7297 s
->info
->fname
= name
;
7299 /* start modifications */
7300 s
->bufinfo
.bufstate
= t
->bufinfo
.bufstate
;
7301 /* end modifications */
7303 llassert (valueTable_isUndefined (s
->state
));
7304 s
->state
= valueTable_copy (t
->state
);
7306 DPRINTF (("==> Copying state: %s", valueTable_unparse (s
->state
)));
7307 DPRINTF (("==> new: %s", sRef_unparseFull (s
)));
7312 sRef_makeType (ctype ct
)
7314 sRef s
= sRef_newRef ();
7316 sRef_checkMutable (s
);
7321 s
->defstate
= SS_UNKNOWN
;
7322 s
->aliaskind
= AK_UNKNOWN
;
7323 sRef_setNullStateN (s
, NS_UNKNOWN
);
7325 /* start modification */
7326 s
->bufinfo
.bufstate
= BB_NOTNULLTERMINATED
;
7327 /* end modification */
7330 if (ctype_isUA (ct
))
7332 typeId uid
= ctype_typeId (ct
);
7333 uentry ue
= usymtab_getTypeEntrySafe (uid
);
7335 if (uentry_isValid (ue
))
7337 sRef_mergeStateQuiet (s
, uentry_getSref (ue
));
7341 s
->oaliaskind
= s
->aliaskind
;
7342 s
->oexpkind
= s
->expkind
;
7343 llassert (valueTable_isUndefined (s
->state
));
7344 s
->state
= context_createValueTable (s
, stateInfo_makeLoc (g_currentloc
, SA_CREATED
));
7346 DPRINTF (("Create: %s", sRef_unparseFull (s
)));
7351 sRef_makeConst (ctype ct
)
7353 sRef s
= sRef_newRef ();
7358 s
->defstate
= SS_UNKNOWN
;
7359 s
->aliaskind
= AK_UNKNOWN
;
7360 sRef_setNullStateN (s
, NS_UNKNOWN
);
7362 /* start modification */
7363 s
->bufinfo
.bufstate
= BB_NULLTERMINATED
;
7364 /* end modification */
7366 /* evans 2002-04-22: added isManifestBool to avoid errors for -boolfalse initializations */
7367 if (!ctype_isManifestBool (ct
) && ctype_isUA (ct
))
7369 typeId uid
= ctype_typeId (ct
);
7370 uentry te
= usymtab_getTypeEntrySafe (uid
);
7372 if (uentry_isValid (te
))
7374 sRef_mergeStateQuiet (s
, uentry_getSref (te
));
7378 s
->oaliaskind
= s
->aliaskind
;
7379 s
->oexpkind
= s
->expkind
;
7381 llassert (valueTable_isUndefined (s
->state
));
7382 s
->state
= context_createValueTable (s
, stateInfo_makeLoc (g_currentloc
, SA_CREATED
));
7387 bool sRef_hasName (sRef s
)
7389 if (sRef_isInvalid (s
))
7398 uentry u
= usymtab_getRefQuiet (s
->info
->cvar
->lexlevel
,
7399 s
->info
->cvar
->index
);
7400 return (uentry_hasName (u
));
7404 if (s
->info
->paramno
>= 0)
7406 uentry u
= uentryList_getN (context_getParams (),
7409 return (uentry_hasName (u
));
7413 llassert (s
->info
->paramno
== PARAMUNKNOWN
);
7423 sRef_sameName (sRef s1
, sRef s2
)
7425 if (sRef_isInvalid (s1
))
7427 return sRef_isInvalid (s2
);
7430 if (sRef_isInvalid (s2
))
7438 if (s2
->kind
== SK_CVAR
)
7440 return (s1
->info
->cvar
->lexlevel
== s2
->info
->cvar
->lexlevel
7441 && s1
->info
->cvar
->index
== s2
->info
->cvar
->index
);
7443 else if (s2
->kind
== SK_PARAM
)
7445 if (context_inFunctionLike ())
7447 if (s2
->info
->paramno
!= PARAMUNKNOWN
)
7449 uentry u1
= usymtab_getRefQuiet (s1
->info
->cvar
->lexlevel
,
7450 s1
->info
->cvar
->index
);
7451 uentry u2
= uentryList_getN (context_getParams (),
7454 return (cstring_equalFree (uentry_getName (u1
),
7455 uentry_getName (u2
)));
7459 return s1
->info
->paramno
== PARAMUNKNOWN
;
7473 if (s2
->kind
== SK_PARAM
)
7475 return (s1
->info
->paramno
== s2
->info
->paramno
);
7477 else if (s2
->kind
== SK_CVAR
)
7479 if (context_inFunctionLike ())
7481 if (s1
->info
->paramno
== PARAMUNKNOWN
)
7487 uentry u1
= uentryList_getN (context_getParams (),
7489 uentry u2
= usymtab_getRefQuiet (s2
->info
->cvar
->lexlevel
,
7490 s2
->info
->cvar
->index
);
7493 return (cstring_equalFree (uentry_getName (u1
),
7494 uentry_getName (u2
)));
7508 case SK_UNCONSTRAINED
:
7512 if (s2
->kind
== SK_ARRAYFETCH
)
7514 if (bool_equal (s1
->info
->arrayfetch
->indknown
,
7515 s2
->info
->arrayfetch
->indknown
))
7517 if (!s1
->info
->arrayfetch
->indknown
7518 || (s1
->info
->arrayfetch
->ind
== s2
->info
->arrayfetch
->ind
))
7520 return sRef_sameName (s1
->info
->arrayfetch
->arr
,
7521 s2
->info
->arrayfetch
->arr
);
7528 if (s2
->kind
== SK_FIELD
)
7530 if (cstring_equal (s1
->info
->field
->field
,
7531 s2
->info
->field
->field
))
7533 return sRef_sameName (s1
->info
->field
->rec
,
7534 s2
->info
->field
->rec
);
7543 if (s2
->kind
== s1
->kind
)
7545 return sRef_sameName (s1
->info
->ref
,
7553 return sRef_sameName (sRef_getConjA (s1
), s2
);
7557 return (s2
->kind
== SK_UNKNOWN
);
7560 if (s2
->kind
== s1
->kind
)
7562 return (ctype_equal (s1
->type
, s2
->type
));
7567 if (s2
->kind
== SK_SPECIAL
)
7569 return (s1
->info
->spec
== s2
->info
->spec
);
7573 return (s2
->kind
== SK_RESULT
);
7581 sRef_fixOuterRef (/*@returned@*/ sRef s
)
7583 sRef root
= sRef_getRootBase (s
);
7585 if (sRef_isCvar (root
))
7587 uentry ue
= usymtab_getRefQuiet (root
->info
->cvar
->lexlevel
,
7588 root
->info
->cvar
->index
);
7590 if (uentry_isValid (ue
))
7592 sRef uref
= uentry_getSref (ue
);
7593 sRef sr
= sRef_fixBase (s
, uref
);
7599 llcontbug (message ("sRef_fixOuterRef: undefined: %q", sRef_unparseDebug (s
)));
7608 sRef_storeState (sRef s
)
7610 if (sRef_isInvalid (s
)) return;
7612 sRef_checkMutable (s
);
7613 s
->oaliaskind
= s
->aliaskind
;
7614 s
->oexpkind
= s
->expkind
;
7617 static void sRef_resetStateAux (sRef s
, /*@unused@*/ fileloc loc
)
7619 sRef_resetState (s
);
7623 sRef_resetState (sRef s
)
7625 bool changed
= FALSE
;
7626 if (sRef_isInvalid (s
)) return;
7629 if (s
->oaliaskind
== AK_KILLREF
&& !sRef_isParam (s
))
7632 ** killref is used in a kludgey way, to save having to add
7633 ** another alias kind (see usymtab_handleParams)
7636 if (s
->expkind
!= s
->oexpkind
)
7639 s
->expkind
= s
->oexpkind
;
7644 if (s
->expkind
!= s
->oexpkind
)
7647 s
->expkind
= s
->oexpkind
;
7650 if (s
->aliaskind
!= s
->oaliaskind
7651 && s
->aliaskind
!= AK_REFCOUNTED
7652 && s
->aliaskind
!= AK_REFS
)
7655 s
->aliaskind
= s
->oaliaskind
;
7661 sRef_clearDerived (s
);
7667 sRef_resetStateComplete (sRef s
)
7669 sRef_innerAliasSetComplete (sRef_resetStateAux
, s
, fileloc_undefined
);
7673 sRef_fixBase (/*@returned@*/ sRef s
, /*@returned@*/ sRef base
)
7675 sRef tmp
= sRef_undefined
;
7678 if (sRef_isInvalid (s
)) return s
;
7679 if (sRef_isInvalid (base
)) return base
;
7689 tmp
= sRef_fixBase (s
->info
->arrayfetch
->arr
, base
);
7691 if (s
->info
->arrayfetch
->indknown
)
7693 ret
= sRef_makeArrayFetchKnown (tmp
, s
->info
->arrayfetch
->ind
);
7697 ret
= sRef_makeArrayFetch (tmp
);
7701 tmp
= sRef_fixBase (s
->info
->field
->rec
, base
);
7702 ret
= sRef_buildNCField (tmp
, s
->info
->field
->field
);
7705 tmp
= sRef_fixBase (s
->info
->ref
, base
);
7706 ret
= sRef_makePointer (tmp
);
7709 tmp
= sRef_fixBase (s
->info
->ref
, base
);
7710 ret
= sRef_makeAddress (tmp
);
7716 tmp
= sRef_fixBase (s
->info
->conj
->a
, base
);
7717 tmpb
= sRef_fixBase (s
->info
->conj
->b
, base
);
7719 ret
= sRef_makeConj (tmp
, tmpb
);
7728 static /*@exposed@*/ sRef
7729 sRef_fixDirectBase (sRef s
, sRef base
)
7734 if (sRef_isInvalid (s
))
7736 return sRef_undefined
;
7742 if (s
->info
->arrayfetch
->indknown
)
7744 ret
= sRef_makeArrayFetchKnown (base
, s
->info
->arrayfetch
->ind
);
7748 ret
= sRef_makeArrayFetch (base
);
7752 ret
= sRef_buildNCField (base
, s
->info
->field
->field
);
7755 ret
= sRef_makePointer (base
);
7758 ret
= sRef_makeAddress (base
);
7764 tmpa
= sRef_fixDirectBase (s
->info
->conj
->a
, base
);
7765 tmpb
= sRef_fixDirectBase (s
->info
->conj
->b
, base
);
7767 ret
= sRef_makeConj (tmpa
, tmpb
);
7773 sRef_copyState (ret
, s
);
7778 sRef_isAllocIndexRef (sRef s
)
7780 return (sRef_isArrayFetch (s
) && !(s
->info
->arrayfetch
->indknown
)
7781 && sRef_isAllocated (s
->info
->arrayfetch
->arr
));
7785 sRef_showRefLost (sRef s
)
7787 if (sRef_hasAliasInfoLoc (s
))
7789 llgenindentmsg (cstring_makeLiteral ("Original reference lost"),
7790 sRef_getAliasInfoLoc (s
));
7795 sRef_showRefKilled (sRef s
)
7797 if (sRef_isValid (s
))
7799 DPRINTF (("Killed: %s", sRef_unparseFull (s
)));
7800 if (context_getLocIndentSpaces () == 0) {
7801 stateInfo_display (s
->definfo
, message (" Storage %q", sRef_unparseOpt (s
)));
7803 stateInfo_display (s
->definfo
, message ("Storage %q", sRef_unparseOpt (s
)));
7809 sRef_showStateInconsistent (sRef s
)
7811 if (sRef_hasStateInfoLoc (s
))
7814 (message ("Storage %qbecomes inconsistent (released on one branch)",
7815 sRef_unparseOpt (s
)),
7816 sRef_getStateInfoLoc (s
));
7821 sRef_showStateInfo (sRef s
)
7823 if (sRef_isValid (s
)) {
7824 if (context_getLocIndentSpaces () == 0) {
7825 stateInfo_display (s
->definfo
, message (" Storage %q", sRef_unparseOpt (s
)));
7827 stateInfo_display (s
->definfo
, message ("Storage %q", sRef_unparseOpt (s
)));
7833 sRef_showExpInfo (sRef s
)
7835 if (sRef_isValid (s
)) {
7836 if (context_getLocIndentSpaces () == 0) {
7837 stateInfo_display (s
->expinfo
, message (" Storage %q", sRef_unparseOpt (s
)));
7839 stateInfo_display (s
->expinfo
, message ("Storage %q", sRef_unparseOpt (s
)));
7845 sRef_showMetaStateInfo (sRef s
, cstring key
)
7848 metaStateInfo minfo
= context_lookupMetaStateInfo (key
);
7850 llassert (sRef_isReasonable (s
));
7851 llassert (valueTable_isDefined (s
->state
));
7852 llassert (metaStateInfo_isDefined (minfo
));
7854 val
= valueTable_lookup (s
->state
, key
);
7856 if (stateValue_hasLoc (val
))
7859 (message ("%qbecomes %q", sRef_unparseOpt (s
),
7860 stateValue_unparseValue (val
, minfo
)),
7861 stateValue_getLoc (val
));
7866 sRef_showNullInfo (sRef s
)
7868 DPRINTF (("Show null info: %s", sRef_unparseFull (s
)));
7870 if (sRef_hasNullInfoLoc (s
) && sRef_isKnown (s
))
7872 DPRINTF (("has null info: %s",
7873 fileloc_unparse (sRef_getNullInfoLoc (s
))));
7875 switch (sRef_getNullState (s
))
7879 fileloc loc
= sRef_getNullInfoLoc (s
);
7881 if (fileloc_isDefined (loc
) && !fileloc_isLib (loc
))
7884 (message ("Storage %qbecomes null", sRef_unparseOpt (s
)),
7891 fileloc loc
= sRef_getNullInfoLoc (s
);
7893 if (fileloc_isDefined (loc
) && !fileloc_isLib (loc
))
7895 llgenindentmsg (message ("Storage %qbecomes null", sRef_unparseOpt (s
)),
7903 (message ("Storage %qmay become null", sRef_unparseOpt (s
)),
7904 sRef_getNullInfoLoc (s
));
7909 (message ("Storage %qbecomes not null", sRef_unparseOpt (s
)),
7910 sRef_getNullInfoLoc (s
));
7914 (message ("Storage %qnull state becomes unknown",
7915 sRef_unparseOpt (s
)),
7916 sRef_getNullInfoLoc (s
));
7925 (message ("<error case> Storage %q becomes %s",
7927 nstate_unparse (sRef_getNullState (s
))),
7928 sRef_getNullInfoLoc (s
));
7936 sRef_showAliasInfo (sRef s
)
7938 if (sRef_isValid (s
))
7940 if (sRef_isFresh (s
))
7942 if (context_getLocIndentSpaces () == 0) {
7943 stateInfo_display (s
->aliasinfo
, message (" Fresh storage %q", sRef_unparseOpt (s
)));
7945 stateInfo_display (s
->aliasinfo
, message ("Fresh storage %q", sRef_unparseOpt (s
)));
7950 if (context_getLocIndentSpaces () == 0) {
7951 stateInfo_display (s
->aliasinfo
, message (" Storage %q", sRef_unparseOpt (s
)));
7953 stateInfo_display (s
->aliasinfo
, message ("Storage %q", sRef_unparseOpt (s
)));
7960 sRef_mergeNullState (sRef s
, nstate n
)
7962 if (sRef_isReasonable (s
))
7966 old
= sRef_getNullState (s
);
7968 if (n
!= old
&& n
!= NS_UNKNOWN
)
7970 sRef_setNullState (s
, n
, g_currentloc
);
7975 llbuglit ("sRef_mergeNullState: invalid");
7980 sRef_possiblyNull (sRef s
)
7982 if (sRef_isReasonable (s
))
7984 if (sRef_getNullState (s
) == NS_ABSNULL
)
7986 ctype rct
= ctype_realType (s
->type
);
7988 if (ctype_isAbstract (rct
))
7994 if (ctype_isUser (rct
))
7996 uentry ue
= usymtab_getTypeEntry (ctype_typeId (rct
));
7998 return (nstate_possiblyNull
7999 (sRef_getNullState (uentry_getSref (ue
))));
8009 return nstate_possiblyNull (sRef_getNullState (s
));
8017 sRef_getScopeName (sRef s
)
8019 sRef base
= sRef_getRootBase (s
);
8021 if (sRef_isRealGlobal (base
))
8023 return (cstring_makeLiteralTemp ("Global"));
8025 else if (sRef_isFileStatic (base
))
8027 return (cstring_makeLiteralTemp ("Static"));
8031 return (cstring_makeLiteralTemp ("Local"));
8036 sRef_unparseScope (sRef s
)
8038 sRef base
= sRef_getRootBase (s
);
8040 if (sRef_isRealGlobal (base
))
8042 return (cstring_makeLiteralTemp ("global"));
8044 else if (sRef_isFileStatic (base
))
8046 return (cstring_makeLiteralTemp ("file static"));
8055 sRef_getScope (sRef s
)
8057 llassert (sRef_isReasonable (s
));
8059 if (sRef_isCvar (s
))
8061 return s
->info
->cvar
->lexlevel
;
8063 else if (sRef_isParam (s
))
8074 sRef_isDead (sRef s
)
8076 return (sRef_isReasonable (s
) && (s
)->defstate
== SS_DEAD
);
8080 sRef_isDeadStorage (sRef s
)
8082 if (sRef_isReasonable (s
))
8084 if (s
->defstate
== SS_DEAD
8085 || s
->defstate
== SS_UNUSEABLE
8086 || s
->defstate
== SS_UNDEFINED
8087 || s
->defstate
== SS_UNKNOWN
)
8093 return (sRef_isDefinitelyNull (s
));
8103 sRef_isPossiblyDead (sRef s
)
8105 return (sRef_isReasonable (s
) && s
->defstate
== SS_HOFFA
);
8108 bool sRef_isStateLive (sRef s
)
8110 if (sRef_isReasonable (s
))
8112 sstate ds
= s
->defstate
;
8114 return (!(ds
== SS_UNDEFINED
8116 || ds
== SS_UNUSEABLE
8117 || ds
== SS_HOFFA
));
8126 bool sRef_isStateUndefined (sRef s
)
8128 return ((sRef_isReasonable(s
)) && ((s
)->defstate
== SS_UNDEFINED
));
8131 bool sRef_isJustAllocated (sRef s
)
8133 if (sRef_isAllocated (s
))
8135 sRefSet_allElements (s
->deriv
, el
)
8137 if (!(sRef_isStateUndefined (el
) || sRef_isUnuseable (el
)))
8141 } end_sRefSet_allElements
;
8150 sRef_isAllocatedStorage (sRef s
)
8152 if (sRef_isReasonable (s
) && ynm_toBoolStrict (sRef_isValidLvalue (s
)))
8154 return (ctype_isVisiblySharable (sRef_getType (s
)));
8163 sRef_isUnuseable (sRef s
)
8165 return ((sRef_isValid(s
)) && ((s
)->defstate
== SS_UNUSEABLE
));
8169 sRef_perhapsNull (sRef s
)
8171 if (sRef_isReasonable (s
))
8173 if (sRef_getNullState (s
) == NS_ABSNULL
)
8175 ctype rct
= ctype_realType (s
->type
);
8177 if (ctype_isAbstract (rct
))
8183 if (ctype_isUser (rct
))
8185 uentry ue
= usymtab_getTypeEntry (ctype_typeId (rct
));
8187 return (nstate_perhapsNull
8188 (sRef_getNullState (uentry_getSref (ue
))));
8198 return nstate_perhapsNull (sRef_getNullState (s
));
8206 ** definitelyNull --- called when TRUE is good
8210 sRef_definitelyNull (sRef s
)
8212 return (sRef_isReasonable (s
)
8213 && (sRef_getNullState (s
) == NS_DEFNULL
|| sRef_getNullState (s
) == NS_CONSTNULL
));
8217 ** based on sRef_similar
8221 sRef_setDerivNullState (sRef set
, sRef guide
, nstate ns
)
8223 if (sRef_isReasonable (set
))
8225 sRef deriv
= sRef_getDeriv (set
, guide
);
8227 if (sRef_isReasonable (deriv
))
8229 sRef_setNullStateN (deriv
, ns
);
8234 static /*@exposed@*/ sRef
8235 sRef_getDeriv (/*@returned@*/ /*@notnull@*/ sRef set
, sRef guide
)
8237 llassert (sRef_isReasonable (set
));
8238 llassert (sRef_isReasonable (guide
));
8240 switch (guide
->kind
)
8243 llassert (set
->kind
== SK_CVAR
);
8247 llassert (set
->kind
== guide
->kind
);
8248 llassert (set
->info
->paramno
== guide
->info
->paramno
);
8253 if (set
->kind
== SK_ARRAYFETCH
8254 && (sRef_similar (set
->info
->arrayfetch
->arr
,
8255 guide
->info
->arrayfetch
->arr
)))
8261 return (sRef_makeAnyArrayFetch
8262 (sRef_getDeriv (set
, guide
->info
->arrayfetch
->arr
)));
8267 if (set
->kind
== SK_PTR
&& sRef_similar (set
->info
->ref
, guide
->info
->ref
))
8273 return (sRef_makePointer (sRef_getDeriv (set
, guide
->info
->ref
)));
8278 if ((set
->kind
== SK_FIELD
&&
8279 (sRef_similar (set
->info
->field
->rec
, guide
->info
->field
->rec
) &&
8280 cstring_equal (set
->info
->field
->field
, guide
->info
->field
->field
))))
8286 return (sRef_makeField (sRef_getDeriv (set
, guide
->info
->field
->rec
),
8287 guide
->info
->field
->field
));
8291 if ((set
->kind
== SK_ADR
) && sRef_similar (set
->info
->ref
, guide
->info
->ref
))
8297 return (sRef_makeAddress (sRef_getDeriv (set
, guide
->info
->ref
)));
8302 return sRef_undefined
;
8306 case SK_UNCONSTRAINED
:
8314 return sRef_undefined
;
8321 ** sRef_aliasCheckPred
8323 ** A confusing but spiffy function:
8325 ** Calls predf (s, e, text, <alias>) on s and all of s's aliases
8326 ** (unless checkAliases (s) is FALSE).
8328 ** For alias calls, calls as
8329 ** predf (alias, e, text, s)
8333 sRef_aliasCheckPred (bool (predf
) (sRef
, exprNode
, sRef
, exprNode
),
8334 /*@null@*/ bool (checkAliases
) (sRef
),
8335 sRef s
, exprNode e
, exprNode err
)
8337 bool error
= (*predf
)(s
, e
, sRef_undefined
, err
);
8340 if (checkAliases
!= NULL
&& !(checkAliases (s
)))
8342 /* don't check aliases */
8346 sRefSet aliases
= usymtab_allAliases (s
);
8348 sRefSet_realElements (aliases
, current
)
8350 if (sRef_isReasonable (current
))
8352 if (sRef_isReasonable (current
))
8354 if (!sRef_similar (current
, s
)
8355 || (error
&& sRef_sameName (current
, s
)))
8357 (void) (*predf
)(current
, e
, s
, err
);
8362 llcontbug (message ("Invalid sRef as alias field of %s", sRef_unparse (s
)));
8365 } end_sRefSet_realElements
;
8367 sRefSet_free (aliases
);
8372 ** return TRUE iff predf (s) is true for s or any alias of s
8376 sRef_aliasCheckSimplePred (sRefTest predf
, sRef s
)
8387 aliases
= usymtab_allAliases (s
);
8389 sRefSet_realElements (aliases
, current
)
8391 if (sRef_isReasonable (current
))
8393 sRef cref
= sRef_updateSref (current
);
8395 /* Whoa! a very kludgey way to make sure the right sref is used
8396 ** where there is a conditional symbol table. I am beginning
8397 ** to think that having a conditional symbol table wasn't such
8403 DPRINTF (("Checking alias: %s", sRef_unparseFull (cref
)));
8404 sRefSet_free (aliases
);
8408 } end_sRefSet_realElements
;
8410 sRefSet_free (aliases
);
8416 sRef_aliasCompleteSimplePred (bool (predf
) (sRef
), sRef s
)
8419 bool result
= FALSE
;
8422 aliases
= usymtab_allAliases (s
);
8424 if ((*predf
)(s
)) result
= TRUE
;
8427 sRefSet_realElements (aliases
, current
)
8429 if (sRef_isReasonable (current
))
8431 current
= sRef_updateSref (current
);
8432 if ((*predf
)(current
)) result
= TRUE
;
8434 } end_sRefSet_realElements
;
8436 sRefSet_free (aliases
);
8441 sRef_aliasSetComplete (void (predf
) (sRef
, fileloc
), sRef s
, fileloc loc
)
8445 aliases
= usymtab_allAliases (s
);
8447 DPRINTF (("All aliases: %s --> %s", sRef_unparseFull (s
), sRefSet_unparseFull (aliases
)));
8451 sRefSet_realElements (aliases
, current
)
8453 if (sRef_isReasonable (current
))
8455 DPRINTF (("Update: %s", sRef_unparseFull (current
)));
8456 current
= sRef_updateSref (current
);
8457 DPRINTF (("Updated ==> %s", sRef_unparseFull (current
)));
8458 ((*predf
)(current
, loc
));
8459 DPRINTF (("Killed: %s", sRef_unparseFull (current
)));
8461 } end_sRefSet_realElements
;
8463 sRefSet_free (aliases
);
8467 sRef_aliasSetCompleteParam (void (predf
) (sRef
, int, fileloc
), sRef s
,
8468 int kind
, fileloc loc
)
8472 if (sRef_isDeep (s
))
8474 aliases
= usymtab_allAliases (s
);
8478 aliases
= usymtab_aliasedBy (s
);
8481 (*predf
)(s
, kind
, loc
);
8483 sRefSet_realElements (aliases
, current
)
8485 if (sRef_isReasonable (current
))
8487 current
= sRef_updateSref (current
);
8488 ((*predf
)(current
, kind
, loc
));
8490 } end_sRefSet_realElements
;
8492 sRefSet_free (aliases
);
8496 ** Version of aliasSetCompleteParam for alkind parameters
8500 sRef_aliasSetCompleteAlkParam (void (predf
) (sRef
, alkind
, fileloc
), sRef s
,
8501 alkind kind
, fileloc loc
)
8505 if (sRef_isDeep (s
))
8507 aliases
= usymtab_allAliases (s
);
8511 aliases
= usymtab_aliasedBy (s
);
8514 (*predf
)(s
, kind
, loc
);
8516 sRefSet_realElements (aliases
, current
)
8518 if (sRef_isReasonable (current
))
8520 current
= sRef_updateSref (current
);
8521 ((*predf
)(current
, kind
, loc
));
8523 } end_sRefSet_realElements
;
8525 sRefSet_free (aliases
);
8529 sRef_innerAliasSetComplete (void (predf
) (sRef
, fileloc
), sRef s
, fileloc loc
)
8535 if (!sRef_isReasonable (s
)) return;
8538 ** Type equivalence checking is necessary --- there might be casting.
8545 case SK_UNCONSTRAINED
:
8550 inner
= s
->info
->ref
;
8551 aliases
= usymtab_allAliases (inner
);
8552 ct
= sRef_getType (inner
);
8554 sRefSet_realElements (aliases
, current
)
8556 if (sRef_isReasonable (current
))
8558 current
= sRef_updateSref (current
);
8560 if (ctype_equal (ct
, sRef_getType (current
)))
8562 sRef ptr
= sRef_makePointer (current
);
8563 ((*predf
)(ptr
, loc
));
8566 } end_sRefSet_realElements
;
8568 sRefSet_free (aliases
);
8571 inner
= s
->info
->arrayfetch
->arr
;
8572 aliases
= usymtab_allAliases (inner
);
8573 ct
= sRef_getType (inner
);
8575 DPRINTF (("Array fetch: %s", sRefSet_unparse (aliases
)));
8577 sRefSet_realElements (aliases
, current
)
8579 if (sRef_isReasonable (current
))
8581 current
= sRef_updateSref (current
);
8582 DPRINTF (("Current: %s", sRef_unparseFull (current
)));
8584 if (ctype_equal (ct
, sRef_getType (current
)))
8586 if (s
->info
->arrayfetch
->indknown
)
8588 sRef af
= sRef_makeArrayFetchKnown (current
, s
->info
->arrayfetch
->ind
);
8589 DPRINTF (("Defining: %s", sRef_unparseFull (af
)));
8590 /* evans 2001-08-27 This isn't true:
8591 llassert (af->info->arrayfetch->arr == current);
8592 see comments in buildArrayFetchKnown
8594 ((*predf
)(af
, loc
));
8598 sRef af
= sRef_makeArrayFetch (current
);
8599 /* evans 2001-08-27 This isn't true:
8600 llassert (af->info->arrayfetch->arr == current);
8601 see comments in buildArrayFetch
8603 DPRINTF (("Defining: %s", sRef_unparseFull (af
)));
8604 ((*predf
)(af
, loc
));
8609 DPRINTF (("Type mismatch: %s / %s",
8611 ctype_unparse (sRef_getType (current
))));
8614 } end_sRefSet_realElements
;
8616 sRefSet_free (aliases
);
8619 inner
= s
->info
->field
->rec
;
8620 aliases
= usymtab_allAliases (inner
);
8621 ct
= sRef_getType (inner
);
8623 sRefSet_realElements (aliases
, current
)
8625 if (sRef_isReasonable (current
))
8627 current
= sRef_updateSref (current
);
8629 if (ctype_equal (ct
, sRef_getType (current
)))
8631 sRef f
= sRef_makeField (current
, s
->info
->field
->field
);
8636 } end_sRefSet_realElements
;
8638 sRefSet_free (aliases
);
8641 sRef_innerAliasSetComplete (predf
, s
->info
->conj
->a
, loc
);
8642 sRef_innerAliasSetComplete (predf
, s
->info
->conj
->b
, loc
);
8659 sRef_innerAliasSetCompleteParam (void (predf
) (sRef
, sRef
), sRef s
, sRef t
)
8665 if (!sRef_isReasonable (s
)) return;
8668 ** Type equivalence checking is necessary --- there might be casting.
8675 case SK_UNCONSTRAINED
:
8680 inner
= s
->info
->ref
;
8681 aliases
= usymtab_allAliases (inner
);
8682 ct
= sRef_getType (inner
);
8684 sRefSet_realElements (aliases
, current
)
8686 if (sRef_isReasonable (current
))
8688 current
= sRef_updateSref (current
);
8690 if (ctype_equal (ct
, sRef_getType (current
)))
8692 sRef ptr
= sRef_makePointer (current
);
8697 } end_sRefSet_realElements
;
8699 sRefSet_free (aliases
);
8702 inner
= s
->info
->arrayfetch
->arr
;
8703 aliases
= usymtab_allAliases (inner
);
8704 ct
= sRef_getType (inner
);
8706 sRefSet_realElements (aliases
, current
)
8708 if (sRef_isReasonable (current
))
8710 current
= sRef_updateSref (current
);
8712 if (ctype_equal (ct
, sRef_getType (current
)))
8715 if (s
->info
->arrayfetch
->indknown
)
8717 sRef af
= sRef_makeArrayFetchKnown (current
, s
->info
->arrayfetch
->ind
);
8723 sRef af
= sRef_makeArrayFetch (current
);
8729 } end_sRefSet_realElements
;
8731 sRefSet_free (aliases
);
8734 inner
= s
->info
->field
->rec
;
8735 aliases
= usymtab_allAliases (inner
);
8736 ct
= sRef_getType (inner
);
8739 sRefSet_realElements (aliases
, current
)
8741 if (sRef_isReasonable (current
))
8743 current
= sRef_updateSref (current
);
8745 if (ctype_equal (ct
, sRef_getType (current
)))
8747 sRef f
= sRef_makeField (current
, s
->info
->field
->field
);
8752 } end_sRefSet_realElements
;
8754 sRefSet_free (aliases
);
8757 sRef_innerAliasSetCompleteParam (predf
, s
->info
->conj
->a
, t
);
8758 sRef_innerAliasSetCompleteParam (predf
, s
->info
->conj
->b
, t
);
8774 static void sRef_combineExKinds (/*@notnull@*/ sRef res
, /*@notnull@*/ sRef other
)
8776 exkind a1
= sRef_getExKind (res
);
8777 exkind a2
= sRef_getExKind (other
);
8779 if (a1
== a2
|| a2
== XO_UNKNOWN
)
8783 else if (a1
== XO_UNKNOWN
)
8785 res
->expinfo
= stateInfo_update (res
->expinfo
, other
->expinfo
);
8790 res
->expkind
= XO_OBSERVER
;
8795 ** Currently, this is a very ad hoc implementation, with lots of fixes to
8796 ** make real code work okay. I need to come up with some more general
8797 ** rules or principles here.
8801 sRef_combineAliasKindsError (/*@notnull@*/ sRef res
,
8802 /*@notnull@*/ sRef other
,
8803 clause cl
, fileloc loc
)
8805 bool hasError
= FALSE
;
8806 alkind ares
= sRef_getAliasKind (res
);
8807 alkind aother
= sRef_getAliasKind (other
);
8809 sRef_checkMutable (res
);
8811 if (alkind_isDependent (ares
))
8813 if (aother
== AK_KEPT
)
8815 res
->aliasinfo
= stateInfo_update (res
->aliasinfo
, other
->aliasinfo
);
8816 res
->aliaskind
= AK_KEPT
;
8820 if (aother
== AK_LOCAL
|| aother
== AK_STATIC
8821 || alkind_isTemp (aother
))
8823 DPRINTF (("Setting dependent: %s", sRef_unparseFull (res
)));
8824 res
->aliaskind
= AK_DEPENDENT
;
8828 else if (alkind_isDependent (aother
))
8830 if (ares
== AK_KEPT
)
8832 res
->aliaskind
= AK_KEPT
;
8836 if (ares
== AK_LOCAL
|| ares
== AK_STATIC
|| alkind_isTemp (ares
))
8838 DPRINTF (("Setting dependent: %s", sRef_unparseFull (res
)));
8839 res
->aliasinfo
= stateInfo_update (res
->aliasinfo
, other
->aliasinfo
);
8840 res
->aliaskind
= AK_DEPENDENT
;
8844 else if ((ares
== AK_LOCAL
|| ares
== AK_UNIQUE
8845 || ares
== AK_STATIC
|| alkind_isTemp (ares
))
8846 && sRef_isFresh (other
))
8849 ** cases like: if (s == NULL) s = malloc...;
8850 ** don't generate errors
8853 if (usymtab_isAltDefinitelyNullDeep (res
))
8855 res
->aliaskind
= ares
;
8862 else if ((aother
== AK_LOCAL
|| aother
== AK_UNIQUE
8863 || aother
== AK_STATIC
|| alkind_isTemp (aother
))
8864 && sRef_isFresh (res
))
8867 ** cases like: if (s == NULL) s = malloc...;
8868 ** don't generate errors
8871 if (usymtab_isDefinitelyNullDeep (other
))
8873 res
->aliasinfo
= stateInfo_update (res
->aliasinfo
, other
->aliasinfo
);
8874 res
->aliaskind
= aother
;
8881 else if (ares
== AK_NEWREF
&& aother
== AK_REFCOUNTED
8882 && sRef_isConst (other
))
8884 res
->aliaskind
= AK_NEWREF
;
8886 else if (aother
== AK_NEWREF
&& ares
== AK_REFCOUNTED
8887 && sRef_isConst (res
))
8889 res
->aliasinfo
= stateInfo_update (res
->aliasinfo
, other
->aliasinfo
);
8890 res
->aliaskind
= AK_NEWREF
;
8892 else if (sRef_isLocalVar (res
)
8893 && ((ares
== AK_KEPT
&& aother
== AK_LOCAL
)
8894 || (aother
== AK_KEPT
&& ares
== AK_LOCAL
)))
8896 res
->aliaskind
= AK_KEPT
;
8898 else if ((ares
== AK_OWNED
&& aother
== AK_ONLY
)
8899 || (aother
== AK_OWNED
&& ares
== AK_ONLY
))
8901 res
->aliaskind
= AK_OWNED
;
8903 if (aother
== AK_OWNED
)
8905 res
->aliasinfo
= stateInfo_update (res
->aliasinfo
, other
->aliasinfo
);
8915 if (sRef_isThroughArrayFetch (res
))
8918 (FLG_BRANCHSTATE
, FLG_STRICTBRANCHSTATE
,
8920 ("Clauses exit with %q possibly referencing %s storage %s, "
8923 alkind_unparse (aother
),
8924 clause_nameTaken (cl
),
8925 alkind_unparse (ares
),
8926 clause_nameAlternate (cl
)),
8929 sRef_showAliasInfo (res
);
8930 sRef_showAliasInfo (other
);
8931 res
->aliaskind
= AK_ERROR
;
8935 if (ares
== AK_KEPT
|| aother
== AK_KEPT
)
8937 sRef_maybeKill (res
, loc
);
8945 message ("Clauses exit with %q referencing %s storage %s, "
8948 alkind_unparse (aother
),
8949 clause_nameTaken (cl
),
8950 alkind_unparse (ares
),
8951 clause_nameAlternate (cl
)),
8954 sRef_showAliasInfo (res
);
8955 sRef_showAliasInfo (other
);
8957 res
->aliaskind
= AK_ERROR
;
8961 res
->aliaskind
= (sRef_isLocalVar (res
) ? AK_LOCAL
: AK_UNKNOWN
);
8966 sRef_combineAliasKinds (/*@notnull@*/ sRef res
, /*@notnull@*/ sRef other
,
8967 clause cl
, fileloc loc
)
8969 alkind ares
= sRef_getAliasKind (res
);
8970 alkind aother
= sRef_getAliasKind (other
);
8972 sRef_checkMutable (res
);
8974 DPRINTF (("Combine alias kinds: \n\t%s / \n\t%s",
8975 sRef_unparseFull (res
), sRef_unparseFull (other
)));
8976 if (alkind_equal (ares
, aother
)
8977 || aother
== AK_UNKNOWN
8978 || aother
== AK_ERROR
)
8980 ; /* keep current state */
8982 else if (sRef_isDead (res
) || sRef_isDead (other
))
8984 /* dead error reported (or storage is dead) */
8985 res
->aliaskind
= AK_ERROR
;
8987 else if (ares
== AK_UNKNOWN
|| ares
== AK_ERROR
8988 || sRef_isStateUndefined (res
)
8989 || sRef_isDefinitelyNull (res
))
8991 res
->aliasinfo
= stateInfo_update (res
->aliasinfo
, other
->aliasinfo
);
8992 res
->aliaskind
= aother
;
8994 else if (sRef_isStateUndefined (other
)
8995 || sRef_isDefinitelyNull (other
))
8999 else if (((ares
== AK_UNIQUE
|| alkind_isTemp (ares
))
9000 && aother
== AK_LOCAL
)
9001 || ((aother
== AK_UNIQUE
|| alkind_isTemp (aother
))
9002 && ares
== AK_LOCAL
))
9004 if (ares
!= AK_LOCAL
)
9006 res
->aliasinfo
= stateInfo_update (res
->aliasinfo
, other
->aliasinfo
);
9009 res
->aliaskind
= AK_LOCAL
;
9011 else if ((ares
== AK_OWNED
&& aother
== AK_FRESH
)
9012 || (aother
== AK_OWNED
&& ares
== AK_FRESH
))
9014 if (ares
!= AK_FRESH
)
9016 res
->aliasinfo
= stateInfo_update (res
->aliasinfo
, other
->aliasinfo
);
9019 res
->aliaskind
= AK_FRESH
;
9021 else if ((ares
== AK_KEEP
&& aother
== AK_FRESH
) ||
9022 (aother
== AK_KEEP
&& ares
== AK_FRESH
))
9024 if (ares
!= AK_KEEP
)
9026 res
->aliasinfo
= stateInfo_update (res
->aliasinfo
, other
->aliasinfo
);
9029 res
->aliaskind
= AK_KEEP
;
9031 else if ((ares
== AK_LOCAL
&& aother
== AK_STACK
) ||
9032 (aother
== AK_LOCAL
&& ares
== AK_STACK
))
9034 if (ares
!= AK_STACK
)
9036 res
->aliasinfo
= stateInfo_update (res
->aliasinfo
, other
->aliasinfo
);
9039 res
->aliaskind
= AK_STACK
;
9041 else if ((ares
== AK_LOCAL
9042 && (aother
== AK_OWNED
&& sRef_isLocalVar (other
)))
9043 || (aother
== AK_LOCAL
9044 && (ares
== AK_OWNED
&& sRef_isLocalVar (res
))))
9046 if (ares
!= AK_LOCAL
)
9048 res
->aliasinfo
= stateInfo_update (res
->aliasinfo
, other
->aliasinfo
);
9051 res
->aliaskind
= AK_LOCAL
;
9053 else if ((ares
== AK_FRESH
&& alkind_isOnly (aother
))
9054 || (aother
== AK_FRESH
&& alkind_isOnly (ares
)))
9056 res
->aliaskind
= AK_FRESH
;
9058 else if ((aother
== AK_FRESH
&& sRef_definitelyNull (res
))
9059 || (ares
== AK_FRESH
&& sRef_definitelyNull (other
)))
9061 if (ares
!= AK_FRESH
)
9063 res
->aliasinfo
= stateInfo_update (res
->aliasinfo
, other
->aliasinfo
);
9064 res
->aliaskind
= AK_FRESH
;
9067 else if ((sRef_isFresh (res
) && sRef_isConst (other
))
9068 || (sRef_isFresh (other
) && sRef_isConst (res
)))
9071 ** for NULL constantants
9075 if (!sRef_isFresh (res
))
9077 res
->aliasinfo
= stateInfo_update (res
->aliasinfo
, other
->aliasinfo
);
9080 res
->aliaskind
= AK_FRESH
;
9082 else if ((alkind_isStatic (aother
) && sRef_isConst (res
))
9083 || (alkind_isStatic (ares
) && sRef_isConst (other
)))
9085 if (!alkind_isStatic (ares
))
9087 res
->aliasinfo
= stateInfo_update (res
->aliasinfo
, other
->aliasinfo
);
9088 res
->aliaskind
= AK_STATIC
;
9093 sRef_combineAliasKindsError (res
, other
, cl
, loc
);
9097 static void sRef_combineDefState (/*@notnull@*/ sRef res
,
9098 /*@notnull@*/ sRef other
)
9100 sstate s1
= res
->defstate
;
9101 sstate s2
= other
->defstate
;
9104 sRef_checkMutable (res
);
9106 if (s1
== s2
|| s2
== SS_UNKNOWN
)
9110 else if (s1
== SS_UNKNOWN
)
9119 if (s2
== SS_DEFINED
)
9125 llcontbuglit ("ssfixed: not implemented");
9134 flip
= (s2
!= SS_DEFINED
);
9152 res
->definfo
= stateInfo_update (res
->definfo
, other
->definfo
);
9157 extern /*@notnull@*/ sRef
sRef_getConjA (sRef s
)
9160 llassert (sRef_isConj (s
));
9162 ret
= s
->info
->conj
->a
;
9163 llassert (ret
!= NULL
);
9167 extern /*@notnull@*/ sRef
sRef_getConjB (sRef s
)
9170 llassert (sRef_isConj (s
));
9172 ret
= s
->info
->conj
->b
;
9173 llassert (ret
!= NULL
);
9177 extern /*@exposed@*/ sRef
sRef_makeArrow (sRef s
, /*@dependent@*/ cstring f
)
9182 p
= sRef_makePointer (s
);
9183 ret
= sRef_makeField (p
, f
);
9184 DPRINTF (("Arrow: %s => %s",
9185 sRef_unparseFull (s
), sRef_unparseFull (ret
)));
9189 extern /*@exposed@*/ sRef
sRef_buildArrow (sRef s
, cstring f
)
9194 p
= sRef_buildPointer (s
);
9195 ret
= sRef_buildField (p
, f
);
9200 static /*@null@*/ sinfo
sinfo_copy (/*@notnull@*/ sRef s
)
9207 ret
= (sinfo
) dmalloc (sizeof (*ret
));
9208 ret
->cvar
= (cref
) dmalloc (sizeof (*ret
->cvar
));
9209 ret
->cvar
->lexlevel
= s
->info
->cvar
->lexlevel
;
9210 ret
->cvar
->index
= s
->info
->cvar
->index
;
9214 ret
= (sinfo
) dmalloc (sizeof (*ret
));
9215 ret
->paramno
= s
->info
->paramno
;
9216 llassert (ret
->paramno
>= -1);
9220 ret
= (sinfo
) dmalloc (sizeof (*ret
));
9221 ret
->arrayfetch
= (ainfo
) dmalloc (sizeof (*ret
->arrayfetch
));
9222 ret
->arrayfetch
->indknown
= s
->info
->arrayfetch
->indknown
;
9223 ret
->arrayfetch
->ind
= s
->info
->arrayfetch
->ind
;
9224 ret
->arrayfetch
->arr
= s
->info
->arrayfetch
->arr
;
9228 ret
= (sinfo
) dmalloc (sizeof (*ret
));
9229 ret
->field
= (fldinfo
) dmalloc (sizeof (*ret
->field
));
9230 ret
->field
->rec
= s
->info
->field
->rec
;
9231 ret
->field
->field
= s
->info
->field
->field
;
9235 ret
= (sinfo
) dmalloc (sizeof (*ret
));
9236 ret
->object
= s
->info
->object
;
9243 ret
= (sinfo
) dmalloc (sizeof (*ret
));
9244 ret
->ref
= s
->info
->ref
; /* Ref_copy (s->info->ref); */
9248 ret
= (sinfo
) dmalloc (sizeof (*ret
));
9249 ret
->conj
= (cjinfo
) dmalloc (sizeof (*ret
->conj
));
9250 ret
->conj
->a
= s
->info
->conj
->a
; /* sRef_copy (s->info->conj->a); */
9251 ret
->conj
->b
= s
->info
->conj
->b
; /* sRef_copy (s->info->conj->b);*/
9254 ret
= (sinfo
) dmalloc (sizeof (*ret
));
9255 ret
->spec
= s
->info
->spec
;
9258 case SK_UNCONSTRAINED
:
9260 ret
= (sinfo
) dmalloc (sizeof (*ret
));
9261 ret
->fname
= s
->info
->fname
;
9265 llassertprint (s
->info
== NULL
, ("s = %s", sRef_unparse (s
)));
9273 static /*@null@*/ sinfo
sinfo_fullCopy (/*@notnull@*/ sRef s
)
9278 ** Since its a full copy, only storage is assigned
9279 ** to dependent fields.
9286 ret
= (sinfo
) dmalloc (sizeof (*ret
));
9287 ret
->cvar
= (cref
) dmalloc (sizeof (*ret
->cvar
));
9288 ret
->cvar
->lexlevel
= s
->info
->cvar
->lexlevel
;
9289 ret
->cvar
->index
= s
->info
->cvar
->index
;
9293 ret
= (sinfo
) dmalloc (sizeof (*ret
));
9294 ret
->paramno
= s
->info
->paramno
;
9295 llassert (ret
->paramno
>= -1);
9299 ret
= (sinfo
) dmalloc (sizeof (*ret
));
9300 ret
->arrayfetch
= (ainfo
) dmalloc (sizeof (*ret
->arrayfetch
));
9301 ret
->arrayfetch
->indknown
= s
->info
->arrayfetch
->indknown
;
9302 ret
->arrayfetch
->ind
= s
->info
->arrayfetch
->ind
;
9303 ret
->arrayfetch
->arr
= sRef_saveCopy (s
->info
->arrayfetch
->arr
);
9307 ret
= (sinfo
) dmalloc (sizeof (*ret
));
9308 ret
->field
= (fldinfo
) dmalloc (sizeof (*ret
->field
));
9309 ret
->field
->rec
= sRef_saveCopy (s
->info
->field
->rec
);
9310 ret
->field
->field
= s
->info
->field
->field
;
9314 ret
= (sinfo
) dmalloc (sizeof (*ret
));
9315 ret
->object
= s
->info
->object
;
9322 ret
= (sinfo
) dmalloc (sizeof (*ret
));
9323 ret
->ref
= sRef_saveCopy (s
->info
->ref
);
9327 ret
= (sinfo
) dmalloc (sizeof (*ret
));
9328 ret
->conj
= (cjinfo
) dmalloc (sizeof (*ret
->conj
));
9329 ret
->conj
->a
= sRef_saveCopy (s
->info
->conj
->a
);
9330 ret
->conj
->b
= sRef_saveCopy (s
->info
->conj
->b
);
9333 ret
= (sinfo
) dmalloc (sizeof (*ret
));
9334 ret
->spec
= s
->info
->spec
;
9337 case SK_UNCONSTRAINED
:
9338 ret
= (sinfo
) dmalloc (sizeof (*ret
));
9339 ret
->fname
= s
->info
->fname
;
9345 llassert (s
->info
== NULL
);
9355 sinfo_update (/*@notnull@*/ /*@exposed@*/ sRef res
,
9356 /*@notnull@*/ /*@exposed@*/ sRef other
)
9358 llassert (res
->kind
== other
->kind
);
9363 res
->info
->cvar
->lexlevel
= other
->info
->cvar
->lexlevel
;
9364 res
->info
->cvar
->index
= other
->info
->cvar
->index
;
9368 res
->info
->paramno
= other
->info
->paramno
;
9369 llassert (res
->info
->paramno
>= -1);
9373 res
->info
->arrayfetch
->indknown
= other
->info
->arrayfetch
->indknown
;
9374 res
->info
->arrayfetch
->ind
= other
->info
->arrayfetch
->ind
;
9375 res
->info
->arrayfetch
->arr
= other
->info
->arrayfetch
->arr
;
9379 res
->info
->field
->rec
= other
->info
->field
->rec
;
9380 res
->info
->field
->field
= other
->info
->field
->field
;
9384 res
->info
->object
= other
->info
->object
;
9391 res
->info
->ref
= other
->info
->ref
;
9395 res
->info
->conj
->a
= other
->info
->conj
->a
;
9396 res
->info
->conj
->b
= other
->info
->conj
->b
;
9400 res
->info
->spec
= other
->info
->spec
;
9404 case SK_UNCONSTRAINED
:
9405 res
->info
->fname
= other
->info
->fname
;
9409 llassert (res
->info
== NULL
);
9414 static void sinfo_free (/*@special@*/ /*@temp@*/ /*@notnull@*/ sRef s
)
9415 /*@uses s->kind, s->info@*/
9416 /*@releases s->info@*/
9421 DPRINTF (("Free sinfo: [%p]", s
->info
->cvar
));
9422 sfree (s
->info
->cvar
);
9429 DPRINTF (("Free sinfo: [%p]", s
->info
->arrayfetch
));
9430 sfree (s
->info
->arrayfetch
);
9434 DPRINTF (("Free sinfo: [%p]", s
->info
->field
));
9435 sfree (s
->info
->field
);
9444 case SK_EXTERNAL
: /* is copy now! */
9448 DPRINTF (("Free sinfo: [%p]", s
->info
->conj
));
9449 sfree (s
->info
->conj
);
9456 if (s
->info
!= NULL
) {
9457 DPRINTF (("Free sinfo: [%p]", s
->info
));
9463 bool sRef_isNSLocalVar (sRef s
)
9465 if (sRef_isLocalVar (s
))
9467 uentry ue
= sRef_getUentry (s
);
9469 return (!uentry_isStatic (ue
));
9477 bool sRef_isLocalVar (sRef s
)
9479 if (sRef_isValid(s
))
9481 return (s
->kind
== SK_CVAR
9482 && (s
->info
->cvar
->lexlevel
> fileScope
));
9488 bool sRef_isRealLocalVar (sRef s
)
9490 if (sRef_isValid(s
))
9492 if (s
->kind
== SK_CVAR
)
9494 if (s
->info
->cvar
->lexlevel
== functionScope
)
9496 uentry ue
= sRef_getUentry (s
);
9498 if (uentry_isAnyParam (ue
)
9499 || uentry_isRefParam (ue
))
9510 return (s
->info
->cvar
->lexlevel
> functionScope
);
9518 bool sRef_isLocalParamVar (sRef s
)
9520 if (sRef_isValid(s
))
9522 return (s
->kind
== SK_PARAM
9523 || (s
->kind
== SK_CVAR
9524 && (s
->info
->cvar
->lexlevel
> fileScope
)));
9530 static speckind
speckind_fromInt (int i
)
9533 llassert (i
>= SR_NOTHING
&& i
<= SR_SYSTEM
);
9536 return ((speckind
) i
);
9540 static void sRef_updateNullState (/*@notnull@*/ sRef res
, /*@notnull@*/ sRef other
)
9543 res
->nullstate
= other
->nullstate
;
9544 DPRINTF (("update null state==> %s", sRef_unparseFull (res
)));
9545 res
->nullinfo
= stateInfo_update (res
->nullinfo
, other
->nullinfo
);
9546 sRef_resetAliasKind (res
);
9549 void sRef_combineNullState (/*@notnull@*/ sRef res
, /*@notnull@*/ sRef other
)
9551 nstate n1
= sRef_getNullState (res
);
9552 nstate n2
= sRef_getNullState (other
);
9556 if (n1
== n2
|| n2
== NS_UNKNOWN
)
9562 /* note: n2 is not unknown or defnull */
9566 case NS_ERROR
: nn
= NS_ERROR
; break;
9567 case NS_UNKNOWN
: flip
= TRUE
; nn
= n2
; break;
9568 case NS_POSNULL
: break;
9569 case NS_DEFNULL
: nn
= NS_POSNULL
; break;
9570 case NS_RELNULL
: break;
9572 if (n2
== NS_MNOTNULL
)
9583 if (n2
== NS_NOTNULL
)
9602 res
->nullinfo
= stateInfo_update (res
->nullinfo
, other
->nullinfo
);
9605 res
->nullstate
= nn
;
9606 DPRINTF (("update null state==> %s", sRef_unparseFull (res
)));
9607 sRef_resetAliasKind (res
);
9610 cstring
sRef_nullMessage (sRef s
)
9612 llassert (sRef_isReasonable (s
));
9614 switch (sRef_getNullState (s
))
9618 return (cstring_makeLiteralTemp ("null"));
9620 return (cstring_makeLiteralTemp ("possibly null"));
9626 /*@observer@*/ cstring
sRef_ntMessage (sRef s
)
9628 llassert (sRef_isReasonable (s
));
9630 switch (s
->nullstate
)
9634 return (cstring_makeLiteralTemp ("not nullterminated"));
9636 return (cstring_makeLiteralTemp ("possibly non-nullterminated"));
9640 # endif /* DEADCODE */
9643 sRef
sRef_fixResultType (/*@returned@*/ sRef s
, ctype typ
, uentry ue
)
9645 sRef tmp
= sRef_undefined
;
9648 llassert (sRef_isReasonable (s
));
9659 tmp
= sRef_fixResultType (s
->info
->arrayfetch
->arr
, typ
, ue
);
9661 ct
= ctype_realType (sRef_getType (tmp
));
9664 if (ctype_isKnown (ct
))
9666 if (ctype_isAP (ct
))
9675 ("Special clause indexes non-array (%t): *%q",
9676 ct
, sRef_unparse (s
->info
->arrayfetch
->arr
)),
9677 uentry_whereLast (ue
));
9681 tmp
= sRef_fixResultType (s
->info
->arrayfetch
->arr
, typ
, ue
);
9683 if (s
->info
->arrayfetch
->indknown
)
9685 ret
= sRef_makeArrayFetchKnown (tmp
, s
->info
->arrayfetch
->ind
);
9689 ret
= sRef_makeArrayFetch (tmp
);
9695 sRef rec
= sRef_fixResultType (s
->info
->field
->rec
, typ
, ue
);
9696 ctype ct
= ctype_realType (sRef_getType (rec
));
9698 if (ctype_isKnown (ct
))
9700 if (ctype_isSU (ct
))
9702 if (uentry_isValid (uentryList_lookupField (ctype_getFields (ct
),
9703 s
->info
->field
->field
)))
9712 ("Special clause accesses non-existent field of result: %q.%s",
9713 sRef_unparse (rec
), s
->info
->field
->field
),
9714 uentry_whereLast (ue
));
9722 ("Special clause accesses field of non-struct or union result (%t): %q.%s",
9723 ct
, sRef_unparse (rec
), s
->info
->field
->field
),
9724 uentry_whereLast (ue
));
9728 ret
= sRef_makeField (tmp
, s
->info
->field
->field
);
9734 tmp
= sRef_fixResultType (s
->info
->ref
, typ
, ue
);
9736 ct
= ctype_realType (sRef_getType (tmp
));
9738 if (ctype_isKnown (ct
))
9740 if (ctype_isAP (ct
))
9749 ("Special clause dereferences non-pointer (%t): *%q",
9750 ct
, sRef_unparse (s
->info
->ref
)),
9751 uentry_whereLast (ue
));
9755 ret
= sRef_makePointer (tmp
);
9762 ("Special clause uses & operator (not allowed): &%q", sRef_unparse (s
->info
->ref
)),
9763 uentry_whereLast (ue
));
9772 bool sRef_isOnly (sRef s
)
9774 return (sRef_isValid(s
) && alkind_isOnly (s
->aliaskind
));
9777 bool sRef_isDependent (sRef s
)
9779 return (sRef_isValid(s
) && alkind_isDependent (s
->aliaskind
));
9782 bool sRef_isOwned (sRef s
)
9784 return (sRef_isReasonable (s
) && (s
->aliaskind
== AK_OWNED
));
9787 bool sRef_isKeep (sRef s
)
9789 return (sRef_isReasonable (s
) && (s
->aliaskind
== AK_KEEP
));
9793 bool sRef_isTemp (sRef s
)
9795 return (sRef_isReasonable (s
) && alkind_isTemp (s
->aliaskind
));
9797 # endif /* DEADCODE */
9799 bool sRef_isLocalState (sRef s
)
9801 return (sRef_isReasonable (s
) && (s
->aliaskind
== AK_LOCAL
));
9804 bool sRef_isUnique (sRef s
)
9806 return (sRef_isReasonable (s
) && (s
->aliaskind
== AK_UNIQUE
));
9809 bool sRef_isShared (sRef s
)
9811 return (sRef_isReasonable (s
) && (s
->aliaskind
== AK_SHARED
));
9814 bool sRef_isExposed (sRef s
)
9816 return (sRef_isReasonable (s
) && (s
->expkind
== XO_EXPOSED
));
9819 bool sRef_isObserver (sRef s
)
9821 return (sRef_isReasonable (s
) && (s
->expkind
== XO_OBSERVER
));
9824 bool sRef_isFresh (sRef s
)
9826 return (sRef_isReasonable (s
) && (s
->aliaskind
== AK_FRESH
));
9829 bool sRef_isDefinitelyNull (sRef s
)
9831 return (sRef_isReasonable (s
) && (sRef_getNullState (s
) == NS_DEFNULL
9832 || sRef_getNullState (s
) == NS_CONSTNULL
));
9835 bool sRef_isAllocated (sRef s
)
9837 return (sRef_isReasonable (s
) && (s
->defstate
== SS_ALLOCATED
));
9840 bool sRef_isStack (sRef s
)
9842 return (sRef_isReasonable (s
) && (s
->aliaskind
== AK_STACK
));
9845 bool sRef_isNotNull (sRef s
)
9847 return (sRef_isValid(s
) && (sRef_getNullState (s
) == NS_MNOTNULL
9848 || sRef_getNullState (s
) == NS_NOTNULL
));
9851 alkind
sRef_getAliasKind (sRef s
)
9853 if (sRef_isValid(s
)) {
9854 llassert (alkind_isValid (s
->aliaskind
));
9855 return s
->aliaskind
;
9861 nstate
sRef_getNullState (sRef s
)
9863 if (sRef_isReasonable (s
)) {
9864 llassert (nstate_isValid (s
->nullstate
));
9865 return s
->nullstate
;
9871 void sRef_reflectAnnotation (sRef s
, annotationInfo a
, fileloc loc
)
9873 if (sRef_isReasonable (s
))
9875 if (!valueTable_isDefined (s
->state
))
9877 s
->state
= valueTable_create (1);
9880 cstring_copy (metaStateInfo_getName (annotationInfo_getState (a
))),
9881 stateValue_create (annotationInfo_getValue (a
),
9882 stateInfo_makeLoc (loc
, SA_DECLARED
)));
9886 DPRINTF (("reflect loc: %s", fileloc_unparse (loc
)));
9889 metaStateInfo_getName (annotationInfo_getState (a
)),
9890 stateValue_create (annotationInfo_getValue (a
),
9891 stateInfo_makeLoc (loc
, SA_DECLARED
)));
9893 DPRINTF (("sref: %s", sRef_unparse (s
)));
9894 DPRINTF (("sref: %s", sRef_unparseFull (s
)));
9899 void sRef_setMetaStateValueComplete (sRef s
, cstring key
, int value
, fileloc loc
)
9901 sRefSet aliases
= usymtab_allAliases (s
);
9903 sRef_setMetaStateValue (s
, key
, value
, loc
);
9905 sRefSet_realElements (aliases
, current
)
9907 if (sRef_isReasonable (current
))
9909 current
= sRef_updateSref (current
);
9910 sRef_setMetaStateValue (current
, key
, value
, loc
);
9912 } end_sRefSet_realElements
;
9914 sRefSet_free (aliases
);
9917 void sRef_setMetaStateValue (sRef s
, cstring key
, int value
, fileloc loc
)
9919 sRef_checkMutable (s
);
9921 if (sRef_isReasonable (s
))
9923 if (!valueTable_isDefined (s
->state
))
9925 DPRINTF (("inserting state: %s: %s %d", sRef_unparse (s
), key
, value
));
9926 s
->state
= valueTable_create (1);
9927 valueTable_insert (s
->state
, cstring_copy (key
),
9928 stateValue_create (value
,
9929 stateInfo_makeLoc (loc
, SA_CHANGED
)));
9933 DPRINTF (("Updating state: %s: %s %d / %s", sRef_unparse (s
), key
, value
,
9934 fileloc_unparse (loc
)));
9935 if (valueTable_contains (s
->state
, key
))
9938 (s
->state
, key
, stateValue_create (value
,
9939 stateInfo_makeLoc (loc
, SA_CHANGED
)));
9944 (s
->state
, cstring_copy (key
),
9945 stateValue_create (value
, stateInfo_makeLoc (loc
, SA_CHANGED
)));
9948 DPRINTF (("After: %s", sRef_unparseFull (s
)));
9953 bool sRef_checkMetaStateValue (sRef s
, cstring key
, int value
)
9955 if (sRef_isReasonable (s
))
9957 if (valueTable_isDefined (s
->state
))
9961 DPRINTF (("check state: %s: %s %d", sRef_unparse (s
), key
, value
));
9963 val
= valueTable_lookup (s
->state
, key
);
9964 llassert (stateValue_isDefined (val
));
9965 return (stateValue_isError (val
)
9966 || stateValue_getValue (val
) == value
);
9979 /*@observer@*/ stateValue
sRef_getMetaStateValue (sRef s
, cstring key
)
9981 if (sRef_isReasonable (s
))
9983 if (valueTable_isDefined (s
->state
))
9987 val
= valueTable_lookup (s
->state
, key
);
9988 /* Okay if its not defined, just returns stateValue_undefined */
9993 return stateValue_undefined
;
9998 return stateValue_undefined
;
10002 /*@observer@*/ valueTable
sRef_getValueTable (sRef s
)
10004 DPRINTF (("Get value table: %s", sRef_unparse (s
)));
10006 if (sRef_isReasonable (s
))
10008 llassert (sRef_isReasonable (s
));
10009 DPRINTF (("Value table: %s", valueTable_unparse (s
->state
)));
10014 DPRINTF (("No value table!"));
10015 return valueTable_undefined
;
10019 bool sRef_makeStateSpecial (sRef s
)
10022 ** Default defined state can be made special.
10025 llassert (sRef_isReasonable (s
));
10027 if (s
->defstate
== SS_UNKNOWN
|| s
->defstate
== SS_DEFINED
|| s
->defstate
== SS_SPECIAL
)
10029 /* s->aliaskind = AK_IMPTEMP; */ /* evans 2001-07-23 shouldn't effect alias state */
10030 s
->defstate
= SS_SPECIAL
;
10031 DPRINTF (("Made special: %s", sRef_unparseFull (s
)));
10036 /* s->aliaskind = AK_IMPTEMP; */
10037 s
->defstate
= SS_SPECIAL
;
10042 void sRef_markImmutable (sRef s
)
10044 if (sRef_isReasonable (s
))
10046 DPRINTF (("Mark immutable: %s", sRef_unparseFull (s
)));
10051 bool sRef_definitelyNullContext (sRef s
)
10053 return (sRef_definitelyNull (s
)
10054 || usymtab_isDefinitelyNullDeep (s
));
10057 bool sRef_definitelyNullAltContext (sRef s
)
10059 return (sRef_definitelyNull (s
)
10060 || usymtab_isAltDefinitelyNullDeep (s
));
10065 /* start modifications */
10066 struct s_bbufinfo
sRef_getNullTerminatedState (sRef p_s
) {
10067 struct s_bbufinfo BUFSTATE_UNKNOWN
;
10068 BUFSTATE_UNKNOWN
.bufstate
= BB_NOTNULLTERMINATED
;
10069 BUFSTATE_UNKNOWN
.size
= 0;
10070 BUFSTATE_UNKNOWN
.len
= 0;
10072 if (sRef_isValid(p_s
))
10073 return p_s
->bufinfo
;
10074 return BUFSTATE_UNKNOWN
;
10076 # endif /* DEADCODE */
10078 void sRef_setNullTerminatedState(sRef p_s
) {
10079 if(sRef_isReasonable (p_s
)) {
10080 p_s
->bufinfo
.bufstate
= BB_NULLTERMINATED
;
10082 llfatalbug( message("sRef_setNT passed a invalid sRef\n"));
10087 void sRef_setPossiblyNullTerminatedState(sRef p_s
) {
10088 if( sRef_isReasonable (p_s
)) {
10089 p_s
->bufinfo
.bufstate
= BB_POSSIBLYNULLTERMINATED
;
10091 llfatalbug( message("sRef_setPossNT passed a invalid sRef\n"));
10095 void sRef_setNotNullTerminatedState(sRef p_s
) {
10096 if( sRef_isReasonable (p_s
)) {
10097 p_s
->bufinfo
.bufstate
= BB_NOTNULLTERMINATED
;
10099 llfatalbug( message("sRef_unsetNT passed a invalid sRef\n"));
10103 void sRef_setLen(sRef p_s
, int len
) {
10104 if (sRef_isReasonable (p_s
) && sRef_isNullTerminated(p_s
))
10106 p_s
->bufinfo
.len
= len
;
10110 llfatalbug( message("sRef_setLen passed an invalid sRef\n"));
10115 void sRef_setSize(sRef p_s
, int size
) {
10116 if( sRef_isValid(p_s
))
10118 p_s
->bufinfo
.size
= size
;
10122 llfatalbug( message("sRef_setSize passed a invalid sRef\n"));
10126 void sRef_resetLen(sRef p_s
) {
10127 if (sRef_isReasonable (p_s
))
10129 p_s
->bufinfo
.len
= 0;
10133 llfatalbug (message ("sRef_setLen passed an invalid sRef\n"));
10137 /*drl7x 11/28/2000 */
10139 bool sRef_isFixedArray (sRef p_s
) /*@*/ {
10141 c
= sRef_getType (p_s
);
10142 return ( ctype_isFixedArray (c
) );
10145 size_t sRef_getArraySize (sRef p_s
) /*@*/
10148 llassert (sRef_isFixedArray(p_s
) );
10149 DPRINTF (( message ("sRef_getArraySize getting array size for %s", sRef_unparse(p_s
) ) ));
10151 c
= sRef_getType (p_s
);
10152 return (ctype_getArraySize (c
));
10155 void sRef_setValue (sRef s
, multiVal val
)
10157 if (!sRef_isReasonable (s
))
10159 llcontbuglit ("Unreasonable sRef");
10160 llcontbug (message ("sRef: %s", sRef_unparse (s
)));
10164 multiVal_free (s
->val
);
10168 bool sRef_hasValue (sRef s
)
10170 return (sRef_isReasonable (s
)
10171 && multiVal_isDefined (s
->val
));
10174 multiVal
sRef_getValue (sRef s
)
10176 if (sRef_isReasonable (s
))
10181 return multiVal_undefined
;