1 /*
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 University of Virginia,
4 **         Massachusetts Institute of Technology
5 **
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.
10 **
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.
15 **
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.
19 **
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
23 */
24 /*
25 ** storeRef.c
26 **
27 ** Memory management:
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
31 **    function.
32 **
33 **    storeRefs in the file and global scopes are free'd by the uentry.
34 **
35 */
36 
37 # include "splintMacros.nf"
38 # include "basic.h"
39 # include "exprChecks.h"
40 # include "transferChecks.h"
41 # include "sRefTable.h"
42 # include "structNames.h"
43 
44 /*
45 ** Predicate functions that evaluate both arguments in order.
46 */
47 
48 /*@notfunction@*/
49 # define OR(a,b)  (a ? (b, TRUE) : b)
50 
51 /*@notfunction@*/
52 # define AND(a,b) (a ? b : (b, FALSE))
53 
54 static void sRef_checkValidAux (sRef p_s, sRefSet p_checkedsofar) /*@modifies p_checkedsofar@*/ ;
55 
56 static bool sRef_isDerived (sRef p_s) /*@*/ ;
57 
58 static /*@exposed@*/ sRef sRef_fixDirectBase (sRef p_s, sRef p_base)
59    /*@modifies p_base@*/ ;
60 
61 static void sRef_updateNullState (sRef p_res, sRef p_other) /*@modifies p_res@*/ ;
62 
63 static bool sRef_isAllocatedStorage (sRef p_s) /*@*/ ;
64 static void sRef_setNullErrorLoc (sRef p_s, fileloc) /*@*/ ;
65 static void sRef_setNullStateN (sRef p_s, nstate p_n) /*@modifies p_s@*/ ;
66 
67 static int sRef_depth (sRef p_s) /*@*/ ;
68 
69 static void
70   sRef_innerAliasSetComplete (void (p_predf) (sRef, fileloc), sRef p_s,
71 			      fileloc p_loc)
72   /*@modifies p_s@*/ ;
73 
74 static void
75 sRef_innerAliasSetCompleteParam (void (p_predf) (sRef, sRef), sRef p_s, sRef p_t)
76      /*@modifies p_s@*/ ;
77 
78 static speckind speckind_fromInt (int p_i);
79 static bool sRef_equivalent (sRef p_s1, sRef p_s2);
80 static bool sRef_isDeepUnionField (sRef p_s);
81 static void sRef_addDeriv (/*@notnull@*/ sRef p_s, /*@notnull@*/ /*@exposed@*/ sRef p_t);
82 static bool sRef_checkModify (sRef p_s, sRefSet p_sl) /*@*/ ;
83 
84 /*
85 ** If s is definitely null, it has no memory state.
86 */
87 
sRef_resetAliasKind(sRef s)88 static void sRef_resetAliasKind (/*@notnull@*/ sRef s) /*@modifies s->aliaskind@*/
89 {
90   if (s->nullstate == NS_DEFNULL)
91     {
92       /* s->aliaskind = AK_ERROR; */
93     }
94 }
95 
96 # ifdef DEBUGSPLINT
sRef_checkCompletelyReasonable(sRef s)97 extern void sRef_checkCompletelyReasonable (sRef s) /*@*/
98 {
99   DPRINTF (("Check sRef: [%p] %s / %s", s, sRef_unparse (s),
100 	    sRefSet_unparse (sRef_derivedFields (s))));
101 
102   if (sRef_isReasonable (s))
103     {
104       sRefSet_elements (s->deriv, el)
105 	{
106 	  llassert (el != s);
107 	  sRef_checkCompletelyReasonable (el);
108 	} end_sRefSet_elements ;
109     }
110 }
111 # endif
112 
sRef_isReasonable(sRef s)113 /*@falsewhennull@*/ bool sRef_isReasonable (sRef s) /*@*/
114 {
115   if (sRef_isValid (s))
116     {
117 # ifdef DEBUGSPLINT
118       if (!bool_isReasonable (s->safe)
119 	  || !bool_isReasonable (s->modified)
120 	  || !bool_isReasonable (s->immut))
121 	{
122 	  llcontbug (message ("Unreasonable sRef [%p]", s));
123 	  return FALSE;
124 	}
125 
126       if (!sstate_isValid (s->defstate))
127 	{
128 	  llcontbug (message ("Unreasonable sRef [%p]", s));
129 	  return FALSE;
130 	}
131 
132       if (!nstate_isValid (s->nullstate))
133 	{
134 	  llcontbug (message ("Unreasonable sRef [%p]", s));
135 	  return FALSE;
136 	}
137 
138       if (!alkind_isValid (s->aliaskind)
139 	  || !alkind_isValid (s->oaliaskind))
140 	{
141 	  llcontbug (message ("Unreasonable sRef [%p]", s));
142 	  return FALSE;
143 	}
144 
145       if (!exkind_isValid (s->expkind)
146 	  || !exkind_isValid (s->oexpkind))
147 	{
148 	  llcontbug (message ("Unreasonable sRef [%p]", s));
149 	  return FALSE;
150 	}
151 # endif
152 
153       return TRUE;
154     }
155 
156   return FALSE;
157 }
158 
sRef_isUnreasonable(sRef s)159 static /*@nullwhentrue@*/ bool sRef_isUnreasonable (sRef s) /*@*/
160 {
161   return (!sRef_isReasonable (s));
162 }
163 
sRef_checkMutable(sRef s)164 static void sRef_checkMutable (/*@unused@*/ sRef s)
165 {
166   if (sRef_isReasonable (s) && s->immut)
167     {
168       llcontbug (message ("Modification to sRef marked immutable: %q",
169 			  sRef_unparseFull (s)));
170     }
171 }
172 
skind_isSimple(skind sk)173 static bool skind_isSimple (skind sk)
174 {
175   switch (sk)
176     {
177     case SK_PARAM: case SK_CVAR: case SK_CONST:
178     case SK_OBJECT: case SK_UNKNOWN: case SK_NEW:
179       return TRUE;
180     default:
181       return FALSE;
182     }
183 }
184 
185 static void sinfo_free (/*@special@*/ /*@temp@*/ /*@notnull@*/ sRef p_s)
186    /*@uses p_s->kind, p_s->info@*/
187    /*@releases p_s->info@*/ ;
188 
189 static /*@null@*/ sinfo sinfo_copy (/*@notnull@*/ sRef p_s) /*@*/ ;
190 static void sRef_setPartsFromUentry (sRef p_s, uentry p_ue)
191    /*@modifies p_s@*/ ;
192 static bool checkDeadState (/*@notnull@*/ sRef p_el, /*@null@*/ sRef p_e2,
193 			    bool p_tbranch, fileloc p_loc);
194 static /*@dependent@*/ sRef sRef_constructPointerAux (/*@notnull@*/ /*@exposed@*/ sRef p_t) /*@*/ ;
195 
196 static void
197   sRef_combineExKinds (/*@notnull@*/ sRef p_res, /*@notnull@*/ sRef p_other)
198   /*@modifies p_res@*/ ;
199 
200 static void
201   sRef_combineAliasKinds (/*@notnull@*/ sRef p_res, /*@notnull@*/ sRef p_other,
202 			  clause p_cl, fileloc p_loc)
203   /*@modifies p_res@*/ ;
204 
205 static void
206   sRef_combineNullState (/*@notnull@*/ sRef p_res, /*@notnull@*/ sRef p_other)
207   /*@modifies p_res@*/ ;
208 
209 static void
210   sRef_combineDefState (/*@notnull@*/ sRef p_res, /*@notnull@*/ sRef p_other)
211   /*@modifies p_res@*/ ;
212 
213 static void sRef_setStateFromAbstractUentry (sRef p_s, uentry p_ue)
214   /*@modifies p_s@*/ ;
215 
216 static void
217   sinfo_update (/*@notnull@*/ /*@exposed@*/ sRef p_res,
218 		/*@notnull@*/ /*@exposed@*/ sRef p_other);
219 static void sRef_setDefinedAux (sRef p_s, fileloc p_loc, bool p_clear)
220    /*@modifies p_s@*/ ;
221 static void sRef_setDefinedNoClear (sRef p_s, fileloc p_loc)
222    /*@modifies p_s@*/ ;
223 static void sRef_setStateAux (sRef p_s, sstate p_ss, fileloc p_loc)
224    /*@modifies p_s@*/;
225 
226 static /*@exposed@*/ sRef
227   sRef_buildNCField (/*@exposed@*/ sRef p_rec, /*@exposed@*/ cstring p_f);
228 
229 static void
230   sRef_mergeStateAux (/*@notnull@*/ sRef p_res, /*@notnull@*/ sRef p_other,
231 		      clause p_cl, bool p_opt, fileloc p_loc,
232 		      bool p_doDerivs)
233   /*@modifies p_res, p_other@*/ ;
234 
235 static /*@null@*/ sinfo sinfo_fullCopy (/*@notnull@*/ sRef p_s);
236 static bool sRef_doModify (sRef p_s, sRefSet p_sl) /*@modifies p_s@*/ ;
237 static bool sRef_doModifyVal (sRef p_s, sRefSet p_sl) /*@modifies p_s@*/;
238 static bool sRef_checkModifyVal (sRef p_s, sRefSet p_sl) /*@*/ ;
239 
240 static /*@only@*/ sRefSet
241   sRef_mergeDerivs (/*@only@*/ sRefSet p_res, sRefSet p_other,
242 		    bool p_opt, clause p_cl, fileloc p_loc);
243 
244 static /*@only@*/ sRefSet
245   sRef_mergeUnionDerivs (/*@only@*/ sRefSet p_res,
246 			 /*@exposed@*/ sRefSet p_other,
247 			 bool p_opt, clause p_cl, fileloc p_loc);
248 
249 static /*@only@*/ sRefSet
250   sRef_mergePdefinedDerivs (/*@only@*/ sRefSet p_res, sRefSet p_other, bool p_opt,
251 			    clause p_cl, fileloc p_loc);
252 
253 static /*@only@*/ cstring sRef_unparseWithArgs (sRef p_s, uentryList p_args);
254 static /*@only@*/ cstring sRef_unparseNoArgs (sRef p_s);
255 
256 static /*@exposed@*/ sRef sRef_findDerivedPointer (sRef p_s);
257 static /*@exposed@*/ sRef sRef_findDerivedArrayFetch (/*@notnull@*/ sRef, bool, int, bool) ;
258 static /*@exposed@*/ sRef sRef_findDerivedField (/*@notnull@*/ sRef p_rec, cstring p_f);
259 static /*@exposed@*/ sRef
260   sRef_getDeriv (/*@notnull@*/ /*@returned@*/ sRef p_set, sRef p_guide);
261 
262 static bool inFunction = FALSE;
263 static /*@only@*/ sRefTable allRefs;
264 
265 /* # define DEBUGREFS  */
266 
267 # ifdef DEBUGREFS
268 static nsrefs = 0;
269 static totnsrefs = 0;
270 static maxnsrefs = 0;
271 static ntotrefers = 0;
272 static nrefers = 0;
273 # endif
274 
275 static /*@checked@*/ bool protectDerivs = FALSE;
276 
277 /*
278 ** Result of sRef_alloc is dependent since allRefs may
279 ** reference it.  It is only if !inFunction.
280 */
281 
282 static /*@dependent@*/ /*@out@*/ /*@notnull@*/ sRef
sRef_alloc(void)283 sRef_alloc (void)
284 {
285   sRef s = (sRef) dmalloc (sizeof (*s));
286 
287   s->immut = FALSE;
288 
289   DPRINTF (("Alloc sref: [%p]", s));
290 
291   if (inFunction)
292     {
293       allRefs = sRefTable_add (allRefs, s);
294       /*@-branchstate@*/
295     }
296   else
297     {
298       DPRINTF (("Not in function!"));
299     }
300 
301   /*@=branchstate@*/
302 
303 # ifdef DEBUGREFS
304   if (nsrefs >= maxnsrefs)
305     {
306       maxnsrefs = nsrefs;
307     }
308 
309   totnsrefs++;
310   nsrefs++;
311 # endif
312 
313   /*@-mustfree@*/ /*@-freshtrans@*/
314   return s;
315   /*@=mustfree@*/ /*@=freshtrans@*/
316 }
317 
sRef_checkValidAux(sRef s,sRefSet checkedsofar)318 static void sRef_checkValidAux (sRef s, sRefSet checkedsofar)
319 {
320   llassert (FALSE);
321 
322   if (!sRef_isReasonable (s)) return;
323 
324   if (sRefSet_containsSameObject (checkedsofar, s))
325     {
326       return;
327     }
328 
329   /*@-temptrans@*/
330   checkedsofar = sRefSet_insert (checkedsofar, s);
331   /*@=temptrans@*/ /* checksofar will be destroyed before checkValid returns */
332 
333   switch (s->kind)
334     {
335     case SK_UNCONSTRAINED:
336       llassert (cstring_length (s->info->fname) < 100);
337       break;
338 
339     case SK_CVAR:
340       llassert (s->info->cvar->lexlevel >= 0);
341       /* llassert (s->info->cvar->lexlevel <= usymtab_getCurrentDepth ()); */
342       break;
343 
344     case SK_PARAM:
345       llassert (s->info->paramno >= -1);
346       llassert (s->info->paramno <= 999); /* sanity check */
347       break;
348 
349     case SK_ARRAYFETCH:
350       sRef_checkValidAux (s->info->arrayfetch->arr, checkedsofar);
351       break;
352 
353     case SK_FIELD:
354       sRef_checkValidAux (s->info->field->rec, checkedsofar);
355       llassert (cstring_length (s->info->field->field) < 100);
356       break;
357 
358     case SK_PTR:
359       sRef_checkValidAux (s->info->ref, checkedsofar);
360       break;
361 
362    case SK_ADR:
363       sRef_checkValidAux (s->info->ref, checkedsofar);
364       break;
365 
366     case SK_OBJECT:
367       /* check ctype s->info->object */
368       break;
369 
370     case SK_CONJ:
371       sRef_checkValidAux (s->info->conj->a, checkedsofar);
372       sRef_checkValidAux (s->info->conj->b, checkedsofar);
373       break;
374 
375     case SK_NEW:
376       llassert (cstring_length (s->info->fname) < 100);
377       break;
378 
379     case SK_DERIVED:
380       sRef_checkValidAux (s->info->ref, checkedsofar);
381       break;
382 
383     case SK_EXTERNAL:
384       sRef_checkValidAux (s->info->ref, checkedsofar);
385       break;
386 
387     case SK_TYPE:
388     case SK_CONST:
389     case SK_RESULT:
390       /* check ctyp s->type */
391       break;
392 
393     case SK_SPECIAL:
394       llassert (s->info->spec == SR_NOTHING
395 		|| s->info->spec == SR_INTERNAL
396 		|| s->info->spec == SR_SPECSTATE
397 		|| s->info->spec == SR_SYSTEM);
398       break;
399 
400     case SK_UNKNOWN:
401       break;
402 
403       BADDEFAULT;
404     }
405 
406 
407   sRefSet_elements (s->deriv, el)
408     {
409       sRef_checkValidAux (el, checkedsofar);
410     } end_sRefSet_elements ;
411 }
412 
sRef_checkValid(sRef s)413 void sRef_checkValid (/*@unused@*/ sRef s)
414 {
415   return;
416   /*
417   sRefSet checkedsofar = sRefSet_new ();
418   sRef_checkValidAux (s, checkedsofar);
419   */
420 }
421 
422 static /*@dependent@*/ /*@notnull@*/ /*@special@*/ sRef
sRef_new(void)423   sRef_new (void)
424   /*@defines result@*/
425   /*@ensures isnull result->aliasinfo, result->definfo,
426                     result->expinfo, result->info, result->deriv, result->state@*/
427 {
428   sRef s = sRef_alloc ();
429 
430   s->kind = SK_UNKNOWN;
431   s->safe = TRUE;
432   s->modified = FALSE;
433   s->immut = FALSE;
434   s->val = multiVal_undefined;
435 
436   s->type = ctype_unknown;
437   s->defstate = SS_UNKNOWN;
438 
439   /* start modifications */
440   s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
441   s->bufinfo.size = -1;
442   s->bufinfo.len = -1;
443   /* end modifications */
444 
445   s->aliaskind = AK_UNKNOWN;
446   s->oaliaskind = AK_UNKNOWN;
447 
448   s->nullstate = NS_UNKNOWN;
449 
450   s->expkind = XO_UNKNOWN;
451   s->oexpkind = XO_UNKNOWN;
452 
453   s->aliasinfo = stateInfo_undefined;
454   s->definfo = stateInfo_undefined;
455   s->nullinfo = stateInfo_undefined;
456   s->expinfo = stateInfo_undefined;
457 
458   s->info = NULL;
459   s->deriv = sRefSet_undefined;
460 
461   s->state = valueTable_undefined;
462 
463   return s;
464 }
465 
466 static /*@dependent@*/ /*@notnull@*/ /*@special@*/ sRef
sRef_newRef(void)467   sRef_newRef (void)
468   /*@defines result@*/
469   /*@ensures isnull result->aliasinfo, result->definfo,
470                     result->expinfo, result->info, result->deriv@*/
471 {
472   sRef res = sRef_new ();
473   res->immut = FALSE;
474   res->state = valueTable_undefined;
475   return res;
476 }
477 
478 
sRef_protectDerivs(void)479 void sRef_protectDerivs (void) /*@modifies protectDerivs@*/
480 {
481   llassert (!protectDerivs);
482   protectDerivs = TRUE;
483 }
484 
sRef_clearProtectDerivs(void)485 void sRef_clearProtectDerivs (void) /*@modifies protectDerivs@*/
486 {
487   llassert (protectDerivs);
488   protectDerivs = FALSE;
489 }
490 
491 /*
492 ** hmmm...here be kind of a hack.  This function mysteriously appeared
493 ** in my code, but I'm sure I didn't write it.
494 */
495 
496 bool
sRef_isRecursiveField(sRef s)497 sRef_isRecursiveField (sRef s)
498 {
499   if (sRef_isField (s))
500     {
501       if (sRef_depth (s) > 13)
502 	{
503 	  sRef base;
504 	  cstring fieldname;
505 
506 	  fieldname = sRef_getField (s);
507 	  base = sRef_getBase (s);
508 
509 	  while (sRef_isReasonable (base))
510 	    {
511 	      if (sRef_isField (base))
512 		{
513 		  if (cstring_equal (fieldname, sRef_getField (base)))
514 		    {
515 		      return TRUE;
516 		    }
517 		}
518 
519 	      base = sRef_getBaseSafe (base);
520 	    }
521 	}
522     }
523 
524   return FALSE;
525 }
526 
527 static void
sRef_addDeriv(sRef s,sRef t)528 sRef_addDeriv (/*@notnull@*/ sRef s, /*@notnull@*/ /*@exposed@*/ sRef t)
529 {
530   if (!context_inProtectVars ()
531       && !protectDerivs
532       && sRef_isReasonable (s)
533       && sRef_isReasonable (t)
534       && !sRef_isConst (s))
535     {
536       int sd = sRef_depth (s);
537       int td = sRef_depth (t);
538 
539       if (sd >= td)
540 	{
541 	  return;
542 	}
543 
544       /* This sometimes fails: (evans 2001-07-12)
545       if (sRef_isArrayFetch (t))
546 	{
547 	  DPRINTF (("Derived fetch: %s / %s / %s",
548 		    sRef_unparseFull (s), sRef_unparseFull (t),
549 		    sRef_unparseFull (t->info->arrayfetch->arr)));
550 	  llassert (t->info->arrayfetch->arr == s);
551 	}
552       */
553 
554       if (sRef_isFileOrGlobalScope (s))
555 	{
556 	  if (context_inFunctionLike ()
557 	      && ctype_isKnown (sRef_getType (s))
558 	      && !ctype_isFunction (sRef_getType (s)))
559 	    {
560 	      globSet g = context_getUsedGlobs ();
561 
562 	      if (!globSet_member (g, s))
563 		{
564 		  /*
565 		  ** don't report as a bug
566 		  **
567 
568 		  llcontbug
569 			(message ("sRef_addDeriv: global variable not in used "
570 				  "globs: %q / %s / %q",
571 				  sRef_unparse (s),
572 				  ctype_unparse (sRef_getType (s)),
573 				  sRefSet_unparse (s->deriv)));
574 		  */
575 		}
576 	      else
577 		{
578 		  DPRINTF (("Add deriv: [%p] %s / [%p] %s",
579 			    s, sRef_unparse (s),
580 			    t, sRef_unparse (t)));
581 
582 		  s->deriv = sRefSet_insert (s->deriv, t);
583 		}
584 	    }
585 	}
586       else
587 	{
588 	  DPRINTF (("Add deriv: [%p] %s / [%p] %s",
589 		    s, sRef_unparse (s),
590 		    t, sRef_unparse (t)));
591 
592 	  s->deriv = sRefSet_insert (s->deriv, t);
593 	}
594     }
595 }
596 
597 bool
sRef_deepPred(bool (predf)(sRef),sRef s)598 sRef_deepPred (bool (predf) (sRef), sRef s)
599 {
600   if (sRef_isReasonable (s))
601     {
602       if ((*predf)(s)) return TRUE;
603 
604       switch (s->kind)
605 	{
606 	case SK_PTR:
607 	  return (sRef_deepPred (predf, s->info->ref));
608 	case SK_ARRAYFETCH:
609 	  return (sRef_deepPred (predf, s->info->arrayfetch->arr));
610 	case SK_FIELD:
611 	  return (sRef_deepPred (predf, s->info->field->rec));
612 	case SK_CONJ:
613 	  return (sRef_deepPred (predf, s->info->conj->a)
614 		  || sRef_deepPred (predf, s->info->conj->b));
615 	default:
616 	  return FALSE;
617 	}
618     }
619 
620   return FALSE;
621 }
622 
sRef_modInFunction(void)623 bool sRef_modInFunction (void)
624 {
625   return inFunction;
626 }
627 
sRef_setStateFromType(sRef s,ctype ct)628 void sRef_setStateFromType (sRef s, ctype ct)
629 {
630   if (sRef_isReasonable (s))
631     {
632       if (ctype_isUser (ct))
633 	{
634 	  DPRINTF (("Here we are: %s", sRef_unparseFull (s)));
635 	  sRef_setStateFromUentry
636 	    (s, usymtab_getTypeEntry (ctype_typeId (ct)));
637 	}
638       else if (ctype_isAbstract (ct))
639 	{
640 	  DPRINTF (("Here we are: %s", sRef_unparseFull (s)));
641 	  sRef_setStateFromAbstractUentry
642 	    (s, usymtab_getTypeEntry (ctype_typeId (ct)));
643 	}
644       else
645 	{
646 	  ; /* not a user type */
647 	}
648     }
649 }
650 
sRef_setTypeState(sRef s)651 static void sRef_setTypeState (sRef s)
652 {
653   if (sRef_isReasonable (s))
654     {
655       sRef_setStateFromType (s, s->type);
656     }
657 }
658 
sRef_hasAliasInfoLoc(sRef s)659 bool sRef_hasAliasInfoLoc (sRef s)
660 {
661   return (sRef_isReasonable (s) && (s->aliasinfo != NULL)
662 	  && (fileloc_isDefined (s->aliasinfo->loc)));
663 }
664 
sRef_hasStateInfoLoc(sRef s)665 /*@falsewhennull@*/ bool sRef_hasStateInfoLoc (sRef s)
666 {
667   return (sRef_isReasonable (s) && (s->definfo != NULL)
668 	  && (fileloc_isDefined (s->definfo->loc)));
669 }
670 
sRef_hasExpInfoLoc(sRef s)671 /*@falsewhennull@*/ bool sRef_hasExpInfoLoc (sRef s)
672 {
673   return (sRef_isReasonable (s)
674 	  && (s->expinfo != NULL) && (fileloc_isDefined (s->expinfo->loc)));
675 }
676 
677 # if 0
678 static /*@observer@*/ /*@unused@*/ stateInfo sRef_getInfo (sRef s, cstring key)
679 {
680   stateValue sv;
681 
682   if (!sRef_isReasonable (s)) {
683     return stateInfo_undefined;
684   }
685 
686   sv = valueTable_lookup (s->state, key);
687 
688   if (stateValue_isDefined (sv))
689     {
690       return stateValue_getInfo (sv);
691     }
692 
693   return stateInfo_undefined;
694 }
695 # endif
696 
697 static bool
sRef_hasNullInfoLoc(sRef s)698 sRef_hasNullInfoLoc (sRef s)
699 {
700   return (sRef_isReasonable (s) && s->nullinfo != NULL
701 	  && (fileloc_isDefined (s->nullinfo->loc)));
702 }
703 
704 bool
sRef_hasAliasInfoRef(sRef s)705 sRef_hasAliasInfoRef (sRef s)
706 {
707   return (sRef_isReasonable (s) && (s->aliasinfo != NULL)
708 	  && (sRef_isReasonable (s->aliasinfo->ref)));
709 }
710 
711 static /*@observer@*/ fileloc
sRef_getAliasInfoLoc(sRef s)712 sRef_getAliasInfoLoc (/*@exposed@*/ sRef s)
713 {
714   llassert (sRef_isReasonable (s) && s->aliasinfo != NULL
715 	    && (fileloc_isDefined (s->aliasinfo->loc)));
716   return (s->aliasinfo->loc);
717 }
718 
719 static /*@observer@*/ fileloc
sRef_getStateInfoLoc(sRef s)720 sRef_getStateInfoLoc (/*@exposed@*/ sRef s)
721 {
722   llassert (sRef_isReasonable (s) && s->definfo != NULL
723 	    && (fileloc_isDefined (s->definfo->loc)));
724   return (s->definfo->loc);
725 }
726 
727 static /*@observer@*/ fileloc
sRef_getExpInfoLoc(sRef s)728 sRef_getExpInfoLoc (/*@exposed@*/ sRef s)
729 {
730   llassert (sRef_isReasonable (s) && s->expinfo != NULL
731 	    && (fileloc_isDefined (s->expinfo->loc)));
732   return (s->expinfo->loc);
733 }
734 
735 static /*@observer@*/ fileloc
sRef_getNullInfoLoc(sRef s)736 sRef_getNullInfoLoc (/*@exposed@*/ sRef s)
737 {
738   llassert (sRef_isReasonable (s) && s->nullinfo != NULL
739 	    && (fileloc_isDefined (s->nullinfo->loc)));
740   return (s->nullinfo->loc);
741 }
742 
743 /*@observer@*/ sRef
sRef_getAliasInfoRef(sRef s)744   sRef_getAliasInfoRef (/*@temp@*/ sRef s)
745 {
746   llassert (sRef_isReasonable (s) && s->aliasinfo != NULL);
747   return (s->aliasinfo->ref);
748 }
749 
sRef_inGlobalScope()750 bool sRef_inGlobalScope ()
751 {
752   return !inFunction;
753 }
754 
755 /*
756 ** This function should be called before new sRefs are created
757 ** somewhere where they will have a lifetime greater than the
758 ** current function scope.
759 */
760 
sRef_setGlobalScope()761 void sRef_setGlobalScope ()
762 {
763   llassert (inFunction);
764   DPRINTF (("leave function"));
765   inFunction = FALSE;
766 }
767 
sRef_clearGlobalScope()768 void sRef_clearGlobalScope ()
769 {
770   llassert (!inFunction);
771   DPRINTF (("enter function"));
772   inFunction = TRUE;
773 }
774 
775 static bool oldInFunction = FALSE;
776 static int nestedScope = 0;
777 
sRef_setGlobalScopeSafe()778 void sRef_setGlobalScopeSafe ()
779 {
780   if (nestedScope == 0)
781     {
782       oldInFunction = inFunction;
783     }
784 
785   nestedScope++;
786   DPRINTF (("leave function safe"));
787   inFunction = FALSE;
788 }
789 
sRef_clearGlobalScopeSafe()790 void sRef_clearGlobalScopeSafe ()
791 {
792   nestedScope--;
793   llassert (nestedScope >= 0);
794 
795   if (nestedScope == 0)
796     {
797       inFunction = oldInFunction;
798     }
799 
800   DPRINTF (("clear function: %s", bool_unparse (inFunction)));
801 }
802 
sRef_enterFunctionScope()803 void sRef_enterFunctionScope ()
804 {
805   /* evans 2001-09-09 - cleanup if we are in a macro! */
806   if (context_inMacro ())
807     {
808       if (inFunction) {
809 	sRef_exitFunctionScope ();
810       }
811     }
812 
813   llassert (!inFunction);
814   llassert (sRefTable_isEmpty (allRefs));
815   inFunction = TRUE;
816   DPRINTF (("enter function"));
817 }
818 
sRef_exitFunctionScope()819 void sRef_exitFunctionScope ()
820 {
821   if (inFunction)
822     {
823       DPRINTF (("Exit function scope."));
824       sRefTable_clear (allRefs);
825       DPRINTF (("Exit function scope done."));
826       inFunction = FALSE;
827     }
828   else
829     {
830       llbuglit ("sRef_exitFunctionScope: not in function");
831     }
832 }
833 
sRef_destroyMod()834 void sRef_destroyMod () /*@globals killed allRefs;@*/
835 {
836 # ifdef DEBUGREFS
837   llmsg (message ("Live: %d / %d ", nsrefs, totnsrefs));
838 # endif
839 
840   sRefTable_free (allRefs);
841 }
842 
843 
844 static /*@notnull@*/ /*@exposed@*/ sRef
sRef_fixConj(sRef s)845 sRef_fixConj (/*@notnull@*/ sRef s)
846 {
847   if (sRef_isConj (s))
848     {
849       do {
850 	s = sRef_getConjA (s);
851       } while (sRef_isConj (s));
852 
853       llassert (sRef_isReasonable (s));
854       return s; /* don't need to ref */
855     }
856   else
857     {
858       return s;
859     }
860 }
861 
862 static bool
sRef_isExternallyVisibleAux(sRef s)863 sRef_isExternallyVisibleAux (sRef s)
864 {
865   bool res = FALSE;
866   sRef base = sRef_getRootBase (s);
867 
868   if (sRef_isReasonable (base))
869     {
870       res = sRef_isParam (base) || sRef_isFileOrGlobalScope (base) || sRef_isExternal (base);
871     }
872 
873   return res;
874 }
875 
876 bool
sRef_isExternallyVisible(sRef s)877   sRef_isExternallyVisible (sRef s)
878 {
879   return (sRef_aliasCheckSimplePred (sRef_isExternallyVisibleAux, s));
880 }
881 
882 /*@exposed@*/ uentry
sRef_getBaseUentry(sRef s)883 sRef_getBaseUentry (sRef s)
884 {
885   sRef base = sRef_getRootBase (s);
886   uentry res = uentry_undefined;
887 
888   if (sRef_isReasonable (base))
889     {
890       switch (base->kind)
891 	{
892 	case SK_PARAM:
893 	  res = usymtab_getRefQuiet (paramsScope, usymId_fromInt (base->info->paramno));
894 	  break;
895 
896 	case SK_CVAR:
897 	  res = usymtab_getRefQuiet (base->info->cvar->lexlevel,
898 				     base->info->cvar->index);
899 	  break;
900 
901 	default:
902 	  break;
903 	}
904     }
905 
906   return res;
907 }
908 
909 /*
910 ** lookup the current uentry corresponding to s, and return the corresponding sRef.
911 ** yuk yuk yuk yuk yuk yuk yuk yuk
912 */
913 
914 /*@exposed@*/ sRef
sRef_updateSref(sRef s)915 sRef_updateSref (sRef s)
916 {
917   sRef inner;
918   sRef ret;
919   sRef res;
920 
921   if (!sRef_isReasonable (s)) return sRef_undefined;
922 
923   switch (s->kind)
924     {
925     case SK_UNKNOWN:
926     case SK_OBJECT:
927     case SK_NEW:
928     case SK_TYPE:
929     case SK_DERIVED:
930     case SK_UNCONSTRAINED:
931     case SK_CONST:
932     case SK_SPECIAL:
933     case SK_RESULT:
934       return s;
935     case SK_EXTERNAL:
936       {
937 	sRef r = sRef_updateSref (s->info->ref);
938 
939 	if (r != s->info->ref)
940 	  {
941 	    return sRef_makeExternal (r);
942 	  }
943 	else
944 	  {
945 	    return s;
946 	  }
947       }
948     case SK_PARAM:
949     case SK_CVAR:
950       {
951 	uentry ue = sRef_getUentry (s);
952 
953 	/* must be raw name!  (need the marker) */
954 	/* Must be in the correct scope! */
955 
956 	ue = usymtab_lookupSafeScope (uentry_rawName (ue), sRef_lexLevel (s));
957 
958 	if (uentry_isUndefined (ue))
959 	  {
960 	    return s;
961 	  }
962 	else
963 	  {
964 	    DPRINTF (("Update sref: %s", uentry_unparseFull (ue)));
965 	    return (uentry_getSref (ue));
966 	  }
967       }
968     case SK_ARRAYFETCH:
969       /* special case if ind known */
970       inner = s->info->arrayfetch->arr;
971       ret = sRef_updateSref (inner);
972 
973       if (ret == inner)
974 	{
975 	  res = s;
976 	}
977       else
978 	{
979 	  res = sRef_makeArrayFetch (ret);
980 	}
981 
982       return res;
983 
984     case SK_FIELD:
985       inner = s->info->field->rec;
986       ret = sRef_updateSref (inner);
987 
988       if (ret == inner)
989 	{
990 	  res = s;
991 	}
992       else
993 	{
994 	  res = (sRef_makeField (ret, s->info->field->field));
995 	}
996 
997       return (res);
998     case SK_PTR:
999       inner = s->info->ref;
1000       ret = sRef_updateSref (inner);
1001       if (ret == inner)
1002 	{
1003 	  res = s;
1004 	}
1005       else
1006 	{
1007 	  res = sRef_makePointer (ret);
1008 	}
1009 
1010       return (res);
1011 
1012     case SK_ADR:
1013       inner = s->info->ref;
1014       ret = sRef_updateSref (inner);
1015 
1016       if (ret == inner)
1017 	{
1018 	  res = s;
1019 	}
1020       else
1021 	{
1022 	  res = sRef_makeAddress (ret);
1023 	}
1024 
1025       return (res);
1026 
1027     case SK_CONJ:
1028       {
1029 	sRef innera = s->info->conj->a;
1030 	sRef innerb = s->info->conj->b;
1031 	sRef reta = sRef_updateSref (innera);
1032 	sRef retb = sRef_updateSref (innerb);
1033 
1034 	if (innera == reta && innerb == retb)
1035 	  {
1036 	    res = s;
1037 	  }
1038 	else
1039 	  {
1040 	    res = sRef_makeConj (reta, retb);
1041 	  }
1042 
1043 	return (res);
1044       }
1045     }
1046 
1047   BADEXIT;
1048 }
1049 
1050 uentry
sRef_getUentry(sRef s)1051 sRef_getUentry (sRef s)
1052 {
1053   llassert (sRef_isReasonable (s));
1054 
1055   switch (s->kind)
1056     {
1057     case SK_PARAM:
1058       return (usymtab_getRefQuiet (paramsScope, usymId_fromInt (s->info->paramno)));
1059     case SK_CVAR:
1060       return (usymtab_getRefQuiet (s->info->cvar->lexlevel, s->info->cvar->index));
1061     case SK_CONJ:
1062       {
1063 	if (sRef_isCvar (s->info->conj->a) || sRef_isParam (s->info->conj->a)
1064 	    || sRef_isConj (s->info->conj->a))
1065 	  {
1066 	    return sRef_getUentry (s->info->conj->a);
1067 	  }
1068 	else
1069 	  {
1070 	    return sRef_getUentry (s->info->conj->b);
1071 	  }
1072       }
1073     case SK_FIELD: /* evans 2002-07-17: added case for SK_FIELD */
1074     case SK_UNKNOWN:
1075     case SK_SPECIAL:
1076       return uentry_undefined;
1077     BADDEFAULT;
1078     }
1079 }
1080 
1081 int
sRef_getParam(sRef s)1082 sRef_getParam (sRef s)
1083 {
1084   llassert (sRef_isReasonable (s));
1085   llassert (s->kind == SK_PARAM);
1086 
1087   return s->info->paramno;
1088 }
1089 
1090 bool
sRef_isModified(sRef s)1091 sRef_isModified (sRef s)
1092 {
1093     return (!sRef_isReasonable (s) || s->modified);
1094 }
1095 
sRef_setModified(sRef s)1096 void sRef_setModified (sRef s)
1097 {
1098   if (sRef_isReasonable (s))
1099     {
1100       s->modified = TRUE;
1101 
1102 
1103       if (sRef_isRefsField (s))
1104 	{
1105 	  sRef base = sRef_getBase (s);
1106 
1107 	  llassert (s->kind == SK_FIELD);
1108 
1109 	  if (sRef_isPointer (base))
1110 	    {
1111 	      base = sRef_getBase (base);
1112 	    }
1113 
1114 	  if (sRef_isRefCounted (base))
1115 	    {
1116 	      base->aliaskind = AK_NEWREF;
1117 	    }
1118 	}
1119     }
1120 }
1121 
1122 /*
1123 ** note: this side-effects sRefSet to set modified to TRUE
1124 ** for any sRef similar to s.
1125 */
1126 
1127 bool
sRef_canModifyVal(sRef s,sRefSet sl)1128 sRef_canModifyVal (sRef s, sRefSet sl)
1129 {
1130   if (context_getFlag (FLG_MUSTMOD))
1131     {
1132       return (sRef_doModifyVal (s, sl));
1133     }
1134   else
1135     {
1136       return (sRef_checkModifyVal (s, sl));
1137     }
1138 }
1139 
1140 bool
sRef_canModify(sRef s,sRefSet sl)1141 sRef_canModify (sRef s, sRefSet sl)
1142 {
1143   if (context_getFlag (FLG_MUSTMOD))
1144     {
1145       return (sRef_doModify (s, sl));
1146     }
1147   else
1148     {
1149       return (sRef_checkModify (s, sl));
1150     }
1151 }
1152 
1153 /*
1154 ** No side-effects
1155 */
1156 
1157 static
sRef_checkModifyVal(sRef s,sRefSet sl)1158 bool sRef_checkModifyVal (sRef s, sRefSet sl)
1159 {
1160   DPRINTF (("Check modify val: %s", sRef_unparse (s)));
1161 
1162   if (sRef_isInvalid (s))
1163     {
1164       return TRUE;
1165     }
1166 
1167   switch (s->kind)
1168     {
1169     case SK_UNCONSTRAINED:
1170     case SK_CONST:
1171       return TRUE;
1172     case SK_CVAR:
1173       DPRINTF (("Modify var: %s", sRef_unparse (s)));
1174 
1175       if (sRef_isFileOrGlobalScope (s))
1176 	{
1177 	  if (context_checkGlobMod (s))
1178 	    {
1179 	      return (sRefSet_member (sl, s));
1180 	    }
1181 
1182 	  return TRUE;
1183 	}
1184       else
1185 	{
1186 	  return TRUE;
1187 	}
1188     case SK_PARAM:
1189             return (sRefSet_member (sl, s)
1190 	      || alkind_isOnly (sRef_getOrigAliasKind (s)));
1191     case SK_ARRAYFETCH:
1192       /* special case if ind known */
1193       return (sRefSet_member (sl, s) ||
1194 	      sRef_checkModifyVal (s->info->arrayfetch->arr, sl));
1195     case SK_FIELD:
1196       return (sRefSet_member (sl, s) || sRef_checkModifyVal (s->info->field->rec, sl));
1197     case SK_PTR:
1198       return (sRefSet_member (sl, s) || sRef_checkModifyVal (s->info->ref, sl));
1199     case SK_ADR:
1200       return (sRefSet_member (sl, s) || sRef_checkModifyVal (s->info->ref, sl));
1201     case SK_CONJ:
1202       return ((sRef_checkModifyVal (s->info->conj->a, sl)) &&
1203 	      (sRef_checkModifyVal (s->info->conj->b, sl)));
1204     case SK_UNKNOWN:
1205     case SK_OBJECT:
1206     case SK_NEW:
1207     case SK_TYPE:
1208     case SK_DERIVED:
1209       return TRUE;
1210     case SK_EXTERNAL:
1211       return TRUE;
1212     case SK_SPECIAL:
1213       {
1214 	switch (s->info->spec)
1215 	  {
1216 	  case SR_NOTHING:   return TRUE;
1217 	  case SR_INTERNAL:
1218 	    if (context_getFlag (FLG_INTERNALGLOBS))
1219 	      {
1220 		return (sRefSet_member (sl, s));
1221 	      }
1222 	    else
1223 	      {
1224 		return TRUE;
1225 	      }
1226 	  case SR_SPECSTATE: return TRUE;
1227 	  case SR_SYSTEM:    return (sRefSet_member (sl, s));
1228 	  case SR_GLOBALMARKER: BADBRANCH;
1229 	  }
1230       }
1231     case SK_RESULT: BADBRANCH;
1232     }
1233   BADEXIT;
1234 }
1235 
1236 /*
1237 ** this should probably be elsewhere...
1238 **
1239 ** returns TRUE iff sl indicates that s can be modified
1240 */
1241 
sRef_checkModify(sRef s,sRefSet sl)1242 static bool sRef_checkModify (sRef s, sRefSet sl)
1243 {
1244   llassert (sRef_isReasonable (s));
1245 
1246   switch (s->kind)
1247     {
1248     case SK_UNCONSTRAINED:
1249     case SK_CONST:
1250       return TRUE;
1251     case SK_CVAR:
1252       if (sRef_isFileOrGlobalScope (s))
1253 	{
1254 	  if (context_checkGlobMod (s))
1255 	    {
1256 	      return (sRefSet_member (sl, s));
1257 	    }
1258 
1259 	  return TRUE;
1260 	}
1261       else
1262 	{
1263 	  return TRUE;
1264 	}
1265     case SK_PARAM:
1266       return TRUE;
1267     case SK_ARRAYFETCH:
1268       return (sRefSet_member (sl, s) ||
1269 	      sRef_checkModifyVal (s->info->arrayfetch->arr, sl));
1270     case SK_FIELD:
1271       {
1272 	sRef sr = s->info->field->rec;
1273 
1274 	if (sr->kind == SK_PARAM)
1275 	  return TRUE; /* structs are copied on call */
1276 
1277 	return (sRefSet_member (sl, s) || sRef_checkModifyVal (s->info->field->rec, sl));
1278       }
1279     case SK_PTR:
1280       {
1281 	bool sm;
1282 
1283 	sm = sRefSet_member (sl, s);
1284 
1285 	if (sm)
1286 	  return TRUE;
1287 	else
1288 	  return (sRef_checkModifyVal (s->info->ref, sl));
1289       }
1290     case SK_ADR:
1291       return (sRefSet_member (sl, s) || sRef_checkModifyVal (s->info->ref, sl));
1292     case SK_CONJ:
1293       return ((sRef_checkModify (s->info->conj->a, sl)) &&
1294 	      (sRef_checkModify (s->info->conj->b, sl)));
1295     case SK_NEW:
1296     case SK_OBJECT:
1297     case SK_UNKNOWN:
1298     case SK_TYPE:
1299     case SK_DERIVED:
1300     case SK_EXTERNAL:
1301       return TRUE;
1302     case SK_SPECIAL:
1303       {
1304 	switch (s->info->spec)
1305 	  {
1306 	  case SR_NOTHING:   return TRUE;
1307 	  case SR_INTERNAL:
1308 	    if (context_getFlag (FLG_INTERNALGLOBS))
1309 	      {
1310 		return (sRefSet_member (sl, s));
1311 	      }
1312 	    else
1313 	      {
1314 		return TRUE;
1315 	      }
1316 	  case SR_SPECSTATE: return TRUE;
1317 	  case SR_SYSTEM:    return (sRefSet_member (sl, s));
1318 	  case SR_GLOBALMARKER: BADBRANCH;
1319 	  }
1320       }
1321     case SK_RESULT: BADBRANCH;
1322     }
1323   BADEXIT;
1324 }
1325 
sRef_stateVerb(sRef s)1326 cstring sRef_stateVerb (sRef s)
1327 {
1328   if (sRef_isDead (s))
1329     {
1330       return cstring_makeLiteralTemp ("released");
1331     }
1332   else if (sRef_isKept (s))
1333     {
1334       return cstring_makeLiteralTemp ("kept");
1335     }
1336   else if (sRef_isDependent (s))
1337     {
1338       return cstring_makeLiteralTemp ("dependent");
1339     }
1340   else
1341     {
1342       BADEXIT;
1343     }
1344 }
1345 
sRef_stateAltVerb(sRef s)1346 cstring sRef_stateAltVerb (sRef s)
1347 {
1348   if (sRef_isDead (s))
1349     {
1350       return cstring_makeLiteralTemp ("live");
1351     }
1352   else if (sRef_isKept (s))
1353     {
1354       return cstring_makeLiteralTemp ("not kept");
1355     }
1356   else if (sRef_isDependent (s))
1357     {
1358       return cstring_makeLiteralTemp ("independent");
1359     }
1360   else
1361     {
1362       BADEXIT;
1363     }
1364 }
1365 
1366 static
sRef_doModifyVal(sRef s,sRefSet sl)1367 bool sRef_doModifyVal (sRef s, sRefSet sl)
1368 {
1369   llassert (sRef_isReasonable (s));
1370 
1371 
1372   switch (s->kind)
1373     {
1374     case SK_UNCONSTRAINED:
1375     case SK_CONST:
1376       return TRUE;
1377     case SK_CVAR:
1378       if (sRef_isFileOrGlobalScope (s))
1379 	{
1380 
1381 	  if (context_checkGlobMod (s))
1382 	    {
1383 	      return (sRefSet_modifyMember (sl, s));
1384 	    }
1385 	  else
1386 	    {
1387 	      (void) sRefSet_modifyMember (sl, s);
1388 	    }
1389 
1390 	  	  return TRUE;
1391 	}
1392       else
1393 	{
1394 	  return TRUE;
1395 	}
1396     case SK_PARAM:
1397       return (sRefSet_modifyMember (sl, s)
1398 	      || alkind_isOnly (sRef_getOrigAliasKind (s)));
1399     case SK_ARRAYFETCH:
1400       /* special case if ind known */
1401       /* unconditional OR, need side effect */
1402       return (OR (sRefSet_modifyMember (sl, s),
1403 		  sRef_doModifyVal (s->info->arrayfetch->arr, sl)));
1404     case SK_FIELD:
1405       return (OR (sRefSet_modifyMember (sl, s),
1406 		  sRef_doModifyVal (s->info->field->rec, sl)));
1407     case SK_PTR:
1408       return (OR (sRefSet_modifyMember (sl, s),
1409 		  sRef_doModifyVal (s->info->ref, sl)));
1410     case SK_ADR:
1411       return (OR (sRefSet_modifyMember (sl, s),
1412 		  sRef_doModifyVal (s->info->ref, sl)));
1413     case SK_CONJ:
1414       return (AND (sRef_doModifyVal (s->info->conj->a, sl) ,
1415 		   sRef_doModifyVal (s->info->conj->b, sl)));
1416     case SK_OBJECT:
1417     case SK_DERIVED:
1418     case SK_EXTERNAL:
1419     case SK_UNKNOWN:
1420     case SK_NEW:
1421     case SK_TYPE:
1422       return TRUE;
1423     case SK_SPECIAL:
1424       {
1425 	switch (s->info->spec)
1426 	  {
1427 	  case SR_NOTHING:   return TRUE;
1428 	  case SR_INTERNAL:
1429 	    if (context_getFlag (FLG_INTERNALGLOBS))
1430 	      {
1431 		return (sRefSet_modifyMember (sl, s));
1432 	      }
1433 	    else
1434 	      {
1435 		(void) sRefSet_modifyMember (sl, s);
1436 		return TRUE;
1437 	      }
1438 	  case SR_SPECSTATE: return TRUE;
1439 	  case SR_SYSTEM:    return (sRefSet_modifyMember (sl, s));
1440 	  case SR_GLOBALMARKER: BADBRANCH;
1441 
1442 	  }
1443       }
1444     case SK_RESULT: BADBRANCH;
1445     }
1446   BADEXIT;
1447 }
1448 
1449 /*
1450 ** this should probably be elsewhere...
1451 **
1452 ** returns TRUE iff sl indicates that s can be modified
1453 */
1454 
1455 static
sRef_doModify(sRef s,sRefSet sl)1456 bool sRef_doModify (sRef s, sRefSet sl)
1457 {
1458   llassert (sRef_isReasonable (s));
1459 
1460   switch (s->kind)
1461     {
1462     case SK_UNCONSTRAINED:
1463     case SK_CONST:
1464       return TRUE;
1465     case SK_CVAR:
1466       if (sRef_isFileOrGlobalScope (s))
1467 	{
1468 	  if (context_checkGlobMod (s))
1469 	    {
1470 	      return (sRefSet_modifyMember (sl, s));
1471 	    }
1472 	  else
1473 	    {
1474 	      (void) sRefSet_modifyMember (sl, s);
1475 	    }
1476 
1477 	  return TRUE;
1478 	}
1479       else
1480 	{
1481 	  return TRUE;
1482 	}
1483     case SK_PARAM:
1484       return TRUE;
1485     case SK_ARRAYFETCH:
1486             return (OR (sRefSet_modifyMember (sl, s),
1487 		  sRef_doModifyVal (s->info->arrayfetch->arr, sl)));
1488     case SK_FIELD:
1489       {
1490 	sRef sr = s->info->field->rec;
1491 
1492 	if (sr->kind == SK_PARAM)
1493 	  {
1494 	    return TRUE; /* structs are shallow-copied on call */
1495 	  }
1496 
1497 	return (OR (sRefSet_modifyMember (sl, s),
1498 		    sRef_doModifyVal (s->info->field->rec, sl)));
1499       }
1500     case SK_PTR:
1501       {
1502 	return (OR (sRefSet_modifyMember (sl, s),
1503 		    sRef_doModifyVal (s->info->ref, sl)));
1504       }
1505     case SK_ADR:
1506       return (OR (sRefSet_modifyMember (sl, s),
1507 		  sRef_doModifyVal (s->info->ref, sl)));
1508     case SK_CONJ:
1509       return (AND (sRef_doModify (s->info->conj->a, sl),
1510 		  (sRef_doModify (s->info->conj->b, sl))));
1511     case SK_UNKNOWN:
1512     case SK_NEW:
1513     case SK_TYPE:
1514       return TRUE;
1515     case SK_OBJECT:
1516     case SK_DERIVED:
1517     case SK_EXTERNAL:
1518       return TRUE;
1519     case SK_SPECIAL:
1520       {
1521 	switch (s->info->spec)
1522 	  {
1523 	  case SR_NOTHING:   return TRUE;
1524 	  case SR_INTERNAL:  return TRUE;
1525 	  case SR_SPECSTATE: return TRUE;
1526 	  case SR_SYSTEM:    return (sRefSet_modifyMember (sl, s));
1527 	  case SR_GLOBALMARKER: BADBRANCH;
1528 	  }
1529       }
1530     case SK_RESULT: BADBRANCH;
1531     }
1532   BADEXIT;
1533 }
1534 
1535 static /*@exposed@*/ sRef
sRef_leastCommon(sRef s1,sRef s2)1536   sRef_leastCommon (/*@exposed@*/ sRef s1, sRef s2)
1537 {
1538   llassert (sRef_similar (s1, s2));
1539 
1540   if (!sRef_isReasonable (s1)) return s1;
1541   if (!sRef_isReasonable (s2)) return s1;
1542 
1543   sRef_combineDefState (s1, s2);
1544   sRef_combineNullState (s1, s2);
1545   sRef_combineExKinds (s1, s2);
1546 
1547   if (s1->aliaskind != s2->aliaskind)
1548     {
1549       if (s1->aliaskind == AK_UNKNOWN)
1550 	{
1551 	  s1->aliaskind = s2->aliaskind;
1552 	}
1553       else if (s2->aliaskind == AK_UNKNOWN)
1554 	{
1555 	  ;
1556 	}
1557       else
1558 	{
1559 	  s1->aliaskind = AK_ERROR;
1560 	}
1561     }
1562 
1563   return s1;
1564 }
1565 
sRef_compare(sRef s1,sRef s2)1566 int sRef_compare (sRef s1, sRef s2)
1567 {
1568   if (s1 == s2) return 0;
1569 
1570   if (sRef_isInvalid (s1)) return -1;
1571   if (sRef_isInvalid (s2)) return 1;
1572 
1573   INTCOMPARERETURN (s1->kind, s2->kind);
1574   INTCOMPARERETURN (s1->defstate, s2->defstate);
1575   INTCOMPARERETURN (s1->aliaskind, s2->aliaskind);
1576 
1577   DPRINTF (("Compare null state: %s / %s",
1578 	    sRef_unparseFull (s1),
1579 	    sRef_unparseFull (s2)));
1580 
1581   COMPARERETURN (nstate_compare (sRef_getNullState (s1),
1582 				 sRef_getNullState (s2)));
1583 
1584   switch (s1->kind)
1585     {
1586     case SK_PARAM:
1587       return (int_compare (s1->info->paramno, s2->info->paramno));
1588     case SK_ARRAYFETCH:
1589       {
1590 	COMPARERETURN (sRef_compare (s1->info->arrayfetch->arr,
1591 				     s2->info->arrayfetch->arr));
1592 
1593 	if (s1->info->arrayfetch->indknown && s2->info->arrayfetch->indknown)
1594 	  {
1595 	    return (int_compare (s1->info->arrayfetch->ind,
1596 				 s2->info->arrayfetch->ind));
1597 	  }
1598 	if (!s1->info->arrayfetch->indknown && !s2->info->arrayfetch->indknown)
1599 	  return 0;
1600 
1601 	return 1;
1602       }
1603     case SK_FIELD:
1604       {
1605 	COMPARERETURN (sRef_compare (s1->info->field->rec, s2->info->field->rec));
1606 
1607 	if (cstring_equal (s1->info->field->field, s2->info->field->field))
1608 	  return 0;
1609 
1610 	return 1;
1611       }
1612     case SK_PTR:
1613     case SK_ADR:
1614       return (sRef_compare (s1->info->ref, s2->info->ref));
1615     case SK_CONJ:
1616       COMPARERETURN (sRef_compare (s1->info->conj->a, s2->info->conj->a));
1617       return (sRef_compare (s1->info->conj->b, s2->info->conj->b));
1618     case SK_UNCONSTRAINED:
1619       return (cstring_compare (s1->info->fname, s2->info->fname));
1620     case SK_NEW:
1621     case SK_CVAR:
1622     case SK_UNKNOWN:
1623     case SK_OBJECT:
1624     case SK_TYPE:
1625     case SK_DERIVED:
1626     case SK_EXTERNAL:
1627     case SK_CONST:
1628     case SK_RESULT:
1629       return 0;
1630     case SK_SPECIAL:
1631       return (generic_compare (s1->info->spec, s2->info->spec));
1632     }
1633   BADEXIT;
1634 }
1635 
cref_equal(cref c1,cref c2)1636 static bool cref_equal (cref c1, cref c2)
1637 {
1638   return ((c1->lexlevel == c2->lexlevel) &&
1639 	  (usymId_equal (c1->index, c2->index)));
1640 }
1641 
1642 /*
1643 ** returns true if s1 could be the same storage as s2.
1644 ** i.e., a[?] ~ a[3].  Note its not symmetric ... s1
1645 ** should be more specific.
1646 */
1647 
1648 /*
1649 ** like similar, but matches objects <-> non-objects
1650 */
1651 
1652 static bool
sRef_uniqueReference(sRef s)1653 sRef_uniqueReference (sRef s)
1654 {
1655   return (sRef_isFresh (s) || sRef_isUnique (s)
1656 	  || sRef_isOnly (s) || sRef_isStack (s)
1657 	  || sRef_isAddress (s));
1658 }
1659 
1660 static bool
sRef_similarRelaxedAux(sRef s1,sRef s2)1661 sRef_similarRelaxedAux (sRef s1, sRef s2)
1662 {
1663   if (s1 == s2)
1664     {
1665       if (sRef_isUnknownArrayFetch (s1))
1666 	{
1667 	  return FALSE;
1668 	}
1669       else
1670 	{
1671 	  return TRUE;
1672 	}
1673     }
1674 
1675   if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
1676 
1677   if (sRef_isConj (s2))
1678     return (sRef_similarRelaxedAux (s1, sRef_getConjA (s2)) ||
1679 	    sRef_similarRelaxedAux (s1, sRef_getConjB (s2)));
1680 
1681   switch (s1->kind)
1682     {
1683     case SK_CVAR:
1684       return ((s2->kind == SK_CVAR)
1685 	      && (cref_equal (s1->info->cvar, s2->info->cvar)));
1686     case SK_PARAM:
1687       return ((s2->kind == SK_PARAM)
1688 	      && (s1->info->paramno == s2->info->paramno));
1689     case SK_ARRAYFETCH:
1690       if (s2->kind == SK_ARRAYFETCH)
1691 	{
1692 	  if (sRef_similarRelaxedAux (s1->info->arrayfetch->arr,
1693 				      s2->info->arrayfetch->arr))
1694 	    {
1695 	      if (s1->info->arrayfetch->indknown)
1696 		{
1697 		  if (s2->info->arrayfetch->indknown)
1698 		    {
1699 		      return (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind);
1700 		    }
1701 		  else
1702 		    {
1703 		      return FALSE;
1704 		    }
1705 		}
1706 	      else
1707 		{
1708 		  return FALSE;
1709 		}
1710 	    }
1711 	}
1712       return FALSE;
1713     case SK_FIELD:
1714       return ((s2->kind == SK_FIELD
1715 	       && (sRef_similarRelaxedAux (s1->info->field->rec,
1716 					   s2->info->field->rec)
1717 		   && cstring_equal (s1->info->field->field,
1718 				     s2->info->field->field))));
1719     case SK_PTR:
1720       return ((s2->kind == SK_PTR)
1721 	      && sRef_similarRelaxedAux (s1->info->ref, s2->info->ref));
1722     case SK_ADR:
1723       return ((s2->kind == SK_ADR)
1724 	      && sRef_similarRelaxedAux (s1->info->ref, s2->info->ref));
1725     case SK_CONJ:
1726       return ((sRef_similarRelaxedAux (s1->info->conj->a, s2) ||
1727 	      (sRef_similarRelaxedAux (s1->info->conj->b, s2))));
1728     case SK_SPECIAL:
1729       return (s1->info->spec == s2->info->spec);
1730     case SK_UNCONSTRAINED:
1731       return (cstring_equal (s1->info->fname, s2->info->fname));
1732     case SK_DERIVED:
1733     case SK_CONST:
1734     case SK_TYPE:
1735     case SK_NEW:
1736     case SK_UNKNOWN:
1737     case SK_OBJECT:
1738     case SK_EXTERNAL:
1739     case SK_RESULT:
1740       return FALSE;
1741     }
1742   BADEXIT;
1743 }
1744 
1745 bool
sRef_similarRelaxed(sRef s1,sRef s2)1746 sRef_similarRelaxed (sRef s1, sRef s2)
1747 {
1748   bool us1, us2;
1749 
1750   if (s1 == s2)
1751     {
1752       if (sRef_isThroughArrayFetch (s1))
1753 	{
1754 	  return FALSE;
1755 	}
1756       else
1757 	{
1758 	  return TRUE;
1759 	}
1760     }
1761 
1762   if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
1763 
1764   us1 = sRef_uniqueReference (s1);
1765   us2 = sRef_uniqueReference (s2);
1766 
1767   if ((s1->kind == SK_EXTERNAL && (s2->kind != SK_EXTERNAL && !us2))
1768       || (s2->kind == SK_EXTERNAL && (s1->kind != SK_EXTERNAL && !us1)))
1769     {
1770       /*
1771       ** Previously, also:
1772       **   || (sRef_isExposed (s1) && !us2) || (sRef_isExposed (s2) && !us1)) ????
1773       **
1774       ** No clue why this was there?!
1775       */
1776 
1777 
1778       if (sRef_isExposed (s1) && sRef_isCvar (s1))
1779 	{
1780 	  uentry ue1 = sRef_getUentry (s1);
1781 
1782 	  if (uentry_isRefParam (ue1))
1783 	    {
1784 	      return sRef_similarRelaxedAux (s1, s2);
1785 	    }
1786 	}
1787 
1788       if (sRef_isExposed (s2) && sRef_isCvar (s2))
1789 	{
1790 	  uentry ue2 = sRef_getUentry (s2);
1791 
1792 	  if (uentry_isRefParam (ue2))
1793 	    {
1794 	      return sRef_similarRelaxedAux (s1, s2);
1795 	    }
1796 	}
1797 
1798             return (ctype_match (s1->type, s2->type));
1799     }
1800   else
1801     {
1802             return sRef_similarRelaxedAux (s1, s2);
1803     }
1804 }
1805 
1806 bool
sRef_similar(sRef s1,sRef s2)1807 sRef_similar (sRef s1, sRef s2)
1808 {
1809   if (s1 == s2) return TRUE;
1810   if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
1811 
1812   if (sRef_isConj (s2))
1813     {
1814       return (sRef_similar (s1, sRef_getConjA (s2)) ||
1815 	      sRef_similar (s1, sRef_getConjB (s2)));
1816     }
1817 
1818   if (sRef_isDerived (s2))
1819    {
1820      return (sRef_includedBy (s1, s2->info->ref));
1821    }
1822 
1823   switch (s1->kind)
1824     {
1825     case SK_CVAR:
1826       return ((s2->kind == SK_CVAR)
1827 	      && (cref_equal (s1->info->cvar, s2->info->cvar)));
1828     case SK_PARAM:
1829       return ((s2->kind == SK_PARAM)
1830 	      && (s1->info->paramno == s2->info->paramno));
1831     case SK_ARRAYFETCH:
1832       if (s2->kind == SK_ARRAYFETCH)
1833 	{
1834 	  if (sRef_similar (s1->info->arrayfetch->arr,
1835 			    s2->info->arrayfetch->arr))
1836 	    {
1837 	      if (s1->info->arrayfetch->indknown)
1838 		{
1839 		  if (s2->info->arrayfetch->indknown)
1840 		    {
1841 		      return (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind);
1842 		    }
1843 		  else
1844 		    {
1845 		      return TRUE;
1846 		    }
1847 		}
1848 	      else
1849 		{
1850 		  return TRUE;
1851 		}
1852 	    }
1853 	}
1854       else
1855 	{
1856 	  if (s2->kind == SK_PTR)
1857 	    {
1858 	      if (sRef_similar (s1->info->arrayfetch->arr,
1859 				s2->info->ref))
1860 		{
1861 		  return TRUE;
1862 		}
1863 	    }
1864 	}
1865 
1866       return FALSE;
1867     case SK_FIELD:
1868       return ((s2->kind == SK_FIELD
1869 	       && (sRef_similar (s1->info->field->rec,
1870 				 s2->info->field->rec)
1871 		   && cstring_equal (s1->info->field->field,
1872 				     s2->info->field->field))));
1873     case SK_PTR:
1874       if (s2->kind == SK_PTR)
1875 	{
1876 	  return sRef_similar (s1->info->ref, s2->info->ref);
1877 	}
1878       else
1879 	{
1880 	  if (s2->kind == SK_ARRAYFETCH)
1881 	    {
1882 	      if (sRef_similar (s2->info->arrayfetch->arr,
1883 				s1->info->ref))
1884 		{
1885 		  return TRUE;
1886 		}
1887 	    }
1888 	}
1889 
1890       return FALSE;
1891     case SK_ADR:
1892       return ((s2->kind == SK_ADR)
1893 	      && sRef_similar (s1->info->ref, s2->info->ref));
1894     case SK_CONJ:
1895       return ((sRef_similar (s1->info->conj->a, s2) ||
1896 	      (sRef_similar (s1->info->conj->b, s2))));
1897     case SK_DERIVED:
1898       return (sRef_includedBy (s2, s1->info->ref));
1899     case SK_UNCONSTRAINED:
1900       return (s2->kind == SK_UNCONSTRAINED
1901 	      && cstring_equal (s1->info->fname, s2->info->fname));
1902     case SK_CONST:
1903     case SK_TYPE:
1904     case SK_NEW:
1905     case SK_UNKNOWN:
1906     case SK_OBJECT:
1907     case SK_EXTERNAL:
1908     case SK_RESULT:
1909       return FALSE;
1910     case SK_SPECIAL:
1911       return (s2->kind == SK_SPECIAL
1912 	      && (s1->info->spec == s2->info->spec));
1913     }
1914 
1915   /*@notreached@*/ DPRINTF (("Fell through for: %s / %s", sRef_unparse (s1), sRef_unparse (s2)));
1916   BADEXIT;
1917 }
1918 
1919 /*
1920 ** return TRUE iff small can be derived from big.
1921 **
1922 ** (e.g. x, x.a is includedBy x;
1923 **       x.a is included By x.a;
1924 */
1925 
1926 bool
sRef_includedBy(sRef small,sRef big)1927 sRef_includedBy (sRef small, sRef big)
1928 {
1929   if (small == big) return TRUE;
1930   if (sRef_isInvalid (small) || sRef_isInvalid (big)) return FALSE;
1931 
1932   if (sRef_isConj (big))
1933     return (sRef_similar (small, sRef_getConjA (big)) ||
1934 	    sRef_similar (small, sRef_getConjB (big)));
1935 
1936   switch (small->kind)
1937     {
1938     case SK_CVAR:
1939     case SK_PARAM:
1940       return (sRef_same (small, big));
1941     case SK_ARRAYFETCH:
1942       if (big->kind == SK_ARRAYFETCH)
1943 	{
1944 	  if (sRef_same (small->info->arrayfetch->arr, big->info->arrayfetch->arr))
1945 	    {
1946 	      if (small->info->arrayfetch->indknown)
1947 		{
1948 		  if (big->info->arrayfetch->indknown)
1949 		    {
1950 		      return (small->info->arrayfetch->ind == big->info->arrayfetch->ind);
1951 		    }
1952 		  else
1953 		    {
1954 		      return TRUE;
1955 		    }
1956 		}
1957 	      else
1958 		{
1959 		  return TRUE;
1960 		}
1961 	    }
1962 	}
1963       return (sRef_includedBy (small->info->arrayfetch->arr, big));
1964     case SK_FIELD:
1965       if (big->kind == SK_FIELD)
1966 	{
1967 	  return
1968 	    (sRef_same (small->info->field->rec, big->info->field->rec) &&
1969 	     cstring_equal (small->info->field->field, big->info->field->field));
1970 	}
1971       else
1972 	{
1973 	  return (sRef_includedBy (small->info->field->rec, big));
1974 	}
1975 
1976     case SK_PTR:
1977       if (big->kind == SK_PTR)
1978 	{
1979 	  return sRef_same (small->info->ref, big->info->ref);
1980 	}
1981       else
1982 	{
1983 	  return (sRef_includedBy (small->info->ref, big));
1984 	}
1985 
1986     case SK_ADR:
1987       return ((big->kind == SK_ADR) && sRef_similar (small->info->ref, big->info->ref));
1988     case SK_CONJ:
1989       return ((sRef_includedBy (small->info->conj->a, big) ||
1990 	      (sRef_includedBy (small->info->conj->b, big))));
1991     case SK_DERIVED:
1992       return (sRef_includedBy (small->info->ref, big));
1993     case SK_UNCONSTRAINED:
1994     case SK_CONST:
1995     case SK_TYPE:
1996     case SK_NEW:
1997     case SK_UNKNOWN:
1998     case SK_OBJECT:
1999     case SK_EXTERNAL:
2000     case SK_RESULT:
2001       return FALSE;
2002     case SK_SPECIAL:
2003       switch (small->info->spec)
2004 	{
2005 	case SR_NOTHING: return TRUE;
2006 	case SR_SPECSTATE:
2007 	case SR_INTERNAL: return (sRef_isSpecInternalState (big) ||
2008 				  sRef_isFileStatic (big));
2009 	case SR_SYSTEM: return (sRef_isSystemState (big));
2010 	case SR_GLOBALMARKER: BADBRANCH;
2011 	}
2012     }
2013   BADEXIT;
2014 }
2015 
2016 /*
2017 ** Same is similar to similar, but not quite the same.
2018 ** same and realSame aren't the same, but they are really similar.
2019 ** similarly, same is the same as same. but realSame is
2020 ** not really the same as same, or similar to similar.
2021 **
2022 ** Similarly to similar, same checks if two sRefs are the same.
2023 ** The similarities end, however, when same compares arrays
2024 ** with unknown indexes.  Similar returns false; same returns true.
2025 **
2026 ** Similarly to similar and same, realSame is the same as same,
2027 ** except they do not behave the same when face with unknown
2028 ** sRefs.  Same thinks they are not the same, but realSame thinks
2029 ** the are.
2030 **
2031 */
2032 
2033 bool
sRef_realSame(sRef s1,sRef s2)2034 sRef_realSame (sRef s1, sRef s2)
2035 {
2036   if (s1 == s2) return TRUE;
2037 
2038   if (sRef_isUnreasonable (s1)
2039       || sRef_isUnreasonable (s2))
2040     {
2041       return FALSE;
2042     }
2043 
2044   switch (s1->kind)
2045     {
2046     case SK_CVAR:
2047       return ((s2->kind == SK_CVAR) && (cref_equal (s1->info->cvar, s2->info->cvar)));
2048     case SK_PARAM:
2049       return ((s2->kind == SK_PARAM) && (s1->info->paramno == s2->info->paramno));
2050     case SK_ARRAYFETCH:
2051       if (s2->kind == SK_ARRAYFETCH)
2052 	{
2053 	  if (sRef_realSame (s1->info->arrayfetch->arr, s2->info->arrayfetch->arr))
2054 	    {
2055 	      if (s1->info->arrayfetch->indknown && s2->info->arrayfetch->indknown)
2056 		{
2057 		  return (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind);
2058 		}
2059 	      if (!s1->info->arrayfetch->indknown && !s2->info->arrayfetch->indknown)
2060 		{
2061 		  return TRUE;
2062 		}
2063 	      return FALSE;
2064 	    }
2065 	}
2066       return FALSE;
2067     case SK_FIELD:
2068       return ((s2->kind == SK_FIELD &&
2069 	       (sRef_realSame (s1->info->field->rec, s2->info->field->rec) &&
2070 		cstring_equal (s1->info->field->field, s2->info->field->field))));
2071     case SK_PTR:
2072       return ((s2->kind == SK_PTR) && sRef_realSame (s1->info->ref, s2->info->ref));
2073     case SK_ADR:
2074       return ((s2->kind == SK_ADR) && sRef_realSame (s1->info->ref, s2->info->ref));
2075     case SK_CONJ:
2076       return ((sRef_realSame (s1->info->conj->a, s2) ||
2077 	      (sRef_realSame (s1->info->conj->b, s2))));
2078     case SK_OBJECT:
2079       return ((s2->kind == SK_OBJECT)
2080 	      && ctype_match (s1->info->object, s2->info->object));
2081     case SK_EXTERNAL:
2082       return ((s2->kind == SK_EXTERNAL)
2083 	      && sRef_realSame (s1->info->ref, s2->info->ref));
2084     case SK_SPECIAL:
2085       return ((s2->kind == SK_SPECIAL) && s1->info->spec == s2->info->spec);
2086     case SK_DERIVED:
2087       return ((s2->kind == SK_DERIVED) && sRef_realSame (s1->info->ref, s2->info->ref));
2088     case SK_UNCONSTRAINED:
2089       return ((s2->kind == SK_UNCONSTRAINED)
2090 	      && (cstring_equal (s1->info->fname, s2->info->fname)));
2091     case SK_TYPE:
2092     case SK_CONST:
2093     case SK_NEW:
2094     case SK_UNKNOWN:
2095     case SK_RESULT:
2096       return TRUE; /* changed this! was false */
2097     }
2098   BADEXIT;
2099 }
2100 
2101 bool
sRef_sameObject(sRef s1,sRef s2)2102 sRef_sameObject (sRef s1, sRef s2)
2103 {
2104   return (s1 == s2);
2105 }
2106 
2107 /*
2108 ** same is similar to similar, but not quite the same.
2109 **
2110 ** Similarly to similar, same checks is two sRefs are the same.
2111 ** The similarities end, however, when same compares arrays
2112 ** with unknown indexes.  Similar returns false; same returns true.
2113 */
2114 
2115 bool
sRef_same(sRef s1,sRef s2)2116 sRef_same (sRef s1, sRef s2)
2117 {
2118   if (s1 == s2) return TRUE;
2119   if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
2120 
2121   switch (s1->kind)
2122     {
2123     case SK_CVAR:
2124       return ((s2->kind == SK_CVAR) && (cref_equal (s1->info->cvar, s2->info->cvar)));
2125     case SK_PARAM:
2126       return ((s2->kind == SK_PARAM) && (s1->info->paramno == s2->info->paramno));
2127     case SK_ARRAYFETCH:
2128       if (s2->kind == SK_ARRAYFETCH)
2129 	{
2130 	  llassert (s1->info->field->rec != s1);
2131 	  if (sRef_same (s1->info->arrayfetch->arr, s2->info->arrayfetch->arr))
2132 	    {
2133 	      if (s1->info->arrayfetch->indknown && s2->info->arrayfetch->indknown)
2134 		{
2135 		  return (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind);
2136 		}
2137 	      return TRUE;
2138 	    }
2139 	}
2140       return FALSE;
2141     case SK_FIELD:
2142       {
2143 	llassert (s1->info->field->rec != s1);
2144 	return ((s2->kind == SK_FIELD &&
2145 		 (sRef_same (s1->info->field->rec, s2->info->field->rec) &&
2146 		  cstring_equal (s1->info->field->field, s2->info->field->field))));
2147       }
2148     case SK_PTR:
2149       {
2150 	llassert (s1->info->ref != s1);
2151 	return ((s2->kind == SK_PTR) && sRef_same (s1->info->ref, s2->info->ref));
2152       }
2153     case SK_ADR:
2154       {
2155 	llassert (s1->info->ref != s1);
2156 	return ((s2->kind == SK_ADR) && sRef_same (s1->info->ref, s2->info->ref));
2157       }
2158     case SK_CONJ:
2159       llassert (s1->info->conj->a != s1);
2160       llassert (s1->info->conj->b != s1);
2161       return ((sRef_same (s1->info->conj->a, s2)) && /* or or and? */
2162 	      (sRef_same (s1->info->conj->b, s2)));
2163     case SK_SPECIAL:
2164       return ((s2->kind == SK_SPECIAL) && s1->info->spec == s2->info->spec);
2165     case SK_DERIVED:
2166       llassert (s1->info->ref != s1);
2167       return ((s2->kind == SK_DERIVED) && sRef_same (s1->info->ref, s2->info->ref));
2168     case SK_CONST:
2169     case SK_UNCONSTRAINED:
2170     case SK_TYPE:
2171     case SK_UNKNOWN:
2172     case SK_NEW:
2173     case SK_OBJECT:
2174     case SK_EXTERNAL:
2175     case SK_RESULT:
2176       return FALSE;
2177     }
2178   BADEXIT;
2179 }
2180 
2181 /*
2182 ** sort of similar, for use in def/use
2183 */
2184 
2185 static bool
sRef_closeEnough(sRef s1,sRef s2)2186 sRef_closeEnough (sRef s1, sRef s2)
2187 {
2188   if (s1 == s2) return TRUE;
2189   if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
2190 
2191   switch (s1->kind)
2192     {
2193     case SK_CVAR:
2194       return (((s2->kind == SK_CVAR) &&
2195 	       (cref_equal (s1->info->cvar, s2->info->cvar))) ||
2196 	      (s2->kind == SK_UNCONSTRAINED && s1->info->cvar->lexlevel == 0));
2197     case SK_UNCONSTRAINED:
2198       return (s2->kind == SK_UNCONSTRAINED
2199 	      || ((s2->kind == SK_CVAR) && (s2->info->cvar->lexlevel == 0)));
2200     case SK_PARAM:
2201       return ((s2->kind == SK_PARAM)
2202 	      && (s1->info->paramno == s2->info->paramno));
2203     case SK_ARRAYFETCH:
2204       if (s2->kind == SK_ARRAYFETCH)
2205 	{
2206 	  if (sRef_closeEnough (s1->info->arrayfetch->arr, s2->info->arrayfetch->arr))
2207 	    {
2208 	      if (s1->info->arrayfetch->indknown && s2->info->arrayfetch->indknown)
2209 		{
2210 		  return (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind);
2211 		}
2212 	      return TRUE;
2213 	    }
2214 	}
2215       return FALSE;
2216     case SK_FIELD:
2217       return ((s2->kind == SK_FIELD &&
2218 	       (sRef_closeEnough (s1->info->field->rec, s2->info->field->rec) &&
2219 		cstring_equal (s1->info->field->field, s2->info->field->field))));
2220     case SK_PTR:
2221       return ((s2->kind == SK_PTR) && sRef_closeEnough (s1->info->ref, s2->info->ref));
2222     case SK_ADR:
2223       return ((s2->kind == SK_ADR) && sRef_closeEnough (s1->info->ref, s2->info->ref));
2224     case SK_DERIVED:
2225       return ((s2->kind == SK_DERIVED) && sRef_closeEnough (s1->info->ref, s2->info->ref));
2226     case SK_CONJ:
2227       return ((sRef_closeEnough (s1->info->conj->a, s2)) ||
2228 	      (sRef_closeEnough (s1->info->conj->b, s2)));
2229     case SK_SPECIAL:
2230       return ((s2->kind == SK_SPECIAL) && s1->info->spec == s2->info->spec);
2231     case SK_TYPE:
2232     case SK_CONST:
2233     case SK_UNKNOWN:
2234     case SK_NEW:
2235     case SK_OBJECT:
2236     case SK_EXTERNAL:
2237     case SK_RESULT:
2238 
2239       return FALSE;
2240     }
2241   BADEXIT;
2242 }
2243 
2244 /*
2245   drl add 12/24/2000
2246   s is an sRef of a formal paramenter in a function call constraint
2247   we trys to return a constraint expression derived from the actual parementer of a function call.
2248 */
2249 
sRef_fixConstraintParam(sRef s,exprNodeList args)2250 /*@only@*/ constraintExpr sRef_fixConstraintParam (/*@observer@*/  sRef s, /*@observer@*/ /*@temp@*/ exprNodeList args)
2251 {
2252   constraintExpr ce;
2253 
2254   if (sRef_isInvalid (s))
2255     llfatalbug((message("Invalid sRef")));
2256 
2257   switch (s->kind)
2258     {
2259     case SK_RESULT:
2260       {
2261 	ce = constraintExpr_makeTermsRef (s);
2262 	return ce;
2263       }
2264     case SK_FIELD:
2265       {
2266 	sRef temp;
2267 
2268 	temp = (sRef_makeField (sRef_fixBaseParam (s->info->field->rec, args),
2269 			      s->info->field->field));
2270 	ce = constraintExpr_makeTermsRef (temp);
2271 	return ce;
2272       }
2273     case SK_PTR:
2274       {
2275 	sRef temp;
2276 	temp = (sRef_makePointer (sRef_fixBaseParam (s->info->ref, args)));
2277 	ce = constraintExpr_makeTermsRef (temp);
2278 	return ce;
2279       }
2280 
2281     case SK_ARRAYFETCH:
2282        {
2283 	sRef temp;
2284 	temp = sRef_saveCopy(s);
2285 	temp = sRef_fixBaseParam (temp, args);
2286 	ce = constraintExpr_makeTermsRef (temp);
2287 
2288 	sRef_free(temp);
2289 	return ce;
2290       }
2291     case SK_CVAR:
2292       {
2293 	sRef temp;
2294 	temp = sRef_saveCopy(s);
2295 	ce = constraintExpr_makeTermsRef (temp);
2296 	sRef_free(temp);
2297 	return ce;
2298       }
2299     case SK_PARAM:
2300       {
2301 	exprNode e;
2302 	llassert (exprNodeList_size (args) > s->info->paramno);
2303 	e = exprNodeList_nth (args, s->info->paramno);
2304 
2305 	llassert (!(exprNode_isError (e)));
2306 	ce = constraintExpr_makeExprNode (e);
2307 	return ce;
2308       }
2309 
2310     default:
2311       {
2312 	sRef temp;
2313 	llcontbug (message ("Trying to do fixConstraintParam on nonparam, nonglobal: %q for function with arguments %q",
2314 			    sRef_unparse (s), exprNodeList_unparse(args)));
2315       temp = sRef_saveCopy(s);
2316       ce = constraintExpr_makeTermsRef (temp);
2317 
2318       sRef_free(temp);
2319       return ce;
2320       }
2321     }
2322 }
2323 
2324 /*@exposed@*/ sRef
sRef_fixBaseParam(sRef s,exprNodeList args)2325 sRef_fixBaseParam (/*@returned@*/ sRef s, exprNodeList args)
2326 {
2327   if (sRef_isInvalid (s)) return (sRef_undefined);
2328 
2329   switch (s->kind)
2330     {
2331     case SK_UNCONSTRAINED:
2332     case SK_CVAR:
2333       return s;
2334     case SK_PARAM:
2335       {
2336 	if (exprNodeList_size (args) > s->info->paramno)
2337 	  {
2338 	    exprNode e = exprNodeList_nth (args, s->info->paramno);
2339 
2340 	    if (exprNode_isError (e))
2341 	      {
2342 		return sRef_makeUnknown ();
2343 	      }
2344 
2345 	    return (exprNode_getSref (e));
2346 	  }
2347 	else
2348 	  {
2349 	    return sRef_makeUnknown ();
2350 	  }
2351       }
2352     case SK_ARRAYFETCH:
2353 
2354       if (s->info->arrayfetch->indknown)
2355 	{
2356 	  return (sRef_makeArrayFetchKnown
2357 		  (sRef_fixBaseParam (s->info->arrayfetch->arr, args),
2358 		   s->info->arrayfetch->ind));
2359 	}
2360       else
2361 	{
2362 	  return (sRef_makeArrayFetch
2363 		  (sRef_fixBaseParam (s->info->arrayfetch->arr, args)));
2364 	}
2365     case SK_FIELD:
2366       {
2367 	sRef res;
2368 	DPRINTF (("Fix field: %s", sRef_unparseFull (s)));
2369 	res = sRef_makeField (sRef_fixBaseParam (s->info->field->rec, args),
2370 			      s->info->field->field);
2371 	DPRINTF (("Returns: %s", sRef_unparseFull (res)));
2372 	return res;
2373       }
2374     case SK_PTR:
2375       return (sRef_makePointer (sRef_fixBaseParam (s->info->ref, args)));
2376 
2377     case SK_ADR:
2378       return (sRef_makeAddress (sRef_fixBaseParam (s->info->ref, args)));
2379 
2380     case SK_CONJ:
2381       return (sRef_makeConj (sRef_fixBaseParam (s->info->conj->a, args),
2382 			     sRef_fixBaseParam (s->info->conj->b, args)));
2383     case SK_DERIVED:
2384     case SK_SPECIAL:
2385     case SK_TYPE:
2386     case SK_CONST:
2387     case SK_NEW:
2388     case SK_UNKNOWN:
2389     case SK_OBJECT:
2390     case SK_EXTERNAL:
2391     case SK_RESULT:
2392       return s;
2393     }
2394   BADEXIT;
2395 }
2396 
2397 /*@exposed@*/ sRef
sRef_undumpGlobal(char ** c)2398 sRef_undumpGlobal (char **c)
2399 {
2400   char p = **c;
2401 
2402   (*c)++;
2403 
2404   switch (p)
2405     {
2406     case 'g':
2407       {
2408 	usymId uid = usymId_fromInt (reader_getInt (c));
2409 	sstate defstate;
2410 	nstate nullstate;
2411 	sRef ret;
2412 
2413 	reader_checkChar (c, '@');
2414 	defstate = sstate_fromInt (reader_getInt (c));
2415 
2416 	reader_checkChar (c, '@');
2417 	nullstate = nstate_fromInt (reader_getInt (c));
2418 
2419 	ret = sRef_makeGlobal (uid, ctype_unknown, stateInfo_currentLoc ());
2420 	sRef_setNullStateN (ret, nullstate);
2421 	ret->defstate = defstate;
2422 	return ret;
2423       }
2424     case 's':
2425       {
2426 	int i = reader_getInt (c);
2427 	speckind sk = speckind_fromInt (i);
2428 
2429 	switch (sk)
2430 	  {
2431 	  case SR_NOTHING:   return (sRef_makeNothing ());
2432 	  case SR_INTERNAL:  return (sRef_makeInternalState ());
2433 	  case SR_SPECSTATE: return (sRef_makeSpecState ());
2434 	  case SR_SYSTEM:    return (sRef_makeSystemState ());
2435 	  case SR_GLOBALMARKER: BADBRANCH;
2436 	  }
2437 	BADEXIT;
2438       }
2439     case '-':
2440       return sRef_undefined;
2441     case 'u':
2442       return sRef_makeUnknown ();
2443     case 'x':
2444       return sRef_makeUnknown ();
2445     default:
2446       llfatalerror (message ("sRef_undumpGlobal: bad line: %s",
2447 			     cstring_fromChars (*c)));
2448     }
2449   BADEXIT;
2450 }
2451 
sRef_undumpBody(char ** c)2452 static /*@exposed@*/ sRef sRef_undumpBody (char **c)
2453 {
2454   char p = **c;
2455 
2456   (*c)++;
2457 
2458   switch (p)
2459     {
2460     case 'g':
2461       return (sRef_makeGlobal (usymId_fromInt (reader_getInt (c)),
2462 			       ctype_unknown, stateInfo_currentLoc ()));
2463     case 'p':
2464       return (sRef_makeParam (reader_getInt (c), ctype_unknown,
2465 			      stateInfo_makeLoc (g_currentloc, SA_DECLARED)));
2466     case 'r':
2467       return (sRef_makeResult (ctype_undump (c)));
2468     case 'a':
2469       {
2470 	if ((**c >= '0' && **c <= '9') || **c == '-')
2471 	  {
2472 	    int i = reader_getInt (c);
2473 	    sRef arr = sRef_undump (c);
2474 	    sRef ret = sRef_buildArrayFetchKnown (arr, i);
2475 
2476 	    return ret;
2477 	  }
2478 	else
2479 	  {
2480 	    sRef arr = sRef_undump (c);
2481 	    sRef ret = sRef_buildArrayFetch (arr);
2482 
2483 	    return ret;
2484 	  }
2485       }
2486     case 'f':
2487       {
2488 	cstring fname = cstring_undefined;
2489 	sRef ret;
2490 
2491 	while (**c != '.')
2492 	  {
2493 	    fname = cstring_appendChar (fname, **c);
2494 	    (*c)++;
2495 	  }
2496 	(*c)++;
2497 
2498 	ret = sRef_buildField (sRef_undump (c), fname);
2499 	cstring_markOwned (fname);
2500 	return (ret);
2501       }
2502     case 's':
2503       {
2504 	int i = reader_getInt (c);
2505 	speckind sk = speckind_fromInt (i);
2506 
2507 	switch (sk)
2508 	  {
2509 	  case SR_NOTHING:   return (sRef_makeNothing ());
2510 	  case SR_INTERNAL:  return (sRef_makeInternalState ());
2511 	  case SR_SPECSTATE: return (sRef_makeSpecState ());
2512 	  case SR_SYSTEM:    return (sRef_makeSystemState ());
2513 	  case SR_GLOBALMARKER: BADBRANCH;
2514 	  }
2515 	BADEXIT;
2516       }
2517     case 't':
2518       {
2519 	sRef ptr = sRef_undump (c);
2520 	sRef ret = sRef_makePointer (ptr);
2521 
2522 	return (ret);
2523       }
2524     case 'd':
2525       {
2526 	sRef adr = sRef_undump (c);
2527 	sRef ret = sRef_makeAddress (adr);
2528 
2529 	return (ret);
2530       }
2531     case 'o':
2532       {
2533 	return (sRef_makeObject (ctype_undump (c)));
2534       }
2535     case 'c':
2536       {
2537 	sRef s1 = sRef_undump (c);
2538 	sRef s2 = ((*c)++, sRef_undump (c));
2539 	sRef ret = sRef_makeConj (s1, s2);
2540 
2541 	return (ret);
2542       }
2543     case '-':
2544       return sRef_undefined;
2545     case 'u':
2546       return sRef_makeUnknown ();
2547     case 'x':
2548       return sRef_makeUnknown ();
2549     default:
2550       llfatalerror (message ("sRef_undump: bad line: %s", cstring_fromChars (*c)));
2551     }
2552   BADEXIT;
2553 }
2554 
sRef_undump(char ** c)2555 /*@exposed@*/ sRef sRef_undump (char **c)
2556 {
2557   sRef res = sRef_undumpBody (c);
2558 
2559   if (reader_optCheckChar (c, '='))
2560     {
2561       multiVal mv = multiVal_undump (c);
2562       sRef_setValue (res, mv);
2563       reader_checkChar (c, '=');
2564     }
2565 
2566   return res;
2567 }
2568 
sRef_dumpBody(sRef s)2569 static /*@only@*/ cstring sRef_dumpBody (sRef s)
2570 {
2571   if (sRef_isInvalid (s))
2572     {
2573       return (cstring_makeLiteral ("-"));
2574     }
2575   else
2576     {
2577       switch (s->kind)
2578 	{
2579 	case SK_PARAM:
2580 	  return (message ("p%d", s->info->paramno));
2581 	case SK_ARRAYFETCH:
2582 	  if (s->info->arrayfetch->indknown)
2583 	    {
2584 	      return (message ("a%d%q", s->info->arrayfetch->ind,
2585 			       sRef_dump (s->info->arrayfetch->arr)));
2586 	    }
2587 	  else
2588 	    {
2589 	      return (message ("a%q", sRef_dump (s->info->arrayfetch->arr)));
2590 	    }
2591 	case SK_FIELD:
2592 	  return (message ("f%s.%q", s->info->field->field,
2593 			   sRef_dump (s->info->field->rec)));
2594 	case SK_PTR:
2595 	  return (message ("t%q", sRef_dump (s->info->ref)));
2596 	case SK_ADR:
2597 	  return (message ("d%q", sRef_dump (s->info->ref)));
2598 	case SK_OBJECT:
2599 	  return (message ("o%q", ctype_dump (s->info->object)));
2600 	case SK_SPECIAL:
2601 	  return (message ("s%d", (int) s->info->spec));
2602 	case SK_CONJ:
2603 	  return (message ("c%q.%q",
2604 			   sRef_dump (s->info->conj->a),
2605 			   sRef_dump (s->info->conj->b)));
2606 	case SK_CVAR:
2607 	  if (sRef_isFileOrGlobalScope (s))
2608 	    {
2609 	      return (message ("g%d",
2610 			       usymtab_convertId (s->info->cvar->index)));
2611 	    }
2612 	  else
2613 	    {
2614 	      llcontbug (message ("Dumping local variable: %q",
2615 				  sRef_unparseDebug (s)));
2616 	      return (cstring_makeLiteral ("u"));
2617 	    }
2618 	case SK_UNKNOWN:
2619 	  return (cstring_makeLiteral ("u"));
2620 	case SK_RESULT:
2621 	  return (message ("r%q", ctype_dump (s->type)));
2622 	case SK_TYPE:
2623 	case SK_CONST:
2624 	case SK_EXTERNAL:
2625 	case SK_DERIVED:
2626 	case SK_NEW:
2627 	case SK_UNCONSTRAINED:
2628 	  llcontbug (message ("sRef_dump: bad kind: %q",
2629 			      sRef_unparseFull (s)));
2630 	  return (cstring_makeLiteral ("x"));
2631 	}
2632     }
2633 
2634   BADEXIT;
2635 }
2636 
sRef_dump(sRef s)2637 /*@only@*/ cstring sRef_dump (sRef s)
2638 {
2639   cstring res = sRef_dumpBody (s);
2640 
2641   if (sRef_hasValue (s))
2642     {
2643       res = message ("%q=%q=", res, multiVal_dump (sRef_getValue (s)));
2644     }
2645 
2646   return res;
2647 }
2648 
sRef_dumpGlobal(sRef s)2649 cstring sRef_dumpGlobal (sRef s)
2650 {
2651   llassert (!sRef_hasValue (s));
2652 
2653   if (sRef_isInvalid (s))
2654     {
2655       return (cstring_makeLiteral ("-"));
2656     }
2657   else
2658     {
2659       switch (s->kind)
2660 	{
2661 	case SK_CVAR:
2662 	  if (sRef_isFileOrGlobalScope (s))
2663 	    {
2664 	      return (message ("g%d@%d@%d",
2665 			       usymtab_convertId (s->info->cvar->index),
2666 			       (int) s->defstate,
2667 			       (int) sRef_getNullState (s)));
2668 	    }
2669 	  else
2670 	    {
2671 	      llcontbug (message ("Dumping local variable: %q",
2672 				  sRef_unparseDebug (s)));
2673 	      return (cstring_makeLiteral ("u"));
2674 	    }
2675 	case SK_UNKNOWN:
2676 	  return (cstring_makeLiteral ("u"));
2677 	case SK_SPECIAL:
2678 	  return (message ("s%d", (int) s->info->spec));
2679 	default:
2680 	  llcontbug (message ("sRef_dumpGlobal: bad kind: %q",
2681 			      sRef_unparseFull (s)));
2682 	  return (cstring_makeLiteral ("x"));
2683 	}
2684     }
2685 
2686   BADEXIT;
2687 }
2688 
2689 ctype
sRef_deriveType(sRef s,uentryList cl)2690 sRef_deriveType (sRef s, uentryList cl)
2691 {
2692   if (sRef_isInvalid (s)) return ctype_unknown;
2693 
2694   switch (s->kind)
2695     {
2696     case SK_CVAR:
2697       return (uentry_getType (usymtab_getRefQuiet (s->info->cvar->lexlevel,
2698 					      s->info->cvar->index)));
2699     case SK_UNCONSTRAINED:
2700       return (ctype_unknown);
2701     case SK_PARAM:
2702       if (s->info->paramno >= 0)
2703 	{
2704 	  return uentry_getType (uentryList_getN (cl, s->info->paramno));
2705 	}
2706       else
2707 	{
2708 	  return ctype_unknown;
2709 	}
2710     case SK_ARRAYFETCH:
2711       {
2712 	ctype ca = sRef_deriveType (s->info->arrayfetch->arr, cl);
2713 
2714 	if (ctype_isArray (ca))
2715 	  {
2716 	    return (ctype_baseArrayPtr (ca));
2717 	  }
2718 	else if (ctype_isUnknown (ca))
2719 	  {
2720 	    return (ca);
2721 	  }
2722 	else
2723 	  {
2724 	    llcontbuglit ("sRef_deriveType: inconsistent array type");
2725 	    return ca;
2726 	  }
2727       }
2728     case SK_FIELD:
2729       {
2730 	ctype ct = sRef_deriveType (s->info->field->rec, cl);
2731 
2732 	if (ctype_isStructorUnion (ct))
2733 	  {
2734 	    uentry ue = uentryList_lookupField (ctype_getFields (ct),
2735 					       s->info->field->field);
2736 
2737 	    if (uentry_isValid (ue))
2738 	      {
2739 		return (uentry_getType (ue));
2740 	      }
2741 	    else
2742 	      {
2743 		llcontbuglit ("sRef_deriveType: bad field");
2744 		return ctype_unknown;
2745 	      }
2746 	  }
2747 	else if (ctype_isUnknown (ct))
2748 	  {
2749 	    return (ct);
2750 	  }
2751 	else
2752 	  {
2753 	    llcontbuglit ("sRef_deriveType: inconsistent field type");
2754 	    return (ct);
2755 	  }
2756       }
2757     case SK_PTR:
2758       {
2759 	ctype ct = sRef_deriveType (s->info->ref, cl);
2760 
2761 	if (ctype_isUnknown (ct)) return ct;
2762 	if (ctype_isPointer (ct)) return (ctype_baseArrayPtr (ct));
2763 	else
2764 	  {
2765 	    llcontbuglit ("sRef_deriveType: inconsistent pointer type");
2766 	    return (ct);
2767 	  }
2768       }
2769     case SK_ADR:
2770       {
2771 	ctype ct = sRef_deriveType (s->info->ref, cl);
2772 
2773 	if (ctype_isUnknown (ct)) return ct;
2774 	return ctype_makePointer (ct);
2775       }
2776     case SK_DERIVED:
2777       {
2778 	return sRef_deriveType (s->info->ref, cl);
2779       }
2780     case SK_OBJECT:
2781       {
2782 	return (s->info->object);
2783       }
2784     case SK_CONJ:
2785       {
2786 	return (ctype_makeConj (sRef_deriveType (s->info->conj->a, cl),
2787 			       sRef_deriveType (s->info->conj->b, cl)));
2788       }
2789     case SK_RESULT:
2790     case SK_CONST:
2791     case SK_TYPE:
2792       {
2793 	return (s->type);
2794       }
2795     case SK_SPECIAL:
2796     case SK_UNKNOWN:
2797     case SK_EXTERNAL:
2798     case SK_NEW:
2799       return ctype_unknown;
2800     }
2801   BADEXIT;
2802 }
2803 
2804 ctype
sRef_getType(sRef s)2805 sRef_getType (sRef s)
2806 {
2807   if (sRef_isInvalid (s)) return ctype_unknown;
2808   return s->type;
2809 }
2810 
2811 
2812 /*@only@*/ cstring
sRef_unparseOpt(sRef s)2813 sRef_unparseOpt (sRef s)
2814 {
2815   sRef rb = sRef_getRootBase (s);
2816 
2817   if (sRef_isMeaningful (rb) && !sRef_isConst (rb))
2818     {
2819       cstring ret = sRef_unparse (s);
2820 
2821       llassertprint (!cstring_equalLit (ret, "?"), ("print: %s", sRef_unparseDebug (s)));
2822 
2823       if (!cstring_isEmpty (ret))
2824 	{
2825 	  return (cstring_appendChar (ret, ' '));
2826 	}
2827       else
2828 	{
2829 	  return ret;
2830 	}
2831     }
2832 
2833   return cstring_undefined;
2834 }
2835 
2836 cstring
sRef_unparsePreOpt(sRef s)2837 sRef_unparsePreOpt (sRef s)
2838 {
2839   sRef rb = sRef_getRootBase (s);
2840 
2841   if (sRef_isMeaningful (rb) && !sRef_isConst (rb))
2842     {
2843       cstring ret = sRef_unparse (s);
2844 
2845       llassertprint (!cstring_equalLit (ret, "?"), ("print: %s", sRef_unparseDebug (s)));
2846       return (cstring_prependCharO (' ', ret));
2847     }
2848 
2849   return cstring_undefined;
2850 }
2851 
2852 /*@only@*/ cstring
sRef_unparse(sRef s)2853 sRef_unparse (sRef s)
2854 {
2855   if (sRef_isInvalid (s)) return (cstring_makeLiteral ("?"));
2856 
2857   if (context_inFunctionLike ())
2858     {
2859       return (sRef_unparseWithArgs (s, context_getParams ()));
2860     }
2861   else
2862     {
2863       DPRINTF (("Not in function like: %s", context_unparse ()));
2864       return (sRef_unparseNoArgs (s));
2865     }
2866 }
2867 
2868 static /*@only@*/ cstring
sRef_unparseWithArgs(sRef s,uentryList args)2869 sRef_unparseWithArgs (sRef s, uentryList args)
2870 {
2871   if (sRef_isInvalid (s))
2872     {
2873       return (cstring_makeLiteral ("?"));
2874     }
2875 
2876   switch (s->kind)
2877     {
2878     case SK_CVAR:
2879       return (uentry_getName (usymtab_getRefQuiet (s->info->cvar->lexlevel,
2880 						   s->info->cvar->index)));
2881     case SK_UNCONSTRAINED:
2882       return (cstring_copy (s->info->fname));
2883     case SK_PARAM:
2884       {
2885 	if (s->info->paramno < uentryList_size (args)
2886 	    && s->info->paramno >= 0)
2887 	  {
2888 	    uentry ue = uentryList_getN (args, s->info->paramno);
2889 
2890 	    if (uentry_isValid (ue))
2891 	      return uentry_getName (ue);
2892 	  }
2893 
2894 	return (message ("parameter %d", s->info->paramno + 1));
2895       }
2896     case SK_ARRAYFETCH:
2897       if (s->info->arrayfetch->indknown)
2898 	{
2899 	  return (message ("%q[%d]", sRef_unparseWithArgs (s->info->arrayfetch->arr, args),
2900 				s->info->arrayfetch->ind));
2901 	}
2902       else
2903 	{
2904 	  return (message ("%q[]", sRef_unparseWithArgs (s->info->arrayfetch->arr, args)));
2905 	}
2906     case SK_FIELD:
2907       if (s->info->field->rec->kind == SK_PTR)
2908 	{
2909 	  sRef ptr = s->info->field->rec;
2910 
2911 	  return (message ("%q->%s", sRef_unparseWithArgs (ptr->info->ref, args),
2912 			   s->info->field->field));
2913 	}
2914       return (message ("%q.%s", sRef_unparseWithArgs (s->info->field->rec, args),
2915 		       s->info->field->field));
2916 
2917     case SK_PTR:
2918       {
2919 	sRef ref = sRef_fixConj (s->info->ref);
2920 	skind sk = ref->kind;
2921 	cstring ret;
2922 
2923 	if (sk == SK_NEW)
2924 	  {
2925 	    ret = message ("storage pointed to by %q",
2926 			   sRef_unparseWithArgs (ref, args));
2927 	  }
2928 	else if (skind_isSimple (sk) || sk == SK_PTR)
2929 	  {
2930 	    ret = message ("*%q", sRef_unparseWithArgs (ref, args));
2931 	  }
2932 	else
2933 	  {
2934 	    ret = message ("*(%q)", sRef_unparseWithArgs (ref, args));
2935 	  }
2936 
2937 	return ret;
2938       }
2939     case SK_ADR:
2940       return (message ("&%q", sRef_unparseWithArgs (s->info->ref, args)));
2941     case SK_OBJECT:
2942       return (cstring_copy (ctype_unparse (s->info->object)));
2943     case SK_CONJ:
2944       return (sRef_unparseWithArgs (sRef_getConjA (s), args));
2945     case SK_NEW:
2946       if (cstring_isDefined (s->info->fname))
2947 	{
2948 	  return (message ("[result of %s]", s->info->fname));
2949 	}
2950       else
2951 	{
2952 	  return (cstring_makeLiteral ("<new>"));
2953 	}
2954     case SK_UNKNOWN:
2955       return (cstring_makeLiteral ("?"));
2956     case SK_DERIVED:
2957       return (message ("<derived %q>", sRef_unparse (s->info->ref)));
2958     case SK_EXTERNAL:
2959       return (message ("<external %q>", sRef_unparse (s->info->ref)));
2960     case SK_TYPE:
2961       return (message ("<type %s>", ctype_unparse (s->type)));
2962     case SK_CONST:
2963       return (message ("<const %s>", ctype_unparse (s->type)));
2964     case SK_SPECIAL:
2965       switch (s->info->spec)
2966 	{
2967 	case SR_NOTHING: return cstring_makeLiteral ("nothing");
2968 	case SR_INTERNAL: return cstring_makeLiteral ("internal state");
2969 	case SR_SPECSTATE: return cstring_makeLiteral ("spec state");
2970 	case SR_SYSTEM: return cstring_makeLiteral ("file system state");
2971 	case SR_GLOBALMARKER: return cstring_makeLiteral ("<global marker>");
2972 	}
2973       BADBRANCH;
2974     case SK_RESULT:
2975       return cstring_makeLiteral ("result");
2976     default:
2977       {
2978 	llbug (message ("Bad sref, kind = %d", (int) s->kind));
2979       }
2980     }
2981 
2982   BADEXIT;
2983 }
2984 
2985 /*@only@*/ cstring
sRef_unparseDebug(sRef s)2986 sRef_unparseDebug (sRef s)
2987 {
2988   if (sRef_isInvalid (s))
2989     {
2990       return (cstring_makeLiteral ("<undef>"));
2991     }
2992 
2993 
2994   switch (s->kind)
2995     {
2996     case SK_UNCONSTRAINED:
2997       return (message ("<unconstrained %s>", s->info->fname));
2998     case SK_CVAR:
2999       {
3000 	uentry ce;
3001 
3002 	ce = usymtab_getRefQuiet (s->info->cvar->lexlevel, s->info->cvar->index);
3003 
3004 	if (uentry_isInvalid (ce))
3005 	  {
3006 	    return (message ("<scope: %d.%d *invalid*>",
3007 			     s->info->cvar->lexlevel,
3008 			     s->info->cvar->index));
3009 	  }
3010 	else
3011 	  {
3012 	    return (message ("<scope: %d.%d *%q*>",
3013 			     s->info->cvar->lexlevel,
3014 			     s->info->cvar->index,
3015 			     uentry_getName (ce)));
3016 	  }
3017 
3018       }
3019     case SK_PARAM:
3020       {
3021 	return (message ("<parameter %d>", s->info->paramno + 1));
3022       }
3023     case SK_ARRAYFETCH:
3024       if (s->info->arrayfetch->indknown)
3025 	{
3026 	  return (message ("%q[%d]", sRef_unparseDebug (s->info->arrayfetch->arr),
3027 			   s->info->arrayfetch->ind));
3028 	}
3029       else
3030 	{
3031 	  return (message ("%q[]", sRef_unparseDebug (s->info->arrayfetch->arr)));
3032 	}
3033     case SK_FIELD:
3034       return (message ("%q.%s", sRef_unparseDebug (s->info->field->rec),
3035 		       s->info->field->field));
3036     case SK_PTR:
3037       if (sRef_isField (s->info->ref))
3038 	{
3039 	  sRef fld = s->info->ref;
3040 
3041 	  return (message ("%q->%s", sRef_unparseDebug (fld->info->field->rec),
3042 			   fld->info->field->field));
3043 	}
3044       else
3045 	{
3046 	  return (message ("*(%q)", sRef_unparseDebug (s->info->ref)));
3047 	}
3048     case SK_ADR:
3049       return (message ("&%q", sRef_unparseDebug (s->info->ref)));
3050     case SK_OBJECT:
3051       return (message ("<object type %s>", ctype_unparse (s->info->object)));
3052     case SK_CONJ:
3053       return (message ("%q | %q", sRef_unparseDebug (s->info->conj->a),
3054 		       sRef_unparseDebug (s->info->conj->b)));
3055     case SK_NEW:
3056       return message ("<new: %s>", s->info->fname);
3057     case SK_DERIVED:
3058       return (message ("<derived %q>", sRef_unparseDebug (s->info->ref)));
3059     case SK_EXTERNAL:
3060       return (message ("<external %q>", sRef_unparseDebug (s->info->ref)));
3061     case SK_TYPE:
3062       return (message ("<type %s>", ctype_unparse (s->type)));
3063     case SK_CONST:
3064       if (sRef_hasValue (s))
3065 	{
3066 	  return (message ("<const %s=%q>", ctype_unparse (s->type), multiVal_unparse (sRef_getValue (s))));
3067 	}
3068       else
3069 	{
3070 	  return (message ("<const %s>", ctype_unparse (s->type)));
3071 	}
3072     case SK_RESULT:
3073       return (message ("<result %s>", ctype_unparse (s->type)));
3074     case SK_SPECIAL:
3075       return (message ("<spec %s>",
3076 		       cstring_makeLiteralTemp
3077 		       (s->info->spec == SR_NOTHING ? "nothing"
3078 			: s->info->spec == SR_INTERNAL ? "internalState"
3079 			: s->info->spec == SR_SPECSTATE ? "spec state"
3080 			: s->info->spec == SR_SYSTEM ? "fileSystem"
3081 			: "error")));
3082     case SK_UNKNOWN:
3083       return cstring_makeLiteral ("<unknown>");
3084     }
3085 
3086   BADEXIT;
3087 }
3088 
3089 static /*@only@*/ cstring
sRef_unparseNoArgs(sRef s)3090 sRef_unparseNoArgs (sRef s)
3091 {
3092   if (sRef_isInvalid (s)) return (cstring_makeLiteral ("?"));
3093 
3094   switch (s->kind)
3095     {
3096     case SK_UNCONSTRAINED:
3097       return (cstring_copy (s->info->fname));
3098     case SK_CVAR:
3099       {
3100 	uentry ce = usymtab_getRefQuiet (s->info->cvar->lexlevel,
3101 					 s->info->cvar->index);
3102 
3103 	if (uentry_isInvalid (ce))
3104 	  {
3105 	    llcontbug (message ("sRef_unparseNoArgs: bad cvar: %q",
3106 				sRef_unparseDebug (s)));
3107 	    return (sRef_unparseDebug (s));
3108 	  }
3109 	else
3110 	  {
3111 	    return (uentry_getName (ce));
3112 	  }
3113       }
3114     case SK_ARRAYFETCH:
3115       if (s->info->arrayfetch->indknown)
3116 	{
3117 	  return (message ("%q[%d]", sRef_unparseNoArgs (s->info->arrayfetch->arr),
3118 			   s->info->arrayfetch->ind));
3119 	}
3120       else
3121 	{
3122 	  return (message ("%q[]", sRef_unparseNoArgs (s->info->arrayfetch->arr)));
3123 	}
3124     case SK_FIELD:
3125       return (message ("%q.%s", sRef_unparseNoArgs (s->info->field->rec),
3126 		       s->info->field->field));
3127     case SK_PTR:
3128       {
3129 	sRef ref = sRef_fixConj (s->info->ref);
3130 	skind sk = ref->kind;
3131 	cstring ret;
3132 
3133 	if (skind_isSimple (sk) || sk == SK_PTR)
3134 	  {
3135 	    ret = message ("*%q", sRef_unparseNoArgs (ref));
3136 	  }
3137 	else
3138 	  {
3139 	    ret = message ("*(%q)", sRef_unparseNoArgs (ref));
3140 	  }
3141 
3142 	return (ret);
3143       }
3144     case SK_ADR:
3145       return (message ("&%q", sRef_unparseNoArgs (s->info->ref)));
3146     case SK_OBJECT:
3147       return (cstring_copy (ctype_unparse (s->info->object)));
3148     case SK_CONJ:
3149       return (sRef_unparseNoArgs (s->info->conj->a));
3150     case SK_NEW:
3151       return (message ("result of %s", s->info->fname));
3152     case SK_DERIVED:
3153       return (message ("<der %q>", sRef_unparseNoArgs (s->info->ref)));
3154     case SK_EXTERNAL:
3155       return message ("<ext %q>", sRef_unparseNoArgs (s->info->ref));
3156     case SK_SPECIAL:
3157       return (cstring_makeLiteral
3158 	      (s->info->spec == SR_NOTHING ? "nothing"
3159 	       : s->info->spec == SR_INTERNAL ? "internal state"
3160 	       : s->info->spec == SR_SPECSTATE ? "spec state"
3161 	       : s->info->spec == SR_SYSTEM ? "file system state"
3162 	       : "<spec error>"));
3163     case SK_RESULT:
3164       return cstring_makeLiteral ("result");
3165     case SK_CONST:
3166     case SK_TYPE:
3167     case SK_UNKNOWN:
3168       return cstring_makeLiteral ("?");
3169     case SK_PARAM:
3170       /* llcontbug (message ("sRef_unparseNoArgs: bad case: %q", sRef_unparseDebug (s))); */
3171       return (sRef_unparseDebug (s));
3172     }
3173   BADEXIT;
3174 }
3175 
sRef_makeUnconstrained(cstring fname)3176 /*@dependent@*/ sRef sRef_makeUnconstrained (cstring fname)
3177 {
3178   sRef s = sRef_new ();
3179 
3180   s->kind = SK_UNCONSTRAINED;
3181   s->info = (sinfo) dmalloc (sizeof (*s->info));
3182   s->info->fname = cstring_copy (fname); /* evans 2002-07-12: this was exposed, causing memory errors */
3183 
3184   return (s);
3185 }
3186 
sRef_unconstrainedName(sRef s)3187 cstring sRef_unconstrainedName (sRef s)
3188 {
3189   llassert (sRef_isUnconstrained (s));
3190 
3191   return s->info->fname;
3192 }
3193 
sRef_isUnconstrained(sRef s)3194 bool sRef_isUnconstrained (sRef s)
3195 {
3196   return (sRef_isReasonable(s) && s->kind == SK_UNCONSTRAINED);
3197 }
3198 
3199 static /*@dependent@*/ /*@notnull@*/ sRef
sRef_makeCvarAux(int level,usymId index,ctype ct,stateInfo stinfo)3200   sRef_makeCvarAux (int level, usymId index, ctype ct, /*@only@*/ stateInfo stinfo)
3201 {
3202   sRef s = sRef_newRef ();
3203 
3204   s->kind = SK_CVAR;
3205   s->info = (sinfo) dmalloc (sizeof (*s->info));
3206 
3207   s->info->cvar = (cref) dmalloc (sizeof (*s->info->cvar));
3208   s->info->cvar->lexlevel = level;
3209   s->info->cvar->index = index;
3210 
3211   /* for now, all globals are defined; all locals, aren't */
3212 
3213   if (level <= fileScope)
3214     {
3215       s->defstate = SS_UNKNOWN;
3216     }
3217   else
3218     {
3219       ctype rct = ctype_realType (ct);
3220 
3221       if (level != paramsScope
3222 	  && (ctype_isStructorUnion (rct) || ctype_isRealArray (rct)))
3223 	{
3224 	  s->defstate = SS_ALLOCATED;
3225 	  s->oaliaskind = s->aliaskind = AK_STACK;
3226 	}
3227       else
3228 	{
3229 	  s->defstate = SS_UNDEFINED;
3230 	  s->oaliaskind = s->aliaskind = AK_LOCAL;
3231 	}
3232     }
3233 
3234   s->type = ct;
3235 
3236   llassert (level >= globScope);
3237   llassert (usymId_isValid (index));
3238 
3239   DPRINTF (("Made cvar: [%p] %s", s, sRef_unparseDebug (s)));
3240   llassert (valueTable_isUndefined (s->state));
3241   s->state = context_createValueTable (s, stinfo);
3242   return s;
3243 }
3244 
sRef_makeCvar(int level,usymId index,ctype ct,stateInfo stinfo)3245 /*@dependent@*/ sRef sRef_makeCvar (int level, usymId index, ctype ct, /*@only@*/ stateInfo stinfo)
3246 {
3247   return (sRef_makeCvarAux (level, index, ct, stinfo));
3248 }
3249 
sRef_lexLevel(sRef s)3250 int sRef_lexLevel (sRef s)
3251 {
3252   if (sRef_isReasonable (s))
3253     {
3254       sRef conj;
3255 
3256       conj = sRef_fixConj (s);
3257       s = sRef_getRootBase (conj);
3258 
3259       if (sRef_isReasonable (s) && s->kind == SK_CVAR)
3260 	{
3261 	  return (s->info->cvar->lexlevel);
3262 	}
3263     }
3264 
3265   return globScope;
3266 }
3267 
3268 sRef
sRef_makeGlobal(usymId l,ctype ct,stateInfo stinfo)3269 sRef_makeGlobal (usymId l, ctype ct, /*@only@*/ stateInfo stinfo)
3270 {
3271   return (sRef_makeCvar (globScope, l, ct, stinfo));
3272 }
3273 
3274 void
sRef_setParamNo(sRef s,int l)3275 sRef_setParamNo (sRef s, int l)
3276 {
3277   llassert (sRef_isReasonable (s) && s->kind == SK_PARAM);
3278   s->info->paramno = l;
3279   llassert (l >= -1);
3280 }
3281 
3282 /*@dependent@*/ sRef
sRef_makeParam(int l,ctype ct,stateInfo stinfo)3283 sRef_makeParam (int l, ctype ct, stateInfo stinfo)
3284 {
3285   sRef s = sRef_new ();
3286 
3287   s->kind = SK_PARAM;
3288   s->type = ct;
3289 
3290   s->info = (sinfo) dmalloc (sizeof (*s->info));
3291   s->info->paramno = l;
3292   llassert (l >= -1);
3293   s->defstate = SS_UNKNOWN;
3294   /* (probably defined, unless its an out parameter) */
3295 
3296   llassert (valueTable_isUndefined (s->state));
3297   s->state = context_createValueTable (s, stinfo);
3298   return s;
3299 }
3300 
3301 bool
sRef_isIndexKnown(sRef arr)3302 sRef_isIndexKnown (sRef arr)
3303 {
3304   bool res;
3305 
3306   llassert (sRef_isReasonable (arr));
3307   arr = sRef_fixConj (arr);
3308 
3309   llassert (arr->kind == SK_ARRAYFETCH);
3310   res = arr->info->arrayfetch->indknown;
3311   return (res);
3312 }
3313 
3314 int
sRef_getIndex(sRef arr)3315 sRef_getIndex (sRef arr)
3316 {
3317   int result;
3318 
3319   llassert (sRef_isReasonable (arr));
3320   arr = sRef_fixConj (arr);
3321 
3322   llassert (arr->kind == SK_ARRAYFETCH);
3323 
3324   if (!arr->info->arrayfetch->indknown)
3325     {
3326       llcontbug (message ("sRef_getIndex: unknown: %q", sRef_unparse (arr)));
3327       result = 0;
3328     }
3329   else
3330     {
3331       result = arr->info->arrayfetch->ind;
3332     }
3333 
3334   return result;
3335 }
3336 
sRef_isZerothArrayFetch(sRef s)3337 static bool sRef_isZerothArrayFetch (/*@notnull@*/ sRef s)
3338 {
3339   return (s->kind == SK_ARRAYFETCH
3340 	  && s->info->arrayfetch->indknown
3341 	  && (s->info->arrayfetch->ind == 0));
3342 }
3343 
sRef_makeAddress(sRef t)3344 /*@exposed@*/ sRef sRef_makeAddress (/*@exposed@*/ sRef t)
3345 {
3346 
3347   if (sRef_isInvalid (t)) return sRef_undefined;
3348 
3349   if (sRef_isPointer (t))
3350     {
3351       return (t->info->ref);
3352     }
3353   else if (sRef_isZerothArrayFetch (t))
3354     {
3355       return (t->info->arrayfetch->arr);
3356     }
3357   else
3358     {
3359       sRef s = sRef_newRef ();
3360 
3361       s->kind = SK_ADR;
3362       s->type = ctype_makePointer (t->type);
3363       s->info = (sinfo) dmalloc (sizeof (*s->info));
3364       s->info->ref = t;
3365 
3366       if (t->defstate == SS_UNDEFINED)
3367 	/* no! it is allocated even still: && !ctype_isPointer (t->type)) */
3368 	{
3369 	  s->defstate = SS_ALLOCATED;
3370 	}
3371       else
3372 	{
3373 	  s->defstate = t->defstate;
3374 	}
3375 
3376       if (t->aliaskind == AK_LOCAL)
3377 	{
3378 	  if (sRef_isLocalVar (t))
3379 	    {
3380 	      s->aliaskind = AK_STACK;
3381 	    }
3382 	}
3383 
3384       llassert (valueTable_isUndefined (s->state));
3385       s->state = context_createValueTable (s,
3386 					   stateInfo_makeLoc (g_currentloc, SA_CREATED));
3387       return s;
3388     }
3389 }
3390 
sRef_getField(sRef s)3391 cstring sRef_getField (sRef s)
3392 {
3393   cstring res;
3394 
3395   llassert (sRef_isReasonable (s));
3396   s = sRef_fixConj (s);
3397 
3398   llassertprint (sRef_isReasonable (s) && (s->kind == SK_FIELD),
3399 		 ("s = %s", sRef_unparseDebug (s)));
3400 
3401   res = s->info->field->field;
3402   return (res);
3403 }
3404 
sRef_getBase(sRef s)3405 sRef sRef_getBase (sRef s)
3406 {
3407   sRef res;
3408 
3409   if (sRef_isInvalid (s)) return (sRef_undefined);
3410 
3411   s = sRef_fixConj (s);
3412 
3413   switch (s->kind)
3414     {
3415     case SK_ADR:
3416     case SK_PTR:
3417     case SK_DERIVED:
3418     case SK_EXTERNAL:
3419       res = s->info->ref;
3420       break;
3421     case SK_FIELD:
3422       res = s->info->field->rec;
3423       break;
3424 
3425     case SK_ARRAYFETCH:
3426       res = s->info->arrayfetch->arr;
3427       break;
3428 
3429     default:
3430       res = sRef_undefined; /* shouldn't need it */
3431     }
3432 
3433   return (res);
3434 }
3435 
3436 /*
3437 ** same as getBase, except returns invalid
3438 ** (and doesn't use adr's)
3439 */
3440 
3441 sRef
sRef_getBaseSafe(sRef s)3442 sRef_getBaseSafe (sRef s)
3443 {
3444   sRef res;
3445 
3446   if (sRef_isInvalid (s)) { return sRef_undefined; }
3447 
3448   s = sRef_fixConj (s);
3449 
3450   switch (s->kind)
3451     {
3452     case SK_PTR:
3453             res = s->info->ref;
3454       break;
3455     case SK_FIELD:
3456             res = s->info->field->rec; break;
3457     case SK_ARRAYFETCH:
3458             res = s->info->arrayfetch->arr;
3459       break;
3460     default:
3461       res = sRef_undefined; break;
3462     }
3463 
3464   return res;
3465 }
3466 
3467 /*@constant int MAXBASEDEPTH;@*/
3468 # define MAXBASEDEPTH 25
3469 
3470 static /*@exposed@*/ sRef
sRef_getRootBaseAux(sRef s,int depth)3471 sRef_getRootBaseAux (sRef s, int depth)
3472 {
3473   if (sRef_isInvalid (s)) return sRef_undefined;
3474 
3475   if (depth > MAXBASEDEPTH)
3476     {
3477       llgenmsg (message
3478 		("Warning: reference base limit exceeded for %q. "
3479 		 "This either means there is a variable with at least "
3480 		 "%d indirections from this reference, or "
3481 		 "there is a bug in Splint.",
3482 		 sRef_unparse (s),
3483 		 MAXBASEDEPTH),
3484 		g_currentloc);
3485 
3486       return sRef_undefined;
3487     }
3488 
3489   switch (s->kind)
3490     {
3491     case SK_ADR:
3492     case SK_PTR:
3493       return (sRef_getRootBaseAux (s->info->ref, depth + 1));
3494     case SK_FIELD:
3495       return (sRef_getRootBaseAux (s->info->field->rec, depth + 1));
3496     case SK_ARRAYFETCH:
3497       return (sRef_getRootBaseAux (s->info->arrayfetch->arr, depth + 1));
3498     case SK_CONJ:
3499       return (sRef_getRootBaseAux (sRef_fixConj (s), depth + 1));
3500     default:
3501       return s;
3502     }
3503 }
3504 
sRef_getRootBase(sRef s)3505 sRef sRef_getRootBase (sRef s)
3506 {
3507   return (sRef_getRootBaseAux (s, 0));
3508 }
3509 
sRef_isDeep(sRef s)3510 static bool sRef_isDeep (sRef s)
3511 {
3512   if (sRef_isInvalid (s)) return FALSE;
3513 
3514   switch (s->kind)
3515     {
3516     case SK_ADR:
3517     case SK_PTR:
3518     case SK_FIELD:
3519     case SK_ARRAYFETCH:
3520       return TRUE;
3521     case SK_CONJ:
3522       return (sRef_isDeep (sRef_fixConj (s)));
3523     default:
3524       return FALSE;
3525     }
3526 }
3527 
sRef_depth(sRef s)3528 static int sRef_depth (sRef s)
3529 {
3530   if (sRef_isInvalid (s)) return 0;
3531 
3532   switch (s->kind)
3533     {
3534     case SK_ADR:
3535     case SK_PTR:
3536     case SK_DERIVED:
3537     case SK_EXTERNAL:
3538       return 1 + sRef_depth (s->info->ref);
3539     case SK_FIELD:
3540       return 1 + sRef_depth (s->info->field->rec);
3541     case SK_ARRAYFETCH:
3542       return 1 + sRef_depth (s->info->arrayfetch->arr);
3543     case SK_CONJ:
3544       return (sRef_depth (sRef_fixConj (s)));
3545     default:
3546       return 1;
3547     }
3548 }
3549 
3550 sRef
sRef_makeObject(ctype o)3551 sRef_makeObject (ctype o)
3552 {
3553   sRef s = sRef_newRef ();
3554 
3555   s->kind = SK_OBJECT;
3556   s->info = (sinfo) dmalloc (sizeof (*s->info));
3557   s->info->object = o;
3558   llassert (valueTable_isUndefined (s->state));
3559   s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_CREATED));
3560   return s;
3561 }
3562 
3563 /*
3564 ** This is used to represent storage referenced by a parameter.
3565 */
3566 
sRef_makeExternal(sRef t)3567 sRef sRef_makeExternal (sRef t)
3568 {
3569   sRef s = sRef_newRef ();
3570 
3571   llassert (sRef_isReasonable (t));
3572 
3573   s->kind = SK_EXTERNAL;
3574   s->info = (sinfo) dmalloc (sizeof (*s->info));
3575   s->type = t->type;
3576   s->info->ref = t;
3577   llassert (valueTable_isUndefined (s->state));
3578   s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_DECLARED));
3579   return s;
3580 }
3581 
sRef_makeDerived(sRef t)3582 /*@dependent@*/ sRef sRef_makeDerived (/*@exposed@*/ sRef t)
3583 {
3584   if (sRef_isReasonable (t))
3585     {
3586       sRef s = sRef_newRef ();
3587 
3588       s->kind = SK_DERIVED;
3589       s->info = (sinfo) dmalloc (sizeof (*s->info));
3590       s->info->ref = t;
3591 
3592       s->type = t->type;
3593       llassert (valueTable_isUndefined (s->state));
3594       s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_CREATED));
3595       return s;
3596     }
3597   else
3598     {
3599       return sRef_undefined;
3600     }
3601 }
3602 
3603 /*
3604 ** definitely NOT symmetric:
3605 **
3606 **   res fills in unknown state information from other
3607 */
3608 
3609 void
sRef_mergeStateQuiet(sRef res,sRef other)3610 sRef_mergeStateQuiet (sRef res, sRef other)
3611 {
3612   llassert (sRef_isReasonable (res));
3613   llassert (sRef_isReasonable (other));
3614 
3615   res->modified = res->modified || other->modified;
3616   res->safe = res->safe && other->safe;
3617 
3618   if (res->defstate == SS_UNKNOWN)
3619     {
3620       res->defstate = other->defstate;
3621       res->definfo = stateInfo_update (res->definfo, other->definfo);
3622     }
3623 
3624   if (res->aliaskind == AK_UNKNOWN ||
3625       (res->aliaskind == AK_LOCAL && alkind_isKnown (other->aliaskind)))
3626     {
3627       res->aliaskind = other->aliaskind;
3628       res->oaliaskind = other->oaliaskind;
3629       res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
3630     }
3631 
3632   if (res->expkind == XO_UNKNOWN)
3633     {
3634       res->expkind = other->expkind;
3635       res->oexpkind = other->oexpkind;
3636       res->expinfo = stateInfo_update (res->expinfo, other->expinfo);
3637     }
3638 
3639   /* out takes precedence over implicitly defined */
3640   if (res->defstate == SS_DEFINED && other->defstate != SS_UNKNOWN)
3641     {
3642       res->defstate = other->defstate;
3643       res->definfo = stateInfo_update (res->definfo, other->definfo);
3644     }
3645 
3646   if (sRef_getNullState (other) == NS_ERROR || sRef_getNullState (res) == NS_ERROR)
3647     {
3648       sRef_setNullState (res, NS_ERROR, fileloc_undefined);
3649     }
3650   else
3651     {
3652       if (sRef_getNullState (other) != NS_UNKNOWN
3653 	  && (sRef_getNullState (res) == NS_UNKNOWN || sRef_getNullState (res) == NS_NOTNULL
3654 	      || sRef_getNullState (res) == NS_MNOTNULL))
3655 	{
3656 	  sRef_updateNullState (res, other);
3657 	}
3658     }
3659 }
3660 
3661 /*
3662 ** definitely NOT symmetric:
3663 **
3664 **   res fills in known state information from other
3665 */
3666 
3667 void
sRef_mergeStateQuietReverse(sRef res,sRef other)3668 sRef_mergeStateQuietReverse (/*@dependent@*/ sRef res, /*@dependent@*/ sRef other)
3669 {
3670   bool changed = FALSE;
3671 
3672   llassert (sRef_isReasonable (res));
3673   llassert (sRef_isReasonable (other));
3674   sRef_checkMutable (res);
3675 
3676   if (res->kind != other->kind)
3677     {
3678       changed = TRUE;
3679 
3680       sinfo_free (res);
3681 
3682       res->kind = other->kind;
3683       res->type = other->type;
3684       res->info = sinfo_fullCopy (other);
3685     }
3686   else
3687     {
3688       if (!ctype_equal (res->type, other->type))
3689 	{
3690 	  changed = TRUE;
3691 	  res->type = other->type;
3692 	}
3693 
3694       sinfo_update (res, other);
3695     }
3696 
3697   res->modified = res->modified || other->modified;
3698   res->safe = res->safe && other->safe;
3699 
3700   if (res->aliaskind != other->aliaskind
3701       && (res->aliaskind == AK_UNKNOWN
3702 	  || ((res->aliaskind == AK_LOCAL
3703 	       || (res->aliaskind == AK_REFCOUNTED
3704 		   && other->aliaskind != AK_LOCAL))
3705 	      && other->aliaskind != AK_UNKNOWN)))
3706     {
3707       changed = TRUE;
3708       res->aliaskind = other->aliaskind;
3709       res->oaliaskind = other->oaliaskind;
3710       res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
3711     }
3712 
3713   if (other->expkind != XO_UNKNOWN && other->expkind != res->expkind)
3714     {
3715       changed = TRUE;
3716       res->expkind = other->expkind;
3717       res->expinfo = stateInfo_update (res->expinfo, other->expinfo);
3718     }
3719 
3720   if (other->oexpkind != XO_UNKNOWN)
3721     {
3722       res->oexpkind = other->oexpkind;
3723     }
3724 
3725   /* out takes precedence over implicitly defined */
3726 
3727   if (res->defstate != other->defstate)
3728     {
3729       if (other->defstate != SS_UNKNOWN)
3730 	{
3731 	  res->defstate = other->defstate;
3732 	  res->definfo = stateInfo_update (res->definfo, other->definfo);
3733 	}
3734     }
3735 
3736   if (sRef_getNullState (other) == NS_ERROR || sRef_getNullState (res) == NS_ERROR)
3737     {
3738       if (sRef_getNullState (res) != NS_ERROR)
3739 	{
3740 	  sRef_setNullStateN (res, NS_ERROR);
3741 	  changed = TRUE;
3742 	}
3743     }
3744   else
3745     {
3746       if (sRef_getNullState (other) != NS_UNKNOWN
3747 	  && sRef_getNullState (other) != sRef_getNullState (res))
3748 	{
3749 	  changed = TRUE;
3750 	  sRef_updateNullState (res, other);
3751 	}
3752     }
3753 
3754   if (changed)
3755     {
3756       sRef_clearDerived (res);
3757     }
3758 }
3759 
3760 void
sRef_mergeState(sRef res,sRef other,clause cl,fileloc loc)3761 sRef_mergeState (sRef res, sRef other, clause cl, fileloc loc)
3762 {
3763   if (sRef_isReasonable (res) && sRef_isReasonable (other))
3764     {
3765       sRef_mergeStateAux (res, other, cl, FALSE, loc, TRUE);
3766     }
3767   else
3768     {
3769       if (sRef_isInvalid (res))
3770 	{
3771 	  llbug (message ("sRef_mergeState: invalid res sRef: %q",
3772 			  sRef_unparseDebug (other)));
3773 	}
3774       else
3775 	{
3776 	  llbug (message ("sRef_mergeState: invalid other sRef: %q",
3777 			  sRef_unparseDebug (res)));
3778 	}
3779     }
3780 }
3781 
3782 void
sRef_mergeOptState(sRef res,sRef other,clause cl,fileloc loc)3783 sRef_mergeOptState (sRef res, sRef other, clause cl, fileloc loc)
3784 {
3785   if (sRef_isReasonable (res) && sRef_isReasonable (other))
3786     {
3787       sRef_mergeStateAux (res, other, cl, TRUE, loc, TRUE);
3788     }
3789   else
3790     {
3791       if (sRef_isInvalid (res))
3792 	{
3793 	  llbug (message ("sRef_mergeOptState: invalid res sRef: %q",
3794 			  sRef_unparseDebug (other)));
3795 	}
3796       else
3797 	{
3798 	  llbug (message ("sRef_mergeOptState: invalid other sRef: %q",
3799 			  sRef_unparseDebug (res)));
3800 	}
3801     }
3802 }
3803 
3804 static void
sRef_mergeStateAux(sRef res,sRef other,clause cl,bool opt,fileloc loc,bool doDerivs)3805 sRef_mergeStateAux (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other,
3806 		    clause cl, bool opt, fileloc loc,
3807 		    bool doDerivs)
3808    /*@modifies res@*/
3809 {
3810   llassertfatal (sRef_isReasonable (res));
3811   llassertfatal (sRef_isReasonable (other));
3812 
3813   DPRINTF (("Merge aux: %s / %s",
3814 	    sRef_unparseFull (res),
3815 	    sRef_unparseFull (other)));
3816 
3817   sRef_checkMutable (res);
3818   sRef_checkMutable (other);
3819 
3820   res->modified = res->modified || other->modified;
3821 
3822   if (res->kind == other->kind
3823       || (other->kind == SK_UNKNOWN || res->kind == SK_UNKNOWN))
3824     {
3825       sstate odef = other->defstate;
3826       sstate rdef = res->defstate;
3827       nstate onull = sRef_getNullState (other);
3828 
3829       /*
3830       ** yucky stuff to handle
3831       **
3832       **   if (s) free (s);
3833       */
3834 
3835       if (other->defstate == SS_DEAD
3836 	  && ((sRef_isOnly (res) && sRef_definitelyNull (res))
3837 	      || (res->defstate == SS_UNDEFINED
3838 		  || res->defstate == SS_UNUSEABLE)))
3839 	{
3840 	  if (res->defstate == SS_UNDEFINED
3841 	      || res->defstate == SS_UNUSEABLE)
3842 	    {
3843 	      res->defstate = SS_UNUSEABLE;
3844 	    }
3845 	  else
3846 	    {
3847 	      res->defstate = SS_DEAD;
3848 	    }
3849 
3850 	  res->definfo = stateInfo_update (res->definfo, other->definfo);
3851 	  sRef_clearDerived (other);
3852 	  sRef_clearDerived (res);
3853 	}
3854       else if (res->defstate == SS_DEAD
3855 	       && ((sRef_isOnly (other) && sRef_definitelyNull (other))
3856 		   || (other->defstate == SS_UNDEFINED
3857 		       || other->defstate == SS_UNUSEABLE)))
3858 	{
3859 	  if (other->defstate == SS_UNDEFINED
3860 	      || other->defstate == SS_UNUSEABLE)
3861 	    {
3862 	      res->defstate = SS_UNUSEABLE;
3863 	    }
3864 	  else
3865 	    {
3866 	      res->defstate = SS_DEAD;
3867 	    }
3868 
3869 	  res->definfo = stateInfo_update (res->definfo, other->definfo);
3870 	  sRef_clearDerived (other);
3871 	  sRef_clearDerived (res);
3872 	}
3873       else if (res->defstate == SS_DEFINED
3874 	       && (other->defstate == SS_ALLOCATED
3875 		   && sRef_definitelyNull (other)))
3876 	{
3877 	  other->defstate = SS_DEFINED; /* definitely null! */
3878 	}
3879       else if (other->defstate == SS_DEFINED
3880 	       && (res->defstate == SS_ALLOCATED && sRef_definitelyNull (res)))
3881 	{
3882 	  res->defstate = SS_DEFINED;
3883 	  res->definfo = stateInfo_update (res->definfo, other->definfo);
3884 	}
3885       else
3886 	{
3887 	  ; /* okay */
3888 	}
3889 
3890       if (res->defstate == SS_DEAD && other->defstate == SS_DEAD)
3891 	{
3892 	  sRef_clearDerived (other);
3893 	  sRef_clearDerived (res);
3894 	}
3895 
3896       /*
3897       ** only & dead isn't really an only!
3898       */
3899 
3900       if (alkind_isOnly (other->aliaskind) && other->defstate == SS_DEAD)
3901 	{
3902 	  other->aliaskind = AK_UNKNOWN;
3903 	}
3904 
3905       if (alkind_isOnly (res->aliaskind) && res->defstate == SS_DEAD)
3906 	{
3907 	  res->aliaskind = AK_UNKNOWN;
3908 	}
3909 
3910       /*
3911       ** Dead and dependent -> dead
3912       */
3913 
3914       if (alkind_isDependent (other->aliaskind) && res->defstate == SS_DEAD)
3915 	{
3916 	  other->aliaskind = AK_UNKNOWN;
3917 	  other->defstate = SS_DEAD;
3918 	  sRef_clearDerived (res);
3919 	  sRef_clearDerived (other);
3920 	}
3921 
3922       if (alkind_isDependent (res->aliaskind) && other->defstate == SS_DEAD)
3923 	{
3924 	  res->aliaskind = AK_UNKNOWN;
3925 	  res->defstate = SS_DEAD;
3926 	  sRef_clearDerived (res);
3927 	  sRef_clearDerived (other);
3928 	}
3929 
3930       /*
3931       ** must do alias combine first, since it depends on
3932       ** original values of state and null.
3933       */
3934 
3935       sRef_combineAliasKinds (res, other, cl, loc);
3936       sRef_combineDefState (res, other);
3937       sRef_combineNullState (res, other);
3938 
3939       if (rdef == SS_ALLOCATED || rdef == SS_SPECIAL)
3940 	{
3941 	  if (odef == SS_DEFINED)
3942 	    {
3943 	      if (onull == NS_DEFNULL || onull == NS_CONSTNULL)
3944 		{
3945 		  res->deriv = sRefSet_copyInto (res->deriv, other->deriv);
3946 		  DPRINTF (("Copy derivs: %s", sRef_unparseFull (res)));
3947 		}
3948 	    }
3949 	  else if (odef == SS_ALLOCATED || odef == SS_SPECIAL)
3950 	    {
3951 
3952 	      if (doDerivs)
3953 		{
3954 		  if (ctype_isUnion (ctype_realType (sRef_getType (res))))
3955 		    {
3956 		      res->deriv = sRef_mergeUnionDerivs (res->deriv,
3957 							  other->deriv,
3958 							  opt, cl, loc);
3959 		      DPRINTF (("Copy derivs: %s", sRef_unparseFull (res)));
3960 		    }
3961 		  else
3962 		    {
3963 		      res->deriv = sRef_mergeDerivs (res->deriv, other->deriv,
3964 						     opt, cl, loc);
3965 		      DPRINTF (("Copy derivs: %s", sRef_unparseFull (res)));
3966 		    }
3967 		}
3968 	    }
3969 	  else
3970 	    {
3971 	      if (doDerivs)
3972 		{
3973 		  res->deriv = sRef_mergeDerivs (res->deriv, other->deriv,
3974 						 opt, cl, loc);
3975 		  DPRINTF (("Copy derivs: %s", sRef_unparseFull (res)));
3976 		}
3977 	      else
3978 		{
3979 		  ;
3980 		}
3981 	    }
3982 	}
3983       else
3984 	{
3985 	  if (rdef == SS_PDEFINED
3986 	      || (rdef == SS_DEFINED && odef == SS_PDEFINED))
3987 	    {
3988 		if (doDerivs)
3989 		    {
3990 		      res->deriv = sRef_mergePdefinedDerivs (res->deriv, other->deriv,
3991 							     opt, cl, loc);
3992 		      DPRINTF (("Copy derivs: %s", sRef_unparseFull (res)));
3993 		    }
3994 	    }
3995 	  else
3996 	    {
3997 	      if ((rdef == SS_DEFINED  || rdef == SS_UNKNOWN)
3998 		  && res->defstate == SS_ALLOCATED)
3999 		{
4000 		  res->deriv = sRefSet_copyInto (res->deriv, other->deriv);
4001 		}
4002 	      else
4003 		{
4004 		  if (doDerivs)
4005 		    {
4006 		      res->deriv = sRef_mergeDerivs (res->deriv, other->deriv,
4007 						     opt, cl, loc);
4008 		      DPRINTF (("Copy derivs: %s", sRef_unparseFull (res)));
4009 		    }
4010 		}
4011 	    }
4012 	}
4013 
4014 
4015       sRef_combineExKinds (res, other);
4016     }
4017   else
4018     {
4019       if (res->kind == SK_ARRAYFETCH && other->kind == SK_PTR)
4020 	{
4021 	  sRef nother = sRef_buildArrayFetchKnown (sRef_getBase (other), 0);
4022 
4023 	  sRef_copyState (nother, other);
4024 	  sRef_mergeStateAux (res, nother, cl, opt, loc, doDerivs);
4025 	}
4026       else if (res->kind == SK_PTR && other->kind == SK_ARRAYFETCH)
4027 	{
4028 	  sRef nother = sRef_buildPointer (sRef_getBase (other));
4029 
4030 	  if (sRef_isReasonable (nother))
4031 	    {
4032 	      sRef_copyState (nother, other);
4033 	      sRef_mergeStateAux (res, nother, cl, opt, loc, doDerivs);
4034 	    }
4035 	}
4036       else
4037 	{
4038 	  llcontbug (message ("merge conj: %q / %q", sRef_unparseFull (res),
4039 			      sRef_unparseFull (other)));
4040 
4041 	}
4042     }
4043 
4044   /*
4045   ** Merge value table states
4046   */
4047 
4048 # if 0
4049   /*
4050   ** This doesn't do anything.  And its broken too...
4051   */
4052 
4053   valueTable_elements (res->state, key, sv)
4054     {
4055       stateValue os = valueTable_lookup (other->state, key);
4056       /*@unused@*/ int val;
4057       /*@unused@*/ char *msg;
4058 
4059       llassert (stateValue_isDefined (os));
4060 
4061       DPRINTF (("Merge state: %s / %s",
4062 		cstring_toCharsSafe (stateValue_unparse (sv)),
4063 		cstring_toCharsSafe (stateValue_unparse (os))));
4064       /*
4065 	val = valueMatix_lookup (key,
4066 	stateValue_getValue (os),
4067 	stateValue_getValue (sv),
4068 	&msg);
4069 	DPRINTF (("Val: %d / %s", val, msg));
4070       */
4071   } end_valueTable_elements ;
4072 # endif
4073 
4074   DPRINTF (("Merge aux: %s / %s",
4075 	    sRef_unparseFull (res),
4076 	    sRef_unparseFull (other)));
4077 }
4078 
4079 static sRefSet
sRef_mergeUnionDerivs(sRefSet res,sRefSet other,bool opt,clause cl,fileloc loc)4080 sRef_mergeUnionDerivs (/*@only@*/ sRefSet res,
4081 		       /*@exposed@*/ sRefSet other, bool opt,
4082 		       clause cl, fileloc loc)
4083 {
4084   if (sRefSet_isEmpty (res))
4085     {
4086       return sRefSet_copyInto (res, other);
4087     }
4088   else
4089     {
4090       sRefSet_allElements (other, el)
4091 	{
4092 	  if (sRef_isReasonable (el))
4093 	    {
4094 	      sRef e2 = sRefSet_lookupMember (other, el);
4095 
4096 	      if (sRef_isReasonable (e2))
4097 		{
4098 		  sRef_mergeStateAux (el, e2, cl, opt, loc, FALSE);
4099 		}
4100 	      else
4101 		{
4102 		  res = sRefSet_insert (res, el);
4103 		}
4104 	    }
4105 	} end_sRefSet_allElements ;
4106 
4107       return res;
4108     }
4109 }
4110 
4111 static /*@only@*/ sRefSet
sRef_mergeDerivs(sRefSet res,sRefSet other,bool opt,clause cl,fileloc loc)4112 sRef_mergeDerivs (/*@only@*/ sRefSet res, sRefSet other,
4113 		  bool opt, clause cl, fileloc loc)
4114 {
4115   sRefSet ret = sRefSet_new ();
4116 
4117   sRefSet_allElements (res, el)
4118     {
4119       if (sRef_isReasonable (el))
4120 	{
4121 	  sRef e2 = sRefSet_lookupMember (other, el);
4122 
4123 	  if (sRef_isReasonable (e2))
4124 	    {
4125 	      if (el->defstate == SS_ALLOCATED &&
4126 		  e2->defstate == SS_PDEFINED)
4127 		{
4128 		  e2->defstate = SS_ALLOCATED;
4129 		}
4130 	      else if (e2->defstate == SS_ALLOCATED &&
4131 		       el->defstate == SS_PDEFINED)
4132 		{
4133 		  el->defstate = SS_ALLOCATED;
4134 		  el->definfo = stateInfo_update (el->definfo, e2->definfo);
4135 		  sRef_clearDerived (el);
4136 		}
4137 	      else if ((el->defstate == SS_DEAD || sRef_isKept (el)) &&
4138 		       (e2->defstate == SS_DEFINED && !sRef_isKept (e2)))
4139 		{
4140 		  DPRINTF (("Checking dead: %s / %s", sRef_unparseFull (el),
4141 			    sRef_unparseFull (e2)));
4142 
4143 		  if (checkDeadState (el, e2, TRUE, loc))
4144 		    {
4145 		      if (sRef_isThroughArrayFetch (el))
4146 			{
4147 			  sRef_maybeKill (el, loc);
4148 			  sRef_maybeKill (e2, loc);
4149 			}
4150 		    }
4151 		}
4152 	      else if ((e2->defstate == SS_DEAD || sRef_isKept (e2)) &&
4153 		       (el->defstate == SS_DEFINED && !sRef_isKept (el)))
4154 		{
4155 		  DPRINTF (("Checking dead: %s / %s", sRef_unparseFull (el),
4156 			    sRef_unparseFull (e2)));
4157 
4158 		  if (checkDeadState (e2, el, FALSE, loc))
4159 		    {
4160 		      if (sRef_isThroughArrayFetch (el))
4161 			{
4162 			  sRef_maybeKill (el, loc);
4163 			  sRef_maybeKill (e2, loc);
4164 			}
4165 		    }
4166 		}
4167 	      else if (el->defstate == SS_DEFINED &&
4168 		       e2->defstate == SS_PDEFINED)
4169 		{
4170 		  DPRINTF (("set pdefined: %s", sRef_unparseFull (el)));
4171 		  el->defstate = SS_PDEFINED;
4172 		  el->definfo = stateInfo_update (el->definfo, e2->definfo);
4173 		}
4174 	      else if (e2->defstate == SS_DEFINED &&
4175 		       el->defstate == SS_PDEFINED)
4176 		{
4177 		  DPRINTF (("set pdefined: %s", sRef_unparseFull (e2)));
4178 		  e2->defstate = SS_PDEFINED;
4179 		  e2->definfo = stateInfo_update (e2->definfo, el->definfo);
4180 		}
4181 	      else
4182 		{
4183 		  ; /* okay */
4184 		}
4185 
4186 	      if (ctype_isUnion (ctype_realType (sRef_getType (el))))
4187 		{
4188 		  el->deriv = sRef_mergeUnionDerivs (el->deriv, e2->deriv,
4189 						     opt, cl, loc);
4190 		}
4191 	      else
4192 		{
4193 		  el->deriv = sRef_mergeDerivs (el->deriv, e2->deriv, opt, cl, loc);
4194 		}
4195 
4196 	      if (sRef_equivalent (el, e2))
4197 		{
4198 		  ret = sRefSet_insert (ret, el);
4199 		}
4200 	      else
4201 		{
4202 		  sRef sr = sRef_leastCommon (el, e2);
4203 
4204 		  if (sRef_isReasonable (sr))
4205 		    {
4206 		      ret = sRefSet_insert (ret, sr);
4207 		    }
4208 		  else
4209 		    {
4210 		      ;
4211 		    }
4212 		}
4213 
4214 	      (void) sRefSet_delete (other, e2);
4215 	    }
4216 	  else /* not defined */
4217 	    {
4218 	      DPRINTF (("Checking dead: %s", sRef_unparseFull (el)));
4219 	      (void) checkDeadState (el, e2, TRUE, loc);
4220 	    }
4221 	}
4222     } end_sRefSet_allElements;
4223 
4224   sRefSet_allElements (other, el)
4225     {
4226       if (sRef_isReasonable (el))
4227 	{
4228 	  DPRINTF (("Checking dead: %s", sRef_unparseFull (el)));
4229 	  (void) checkDeadState (el, sRef_undefined, FALSE, loc);
4230 	}
4231     } end_sRefSet_allElements;
4232 
4233   sRefSet_free (res);
4234   return (ret);
4235 }
4236 
4237 /*
4238 ** Returns TRUE is there is an error.
4239 */
4240 
checkDeadState(sRef el,sRef e2,bool tbranch,fileloc loc)4241 static bool checkDeadState (/*@notnull@*/ sRef el, sRef e2, bool tbranch, fileloc loc)
4242 {
4243   /*
4244   ** usymtab_isGuarded --- the utab should still be in the
4245   ** state of the alternate branch.
4246   **
4247   ** tbranch TRUE means el is released in the last branch, e.g.
4248   **     if (x != NULL) { ; } else { sfree (x); }
4249   ** so, if x is null in the other branch no error is reported.
4250   **
4251   ** tbranch FALSE means this is the other branch:
4252   **     if (x != NULL) { sfree (x); } else { ; }
4253   ** so, if x is null in this branch there is no error.
4254   */
4255 
4256 
4257   if ((sRef_isDead (el) || sRef_isKept (el))
4258       && !sRef_isDeepUnionField (el)
4259       && !sRef_isThroughArrayFetch (el))
4260     {
4261 
4262       if (!tbranch)
4263 	{
4264 	  if (usymtab_isDefinitelyNullDeep (el))
4265 	    {
4266 	      return TRUE;
4267 	    }
4268 	}
4269       else
4270 	{
4271 	  if (usymtab_isAltDefinitelyNullDeep (el))
4272 	    {
4273 	      return TRUE;
4274 	    }
4275 	}
4276 
4277       if (optgenerror
4278 	  (FLG_BRANCHSTATE,
4279 	   message ("Storage %q is %q in one path, but live in another.",
4280 		    sRef_unparse (el),
4281 		    cstring_makeLiteral (sRef_isKept (el)
4282 					 ? "kept" : "released")),
4283 	   loc))
4284 	{
4285 	  if (sRef_isKept (el))
4286 	    {
4287 	      sRef_showAliasInfo (el);
4288 	    }
4289 	  else
4290 	    {
4291 	      sRef_showStateInfo (el);
4292 	    }
4293 
4294 	  if (sRef_isValid (e2))
4295 	    {
4296 	      if (sRef_isKept (e2))
4297 		{
4298 		  sRef_showAliasInfo (e2);
4299 		}
4300 	      else
4301 		{
4302 		  sRef_showStateInfo (e2);
4303 		}
4304 	    }
4305 
4306 	  /* prevent further errors */
4307 	  el->defstate = SS_UNKNOWN;
4308 	  sRef_setAliasKind (el, AK_ERROR, fileloc_undefined);
4309 	  return FALSE;
4310 	}
4311     }
4312 
4313   return TRUE;
4314 }
4315 
4316 static void
checkDerivDeadState(sRef el,bool tbranch,fileloc loc)4317 checkDerivDeadState (/*@notnull@*/ sRef el, bool tbranch, fileloc loc)
4318 {
4319   if (checkDeadState (el, sRef_undefined, tbranch, loc))
4320     {
4321       sRefSet_allElements (el->deriv, t)
4322 	{
4323 	  if (sRef_isReasonable (t))
4324 	    {
4325 	      checkDerivDeadState (t, tbranch, loc);
4326 	    }
4327 	} end_sRefSet_allElements;
4328     }
4329 }
4330 
4331 static sRefSet
sRef_mergePdefinedDerivs(sRefSet res,sRefSet other,bool opt,clause cl,fileloc loc)4332   sRef_mergePdefinedDerivs (sRefSet res, sRefSet other, bool opt,
4333 			    clause cl, fileloc loc)
4334 {
4335   sRefSet ret = sRefSet_new ();
4336 
4337   sRefSet_allElements (res, el)
4338     {
4339       if (sRef_isReasonable (el))
4340 	{
4341 	  sRef e2 = sRefSet_lookupMember (other, el);
4342 
4343 	  if (sRef_isReasonable (e2))
4344 	    {
4345 	      if (sRef_isAllocated (el) && !sRef_isAllocated (e2))
4346 		{
4347 		  ;
4348 		}
4349 	      else if (sRef_isAllocated (e2) && !sRef_isAllocated (el))
4350 		{
4351 		  el->deriv = sRefSet_copyInto (el->deriv, e2->deriv);
4352 		}
4353 	      else
4354 		{
4355 		  el->deriv = sRef_mergePdefinedDerivs (el->deriv, e2->deriv,
4356 							opt, cl, loc);
4357 		}
4358 
4359 	      sRef_mergeStateAux (el, e2, cl, opt, loc, FALSE);
4360 
4361 	      ret = sRefSet_insert (ret, el);
4362 	      (void) sRefSet_delete (other, e2);
4363 	    }
4364 	  else
4365 	    {
4366 	      if (!opt)
4367 		{
4368 		  checkDerivDeadState (el, (cl == FALSECLAUSE), loc);
4369 		}
4370 
4371 	      ret = sRefSet_insert (ret, el);
4372 	    }
4373 	}
4374     } end_sRefSet_allElements;
4375 
4376   sRefSet_allElements (other, el)
4377     {
4378       if (sRef_isReasonable (el))
4379 	{
4380 	  if (!sRefSet_member (ret, el))
4381 	    {
4382 	      	      	      /* was cl == FALSECLAUSE */
4383 	      checkDerivDeadState (el, FALSE, loc);
4384 	      ret = sRefSet_insert (ret, el);
4385 	    }
4386 	  else
4387 	    {
4388 	      /*
4389 	      ** it's okay --- member is a different equality test
4390 	      */
4391 	    }
4392 	}
4393     } end_sRefSet_allElements;
4394 
4395   sRefSet_free (res);
4396   return (ret);
4397 }
4398 
sRef_makeConj(sRef a,sRef b)4399 sRef sRef_makeConj (/*@exposed@*/ /*@returned@*/ sRef a, /*@exposed@*/ sRef b)
4400 {
4401   llassert (sRef_isReasonable (a));
4402   llassert (sRef_isReasonable (b));
4403 
4404   if (!sRef_equivalent (a, b))
4405     {
4406       sRef s = sRef_newRef ();
4407 
4408       s->kind = SK_CONJ;
4409       s->info = (sinfo) dmalloc (sizeof (*s->info));
4410       s->info->conj = (cjinfo) dmalloc (sizeof (*s->info->conj));
4411       s->info->conj->a = a;
4412       s->info->conj->b = b;
4413 
4414       if (ctype_equal (a->type, b->type)) s->type = a->type;
4415       else s->type = ctype_makeConj (a->type, b->type);
4416 
4417       if (a->defstate == b->defstate)
4418 	{
4419 	  s->defstate = a->defstate;
4420 	  s->definfo = stateInfo_update (s->definfo, a->definfo);
4421 	  s->definfo = stateInfo_update (s->definfo, b->definfo);
4422 	}
4423       else
4424 	{
4425 	  s->defstate = SS_UNKNOWN;
4426 	}
4427 
4428       sRef_setNullStateN (s, NS_UNKNOWN);
4429 
4430       s->safe = a->safe && b->safe;
4431       s->aliaskind = alkind_resolve (a->aliaskind, b->aliaskind);
4432 
4433       llassert (valueTable_isUndefined (s->state));
4434       s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_MERGED));
4435       return s;
4436     }
4437   else
4438     {
4439       /*@-exposetrans@*/ return a; /*@=exposetrans@*/
4440     }
4441 }
4442 
4443 /*@dependent@*/ sRef
sRef_makeUnknown()4444 sRef_makeUnknown ()
4445 {
4446   sRef s = sRef_new ();
4447 
4448   s->kind = SK_UNKNOWN;
4449   return s;
4450 }
4451 
4452 static /*@owned@*/ /*@notnull@*/ sRef
sRef_makeSpecial(speckind sk)4453 sRef_makeSpecial (speckind sk) /*@*/
4454 {
4455   sRef s = sRef_new ();
4456 
4457   s->kind = SK_SPECIAL;
4458   s->info = (sinfo) dmalloc (sizeof (*s->info));
4459   s->info->spec = sk;
4460   /*@-dependenttrans@*/
4461   return s;
4462   /*@=dependenttrans@*/
4463 }
4464 
4465 static /*@owned@*/ sRef srnothing = sRef_undefined;
4466 static /*@owned@*/ sRef srinternal = sRef_undefined;
4467 static /*@owned@*/ sRef srsystem = sRef_undefined;
4468 static /*@owned@*/ sRef srspec = sRef_undefined;
4469 
4470 /*@dependent@*/ sRef
sRef_makeNothing(void)4471 sRef_makeNothing (void)
4472 {
4473   if (sRef_isInvalid (srnothing))
4474     {
4475       srnothing = sRef_makeSpecial (SR_NOTHING);
4476     }
4477 
4478   return srnothing;
4479 }
4480 
4481 sRef
sRef_makeInternalState(void)4482 sRef_makeInternalState (void)
4483 {
4484   if (sRef_isInvalid (srinternal))
4485     {
4486       srinternal = sRef_makeSpecial (SR_INTERNAL);
4487     }
4488 
4489   return srinternal;
4490 }
4491 
4492 sRef
sRef_makeSpecState(void)4493 sRef_makeSpecState (void)
4494 {
4495   if (sRef_isInvalid (srspec))
4496     {
4497       srspec = sRef_makeSpecial (SR_SPECSTATE);
4498     }
4499 
4500   return srspec;
4501 }
4502 
4503 sRef
sRef_makeSystemState(void)4504 sRef_makeSystemState (void)
4505 {
4506   if (sRef_isInvalid (srsystem))
4507     {
4508       srsystem = sRef_makeSpecial (SR_SYSTEM);
4509     }
4510 
4511   return srsystem;
4512 }
4513 
4514 sRef
sRef_makeGlobalMarker(void)4515 sRef_makeGlobalMarker (void)
4516 {
4517   sRef s = sRef_makeSpecial (SR_GLOBALMARKER);
4518   llassert (valueTable_isUndefined (s->state));
4519   s->state = context_createGlobalMarkerValueTable (stateInfo_undefined);
4520   return s;
4521 }
4522 
4523 sRef
sRef_makeResult(ctype c)4524 sRef_makeResult (ctype c)
4525 {
4526   sRef s = sRef_newRef ();
4527 
4528   s->kind = SK_RESULT;
4529   s->type = c;
4530   s->defstate = SS_UNKNOWN;
4531   s->aliaskind = AK_UNKNOWN;
4532   sRef_setNullStateN (s, NS_UNKNOWN);
4533   llassert (valueTable_isUndefined (s->state));
4534   s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_DECLARED));
4535 
4536   DPRINTF (("Result: [%p] %s", s, sRef_unparseFull (s)));
4537   return s;
4538 }
4539 
4540 
4541 bool
sRef_isNothing(sRef s)4542 sRef_isNothing (sRef s)
4543 {
4544   return (sRef_isKindSpecial (s) && s->info->spec == SR_NOTHING);
4545 }
4546 
4547 bool
sRef_isInternalState(sRef s)4548 sRef_isInternalState (sRef s)
4549 {
4550   return (sRef_isKindSpecial (s) && s->info->spec == SR_INTERNAL);
4551 }
4552 
4553 bool
sRef_isSpecInternalState(sRef s)4554 sRef_isSpecInternalState (sRef s)
4555 {
4556   return (sRef_isKindSpecial (s)
4557 	  && (s->info->spec == SR_INTERNAL || s->info->spec == SR_SPECSTATE));
4558 }
4559 
4560 bool
sRef_isSpecState(sRef s)4561 sRef_isSpecState (sRef s)
4562 {
4563   return (sRef_isKindSpecial (s) && s->info->spec == SR_SPECSTATE);
4564 }
4565 
4566 bool
sRef_isResult(sRef s)4567 sRef_isResult (sRef s)
4568 {
4569   return (sRef_isReasonable (s) && s->kind == SK_RESULT);
4570 }
4571 
4572 bool
sRef_isSystemState(sRef s)4573 sRef_isSystemState (sRef s)
4574 {
4575   return (sRef_isKindSpecial (s) && s->info->spec == SR_SYSTEM);
4576 }
4577 
4578 bool
sRef_isGlobalMarker(sRef s)4579 sRef_isGlobalMarker (sRef s)
4580 {
4581   return (sRef_isKindSpecial (s) && s->info->spec == SR_GLOBALMARKER);
4582 }
4583 
4584 usymId
sRef_getScopeIndex(sRef s)4585 sRef_getScopeIndex (sRef s)
4586 {
4587   llassert (sRef_isReasonable (s));
4588   llassert (sRef_isCvar (s));
4589 
4590   return (s->info->cvar->index);
4591 }
4592 
4593 void
sRef_makeSafe(sRef s)4594 sRef_makeSafe (sRef s)
4595 {
4596   if (sRef_isReasonable (s))
4597     {
4598       s->safe = TRUE;
4599     }
4600 }
4601 
4602 void
sRef_makeUnsafe(sRef s)4603 sRef_makeUnsafe (sRef s)
4604 {
4605   if (sRef_isReasonable (s))
4606     {
4607       s->safe = FALSE;
4608     }
4609 }
4610 
4611 /*
4612 ** memory state operations
4613 */
4614 
sRef_unparseFull(sRef s)4615 /*@only@*/ cstring sRef_unparseFull (sRef s)
4616 {
4617   if (sRef_isInvalid (s)) return (cstring_undefined);
4618 
4619   return (message ("[%p] %q - %q { %q } [%s] { %q } < %q >",
4620 		   s,
4621 		   sRef_unparseDebug (s),
4622 		   sRef_unparseState (s),
4623 		   stateInfo_unparse (s->definfo),
4624 		   exkind_unparse (s->oexpkind),
4625 		   sRefSet_unparseDebug (s->deriv),
4626 		   valueTable_unparse (s->state)));
4627 }
4628 
sRef_unparseDeep(sRef s)4629 /*@unused@*/ cstring sRef_unparseDeep (sRef s)
4630 {
4631   cstring st = cstring_undefined;
4632 
4633   st = message ("%q:", sRef_unparseFull (s));
4634 
4635   if (sRef_isReasonable (s))
4636     {
4637       sRefSet_allElements (s->deriv, el)
4638 	{
4639 	  st = message("%q\n%q", st, sRef_unparseDeep (el));
4640 	} end_sRefSet_allElements ;
4641     }
4642 
4643   return st;
4644 }
4645 
sRef_unparseState(sRef s)4646 /*@only@*/ cstring sRef_unparseState (sRef s)
4647 {
4648   if (sRef_isConj (s))
4649     {
4650       return (message ("%q | %q",
4651 		       sRef_unparseState (s->info->conj->a),
4652 		       sRef_unparseState (s->info->conj->b)));
4653     }
4654 
4655   if (sRef_isInvalid (s))
4656     {
4657       return (cstring_makeLiteral ("<invalid>"));
4658     }
4659 
4660   return (message ("%s.%s.%s.%s",
4661 		   alkind_unparse (s->aliaskind),
4662 		   nstate_unparse (sRef_getNullState (s)),
4663 		   exkind_unparse (s->expkind),
4664 		   sstate_unparse (s->defstate)));
4665 }
4666 
sRef_isNotUndefined(sRef s)4667 bool sRef_isNotUndefined (sRef s)
4668 {
4669   return (sRef_isInvalid (s)
4670 	  || (s->defstate != SS_UNDEFINED
4671 	      && s->defstate != SS_UNUSEABLE
4672 	      && s->defstate != SS_DEAD));
4673 }
4674 
sRef_isWriteable(sRef s)4675 ynm sRef_isWriteable (sRef s)
4676 {
4677   if (sRef_isInvalid (s)) return MAYBE;
4678 
4679   if (sRef_isConj (s) && s->defstate == SS_UNKNOWN)
4680     {
4681       if (ynm_toBoolStrict (sRef_isWriteable (sRef_getConjA (s))))
4682 	{
4683 	  if (ynm_toBoolStrict (sRef_isWriteable (sRef_getConjB (s))))
4684 	    {
4685 	      return YES;
4686 	    }
4687 	  return MAYBE;
4688 	}
4689       else
4690 	{
4691 	  if (ynm_toBoolStrict (sRef_isWriteable (sRef_getConjB (s))))
4692 	    {
4693 	      return MAYBE;
4694 	    }
4695 	  return NO;
4696 	}
4697     }
4698 
4699   return (ynm_fromBool (s->defstate != SS_UNUSEABLE));
4700 }
4701 
sRef_hasNoStorage(sRef s)4702 bool sRef_hasNoStorage (sRef s)
4703 {
4704   return (!sRef_isAllocatedStorage (s) || sRef_isDefinitelyNull (s));
4705 }
4706 
sRef_isStrictReadable(sRef s)4707 bool sRef_isStrictReadable (sRef s)
4708 {
4709   return (ynm_toBoolStrict (sRef_isValidLvalue (s)));
4710 }
4711 
4712 /*
4713 ** Is this what is does?
4714 ** Returns YES if s can be used as an rvalue,
4715 **         MAYBE if its not clear
4716 **         NO if s cannot be safely used as an rvalue.
4717 */
4718 
sRef_isValidLvalue(sRef s)4719 ynm sRef_isValidLvalue (sRef s)
4720 {
4721   sstate ss;
4722 
4723   if (sRef_isInvalid (s)) return YES;
4724 
4725   ss = s->defstate;
4726 
4727   if (sRef_isConj (s) && s->defstate == SS_UNKNOWN)
4728     {
4729       if (ynm_toBoolStrict (sRef_isValidLvalue (sRef_getConjA (s))))
4730 	{
4731 	  if (ynm_toBoolStrict (sRef_isValidLvalue (sRef_getConjB (s))))
4732 	    {
4733 	      return YES;
4734 	    }
4735 	  return MAYBE;
4736 	}
4737       else
4738 	{
4739 	  if (ynm_toBoolStrict (sRef_isValidLvalue (sRef_getConjB (s))))
4740 	    {
4741 	      return MAYBE;
4742 	    }
4743 	  return NO;
4744 	}
4745     }
4746   else if (ss == SS_HOFFA)
4747     {
4748       if (context_getFlag (FLG_STRICTUSERELEASED))
4749 	{
4750 	  return MAYBE;
4751 	}
4752       else
4753 	{
4754 	  return YES;
4755 	}
4756     }
4757   else
4758     {
4759       return (ynm_fromBool (ss == SS_DEFINED
4760 			    || ss == SS_FIXED
4761 			    || ss == SS_RELDEF
4762 			    || ss == SS_PDEFINED
4763 			    || ss == SS_PARTIAL
4764 			    || ss == SS_SPECIAL
4765 			    || ss == SS_ALLOCATED
4766 			    || ss == SS_KILLED /* evans 2001-05-26: added this for killed globals */
4767 			    || ss == SS_UNKNOWN));
4768     }
4769 }
4770 
whatUndefined(sRef fref,int depth)4771 static /*@exposed@*/ sRef whatUndefined (/*@exposed@*/ sRef fref, int depth)
4772 {
4773   ctype ct;
4774 
4775 
4776   if (depth > MAXDEPTH)
4777     {
4778       llgenmsg (message
4779 		("Warning: check definition limit exceeded, checking %q. "
4780 		 "This either means there is a variable with at least "
4781 		 "%d indirections apparent in the program text, or "
4782 		 "there is a bug in Splint.",
4783 		 sRef_unparse (fref),
4784 		 MAXDEPTH),
4785 		g_currentloc);
4786 
4787       return sRef_undefined;
4788     }
4789 
4790   if (!sRef_isKnown (fref) || sRef_isAnyDefined (fref))
4791     {
4792       return sRef_undefined;
4793     }
4794 
4795   if (sRef_isUnuseable (fref) || sRef_isStateUndefined (fref))
4796     {
4797       return fref;
4798     }
4799 
4800   ct = ctype_realType (sRef_getType (fref));
4801 
4802   if (ctype_isUnknown (ct))
4803     {
4804       return sRef_undefined;
4805     }
4806   else if (ctype_isPointer (ct) || ctype_isArray (ct))
4807     {
4808       if (sRef_isStateUnknown (fref))
4809 	{
4810 	  return sRef_undefined;
4811 	}
4812       else
4813 	{
4814 	  sRef fptr = sRef_constructDeref (fref);
4815 
4816 	  return (whatUndefined (fptr, depth + 1));
4817 	}
4818     }
4819   else if (ctype_isStruct (ct))
4820     {
4821       bool hasOneDefined = FALSE;
4822 
4823       if (sRef_isStateUnknown (fref))
4824 	{
4825 	  return fref;
4826 	}
4827 
4828       if (sRef_isPdefined (fref) || sRef_isAnyDefined (fref))
4829 	{
4830 	  sRefSet_realElements (sRef_derivedFields (fref), sr)
4831 	    {
4832 	      hasOneDefined = TRUE;
4833 
4834 	      if (sRef_isField (sr))
4835 		{
4836 		  cstring fieldname = sRef_getField (sr);
4837 		  sRef fldref = sRef_makeField (fref, fieldname);
4838 		  bool shouldCheck = !sRef_isRecursiveField (fldref);
4839 
4840 		  if (shouldCheck)
4841 		    {
4842 		      sRef wdef = whatUndefined (fldref, depth + 1);
4843 
4844 		      if (sRef_isReasonable (wdef))
4845 			{
4846 			  return wdef;
4847 			}
4848 		    }
4849 		}
4850 	    } end_sRefSet_realElements;
4851 	}
4852       else if (sRef_isAllocated (fref))
4853 	{
4854 	  /*
4855 	  ** for structures, each field must be completely defined
4856 	  */
4857 
4858 	  uentryList fields = ctype_getFields (ct);
4859 
4860 	  uentryList_elements (fields, ue)
4861 	    {
4862 	      cstring name = uentry_getRealName (ue);
4863 	      sRef ffield = sRef_makeField (fref, name);
4864 	      bool shouldCheck = !sRef_isRecursiveField (ffield);
4865 
4866 	      if (sRef_isRelDef (uentry_getSref (ue)))
4867 		{
4868 		  ; /* no error */
4869 		}
4870 	      else
4871 		{
4872 		  if (shouldCheck)
4873 		    {
4874 		      sRef wdef = whatUndefined (ffield, depth + 1);
4875 
4876 		      if (sRef_isInvalid (wdef))
4877 			{
4878 			  return wdef;
4879 			}
4880 		    }
4881 		}
4882 	    } end_uentryList_elements;
4883 	}
4884       else
4885 	{
4886 	  ;
4887 	}
4888     }
4889   else if (ctype_isUnion (ct))
4890     {
4891       ;
4892     }
4893   else
4894     {
4895       ;
4896     }
4897 
4898   return sRef_undefined;
4899 }
4900 
checkDefined(sRef sr)4901 static bool checkDefined (/*@temp@*/ sRef sr)
4902 {
4903   /*@-temptrans@*/ /* the result from whatUndefined is lost */
4904   return (sRef_isInvalid (whatUndefined (sr, 0)));
4905   /*@=temptrans@*/
4906 }
4907 
sRef_isReallyDefined(sRef s)4908 bool sRef_isReallyDefined (sRef s)
4909 {
4910   if (sRef_isReasonable (s))
4911     {
4912       if (sRef_isAnyDefined (s))
4913 	{
4914 	  return TRUE;
4915 	}
4916       else
4917 	{
4918 	  if (sRef_isAllocated (s) || sRef_isPdefined (s))
4919 	    {
4920 	      return checkDefined (s);
4921 	    }
4922 	  else
4923 	    {
4924 	      return FALSE;
4925 	    }
4926 	}
4927     }
4928   else
4929     {
4930       return TRUE;
4931     }
4932 }
4933 
sRef_showNotReallyDefined(sRef s)4934 void sRef_showNotReallyDefined (sRef s)
4935 {
4936   if (sRef_isReasonable (s))
4937     {
4938       if (sRef_isAnyDefined (s))
4939 	{
4940 	  BADBRANCH;
4941 	}
4942       else
4943 	{
4944 	  if (sRef_isAllocated (s) || sRef_isPdefined (s))
4945 	    {
4946 	      /*@-temptrans@*/ /* the result of whatUndefined is lost */
4947 	      sRef ref = whatUndefined (s, 0);
4948 
4949 	      llassert (sRef_isReasonable (ref));
4950 
4951 	      if (ref != s)
4952 		{
4953 		  llgenindentmsgnoloc
4954 		    (message ("This sub-reference is %s: %q",
4955 			      sstate_unparse (sRef_getDefState (ref)),
4956 			      sRef_unparse (ref)));
4957 		}
4958 	    }
4959 	  else
4960 	    {
4961 	      ;
4962 	    }
4963 	}
4964     }
4965   else
4966     {
4967       BADBRANCH;
4968     }
4969 }
4970 
sRef_getDefState(sRef s)4971 sstate sRef_getDefState (sRef s)
4972 {
4973   if (sRef_isInvalid (s)) return (SS_UNKNOWN);
4974   return (s->defstate);
4975 }
4976 
sRef_setDefState(sRef s,sstate defstate,fileloc loc)4977 void sRef_setDefState (sRef s, sstate defstate, fileloc loc)
4978 {
4979   sRef_checkMutable (s);
4980   sRef_setStateAux (s, defstate, loc);
4981 }
4982 
sRef_clearAliasStateAux(sRef s,fileloc loc)4983 static void sRef_clearAliasStateAux (sRef s, fileloc loc)
4984 {
4985   sRef_checkMutable (s);
4986   sRef_setAliasKind (s, AK_ERROR, loc);
4987 }
4988 
sRef_clearAliasState(sRef s,fileloc loc)4989 void sRef_clearAliasState (sRef s, fileloc loc)
4990 {
4991   sRef_checkMutable (s);
4992   sRef_aliasSetComplete (sRef_clearAliasStateAux, s, loc);
4993 }
4994 
sRef_setAliasKindComplete(sRef s,alkind kind,fileloc loc)4995 void sRef_setAliasKindComplete (sRef s, alkind kind, fileloc loc)
4996 {
4997   sRef_checkMutable (s);
4998   sRef_aliasSetCompleteAlkParam (sRef_setAliasKind, s, kind, loc);
4999 }
5000 
sRef_setAliasKind(sRef s,alkind kind,fileloc loc)5001 void sRef_setAliasKind (sRef s, alkind kind, fileloc loc)
5002 {
5003   sRef_checkMutable (s);
5004 
5005   if (sRef_isReasonable (s))
5006     {
5007       sRef_clearDerived (s);
5008 
5009       if ((kind != s->aliaskind && kind != s->oaliaskind)
5010 	  && fileloc_isDefined (loc))
5011 	{
5012 	  s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, stateAction_fromAlkind (kind), loc);
5013 	}
5014 
5015       s->aliaskind = kind;
5016     }
5017 }
5018 
sRef_setOrigAliasKind(sRef s,alkind kind)5019 void sRef_setOrigAliasKind (sRef s, alkind kind)
5020 {
5021   sRef_checkMutable (s);
5022 
5023   if (sRef_isReasonable (s))
5024     {
5025       s->oaliaskind = kind;
5026     }
5027 }
5028 
sRef_getExKind(sRef s)5029 exkind sRef_getExKind (sRef s)
5030 {
5031   if (sRef_isReasonable (s))
5032     {
5033       return (s->expkind);
5034     }
5035   else
5036     {
5037       return XO_UNKNOWN;
5038     }
5039 }
5040 
sRef_getOrigExKind(sRef s)5041 exkind sRef_getOrigExKind (sRef s)
5042 {
5043   if (sRef_isReasonable (s))
5044     {
5045       return (s->oexpkind);
5046     }
5047   else
5048     {
5049       return XO_UNKNOWN;
5050     }
5051 }
5052 
sRef_clearExKindAux(sRef s,fileloc loc)5053 static void sRef_clearExKindAux (sRef s, fileloc loc)
5054 {
5055   sRef_checkMutable (s);
5056   sRef_setExKind (s, XO_UNKNOWN, loc);
5057 }
5058 
sRef_setObserver(sRef s,fileloc loc)5059 void sRef_setObserver (sRef s, fileloc loc)
5060 {
5061   sRef_checkMutable (s);
5062   sRef_setExKind (s, XO_OBSERVER, loc);
5063 }
5064 
sRef_setExposed(sRef s,fileloc loc)5065 void sRef_setExposed (sRef s, fileloc loc)
5066 {
5067   sRef_checkMutable (s);
5068   sRef_setExKind (s, XO_EXPOSED, loc);
5069 }
5070 
sRef_clearExKindComplete(sRef s,fileloc loc)5071 void sRef_clearExKindComplete (sRef s, fileloc loc)
5072 {
5073   (void) sRef_aliasSetComplete (sRef_clearExKindAux, s, loc);
5074 }
5075 
sRef_setExKind(sRef s,exkind exp,fileloc loc)5076 void sRef_setExKind (sRef s, exkind exp, fileloc loc)
5077 {
5078   sRef_checkMutable (s);
5079 
5080   if (sRef_isReasonable (s))
5081     {
5082       if (s->expkind != exp)
5083 	{
5084 	  s->expinfo = stateInfo_updateLoc (s->expinfo, stateAction_fromExkind (exp), loc);
5085 	}
5086 
5087       s->expkind = exp;
5088     }
5089 }
5090 
5091 /*
5092 ** s1->derived = s2->derived
5093 */
5094 
sRef_copyRealDerived(sRef s1,sRef s2)5095 static void sRef_copyRealDerived (sRef s1, sRef s2)
5096 {
5097   DPRINTF (("Copy real: %s / %s", sRef_unparse (s1), sRef_unparse (s2)));
5098   sRef_checkMutable (s1);
5099 
5100   if (sRef_isReasonable (s1) && sRef_isReasonable (s2))
5101     {
5102       sRef sb = sRef_getRootBase (s1);
5103 
5104       sRefSet_clear (s1->deriv);
5105 
5106       sRefSet_allElements (s2->deriv, el)
5107 	{
5108 	  if (sRef_isReasonable (el))
5109 	    {
5110 	      sRef rb = sRef_getRootBase (el);
5111 
5112 	      if (!sRef_same (rb, sb))
5113 		{
5114 		  sRef fb = sRef_fixDirectBase (el, s1);
5115 
5116 		  if (sRef_isReasonable (fb))
5117 		    {
5118 		      sRef_copyRealDerived (fb, el);
5119 		      sRef_addDeriv (s1, fb);
5120 		    }
5121 		}
5122 	      else
5123 		{
5124 		  sRef_addDeriv (s1, el);
5125 		}
5126 	    }
5127 	} end_sRefSet_allElements ;
5128     }
5129 
5130   }
5131 
sRef_copyRealDerivedComplete(sRef s1,sRef s2)5132 void sRef_copyRealDerivedComplete (sRef s1, sRef s2)
5133 {
5134   sRef_innerAliasSetCompleteParam (sRef_copyRealDerived, s1, s2);
5135 }
5136 
sRef_setUndefined(sRef s,fileloc loc)5137 void sRef_setUndefined (sRef s, fileloc loc)
5138 {
5139   sRef_checkMutable (s);
5140 
5141   if (sRef_isReasonable (s))
5142     {
5143       s->defstate = SS_UNDEFINED;
5144       s->definfo = stateInfo_updateLoc (s->definfo, SA_UNDEFINED, loc);
5145 
5146       sRef_clearDerived (s);
5147     }
5148 }
5149 
sRef_setDefinedAux(sRef s,fileloc loc,bool clear)5150 static void sRef_setDefinedAux (sRef s, fileloc loc, bool clear)
5151 {
5152   sRef_checkMutable (s);
5153   if (sRef_isInvalid (s)) return;
5154 
5155   DPRINTF (("Set defined: %s", sRef_unparseFull (s)));
5156 
5157   s->definfo = stateInfo_updateLoc (s->definfo, SA_DEFINED, loc);
5158   s->defstate = SS_DEFINED;
5159 
5160   DPRINTF (("Set defined: %s", sRef_unparseFull (s)));
5161 
5162   /* e.g., if x is allocated, *x = 3 defines x */
5163 
5164   if (s->kind == SK_PTR)
5165     {
5166       sRef p = s->info->ref;
5167       sRef arr;
5168 
5169       if (p->defstate == SS_ALLOCATED
5170 	  || p->defstate == SS_SPECIAL) /* evans 2001-07-12: shouldn't need this */
5171 	{
5172 	  sRef_setDefinedAux (p, loc, clear);
5173 	}
5174 
5175       /*
5176       ** Defines a[0] also:
5177       */
5178 
5179       arr = sRef_findDerivedArrayFetch (p, FALSE, 0, FALSE);
5180 
5181       if (sRef_isReasonable (arr))
5182 	{
5183 	  sRef_setDefinedAux (arr, loc, clear);
5184 	}
5185     }
5186   else if (s->kind == SK_ARRAYFETCH)
5187     {
5188       if (!s->info->arrayfetch->indknown
5189 	  || (s->info->arrayfetch->ind == 0))
5190 	{
5191 	  sRef p = s->info->arrayfetch->arr;
5192 	  sRef ptr = sRef_constructPointer (p);
5193 
5194 	  if (sRef_isReasonable (ptr))
5195 	    {
5196 	      if (ptr->defstate == SS_ALLOCATED
5197 		  || ptr->defstate == SS_UNDEFINED
5198 		  || ptr->defstate == SS_SPECIAL) /* evans 2001-07-12: shouldn't need this */
5199 		{
5200 		  sRef_setDefinedAux (ptr, loc, clear);
5201 		}
5202 	    }
5203 
5204 	  if (p->defstate == SS_RELDEF)
5205 	    {
5206 	      ;
5207 	    }
5208 	  else if (p->defstate == SS_ALLOCATED || p->defstate == SS_PDEFINED
5209 		   || p->defstate == SS_SPECIAL) /* evans 2001-07-12: shouldn't need this */
5210 	    {
5211 	      p->defstate = SS_DEFINED;
5212 	    }
5213 	  else
5214 	    {
5215 	    }
5216 	}
5217     }
5218   else if (s->kind == SK_FIELD)
5219     {
5220       sRef parent = s->info->field->rec;
5221 
5222       if (sRef_isReasonable (parent))
5223 	{
5224 	  if (ctype_isUnion (ctype_realType (parent->type)))
5225 	    {
5226 	      /*
5227 	      ** Should not clear derived from here.
5228 	      */
5229 
5230 	      sRef_setDefinedNoClear (parent, loc);
5231 	    }
5232 	  else
5233 	    {
5234 	      ; /* Nothing to do for structures. */
5235 	    }
5236 	}
5237 
5238           }
5239   else
5240     {
5241       ;
5242     }
5243 
5244   if (clear)
5245     {
5246       sRef_clearDerived (s);
5247     }
5248   else
5249     {
5250       /* evans 2001-07-12: need to define the derived references */
5251       sRefSet_elements (s->deriv, el)
5252 	{
5253 	  llassert (sRef_isReasonable (el));
5254 	  el->defstate = SS_DEFINED;
5255 	} end_sRefSet_elements ;
5256     }
5257 
5258   DPRINTF (("Set defined: %s", sRef_unparseFull (s)));
5259 }
5260 
sRef_setPartialDefined(sRef s,fileloc loc)5261 static void sRef_setPartialDefined (sRef s, fileloc loc)
5262 {
5263   sRef_checkMutable (s);
5264 
5265   if (!sRef_isPartial (s))
5266     {
5267       sRef_setDefined (s, loc);
5268     }
5269 }
5270 
sRef_setPartialDefinedComplete(sRef s,fileloc loc)5271 void sRef_setPartialDefinedComplete (sRef s, fileloc loc)
5272 {
5273   sRef_innerAliasSetComplete (sRef_setPartialDefined, s, loc);
5274 }
5275 
sRef_setDefinedComplete(sRef s,fileloc loc)5276 void sRef_setDefinedComplete (sRef s, fileloc loc)
5277 {
5278   sRef_innerAliasSetComplete (sRef_setDefined, s, loc);
5279 }
5280 
sRef_setDefinedCompleteDirect(sRef s,fileloc loc)5281 void sRef_setDefinedCompleteDirect (sRef s, fileloc loc)
5282 {
5283   sRefSet aliases;
5284 
5285   aliases = usymtab_allAliases (s);
5286   DPRINTF (("Set defined complete: %s", sRef_unparseFull (s)));
5287   DPRINTF (("All aliases: %s", sRefSet_unparseFull (aliases)));
5288 
5289   sRef_setDefined (s, loc);
5290 
5291   sRefSet_realElements (aliases, current)
5292     {
5293       if (sRef_isReasonable (current))
5294 	{
5295 	  current = sRef_updateSref (current);
5296 	  sRef_setDefined (current, loc);
5297 	}
5298     } end_sRefSet_realElements;
5299 
5300   sRefSet_free (aliases);
5301   sRef_innerAliasSetComplete (sRef_setDefined, s, loc);
5302 }
5303 
sRef_setDefined(sRef s,fileloc loc)5304 void sRef_setDefined (sRef s, fileloc loc)
5305 {
5306   sRef_checkMutable (s);
5307   sRef_setDefinedAux (s, loc, TRUE);
5308 }
5309 
sRef_setDefinedNoClear(sRef s,fileloc loc)5310 static void sRef_setDefinedNoClear (sRef s, fileloc loc)
5311 {
5312   sRef_checkMutable (s);
5313   DPRINTF (("Defining: %s", sRef_unparseFull (s)));
5314   sRef_setDefinedAux (s, loc, FALSE);
5315   DPRINTF (("==> %s", sRef_unparseFull (s)));
5316 }
5317 
sRef_setDefinedNCComplete(sRef s,fileloc loc)5318 void sRef_setDefinedNCComplete (sRef s, fileloc loc)
5319 {
5320   sRef_checkMutable (s);
5321   DPRINTF (("Set Defined Complete: %s", sRef_unparseFull (s)));
5322   sRef_innerAliasSetComplete (sRef_setDefinedNoClear, s, loc);
5323   DPRINTF (("==> %s", sRef_unparseFull (s)));
5324 }
5325 
sRef_isDeepUnionField(sRef s)5326 static bool sRef_isDeepUnionField (sRef s)
5327 {
5328   return (sRef_deepPred (sRef_isUnionField, s));
5329 }
5330 
sRef_isUnionField(sRef s)5331 bool sRef_isUnionField (sRef s)
5332 {
5333   if (sRef_isReasonable (s) && s->kind == SK_FIELD)
5334     {
5335       /*
5336        ** defining one field of a union defines the union
5337        */
5338 
5339       sRef base = s->info->field->rec;
5340 
5341       if (sRef_isReasonable (base))
5342 	{
5343 	  return (ctype_isUnion (ctype_realType (base->type)));
5344 	}
5345     }
5346 
5347   return FALSE;
5348 }
5349 
sRef_setPdefined(sRef s,fileloc loc)5350 void sRef_setPdefined (sRef s, fileloc loc)
5351 {
5352   sRef_checkMutable (s);
5353   if (sRef_isReasonable (s) && !sRef_isPartial (s))
5354     {
5355       sRef base = sRef_getBaseSafe (s);
5356 
5357       if (s->defstate == SS_ALLOCATED)
5358 	{
5359 	  return;
5360 	}
5361 
5362       s->definfo = stateInfo_updateLoc (s->definfo, SA_PDEFINED, loc);
5363       s->defstate = SS_PDEFINED;
5364 
5365       /* e.g., if x is allocated, *x = 3 defines x */
5366 
5367       while (sRef_isReasonable (base) && sRef_isKnown (base))
5368 	{
5369 	  if (base->defstate == SS_DEFINED)
5370 	    {
5371 	      sRef nb;
5372 
5373 	      DPRINTF (("set pdefined: %s", sRef_unparseFull (base)));
5374 	      base->defstate = SS_PDEFINED;
5375 	      nb = sRef_getBaseSafe (base);
5376 	      base = nb;
5377 	    }
5378 	  else
5379 	    {
5380 	      break;
5381 	    }
5382 	}
5383     }
5384 }
5385 
sRef_setStateAux(sRef s,sstate ss,fileloc loc)5386 static void sRef_setStateAux (sRef s, sstate ss, fileloc loc)
5387 {
5388   sRef_checkMutable (s);
5389 
5390   DPRINTF (("Set state: %s => %s", sRef_unparseFull (s), sstate_unparse (ss)));
5391 
5392   if (sRef_isReasonable (s))
5393     {
5394       /* if (s->defstate == SS_RELDEF) return; */
5395 
5396       if (s->defstate != ss && fileloc_isDefined (loc))
5397 	{
5398 	  s->definfo = stateInfo_updateLoc (s->definfo,
5399 					    stateAction_fromSState (ss), loc);
5400 	}
5401 
5402       s->defstate = ss;
5403       sRef_clearDerived (s);
5404 
5405       if (ss == SS_ALLOCATED)
5406 	{
5407 	  sRef base = sRef_getBaseSafe (s);
5408 
5409 	  while (sRef_isReasonable (base) && sRef_isKnown (base))
5410 	    {
5411 	      if (base->defstate == SS_DEFINED)
5412 		{
5413 		  sRef nb;
5414 
5415 		  DPRINTF (("set pdefined: %s", sRef_unparseFull (s)));
5416 		  base->defstate = SS_PDEFINED;
5417 		  nb = sRef_getBaseSafe (base);
5418 		  base = nb;
5419 		}
5420 	      else
5421 		{
5422 		  break;
5423 		}
5424 	    }
5425 	}
5426     }
5427 }
5428 
sRef_setAllocatedComplete(sRef s,fileloc loc)5429 void sRef_setAllocatedComplete (sRef s, fileloc loc)
5430 {
5431   sRef_innerAliasSetComplete (sRef_setAllocated, s, loc);
5432 }
5433 
sRef_setAllocatedShallow(sRef s,fileloc loc)5434 static void sRef_setAllocatedShallow (sRef s, fileloc loc)
5435 {
5436   sRef_checkMutable (s);
5437 
5438   if (sRef_isReasonable (s))
5439     {
5440       if (s->defstate == SS_DEAD || s->defstate == SS_UNDEFINED)
5441 	{
5442 	  s->defstate = SS_ALLOCATED;
5443 	  s->definfo = stateInfo_updateLoc (s->definfo, SA_ALLOCATED, loc);
5444 	}
5445     }
5446 }
5447 
sRef_setAllocatedShallowComplete(sRef s,fileloc loc)5448 void sRef_setAllocatedShallowComplete (sRef s, fileloc loc)
5449 {
5450   sRef_innerAliasSetComplete (sRef_setAllocatedShallow, s, loc);
5451 }
5452 
sRef_setAllocated(sRef s,fileloc loc)5453 void sRef_setAllocated (sRef s, fileloc loc)
5454 {
5455   sRef_checkMutable (s);
5456   sRef_setStateAux (s, SS_ALLOCATED, loc);
5457 }
5458 
sRef_setPartial(sRef s,fileloc loc)5459 void sRef_setPartial (sRef s, fileloc loc)
5460 {
5461   sRef_checkMutable (s);
5462   sRef_setStateAux (s, SS_PARTIAL, loc);
5463 }
5464 
sRef_setShared(sRef s,fileloc loc)5465 void sRef_setShared (sRef s, fileloc loc)
5466 {
5467   sRef_checkMutable (s);
5468 
5469   if (sRef_isReasonable (s))
5470     {
5471       if (s->aliaskind != AK_SHARED && fileloc_isDefined (loc))
5472 	{
5473 	  s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, SA_SHARED, loc);
5474 	}
5475 
5476       s->aliaskind = AK_SHARED;
5477       /* don't! sRef_clearDerived (s); */
5478     }
5479 }
5480 
sRef_setLastReference(sRef s,sRef ref,fileloc loc)5481 void sRef_setLastReference (sRef s, /*@exposed@*/ sRef ref, fileloc loc)
5482 {
5483   sRef_checkMutable (s);
5484 
5485   if (sRef_isReasonable (s))
5486     {
5487       s->aliaskind = sRef_getAliasKind (ref);
5488       s->aliasinfo = stateInfo_updateRefLoc (s->aliasinfo, ref, stateAction_fromAlkind (s->aliaskind), loc);
5489     }
5490 }
5491 
5492 static
sRef_setNullStateAux(sRef s,nstate ns,fileloc loc)5493 void sRef_setNullStateAux (/*@notnull@*/ sRef s, nstate ns, fileloc loc)
5494 {
5495   sRef_checkMutable (s);
5496   s->nullstate = ns;
5497   sRef_resetAliasKind (s);
5498 
5499   if (fileloc_isDefined (loc))
5500     {
5501       s->nullinfo = stateInfo_updateLoc (s->nullinfo, stateAction_fromNState (ns), loc);
5502     }
5503 }
5504 
sRef_setNotNull(sRef s,fileloc loc)5505 void sRef_setNotNull (sRef s, fileloc loc)
5506 {
5507   if (sRef_isReasonable (s))
5508     {
5509       sRef_setNullStateAux (s, NS_NOTNULL, loc);
5510     }
5511 }
5512 
sRef_setNullStateN(sRef s,nstate n)5513 void sRef_setNullStateN (sRef s, nstate n)
5514 {
5515   if (sRef_isReasonable (s))
5516     {
5517       sRef_checkMutable (s);
5518       s->nullstate = n;
5519       DPRINTF (("Set null state ==> %s", sRef_unparseFull (s)));
5520       sRef_resetAliasKind (s);
5521     }
5522 }
5523 
sRef_setNullState(sRef s,nstate n,fileloc loc)5524 void sRef_setNullState (sRef s, nstate n, fileloc loc)
5525 {
5526   if (sRef_isReasonable (s))
5527     {
5528       sRef_setNullStateAux (s, n, loc);
5529     }
5530 }
5531 
sRef_setNullTerminatedStateInnerComplete(sRef s,struct s_bbufinfo b,fileloc loc)5532 void sRef_setNullTerminatedStateInnerComplete (sRef s, struct s_bbufinfo b, /*@unused@*/ fileloc loc)
5533 {
5534   switch (b.bufstate) {
5535   case BB_NULLTERMINATED:
5536     sRef_setNullTerminatedState (s);
5537     sRef_setLen (s, b.len);
5538     break;
5539   case BB_POSSIBLYNULLTERMINATED:
5540     sRef_setPossiblyNullTerminatedState(s);
5541     break;
5542   case BB_NOTNULLTERMINATED:
5543     sRef_setNotNullTerminatedState (s);
5544     break;
5545   }
5546 
5547   sRef_setSize (s, b.size);
5548 
5549   /* PL: TO BE DONE : Aliases are not modified right now, have to be similar to
5550    * setNullStateInnerComplete.
5551    */
5552 }
5553 
sRef_setNullStateInnerComplete(sRef s,nstate n,fileloc loc)5554 void sRef_setNullStateInnerComplete (sRef s, nstate n, fileloc loc)
5555 {
5556   DPRINTF (("Set null state: %s", nstate_unparse (n)));
5557 
5558   sRef_setNullState (s, n, loc);
5559 
5560   switch (n)
5561     {
5562     case NS_POSNULL:
5563       sRef_innerAliasSetComplete (sRef_setPosNull, s, loc);
5564       break;
5565     case NS_DEFNULL:
5566       sRef_innerAliasSetComplete (sRef_setDefNull, s, loc);
5567       break;
5568     case NS_UNKNOWN:
5569       sRef_innerAliasSetComplete (sRef_setNullUnknown, s, loc);
5570       break;
5571     case NS_NOTNULL:
5572       sRef_innerAliasSetComplete (sRef_setNotNull, s, loc);
5573       break;
5574     case NS_MNOTNULL:
5575       sRef_innerAliasSetComplete (sRef_setNotNull, s, loc);
5576       break;
5577     case NS_RELNULL:
5578       sRef_innerAliasSetComplete (sRef_setNullUnknown, s, loc);
5579       break;
5580     case NS_CONSTNULL:
5581       sRef_innerAliasSetComplete (sRef_setDefNull, s, loc);
5582       break;
5583     case NS_ABSNULL:
5584       sRef_innerAliasSetComplete (sRef_setNullUnknown, s, loc);
5585       break;
5586     case NS_ERROR:
5587       sRef_innerAliasSetComplete (sRef_setNullErrorLoc, s, loc);
5588       break;
5589     }
5590 }
5591 
sRef_setPosNull(sRef s,fileloc loc)5592 void sRef_setPosNull (sRef s, fileloc loc)
5593 {
5594   if (sRef_isReasonable (s))
5595     {
5596       sRef_setNullStateAux (s, NS_POSNULL, loc);
5597     }
5598 }
5599 
sRef_setDefNull(sRef s,fileloc loc)5600 void sRef_setDefNull (sRef s, fileloc loc)
5601 {
5602   if (sRef_isReasonable (s))
5603     {
5604       sRef_setNullStateAux (s, NS_DEFNULL, loc);
5605     }
5606 }
5607 
sRef_setNullUnknown(sRef s,fileloc loc)5608 void sRef_setNullUnknown (sRef s, fileloc loc)
5609 {
5610   if (sRef_isReasonable (s))
5611     {
5612       sRef_setNullStateAux (s, NS_UNKNOWN, loc);
5613     }
5614 }
5615 
sRef_setNullError(sRef s)5616 void sRef_setNullError (sRef s)
5617 {
5618   if (sRef_isReasonable (s) && !sRef_isConst (s))
5619     {
5620       sRef_setNullStateAux (s, NS_UNKNOWN, fileloc_undefined);
5621     }
5622 }
5623 
sRef_setNullErrorLoc(sRef s,fileloc loc)5624 void sRef_setNullErrorLoc (sRef s, fileloc loc)
5625 {
5626   if (sRef_isReasonable (s) && !sRef_isConst (s))
5627     {
5628       sRef_setNullStateAux (s, NS_UNKNOWN, loc);
5629     }
5630 }
5631 
sRef_setOnly(sRef s,fileloc loc)5632 void sRef_setOnly (sRef s, fileloc loc)
5633 {
5634   if (sRef_isReasonable (s) && s->aliaskind != AK_ONLY)
5635     {
5636       sRef_checkMutable (s);
5637       s->aliaskind = AK_ONLY;
5638       s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, SA_ONLY, loc);
5639     }
5640 }
5641 
sRef_setDependent(sRef s,fileloc loc)5642 void sRef_setDependent (sRef s, fileloc loc)
5643 {
5644   if (sRef_isReasonable (s) && !sRef_isConst (s) && (s->aliaskind != AK_DEPENDENT))
5645     {
5646       sRef_checkMutable (s);
5647       DPRINTF (("Setting dependent: %s", sRef_unparseFull (s)));
5648       s->aliaskind = AK_DEPENDENT;
5649       s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, SA_DEPENDENT, loc);
5650     }
5651 }
5652 
sRef_setOwned(sRef s,fileloc loc)5653 void sRef_setOwned (sRef s, fileloc loc)
5654 {
5655   if (sRef_isReasonable (s) && !sRef_isConst (s) && (s->aliaskind != AK_OWNED))
5656     {
5657       sRef_checkMutable (s);
5658       s->aliaskind = AK_OWNED;
5659       s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, SA_OWNED, loc);
5660     }
5661 }
5662 
sRef_setKept(sRef s,fileloc loc)5663 void sRef_setKept (sRef s, fileloc loc)
5664 {
5665   if (sRef_isReasonable (s) && !sRef_isConst (s) && (s->aliaskind != AK_KEPT))
5666     {
5667       sRef base = sRef_getBaseSafe (s);
5668 
5669       while (sRef_isReasonable (base) && sRef_isKnown (base))
5670 	{
5671 	  if (base->defstate == SS_DEFINED)
5672 	    {
5673 	      sRef_checkMutable (base);
5674 	      base->defstate = SS_PDEFINED;
5675 	      base = sRef_getBaseSafe (base);
5676 	    }
5677 	  else
5678 	    {
5679 	      break;
5680 	    }
5681 	}
5682 
5683       sRef_checkMutable (s);
5684       s->aliaskind = AK_KEPT;
5685       s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, SA_KEPT, loc);
5686     }
5687 }
5688 
sRef_setKeptAux(sRef s,fileloc loc)5689 static void sRef_setKeptAux (sRef s, fileloc loc)
5690 {
5691   if (!sRef_isShared (s))
5692     {
5693       sRef_setKept (s, loc);
5694     }
5695 }
5696 
sRef_setDependentAux(sRef s,fileloc loc)5697 static void sRef_setDependentAux (sRef s, fileloc loc)
5698 {
5699   if (!sRef_isShared (s))
5700     {
5701       sRef_setDependent (s, loc);
5702     }
5703 }
5704 
sRef_setKeptComplete(sRef s,fileloc loc)5705 void sRef_setKeptComplete (sRef s, fileloc loc)
5706 {
5707   sRef_aliasSetComplete (sRef_setKeptAux, s, loc);
5708 }
5709 
sRef_setDependentComplete(sRef s,fileloc loc)5710 void sRef_setDependentComplete (sRef s, fileloc loc)
5711 {
5712   sRef_aliasSetComplete (sRef_setDependentAux, s, loc);
5713 }
5714 
sRef_setFresh(sRef s,fileloc loc)5715 void sRef_setFresh (sRef s, fileloc loc)
5716 {
5717   if (sRef_isReasonable (s) && !sRef_isConst (s))
5718     {
5719       sRef_checkMutable (s);
5720       s->aliaskind = AK_FRESH;
5721       s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, SA_CREATED, loc);
5722       DPRINTF (("SetFresh: %s", sRef_unparseFull (s)));
5723     }
5724 }
5725 
sRef_kill(sRef s,fileloc loc)5726 void sRef_kill (sRef s, fileloc loc)
5727 {
5728   DPRINTF (("Kill: %s", sRef_unparseFull (s)));
5729 
5730   if (sRef_isReasonable (s) && !sRef_isShared (s) && !sRef_isConst (s))
5731     {
5732       sRef base = sRef_getBaseSafe (s);
5733       sRef_checkMutable (s);
5734 
5735       while (sRef_isReasonable (base) && sRef_isKnown (base))
5736 	{
5737 	  if (base->defstate == SS_DEFINED)
5738 	    {
5739 	      sRef_checkMutable (base);
5740 	      base->defstate = SS_PDEFINED;
5741 	      base = sRef_getBaseSafe (base);
5742 	    }
5743 	  else
5744 	    {
5745 	      break;
5746 	    }
5747 	}
5748 
5749       s->aliaskind = s->oaliaskind;
5750       s->defstate = SS_DEAD;
5751       s->definfo = stateInfo_updateLoc (s->definfo, SA_KILLED, loc);
5752       DPRINTF (("State info: %s", stateInfo_unparse (s->definfo)));
5753       sRef_clearDerived (s);
5754     }
5755 }
5756 
sRef_maybeKill(sRef s,fileloc loc)5757 void sRef_maybeKill (sRef s, fileloc loc)
5758 {
5759   if (sRef_isReasonable (s))
5760     {
5761       sRef base = sRef_getBaseSafe (s);
5762       sRef_checkMutable (s);
5763 
5764       while (sRef_isReasonable (base) && sRef_isKnown (base))
5765 	{
5766 	  if (base->defstate == SS_DEFINED || base->defstate == SS_RELDEF)
5767 	    {
5768 	      sRef_checkMutable (base);
5769 	      base->defstate = SS_PDEFINED;
5770 	      base = sRef_getBaseSafe (base);
5771 	    }
5772 	  else
5773 	    {
5774 	      break;
5775 	    }
5776 
5777 	}
5778 
5779       s->aliaskind = s->oaliaskind;
5780       s->defstate = SS_HOFFA;
5781       s->definfo = stateInfo_updateLoc (s->definfo, SA_PKILLED, loc);
5782       DPRINTF (("State info: %s / %s", sRef_unparse (s),
5783 		stateInfo_unparse (s->definfo)));
5784       sRef_clearDerived (s);
5785     }
5786 
5787   }
5788 
5789 /*
5790 ** just for type checking...
5791 */
5792 
sRef_killAux(sRef s,fileloc loc)5793 static void sRef_killAux (sRef s, fileloc loc)
5794 {
5795   if (sRef_isReasonable (s) && !sRef_isShared (s))
5796     {
5797       if (sRef_isUnknownArrayFetch (s))
5798 	{
5799 	  sRef_maybeKill (s, loc);
5800 	}
5801       else
5802 	{
5803 	  sRef_kill (s, loc);
5804 	}
5805     }
5806 }
5807 
5808 /*
5809 ** kills s and all aliases to s
5810 */
5811 
sRef_killComplete(sRef s,fileloc loc)5812 void sRef_killComplete (sRef s, fileloc loc)
5813 {
5814   DPRINTF (("Kill complete: %s", sRef_unparseFull (s)));
5815   sRef_aliasSetComplete (sRef_killAux, s, loc);
5816 }
5817 
sRef_equivalent(sRef s1,sRef s2)5818 static bool sRef_equivalent (sRef s1, sRef s2)
5819 {
5820   return (sRef_compare (s1, s2) == 0);
5821 }
5822 
5823 /*
5824 ** returns an sRef that will not be free'd on function exit.
5825 */
5826 
sRef_saveCopy(sRef s)5827 /*@only@*/ sRef sRef_saveCopy (sRef s)
5828 {
5829   sRef ret;
5830 
5831   if (sRef_isReasonable (s))
5832     {
5833       bool old = inFunction;
5834 
5835       /*
5836       ** Exit the function scope, so this sRef is not
5837       ** stored in the deallocation table.
5838       */
5839 
5840       inFunction = FALSE;
5841       DPRINTF (("Copying sref: %s", sRef_unparseFull(s)));
5842       ret = sRef_copy (s);
5843       DPRINTF (("Copying ===>: %s", sRef_unparseFull(ret)));
5844       inFunction = old;
5845     }
5846   else
5847     {
5848       ret = sRef_undefined;
5849     }
5850 
5851   /*@-dependenttrans@*/
5852   return ret;
5853   /*@=dependenttrans@*/
5854 }
5855 
sRef_copy(sRef s)5856 sRef sRef_copy (sRef s)
5857 {
5858   if (sRef_isKindSpecial (s) && !sRef_isGlobalMarker (s))
5859     {
5860       /*@-retalias@*/
5861       return s; /* don't copy specials (except for global markers) */
5862       /*@=retalias@*/
5863     }
5864 
5865   if (sRef_isReasonable (s))
5866     {
5867       sRef t = sRef_alloc ();
5868 
5869       DPRINTF (("Copying: [%p] %s", s, sRef_unparse (s)));
5870       DPRINTF (("Full: %s", sRef_unparseFull (s)));
5871 
5872       t->kind = s->kind;
5873       t->safe = s->safe;
5874       t->modified = s->modified;
5875       t->immut = FALSE; /* Note mutability is not copied. */
5876       t->type = s->type;
5877       t->val = multiVal_copy (s->val);
5878 
5879       t->info = sinfo_copy (s);
5880       t->defstate = s->defstate;
5881       t->nullstate = s->nullstate;
5882       DPRINTF (("Set null state==> %s", sRef_unparseFull (t)));
5883 
5884 
5885       /* start modifications */
5886       t->bufinfo.bufstate = s->bufinfo.bufstate;
5887       t->bufinfo.len = s->bufinfo.len;
5888       t->bufinfo.size = s->bufinfo.size;
5889       /* end modifications */
5890 
5891       t->aliaskind = s->aliaskind;
5892       t->oaliaskind = s->oaliaskind;
5893 
5894       t->expkind = s->expkind;
5895       t->oexpkind = s->oexpkind;
5896 
5897       t->nullinfo = stateInfo_copy (s->nullinfo);
5898       t->aliasinfo = stateInfo_copy (s->aliasinfo);
5899       t->definfo = stateInfo_copy (s->definfo);
5900       t->expinfo = stateInfo_copy (s->expinfo);
5901 
5902       t->deriv = sRefSet_newDeepCopy (s->deriv);
5903       t->state = valueTable_copy (s->state);
5904 
5905       DPRINTF (("Made copy: %s => %s", sRef_unparseFull (s), sRef_unparseFull (t)));
5906       return t;
5907     }
5908   else
5909     {
5910       return sRef_undefined;
5911     }
5912 }
5913 
5914 /*@notfunction@*/
5915 # define PREDTEST(func,s) \
5916    do { if (sRef_isInvalid (s)) { return FALSE; } \
5917         else { if (sRef_isConj (s)) \
5918                   { return (func (sRef_getConjA (s)) \
5919 		            || func (sRef_getConjB (s))); }}} while (FALSE);
5920 
sRef_isAddress(sRef s)5921 bool sRef_isAddress (sRef s)
5922 {
5923   PREDTEST (sRef_isAddress, s);
5924   return (s->kind == SK_ADR);
5925 }
5926 
5927 /*
5928 ** pretty weak... maybe a flag should control this.
5929 */
5930 
sRef_isThroughArrayFetch(sRef s)5931 bool sRef_isThroughArrayFetch (sRef s)
5932 {
5933   if (sRef_isReasonable (s))
5934     {
5935       sRef tref = s;
5936 
5937       do
5938 	{
5939 	  sRef lt;
5940 
5941 	  if (sRef_isArrayFetch (tref))
5942 	    {
5943 	      return TRUE;
5944 	    }
5945 
5946 	  lt = sRef_getBase (tref);
5947 	  tref = lt;
5948 	} while (sRef_isReasonable (tref));
5949     }
5950 
5951   return FALSE;
5952 }
5953 
sRef_isArrayFetch(sRef s)5954 bool sRef_isArrayFetch (sRef s)
5955 {
5956   PREDTEST (sRef_isArrayFetch, s);
5957   return (s->kind == SK_ARRAYFETCH);
5958 }
5959 
sRef_isMacroParamRef(sRef s)5960 bool sRef_isMacroParamRef (sRef s)
5961 {
5962   if (context_inMacro () && sRef_isCvar (s))
5963     {
5964       uentry ue = sRef_getUentry (s);
5965       cstring pname = makeParam (uentry_rawName (ue));
5966       uentry mac = usymtab_lookupSafe (pname);
5967 
5968       cstring_free (pname);
5969       return (uentry_isValid (mac));
5970     }
5971 
5972   return FALSE;
5973 }
5974 
sRef_isCvar(sRef s)5975 bool sRef_isCvar (sRef s)
5976 {
5977   PREDTEST (sRef_isCvar, s);
5978   return (s->kind == SK_CVAR);
5979 }
5980 
sRef_isConst(sRef s)5981 bool sRef_isConst (sRef s)
5982 {
5983   PREDTEST (sRef_isConst, s);
5984   return (s->kind == SK_CONST);
5985 }
5986 
sRef_isObject(sRef s)5987 bool sRef_isObject (sRef s)
5988 {
5989   PREDTEST (sRef_isObject, s);
5990   return (s->kind == SK_OBJECT);
5991 }
5992 
sRef_isExternal(sRef s)5993 bool sRef_isExternal (sRef s)
5994 {
5995   PREDTEST (sRef_isExternal, s);
5996   return (s->kind == SK_EXTERNAL);
5997 }
5998 
sRef_isDerived(sRef s)5999 static bool sRef_isDerived (sRef s)
6000 {
6001   PREDTEST (sRef_isDerived, s);
6002   return (s->kind == SK_DERIVED);
6003 }
6004 
sRef_isField(sRef s)6005 bool sRef_isField (sRef s)
6006 {
6007   PREDTEST (sRef_isField, s);
6008   return (s->kind == SK_FIELD);
6009 }
6010 
sRef_isIndex(sRef s)6011 static bool sRef_isIndex (sRef s)
6012 {
6013   PREDTEST (sRef_isIndex, s);
6014   return (s->kind == SK_ARRAYFETCH);
6015 }
6016 
sRef_isAnyParam(sRef s)6017 bool sRef_isAnyParam (sRef s)
6018 {
6019   PREDTEST (sRef_isAnyParam, s);
6020   return (s->kind == SK_PARAM);
6021 }
6022 
sRef_isParam(sRef s)6023 bool sRef_isParam (sRef s)
6024 {
6025   PREDTEST (sRef_isParam, s);
6026   return (s->kind == SK_PARAM);
6027 }
6028 
sRef_isDirectParam(sRef s)6029 bool sRef_isDirectParam (sRef s)
6030 {
6031   PREDTEST (sRef_isDirectParam, s);
6032 
6033   return ((s->kind == SK_CVAR) &&
6034 	  (s->info->cvar->lexlevel == functionScope) &&
6035 	  (context_inFunction () &&
6036 	   (s->info->cvar->index <= usymId_fromInt (uentryList_size (context_getParams ())))));
6037 }
6038 
sRef_isPointer(sRef s)6039 bool sRef_isPointer (sRef s)
6040 {
6041   PREDTEST (sRef_isPointer, s);
6042   return (s->kind == SK_PTR);
6043 }
6044 
6045 /*
6046 ** returns true if storage referenced by s is visible
6047 */
6048 
sRef_isReference(sRef s)6049 bool sRef_isReference (sRef s)
6050 {
6051   PREDTEST (sRef_isReference, s);
6052 
6053   return (sRef_isPointer (s) || sRef_isIndex (s) || sRef_isFileOrGlobalScope (s)
6054 	  || (sRef_isField (s) && (sRef_isReference (s->info->field->rec))));
6055 }
6056 
sRef_isIReference(sRef s)6057 bool sRef_isIReference (sRef s)
6058 {
6059   return (sRef_isPointer (s) || sRef_isAddress (s) || sRef_isIndex (s)
6060 	  || sRef_isField (s) || sRef_isArrayFetch (s));
6061 }
6062 
sRef_isFileOrGlobalScope(sRef s)6063 bool sRef_isFileOrGlobalScope (sRef s)
6064 {
6065   return (sRef_isCvar (s) && (s->info->cvar->lexlevel <= fileScope));
6066 }
6067 
sRef_isRealGlobal(sRef s)6068 bool sRef_isRealGlobal (sRef s)
6069 {
6070   return (sRef_isCvar (s) && (s->info->cvar->lexlevel == globScope));
6071 }
6072 
sRef_isFileStatic(sRef s)6073 bool sRef_isFileStatic (sRef s)
6074 {
6075   return (sRef_isCvar (s) && (s->info->cvar->lexlevel == fileScope));
6076 }
6077 
sRef_isAliasCheckedGlobal(sRef s)6078 bool sRef_isAliasCheckedGlobal (sRef s)
6079 {
6080   if (sRef_isFileOrGlobalScope (s))
6081     {
6082       uentry ue = sRef_getUentry (s);
6083 
6084       return context_checkAliasGlob (ue);
6085     }
6086   else
6087     {
6088       return FALSE;
6089     }
6090 }
6091 
sRef_free(sRef s)6092 void sRef_free (/*@only@*/ sRef s)
6093 {
6094   if (s != sRef_undefined && s->kind != SK_SPECIAL)
6095     {
6096       DPRINTF (("Free sref: [%p]", s));
6097 
6098       sRef_checkValid (s);
6099 
6100       multiVal_free (s->val); /* evans 2002-07-12 */
6101 
6102       stateInfo_free (s->expinfo);
6103       stateInfo_free (s->aliasinfo);
6104       stateInfo_free (s->definfo);
6105       stateInfo_free (s->nullinfo);
6106 
6107       sRefSet_free (s->deriv);
6108       s->deriv = sRefSet_undefined;
6109 
6110       valueTable_free (s->state);
6111       sinfo_free (s);
6112 
6113 
6114       /* drl added to help locate use after release*/
6115       s->expinfo = stateInfo_undefined;
6116       s->aliasinfo = stateInfo_undefined;
6117       s->definfo = stateInfo_undefined;
6118       s->nullinfo = stateInfo_undefined;
6119 
6120       sfree (s);
6121     }
6122 }
6123 
sRef_setType(sRef s,ctype t)6124 void sRef_setType (sRef s, ctype t)
6125 {
6126   if (sRef_isReasonable (s))
6127     {
6128       sRef_checkMutable (s);
6129       s->type = t;
6130     }
6131 }
6132 
sRef_setTypeFull(sRef s,ctype t)6133 void sRef_setTypeFull (sRef s, ctype t)
6134 {
6135   if (sRef_isReasonable (s))
6136     {
6137       sRef_checkMutable (s);
6138       s->type = t;
6139 
6140       sRefSet_allElements (s->deriv, current)
6141 	{
6142 	  sRef_setTypeFull (current, ctype_unknown);
6143 	} end_sRefSet_allElements ;
6144     }
6145 }
6146 
6147 /*@exposed@*/ sRef
sRef_buildField(sRef rec,cstring f)6148   sRef_buildField (/*@exposed@*/ sRef rec, /*@dependent@*/ cstring f)
6149 {
6150   return (sRef_buildNCField (rec, f));
6151 }
6152 
6153 static /*@exposed@*/ sRef
sRef_findDerivedField(sRef rec,cstring f)6154 sRef_findDerivedField (/*@notnull@*/ sRef rec, cstring f)
6155 {
6156   sRefSet_allElements (sRef_derivedFields (rec), sr)
6157     {
6158       if (sRef_isReasonable (sr))
6159 	{
6160 	  if (sRef_isReasonable (sr))
6161 	    {
6162 	      if (sr->info != NULL)
6163 		{
6164 		  if (sr->kind == SK_FIELD && cstring_equal (sr->info->field->field, f))
6165 		    {
6166 		      return sr;
6167 		    }
6168 		}
6169 	    }
6170 	  else
6171 	    {
6172 	      llcontbug (message ("Invalid sRef as derived field of %s", sRef_unparse (rec)));
6173 	    }
6174 	}
6175     } end_sRefSet_allElements;
6176 
6177   return sRef_undefined;
6178 }
6179 
sRef_derivedFields(sRef rec)6180 /*@dependent@*/ /*@observer@*/ sRefSet sRef_derivedFields (/*@temp@*/ sRef rec)
6181 {
6182   if (sRef_isReasonable (rec))
6183     {
6184       sRefSet ret;
6185       ret = rec->deriv;
6186       return (ret);
6187     }
6188   else
6189     {
6190       return (sRefSet_undefined);
6191     }
6192 }
6193 
6194 static /*@exposed@*/ sRef
sRef_findDerivedPointer(sRef s)6195   sRef_findDerivedPointer (sRef s)
6196 {
6197   if (sRef_isReasonable (s))
6198     {
6199       sRefSet_realElements (s->deriv, sr)
6200 	{
6201 	  if (sRef_isReasonable (sr) && sr->kind == SK_PTR)
6202 	    {
6203 	      return sr;
6204 	    }
6205 	} end_sRefSet_realElements;
6206     }
6207 
6208   return sRef_undefined;
6209 }
6210 
6211 bool
sRef_isUnknownArrayFetch(sRef s)6212 sRef_isUnknownArrayFetch (sRef s)
6213 {
6214   return (sRef_isReasonable (s)
6215 	  && s->kind == SK_ARRAYFETCH
6216 	  && !s->info->arrayfetch->indknown);
6217 }
6218 
6219 static /*@exposed@*/ sRef
sRef_findDerivedArrayFetch(sRef s,bool isknown,int idx,bool dead)6220 sRef_findDerivedArrayFetch (/*@notnull@*/ sRef s, bool isknown, int idx, bool dead)
6221 {
6222 
6223   if (isknown)
6224     {
6225       sRefSet_realElements (s->deriv, sr)
6226 	{
6227 	  if (sRef_isReasonable (sr)
6228 	      && sr->kind == SK_ARRAYFETCH
6229 	      && sr->info->arrayfetch->indknown
6230 	      && (sr->info->arrayfetch->ind == idx))
6231 	    {
6232 	      return sr;
6233 	    }
6234 	} end_sRefSet_realElements;
6235     }
6236   else
6237     {
6238       sRefSet_realElements (s->deriv, sr)
6239 	{
6240 	  if (sRef_isReasonable (sr)
6241 	      && sr->kind == SK_ARRAYFETCH
6242 	      && (!sr->info->arrayfetch->indknown
6243 		  || (sr->info->arrayfetch->indknown &&
6244 		      sr->info->arrayfetch->ind == 0)))
6245 	    {
6246 	      if (sRef_isDead (sr) || sRef_isKept (sr))
6247 		{
6248 		  if (dead || context_getFlag (FLG_STRICTUSERELEASED))
6249 		    {
6250 		      return sr;
6251 		    }
6252 		}
6253 	      else
6254 		{
6255 		  return sr;
6256 		}
6257 	    }
6258 	} end_sRefSet_realElements;
6259     }
6260 
6261   return sRef_undefined;
6262 }
6263 
6264 static /*@exposed@*/ sRef
sRef_buildNCField(sRef rec,cstring f)6265 sRef_buildNCField (/*@exposed@*/ sRef rec, /*@exposed@*/ cstring f)
6266 {
6267   sRef s;
6268 
6269   DPRINTF (("Build nc field: %s / %s",
6270 	    sRef_unparseFull (rec), f));
6271 
6272   if (sRef_isInvalid (rec))
6273     {
6274       return sRef_undefined;
6275     }
6276 
6277   /*
6278   ** check if the field already has been referenced
6279   */
6280 
6281   s = sRef_findDerivedField (rec, f);
6282 
6283   if (sRef_isReasonable (s))
6284     {
6285       return s;
6286     }
6287   else
6288     {
6289       ctype ct = ctype_realType (rec->type);
6290 
6291       DPRINTF (("Field of: %s", sRef_unparse (rec)));
6292 
6293       s = sRef_newRef ();
6294       s->kind = SK_FIELD;
6295       s->info = (sinfo) dmalloc (sizeof (*s->info));
6296       s->info->field = (fldinfo) dmalloc (sizeof (*s->info->field));
6297       s->info->field->rec = rec;
6298       s->info->field->field = f; /* doesn't copy f */
6299 
6300       if (ctype_isKnown (ct) && ctype_isSU (ct))
6301 	{
6302 	  uentry ue = uentryList_lookupField (ctype_getFields (ct), f);
6303 
6304 	  if (!uentry_isUndefined (ue))
6305 	    {
6306 	      DPRINTF (("lookup: %s for %s", uentry_unparseFull (ue),
6307 			ctype_unparse (ct)));
6308 
6309 	      s->type = uentry_getType (ue);
6310 
6311 	      if (ctype_isMutable (s->type)
6312 		  && rec->aliaskind != AK_STACK
6313 		  && !alkind_isStatic (rec->aliaskind))
6314 		{
6315 		  s->aliaskind = rec->aliaskind;
6316 		}
6317 	      else
6318 		{
6319 		  s->aliaskind = AK_UNKNOWN;
6320 		}
6321 
6322 	      if (sRef_isStateDefined (rec) || sRef_isStateUnknown (rec)
6323 		  || sRef_isPdefined (rec))
6324 		{
6325 		  sRef_setStateFromUentry (s, ue);
6326 		}
6327 	      else
6328 		{
6329 		  sRef_setPartsFromUentry (s, ue);
6330 		}
6331 
6332 	      s->oaliaskind = s->aliaskind;
6333 	      s->oexpkind = s->expkind;
6334 
6335 	      DPRINTF (("sref: %s", sRef_unparseFull (s)));
6336 	    }
6337 	  else
6338 	    {
6339 	      /*
6340 		Never report this as an error.  It can happen whenever there
6341 		is casting involved.
6342 
6343 	      if (report)
6344 		{
6345 		  llcontbug (message ("buildNCField --- no field %s: %q / %s",
6346 				      f, sRef_unparse (s), ctype_unparse (ct)));
6347 		}
6348 		*/
6349 
6350 	      return sRef_undefined;
6351 	    }
6352 	}
6353 
6354       if (rec->defstate == SS_DEFINED
6355 	  && (s->defstate == SS_UNDEFINED || s->defstate == SS_UNKNOWN))
6356 	{
6357 	  s->defstate = SS_DEFINED;
6358 	}
6359       else if (rec->defstate == SS_PARTIAL)
6360 	{
6361 	  s->defstate = SS_PARTIAL;
6362 	}
6363       else if (rec->defstate == SS_ALLOCATED)
6364 	{
6365 	  if (ctype_isStackAllocated (ct) && ctype_isStackAllocated (s->type))
6366 	    {
6367 	      s->defstate = SS_ALLOCATED;
6368 	    }
6369 	  else
6370 	    {
6371 	      s->defstate = SS_UNDEFINED;
6372 	    }
6373 	}
6374       else if (s->defstate == SS_UNKNOWN)
6375 	{
6376 	  s->defstate = rec->defstate;
6377 	}
6378       else
6379 	{
6380 	  ; /* no change */
6381 	}
6382 
6383       if (s->defstate == SS_UNDEFINED)
6384 	{
6385 	  ctype rt = ctype_realType (s->type);
6386 
6387 	  if (ctype_isArray (rt) || ctype_isSU (rt))
6388 	    {
6389 	      s->defstate = SS_ALLOCATED;
6390 	    }
6391 	}
6392 
6393       sRef_addDeriv (rec, s);
6394       DPRINTF (("Add deriv: %s", sRef_unparseFull (rec)));
6395 
6396       if (ctype_isInt (s->type) && cstring_equal (f, REFSNAME))
6397 	{
6398 	  s->aliaskind = AK_REFS;
6399 	  s->oaliaskind = AK_REFS;
6400 	}
6401 
6402       DPRINTF (("Build field ==> %s", sRef_unparseFull (s)));
6403       return s;
6404     }
6405 }
6406 
6407 bool
sRef_isStackAllocated(sRef s)6408 sRef_isStackAllocated (sRef s)
6409 {
6410   return (sRef_isReasonable(s)
6411 	  && s->defstate == SS_ALLOCATED && ctype_isStackAllocated (s->type));
6412 }
6413 
6414 static
sRef_setArrayFetchState(sRef s,sRef arr)6415 void sRef_setArrayFetchState (/*@notnull@*/ /*@exposed@*/ sRef s,
6416 			      /*@notnull@*/ /*@exposed@*/ sRef arr)
6417 {
6418   sRef_checkMutable (s);
6419 
6420   if (ctype_isRealAP (arr->type))
6421     {
6422       s->type = ctype_baseArrayPtr (arr->type);
6423     }
6424 
6425   /* a hack, methinks... makeArrayFetch (&a[0]) ==> a[] */
6426   /* evans - 2001-08-27: not sure where this was necessary - it
6427   ** causes an assertion in in aliasCheckPred to fail.
6428   */
6429 
6430   if (sRef_isAddress (arr))
6431     {
6432       sRef t = arr->info->ref;
6433 
6434       if (sRef_isArrayFetch (t))
6435 	{
6436 	  s->info->arrayfetch->arr = t->info->arrayfetch->arr;
6437 	}
6438     }
6439   else if (ctype_isRealPointer (arr->type))
6440     {
6441       sRef sp = sRef_findDerivedPointer (arr);
6442 
6443       if (sRef_isReasonable (sp))
6444 	{
6445 
6446 	  if (ctype_isMutable (s->type))
6447 	    {
6448 	      s->expkind = sRef_getExKind (sp);
6449 	      s->expinfo = stateInfo_copy (sp->expinfo);
6450 
6451 	      s->aliaskind = sp->aliaskind;
6452 	      s->aliasinfo = stateInfo_copy (sp->aliasinfo);
6453 	    }
6454 
6455 	  s->defstate = sp->defstate;
6456 
6457 	  if (s->defstate == SS_DEFINED)
6458 	    {
6459 	      if (!context_getFlag (FLG_STRICTDESTROY))
6460 		{
6461 		  s->defstate = SS_PARTIAL;
6462 		}
6463 	    }
6464 
6465 	  DPRINTF (("Set null state: %s / %s", sRef_unparseFull (s), sRef_unparseFull (sp)));
6466 	  sRef_setNullStateN (s, sRef_getNullState (sp));
6467 	}
6468       else
6469 	{
6470 	  if (arr->defstate == SS_UNDEFINED)
6471 	    {
6472 	      s->defstate = SS_UNUSEABLE;
6473 	    }
6474 	  else if ((arr->defstate == SS_ALLOCATED) && !ctype_isSU (s->type))
6475 	    {
6476 	      s->defstate = SS_UNDEFINED;
6477 	    }
6478 	  else
6479 	    {
6480 	      if (!context_getFlag (FLG_STRICTDESTROY))
6481 		{
6482 		  s->defstate = SS_PARTIAL;
6483 		}
6484 	      else
6485 		{
6486 		  s->defstate = SS_DEFINED;
6487 		}
6488 
6489 	      /*
6490 	      ** Very weak checking for array elements.
6491 	      ** Was:
6492 	      **     s->defstate = arr->defstate;
6493 	      */
6494 	    }
6495 
6496 	  s->expkind = sRef_getExKind (arr);
6497 	  s->expinfo = stateInfo_copy (arr->expinfo);
6498 
6499 	  if (arr->aliaskind == AK_LOCAL || arr->aliaskind == AK_FRESH)
6500 	    {
6501 	      s->aliaskind = AK_LOCAL;
6502 	    }
6503 	  else
6504 	    {
6505 	      s->aliaskind = AK_UNKNOWN;
6506 	    }
6507 
6508 	  sRef_setTypeState (s);
6509 	}
6510     }
6511   else
6512     {
6513       if (arr->defstate == SS_DEFINED)
6514 	{
6515 	  /*
6516 	  ** Very weak checking for array elements.
6517 	  ** Was:
6518 	  **     s->defstate = arr->defstate;
6519 	  */
6520 
6521 	  if (context_getFlag (FLG_STRICTDESTROY))
6522 	    {
6523 	      s->defstate = SS_DEFINED;
6524 	    }
6525 	  else
6526 	    {
6527 	      s->defstate = SS_PARTIAL;
6528 	    }
6529 	}
6530       else if (arr->defstate == SS_ALLOCATED)
6531 	{
6532 	  if (ctype_isRealArray (s->type))
6533 	    {
6534 	      s->defstate = SS_ALLOCATED;
6535 	    }
6536 	  else
6537 	    {
6538 	      if (!s->info->arrayfetch->indknown)
6539 		{
6540 		  /*
6541 		  ** is index is unknown, elements is defined or
6542 		  ** allocated is any element is!
6543 		  */
6544 
6545 		  s->defstate = SS_UNDEFINED;
6546 
6547 		  sRefSet_allElements (arr->deriv, sr)
6548 		    {
6549 		      if (sRef_isReasonable (sr))
6550 			{
6551 			  if (sRef_isReasonable (sr))
6552 			    {
6553 			      if (sr->defstate == SS_ALLOCATED)
6554 				{
6555 				  s->defstate = SS_ALLOCATED;
6556 				}
6557 			      else
6558 				{
6559 				  if (sr->defstate == SS_DEFINED)
6560 				    {
6561 				      if (context_getFlag (FLG_STRICTDESTROY))
6562 					{
6563 					  s->defstate = SS_DEFINED;
6564 					}
6565 				      else
6566 					{
6567 					  s->defstate = SS_PARTIAL;
6568 					}
6569 
6570 				      break;
6571 				    }
6572 				}
6573 			    }
6574 			  else
6575 			    {
6576 			      llcontbug (message ("Invalid sRef as derived element of %s", sRef_unparse (arr)));
6577 			    }
6578 			}
6579 		    } end_sRefSet_allElements;
6580 		}
6581 	      else
6582 		{
6583 		  s->defstate = SS_UNDEFINED;
6584 		}
6585 	    }
6586 	}
6587       else
6588 	{
6589 	  s->defstate = arr->defstate;
6590 	}
6591 
6592 
6593       /*
6594       ** kludgey way to guess where aliaskind applies
6595       */
6596 
6597       if (ctype_isMutable (s->type)
6598 	  && !ctype_isPointer (arr->type)
6599 	  && !alkind_isStatic (arr->aliaskind)
6600 	  && !alkind_isStack (arr->aliaskind)) /* evs - 2000-06-20: don't pass stack allocation to members */
6601 	{
6602 	  s->aliaskind = arr->aliaskind;
6603 	}
6604       else
6605 	{
6606 	  s->aliaskind = AK_UNKNOWN;
6607 	}
6608 
6609       sRef_setTypeState (s);
6610     }
6611 
6612   if (sRef_isObserver (arr))
6613     {
6614       s->expkind = XO_OBSERVER;
6615       s->expinfo = stateInfo_copy (arr->expinfo);
6616     }
6617 }
6618 
sRef_buildArrayFetch(sRef arr)6619 /*@exposed@*/ sRef sRef_buildArrayFetch (/*@exposed@*/ sRef arr)
6620 {
6621   sRef s;
6622 
6623   if (!sRef_isReasonable (arr)) {
6624     /*@-nullret@*/ return arr /*@=nullret@*/;
6625   }
6626 
6627   if (ctype_isRealPointer (arr->type))
6628     {
6629       (void) sRef_buildPointer (arr); /* do this to define arr! */
6630     }
6631 
6632   s = sRef_findDerivedArrayFetch (arr, FALSE, 0, FALSE);
6633 
6634   if (sRef_isReasonable (s))
6635     {
6636       /* evans 2001-07-12: this is bogus, clean-up hack */
6637       if (s->info->arrayfetch->arr != arr)
6638 	{
6639 	  sRef res;
6640 	  check (sRefSet_delete (arr->deriv, s));
6641 	  res = sRef_buildArrayFetch (arr);
6642 	  sRef_copyState (res, s);
6643 	  llassert (res->info->arrayfetch->arr == arr);
6644 	  return res;
6645 	}
6646 
6647       s->expkind = sRef_getExKind (arr);
6648       s->expinfo = stateInfo_copy (arr->expinfo);
6649 
6650       return s;
6651     }
6652   else
6653     {
6654       s = sRef_newRef ();
6655 
6656       s->kind = SK_ARRAYFETCH;
6657       s->info = (sinfo) dmalloc (sizeof (*s->info));
6658       s->info->arrayfetch = (ainfo) dmalloc (sizeof (*s->info->arrayfetch));
6659       s->info->arrayfetch->indknown = FALSE;
6660       s->info->arrayfetch->ind = 0;
6661       s->info->arrayfetch->arr = arr;
6662 
6663       sRef_setArrayFetchState (s, arr);
6664 
6665       s->oaliaskind = s->aliaskind;
6666       s->oexpkind = s->expkind;
6667 
6668       if (!context_inProtectVars ())
6669 	{
6670 	  sRef_addDeriv (arr, s);
6671 	}
6672 
6673       if (valueTable_isUndefined (s->state))
6674 	{
6675 	  s->state = context_createValueTable
6676 	    (s, stateInfo_makeLoc (g_currentloc, SA_CREATED));
6677 	}
6678 
6679       return (s);
6680     }
6681 }
6682 
6683 /*@exposed@*/ sRef
sRef_buildArrayFetchKnown(sRef arr,int i)6684   sRef_buildArrayFetchKnown (/*@exposed@*/ sRef arr, int i)
6685 {
6686   sRef s;
6687 
6688   if (!sRef_isReasonable (arr)) {
6689     /*@-nullret@*/ return arr /*@=nullret@*/;
6690   }
6691 
6692   if (ctype_isRealPointer (arr->type))
6693     {
6694       (void) sRef_buildPointer (arr); /* do this to define arr! */
6695     }
6696 
6697   s = sRef_findDerivedArrayFetch (arr, TRUE, i, FALSE);
6698 
6699   if (sRef_isReasonable (s))
6700     {
6701       /* evans 2001-07-12: this is bogus, clean-up hack */
6702       if (s->info->arrayfetch->arr != arr)
6703 	{
6704 	  sRef res;
6705 
6706 	  check (sRefSet_delete (arr->deriv, s));
6707 	  res = sRef_buildArrayFetchKnown (arr, i);
6708 
6709 	  llassert (res->info->arrayfetch->arr == arr);
6710 	  sRef_copyState (res, s);
6711 	  llassert (res->info->arrayfetch->arr == arr);
6712 	  return res;
6713 	}
6714 
6715       s->expkind = sRef_getExKind (arr);
6716       s->expinfo = stateInfo_copy (arr->expinfo);
6717 
6718       llassert (s->info->arrayfetch->arr == arr);
6719       return s;
6720     }
6721   else
6722     {
6723       s = sRef_newRef ();
6724 
6725       s->kind = SK_ARRAYFETCH;
6726       s->info = (sinfo) dmalloc (sizeof (*s->info));
6727       s->info->arrayfetch = (ainfo) dmalloc (sizeof (*s->info->arrayfetch));
6728       s->info->arrayfetch->arr = arr;
6729       s->info->arrayfetch->indknown = TRUE;
6730       s->info->arrayfetch->ind = i;
6731 
6732       sRef_setArrayFetchState (s, arr);
6733       /* evans 2001-08-27 no: can change this - llassert (s->info->arrayfetch->arr == arr); */
6734 
6735       s->oaliaskind = s->aliaskind;
6736       s->oexpkind = s->expkind;
6737       sRef_addDeriv (arr, s);
6738 
6739       llassert (valueTable_isUndefined (s->state));
6740       s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_CREATED));
6741       return (s);
6742     }
6743 }
6744 
6745 /*
6746 ** sets everything except for defstate
6747 */
6748 
6749 static void
sRef_setPartsFromUentry(sRef s,uentry ue)6750 sRef_setPartsFromUentry (sRef s, uentry ue)
6751 {
6752   sRef uref = uentry_getSref (ue);
6753 
6754   llassert (sRef_isReasonable (s));
6755 
6756   s->aliaskind = alkind_derive (s->aliaskind, uentry_getAliasKind (ue));
6757   s->oaliaskind = s->aliaskind;
6758 
6759   if (s->expkind == XO_UNKNOWN)
6760     {
6761       s->expkind = uentry_getExpKind (ue);
6762     }
6763 
6764   s->oexpkind = s->expkind;
6765 
6766   if (sRef_getNullState (s) == NS_UNKNOWN)
6767     {
6768       DPRINTF (("Set null state: %s / %s", sRef_unparseFull (s), uentry_unparseFull (ue)));
6769       sRef_setNullStateN (s, sRef_getNullState (uentry_getSref (ue)));
6770     }
6771   else
6772     {
6773       DPRINTF (("Skipping null null state!"));
6774     }
6775 
6776   if (s->aliaskind == AK_IMPONLY && (sRef_isExposed (s) || sRef_isObserver (s)))
6777     {
6778       s->oaliaskind = s->aliaskind = AK_IMPDEPENDENT;
6779     }
6780 
6781   if (sRef_isReasonable (uref))
6782     {
6783       valueTable utable = uref->state;
6784       valueTable_free (s->state);
6785       s->state = valueTable_copy (utable);
6786     }
6787 }
6788 
6789 static void
sRef_setStateFromAbstractUentry(sRef s,uentry ue)6790 sRef_setStateFromAbstractUentry (sRef s, uentry ue)
6791 {
6792   llassert (sRef_isReasonable (s));
6793   sRef_checkMutable (s);
6794 
6795   sRef_setPartsFromUentry (s, ue);
6796 
6797   s->aliaskind = alkind_derive (s->aliaskind, uentry_getAliasKind (ue));
6798   s->oaliaskind = s->aliaskind;
6799 
6800   if (s->expkind == XO_UNKNOWN)
6801     {
6802       s->expkind = uentry_getExpKind (ue);
6803     }
6804 
6805   s->oexpkind = s->expkind;
6806 }
6807 
6808 void
sRef_setStateFromUentry(sRef s,uentry ue)6809 sRef_setStateFromUentry (sRef s, uentry ue)
6810 {
6811   sstate defstate;
6812 
6813   sRef_checkMutable (s);
6814   llassert (sRef_isReasonable (s));
6815 
6816   sRef_setPartsFromUentry (s, ue);
6817 
6818   defstate = uentry_getDefState (ue);
6819 
6820   if (sstate_isKnown (defstate))
6821     {
6822       s->defstate = defstate;
6823     }
6824   else
6825     {
6826       ;
6827     }
6828 }
6829 
6830 /*@exposed@*/ sRef
sRef_buildPointer(sRef t)6831   sRef_buildPointer (/*@exposed@*/ sRef t)
6832 {
6833   DPRINTF (("build pointer: %s", sRef_unparse (t)));
6834 
6835   if (sRef_isInvalid (t)) return sRef_undefined;
6836 
6837   if (sRef_isAddress (t))
6838     {
6839       DPRINTF (("Return ref: %s", sRef_unparse (t->info->ref)));
6840       return (t->info->ref);
6841     }
6842   else
6843     {
6844       sRef s = sRef_findDerivedPointer (t);
6845 
6846       DPRINTF (("find derived: %s", sRef_unparse (s)));
6847 
6848       if (sRef_isReasonable (s))
6849 	{
6850 	  s->expkind = sRef_getExKind (t);
6851 	  s->expinfo = stateInfo_copy (t->expinfo);
6852 
6853 	  s->oaliaskind = s->aliaskind;
6854 	  s->oexpkind = s->expkind;
6855 
6856 	  return s;
6857 	}
6858       else
6859 	{
6860 	  s = sRef_constructPointerAux (t);
6861 
6862 	  DPRINTF (("construct: %s", sRef_unparse (s)));
6863 
6864 	  if (sRef_isReasonable (s))
6865 	    {
6866 	      sRef_addDeriv (t, s);
6867 
6868 	      s->oaliaskind = s->aliaskind;
6869 	      s->oexpkind = s->expkind;
6870 	    }
6871 
6872 	  return s;
6873 	}
6874     }
6875 }
6876 
6877 /*@exposed@*/ sRef
sRef_constructPointer(sRef t)6878 sRef_constructPointer (/*@exposed@*/ sRef t)
6879    /*@modifies t@*/
6880 {
6881   return sRef_buildPointer (t);
6882 }
6883 
sRef_constructDerefAux(sRef t,bool isdead)6884 static /*@exposed@*/ sRef sRef_constructDerefAux (sRef t, bool isdead)
6885 {
6886   if (sRef_isReasonable (t))
6887     {
6888       sRef s;
6889 
6890       /*
6891       ** if there is a derived t[?], return that.  Otherwise, *t.
6892       */
6893 
6894       s = sRef_findDerivedArrayFetch (t, FALSE, 0, isdead);
6895 
6896       if (sRef_isReasonable (s))
6897 	{
6898 	  DPRINTF (("Found array fetch: %s", sRef_unparseFull (s)));
6899 	  return s;
6900 	}
6901       else
6902 	{
6903 	  sRef ret = sRef_constructPointer (t);
6904 
6905 	  DPRINTF (("Constructed pointer: %s", sRef_unparseFull (ret)));
6906 
6907 	  return ret;
6908 	}
6909     }
6910   else
6911     {
6912       return sRef_undefined;
6913     }
6914 }
6915 
sRef_constructDeref(sRef t)6916 sRef sRef_constructDeref (sRef t)
6917 {
6918   return sRef_constructDerefAux (t, FALSE);
6919 }
6920 
sRef_constructDeadDeref(sRef t)6921 sRef sRef_constructDeadDeref (sRef t)
6922 {
6923   return sRef_constructDerefAux (t, TRUE);
6924 }
6925 
6926 static sRef
sRef_constructPointerAux(sRef t)6927 sRef_constructPointerAux (/*@notnull@*/ /*@exposed@*/ sRef t)
6928 {
6929   sRef s = sRef_newRef ();
6930   ctype rt = t->type;
6931   ctype st;
6932 
6933   llassert (valueTable_isUndefined (s->state));
6934 
6935   s->kind = SK_PTR;
6936   s->info = (sinfo) dmalloc (sizeof (*s->info));
6937   s->info->ref = t;
6938 
6939   if (ctype_isRealAP (rt))
6940     {
6941       s->type = ctype_baseArrayPtr (rt);
6942     }
6943 
6944   st = ctype_realType (s->type);
6945 
6946   if (t->defstate == SS_UNDEFINED)
6947     {
6948       s->defstate = SS_UNUSEABLE;
6949       s->definfo = stateInfo_copy (t->definfo);
6950     }
6951   else if ((t->defstate == SS_ALLOCATED) && !ctype_isSU (st))
6952     {
6953       s->defstate = SS_UNDEFINED;
6954       s->definfo = stateInfo_copy (t->definfo);
6955     }
6956   else
6957     {
6958       s->defstate = t->defstate;
6959       s->definfo = stateInfo_copy (t->definfo);
6960     }
6961 
6962   if (t->aliaskind == AK_LOCAL || t->aliaskind == AK_FRESH)
6963     {
6964       s->aliaskind = AK_LOCAL;
6965     }
6966   else
6967     {
6968       s->aliaskind = AK_UNKNOWN;
6969     }
6970 
6971   s->expkind = sRef_getExKind (t);
6972   s->expinfo = stateInfo_copy (t->expinfo);
6973 
6974   sRef_setTypeState (s);
6975 
6976   s->oaliaskind = s->aliaskind;
6977   s->oexpkind = s->expkind;
6978 
6979   if (valueTable_isUndefined (s->state))
6980     {
6981       s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_CREATED));
6982     }
6983 
6984   DPRINTF (("pointer: %s", sRef_unparseFull (s)));
6985   return s;
6986 }
6987 
sRef_hasDerived(sRef s)6988 bool sRef_hasDerived (sRef s)
6989 {
6990   return (sRef_isReasonable (s) && !sRefSet_isEmpty (s->deriv));
6991 }
6992 
6993 void
sRef_clearDerived(sRef s)6994 sRef_clearDerived (sRef s)
6995 {
6996   if (sRef_isReasonable (s))
6997     {
6998       DPRINTF (("Clear derived: [%p] %s", s, sRef_unparseDebug (s)));
6999       sRefSet_clear (s->deriv);
7000     }
7001 }
7002 
7003 void
sRef_clearDerivedComplete(sRef s)7004 sRef_clearDerivedComplete (sRef s)
7005 {
7006   if (sRef_isReasonable (s))
7007     {
7008       sRef base = sRef_getBaseSafe (s);
7009 
7010       while (sRef_isReasonable (base))
7011 	{
7012 	  DPRINTF (("Clear derived: [%p] %s", base, sRef_unparse (base)));
7013 	  sRefSet_clear (base->deriv);
7014 	  base = sRef_getBaseSafe (base);
7015 	}
7016 
7017       DPRINTF (("Clear derived: [%p] %s", s, sRef_unparse (s)));
7018       sRefSet_clear (s->deriv);
7019     }
7020 }
7021 
sRef_makePointer(sRef s)7022 /*@exposed@*/ sRef sRef_makePointer (/*@exposed@*/ sRef s)
7023      /*@modifies s@*/
7024 {
7025   sRef res = sRef_buildPointer (s);
7026 
7027   DPRINTF (("Res: %s", sRef_unparseFull (res)));
7028   return res;
7029 }
7030 
7031 /*
7032 ** &a[] => a (this is for out params)
7033 */
7034 
7035 /*@exposed@*/ sRef
sRef_makeAnyArrayFetch(sRef arr)7036 sRef_makeAnyArrayFetch (/*@exposed@*/ sRef arr)
7037 {
7038   if (sRef_isAddress (arr))
7039     {
7040       return (arr->info->ref);
7041     }
7042   else
7043     {
7044       return (sRef_buildArrayFetch (arr));
7045     }
7046 }
7047 
7048 /*@exposed@*/ sRef
sRef_makeArrayFetch(sRef arr)7049 sRef_makeArrayFetch (/*@exposed@*/ sRef arr)
7050 {
7051   return (sRef_buildArrayFetch (arr));
7052 }
7053 
7054 /*@exposed@*/ sRef
sRef_makeArrayFetchKnown(sRef arr,int i)7055 sRef_makeArrayFetchKnown (/*@exposed@*/ sRef arr, int i)
7056 {
7057   return (sRef_buildArrayFetchKnown (arr, i));
7058 }
7059 
7060 /*@exposed@*/ sRef
sRef_makeField(sRef rec,cstring f)7061 sRef_makeField (sRef rec, /*@dependent@*/ cstring f)
7062 {
7063   sRef ret;
7064   ret = sRef_buildField (rec, f);
7065   return ret;
7066 }
7067 
7068 /*@exposed@*/ sRef
sRef_makeNCField(sRef rec,cstring f)7069 sRef_makeNCField (/*@exposed@*/ sRef rec, /*@dependent@*/ cstring f)
7070 {
7071   return (sRef_buildNCField (rec, f));
7072 }
7073 
7074 /*@only@*/ cstring
sRef_unparseKindName(sRef s)7075 sRef_unparseKindName (sRef s)
7076 {
7077   cstring result;
7078 
7079   if (s == sRef_undefined) return cstring_makeLiteral ("<invalid>");
7080 
7081   s = sRef_fixConj (s);
7082 
7083   switch (s->kind)
7084     {
7085     case SK_CVAR:
7086       if (sRef_isLocalVar (s))
7087 	{
7088 	  result = cstring_makeLiteral ("Variable");
7089 	}
7090       else
7091 	{
7092 	  result = cstring_makeLiteral ("Undef global");
7093 	}
7094       break;
7095     case SK_PARAM:
7096       result = cstring_makeLiteral ("Out parameter");
7097       break;
7098     case SK_ARRAYFETCH:
7099       if (sRef_isAnyParam (s->info->arrayfetch->arr))
7100 	{
7101 	  result = cstring_makeLiteral ("Out parameter");
7102 	}
7103       else if (sRef_isIndexKnown (s))
7104 	{
7105 	  result = cstring_makeLiteral ("Array element");
7106 	}
7107       else
7108 	{
7109 	  result = cstring_makeLiteral ("Value");
7110 	}
7111       break;
7112     case SK_PTR:
7113       if (sRef_isAnyParam (s->info->ref))
7114 	{
7115 	  result = cstring_makeLiteral ("Out parameter");
7116 	}
7117       else
7118 	{
7119 	  result = cstring_makeLiteral ("Value");
7120 	}
7121       break;
7122     case SK_ADR:
7123       result = cstring_makeLiteral ("Value");
7124       break;
7125     case SK_FIELD:
7126       result = cstring_makeLiteral ("Field");
7127       break;
7128     case SK_OBJECT:
7129       result = cstring_makeLiteral ("Object");
7130       break;
7131     case SK_UNCONSTRAINED:
7132       result = cstring_makeLiteral ("<anything>");
7133       break;
7134     case SK_RESULT:
7135     case SK_SPECIAL:
7136     case SK_UNKNOWN:
7137     case SK_EXTERNAL:
7138     case SK_DERIVED:
7139     case SK_CONST:
7140     case SK_TYPE:
7141       result = cstring_makeLiteral ("<unknown>");
7142       break;
7143     case SK_CONJ:
7144       result = cstring_makeLiteral ("<conj>");
7145       break;
7146     case SK_NEW:
7147       result = cstring_makeLiteral ("Storage");
7148       break;
7149     }
7150 
7151   return result;
7152 }
7153 
7154 /*@only@*/ cstring
sRef_unparseKindNamePlain(sRef s)7155 sRef_unparseKindNamePlain (sRef s)
7156 {
7157   cstring result;
7158 
7159   if (s == sRef_undefined) return cstring_makeLiteral ("<invalid>");
7160 
7161   s = sRef_fixConj (s);
7162 
7163   switch (s->kind)
7164     {
7165     case SK_CVAR:
7166       if (sRef_isLocalVar (s))
7167 	{
7168 	  result = cstring_makeLiteral ("Variable");
7169 	}
7170       else
7171 	{
7172 	  result = cstring_makeLiteral ("Global");
7173 	}
7174       break;
7175     case SK_PARAM:
7176       result = cstring_makeLiteral ("Parameter");
7177       break;
7178     case SK_ARRAYFETCH:
7179       if (sRef_isAnyParam (s->info->arrayfetch->arr))
7180 	{
7181 	  result = cstring_makeLiteral ("Parameter");
7182 	}
7183       else if (sRef_isIndexKnown (s))
7184 	{
7185 	  result = cstring_makeLiteral ("Array element");
7186 	}
7187       else
7188 	{
7189 	  result = cstring_makeLiteral ("Value");
7190 	}
7191       break;
7192     case SK_PTR:
7193       if (sRef_isAnyParam (s->info->ref))
7194 	{
7195 	  result = cstring_makeLiteral ("Parameter");
7196 	}
7197       else
7198 	{
7199 	  result = cstring_makeLiteral ("Value");
7200 	}
7201       break;
7202     case SK_ADR:
7203       result = cstring_makeLiteral ("Value");
7204       break;
7205     case SK_FIELD:
7206       result = cstring_makeLiteral ("Field");
7207       break;
7208     case SK_OBJECT:
7209       result = cstring_makeLiteral ("Object");
7210       break;
7211     case SK_NEW:
7212       result = cstring_makeLiteral ("Storage");
7213       break;
7214     case SK_UNCONSTRAINED:
7215       result = cstring_makeLiteral ("<anything>");
7216       break;
7217     case SK_RESULT:
7218     case SK_TYPE:
7219     case SK_CONST:
7220     case SK_EXTERNAL:
7221     case SK_DERIVED:
7222     case SK_UNKNOWN:
7223     case SK_SPECIAL:
7224       result = cstring_makeLiteral ("<unknown>");
7225       break;
7226     case SK_CONJ:
7227       result = cstring_makeLiteral ("<conj>");
7228       break;
7229     }
7230 
7231   return result;
7232 }
7233 
7234 /*
7235 ** s1 <- s2
7236 */
7237 
7238 void
sRef_copyState(sRef s1,sRef s2)7239 sRef_copyState (sRef s1, sRef s2)
7240 {
7241   if (sRef_isReasonable (s1) && sRef_isReasonable (s2))
7242     {
7243       s1->defstate = s2->defstate;
7244 
7245       /* start modifications */
7246       s1->bufinfo.bufstate = s2->bufinfo.bufstate;
7247       s1->bufinfo.len = s2->bufinfo.len;
7248       s1->bufinfo.size = s2->bufinfo.size;
7249       /* end modifications */
7250 
7251       s1->aliaskind = s2->aliaskind;
7252       s1->aliasinfo = stateInfo_update (s1->aliasinfo, s2->aliasinfo);
7253 
7254       s1->expkind = s2->expkind;
7255       s1->expinfo = stateInfo_update (s1->expinfo, s2->expinfo);
7256 
7257       s1->nullstate = s2->nullstate;
7258       DPRINTF (("Set null state==> %s", sRef_unparseFull (s1)));
7259       s1->nullinfo = stateInfo_update (s1->nullinfo, s2->nullinfo);
7260 
7261       valueTable_free (s1->state);
7262       s1->state = valueTable_copy (s2->state);
7263       s1->safe = s2->safe;
7264     }
7265 }
7266 
7267 sRef
sRef_makeNew(ctype ct,sRef t,cstring name)7268 sRef_makeNew (ctype ct, sRef t, cstring name)
7269 {
7270   sRef s = sRef_newRef ();
7271 
7272   s->kind = SK_NEW;
7273   s->type = ct;
7274 
7275   llassert (sRef_isReasonable (t));
7276   s->defstate = t->defstate;
7277 
7278   s->aliaskind = t->aliaskind;
7279   s->oaliaskind = s->aliaskind;
7280   s->nullstate = t->nullstate;
7281 
7282   s->expkind = t->expkind;
7283   s->oexpkind = s->expkind;
7284 
7285   s->info = (sinfo) dmalloc (sizeof (*s->info));
7286   s->info->fname = name;
7287 
7288   /* start modifications */
7289   s->bufinfo.bufstate = t->bufinfo.bufstate;
7290   /* end modifications */
7291 
7292   llassert (valueTable_isUndefined (s->state));
7293   s->state = valueTable_copy (t->state);
7294 
7295   DPRINTF (("==> Copying state: %s", valueTable_unparse (s->state)));
7296   DPRINTF (("==> new: %s", sRef_unparseFull (s)));
7297   return s;
7298 }
7299 
7300 sRef
sRef_makeType(ctype ct)7301 sRef_makeType (ctype ct)
7302 {
7303   sRef s = sRef_newRef ();
7304 
7305   sRef_checkMutable (s);
7306 
7307   s->kind = SK_TYPE;
7308   s->type = ct;
7309 
7310   s->defstate = SS_UNKNOWN;
7311   s->aliaskind = AK_UNKNOWN;
7312   sRef_setNullStateN (s, NS_UNKNOWN);
7313 
7314   /* start modification */
7315   s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
7316   /* end modification */
7317 
7318 
7319   if (ctype_isUA (ct))
7320     {
7321       typeId uid = ctype_typeId (ct);
7322       uentry ue = usymtab_getTypeEntrySafe (uid);
7323 
7324       if (uentry_isValid (ue))
7325 	{
7326 	  sRef_mergeStateQuiet (s, uentry_getSref (ue));
7327 	}
7328     }
7329 
7330   s->oaliaskind = s->aliaskind;
7331   s->oexpkind = s->expkind;
7332   llassert (valueTable_isUndefined (s->state));
7333   s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_CREATED));
7334 
7335   DPRINTF (("Create: %s", sRef_unparseFull (s)));
7336   return s;
7337 }
7338 
7339 sRef
sRef_makeConst(ctype ct)7340 sRef_makeConst (ctype ct)
7341 {
7342   sRef s = sRef_newRef ();
7343 
7344   s->kind = SK_CONST;
7345   s->type = ct;
7346 
7347   s->defstate = SS_UNKNOWN;
7348   s->aliaskind = AK_UNKNOWN;
7349   sRef_setNullStateN (s, NS_UNKNOWN);
7350 
7351   /* start modification */
7352   s->bufinfo.bufstate = BB_NULLTERMINATED;
7353   /* end modification */
7354 
7355   /* evans 2002-04-22: added isManifestBool to avoid errors for -boolfalse initializations */
7356   if (!ctype_isManifestBool (ct) && ctype_isUA (ct))
7357     {
7358       typeId uid = ctype_typeId (ct);
7359       uentry te = usymtab_getTypeEntrySafe (uid);
7360 
7361       if (uentry_isValid (te))
7362 	{
7363 	  sRef_mergeStateQuiet (s, uentry_getSref (te));
7364 	}
7365     }
7366 
7367   s->oaliaskind = s->aliaskind;
7368   s->oexpkind = s->expkind;
7369 
7370   llassert (valueTable_isUndefined (s->state));
7371   s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_CREATED));
7372 
7373   return s;
7374 }
7375 
sRef_hasName(sRef s)7376 bool sRef_hasName (sRef s)
7377 {
7378   if (sRef_isInvalid (s))
7379     {
7380       return (FALSE);
7381     }
7382 
7383   switch (s->kind)
7384     {
7385     case SK_CVAR:
7386       {
7387 	uentry u = usymtab_getRefQuiet (s->info->cvar->lexlevel,
7388 					 s->info->cvar->index);
7389 	return (uentry_hasName (u));
7390       }
7391     case SK_PARAM:
7392       {
7393 	if (s->info->paramno >= 0)
7394 	  {
7395 	    uentry u = uentryList_getN (context_getParams (),
7396 					s->info->paramno);
7397 
7398 	    return (uentry_hasName (u));
7399 	  }
7400 	else
7401 	  {
7402 	    llassert (s->info->paramno == PARAMUNKNOWN);
7403 	    return FALSE;
7404 	  }
7405       }
7406     default:
7407       return TRUE;
7408     }
7409 }
7410 
7411 bool
sRef_sameName(sRef s1,sRef s2)7412 sRef_sameName (sRef s1, sRef s2)
7413 {
7414   if (sRef_isInvalid (s1))
7415     {
7416       return sRef_isInvalid (s2);
7417     }
7418 
7419   if (sRef_isInvalid (s2))
7420     {
7421       return (FALSE);
7422     }
7423 
7424   switch (s1->kind)
7425     {
7426     case SK_CVAR:
7427       if (s2->kind == SK_CVAR)
7428 	{
7429 	  return (s1->info->cvar->lexlevel == s2->info->cvar->lexlevel
7430 		  && s1->info->cvar->index == s2->info->cvar->index);
7431 	}
7432       else if (s2->kind == SK_PARAM)
7433 	{
7434 	  if (context_inFunctionLike ())
7435 	    {
7436 	      if (s2->info->paramno != PARAMUNKNOWN)
7437 		{
7438 		  uentry u1 = usymtab_getRefQuiet (s1->info->cvar->lexlevel,
7439 						   s1->info->cvar->index);
7440 		  uentry u2 = uentryList_getN (context_getParams (),
7441 					       s2->info->paramno);
7442 
7443 		  return (cstring_equalFree (uentry_getName (u1),
7444 					     uentry_getName (u2)));
7445 		}
7446 	      else
7447 		{
7448 		  return s1->info->paramno == PARAMUNKNOWN;
7449 		}
7450 	    }
7451 	  else
7452 	    {
7453 	      return FALSE;
7454 	    }
7455 	}
7456       else
7457 	{
7458 	  return FALSE;
7459 	}
7460     case SK_PARAM:
7461       {
7462 	if (s2->kind == SK_PARAM)
7463 	  {
7464 	    return (s1->info->paramno == s2->info->paramno);
7465 	  }
7466 	else if (s2->kind == SK_CVAR)
7467 	  {
7468 	    if (context_inFunctionLike ())
7469 	      {
7470 		if (s1->info->paramno == PARAMUNKNOWN)
7471 		  {
7472 		    return FALSE;
7473 		  }
7474 		else
7475 		  {
7476 		    uentry u1 = uentryList_getN (context_getParams (),
7477 						 s1->info->paramno);
7478 		    uentry u2 = usymtab_getRefQuiet (s2->info->cvar->lexlevel,
7479 						     s2->info->cvar->index);
7480 
7481 
7482 		    return (cstring_equalFree (uentry_getName (u1),
7483 					       uentry_getName (u2)));
7484 		  }
7485 	      }
7486 	    else
7487 	      {
7488 		return FALSE;
7489 	      }
7490 	  }
7491 	else
7492 	  {
7493 	    return FALSE;
7494 	  }
7495       }
7496 
7497     case SK_UNCONSTRAINED:
7498       return FALSE;
7499 
7500     case SK_ARRAYFETCH:
7501       if (s2->kind == SK_ARRAYFETCH)
7502 	{
7503 	  if (bool_equal (s1->info->arrayfetch->indknown,
7504 			  s2->info->arrayfetch->indknown))
7505 	    {
7506 	      if (!s1->info->arrayfetch->indknown
7507 		  || (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind))
7508 		{
7509 		  return sRef_sameName (s1->info->arrayfetch->arr,
7510 					s2->info->arrayfetch->arr);
7511 		}
7512 	    }
7513 	}
7514 
7515       return FALSE;
7516     case SK_FIELD:
7517       if (s2->kind == SK_FIELD)
7518 	{
7519 	  if (cstring_equal (s1->info->field->field,
7520 			     s2->info->field->field))
7521 	    {
7522 	      return sRef_sameName (s1->info->field->rec,
7523 				    s2->info->field->rec);
7524 	    }
7525 
7526 	}
7527       return FALSE;
7528     case SK_PTR:
7529     case SK_ADR:
7530     case SK_DERIVED:
7531     case SK_EXTERNAL:
7532       if (s2->kind == s1->kind)
7533 	{
7534 	  return sRef_sameName (s1->info->ref,
7535 				s2->info->ref);
7536 	}
7537 
7538       return FALSE;
7539     case SK_OBJECT:
7540       return FALSE;
7541     case SK_CONJ:
7542       return sRef_sameName (sRef_getConjA (s1), s2);
7543     case SK_NEW:
7544       return FALSE;
7545     case SK_UNKNOWN:
7546       return (s2->kind == SK_UNKNOWN);
7547     case SK_TYPE:
7548     case SK_CONST:
7549       if (s2->kind == s1->kind)
7550 	{
7551 	  return (ctype_equal (s1->type, s2->type));
7552 	}
7553 
7554       return FALSE;
7555     case SK_SPECIAL:
7556       if (s2->kind == SK_SPECIAL)
7557 	{
7558 	  return (s1->info->spec == s2->info->spec);
7559 	}
7560       return FALSE;
7561     case SK_RESULT:
7562       return (s2->kind == SK_RESULT);
7563     default:
7564       return FALSE;
7565     }
7566   BADEXIT;
7567 }
7568 
7569 sRef
sRef_fixOuterRef(sRef s)7570 sRef_fixOuterRef (/*@returned@*/ sRef s)
7571 {
7572   sRef root = sRef_getRootBase (s);
7573 
7574   if (sRef_isCvar (root))
7575     {
7576       uentry ue = usymtab_getRefQuiet (root->info->cvar->lexlevel,
7577 				       root->info->cvar->index);
7578 
7579       if (uentry_isValid (ue))
7580 	{
7581 	  sRef uref = uentry_getSref (ue);
7582 	  sRef sr = sRef_fixBase (s, uref);
7583 
7584 	  return (sr);
7585 	}
7586       else
7587 	{
7588 	  llcontbug (message ("sRef_fixOuterRef: undefined: %q", sRef_unparseDebug (s)));
7589 	  return (s);
7590 	}
7591     }
7592 
7593   return (s);
7594 }
7595 
7596 void
sRef_storeState(sRef s)7597 sRef_storeState (sRef s)
7598 {
7599   if (sRef_isInvalid (s)) return;
7600 
7601   sRef_checkMutable (s);
7602   s->oaliaskind = s->aliaskind;
7603   s->oexpkind = s->expkind;
7604 }
7605 
sRef_resetStateAux(sRef s,fileloc loc)7606 static void sRef_resetStateAux (sRef s, /*@unused@*/ fileloc loc)
7607 {
7608   sRef_resetState (s);
7609 }
7610 
7611 void
sRef_resetState(sRef s)7612 sRef_resetState (sRef s)
7613 {
7614   bool changed = FALSE;
7615   if (sRef_isInvalid (s)) return;
7616 
7617 
7618   if (s->oaliaskind == AK_KILLREF && !sRef_isParam (s))
7619     {
7620       /*
7621       ** killref is used in a kludgey way, to save having to add
7622       ** another alias kind (see usymtab_handleParams)
7623       */
7624 
7625       if (s->expkind != s->oexpkind)
7626 	{
7627 	  changed = TRUE;
7628 	  s->expkind = s->oexpkind;
7629 	}
7630     }
7631   else
7632     {
7633       if (s->expkind != s->oexpkind)
7634 	{
7635 	  changed = TRUE;
7636 	  s->expkind = s->oexpkind;
7637 	}
7638 
7639       if (s->aliaskind != s->oaliaskind
7640 	  && s->aliaskind != AK_REFCOUNTED
7641 	  && s->aliaskind != AK_REFS)
7642 	{
7643 	  changed = TRUE;
7644 	  s->aliaskind = s->oaliaskind;
7645 	}
7646     }
7647 
7648   if (changed)
7649     {
7650       sRef_clearDerived (s);
7651     }
7652 
7653   }
7654 
7655 void
sRef_resetStateComplete(sRef s)7656 sRef_resetStateComplete (sRef s)
7657 {
7658   sRef_innerAliasSetComplete (sRef_resetStateAux, s, fileloc_undefined);
7659 }
7660 
7661 /*@exposed@*/ sRef
sRef_fixBase(sRef s,sRef base)7662 sRef_fixBase (/*@returned@*/ sRef s, /*@returned@*/ sRef base)
7663 {
7664   sRef tmp = sRef_undefined;
7665   sRef ret;
7666 
7667   if (sRef_isInvalid (s)) return s;
7668   if (sRef_isInvalid (base)) return base;
7669 
7670   switch (s->kind)
7671     {
7672     case SK_RESULT:
7673     case SK_PARAM:
7674     case SK_CVAR:
7675       ret = base;
7676       break;
7677     case SK_ARRAYFETCH:
7678       tmp = sRef_fixBase (s->info->arrayfetch->arr, base);
7679 
7680       if (s->info->arrayfetch->indknown)
7681 	{
7682 	  ret = sRef_makeArrayFetchKnown (tmp, s->info->arrayfetch->ind);
7683 	}
7684       else
7685 	{
7686 	  ret = sRef_makeArrayFetch (tmp);
7687 	}
7688       break;
7689     case SK_FIELD:
7690       tmp = sRef_fixBase (s->info->field->rec, base);
7691       ret = sRef_buildNCField (tmp, s->info->field->field);
7692       break;
7693     case SK_PTR:
7694       tmp = sRef_fixBase (s->info->ref, base);
7695       ret = sRef_makePointer (tmp);
7696       break;
7697     case SK_ADR:
7698       tmp = sRef_fixBase (s->info->ref, base);
7699       ret = sRef_makeAddress (tmp);
7700       break;
7701     case SK_CONJ:
7702       {
7703 	sRef tmpb;
7704 
7705 	tmp = sRef_fixBase (s->info->conj->a, base);
7706 	tmpb = sRef_fixBase (s->info->conj->b, base);
7707 
7708 	ret = sRef_makeConj (tmp, tmpb);
7709 	break;
7710       }
7711       BADDEFAULT;
7712     }
7713 
7714   return ret;
7715 }
7716 
7717 static /*@exposed@*/ sRef
sRef_fixDirectBase(sRef s,sRef base)7718 sRef_fixDirectBase (sRef s, sRef base)
7719 {
7720   sRef ret;
7721 
7722 
7723   if (sRef_isInvalid (s))
7724     {
7725       return sRef_undefined;
7726     }
7727 
7728   switch (s->kind)
7729     {
7730     case SK_ARRAYFETCH:
7731       if (s->info->arrayfetch->indknown)
7732 	{
7733 	  ret = sRef_makeArrayFetchKnown (base, s->info->arrayfetch->ind);
7734 	}
7735       else
7736 	{
7737 	  ret = sRef_makeArrayFetch (base);
7738 	}
7739       break;
7740     case SK_FIELD:
7741       ret = sRef_buildNCField (base, s->info->field->field);
7742       break;
7743     case SK_PTR:
7744             ret = sRef_makePointer (base);
7745             break;
7746     case SK_ADR:
7747       ret = sRef_makeAddress (base);
7748       break;
7749     case SK_CONJ:
7750       {
7751 	sRef tmpa, tmpb;
7752 
7753 	tmpa = sRef_fixDirectBase (s->info->conj->a, base);
7754 	tmpb = sRef_fixDirectBase (s->info->conj->b, base);
7755 
7756 	ret = sRef_makeConj (tmpa, tmpb);
7757 	break;
7758       }
7759       BADDEFAULT;
7760     }
7761 
7762     sRef_copyState (ret, s);
7763     return ret;
7764 }
7765 
7766 bool
sRef_isAllocIndexRef(sRef s)7767 sRef_isAllocIndexRef (sRef s)
7768 {
7769   return (sRef_isArrayFetch (s) && !(s->info->arrayfetch->indknown)
7770 	  && sRef_isAllocated (s->info->arrayfetch->arr));
7771 }
7772 
7773 void
sRef_showRefLost(sRef s)7774 sRef_showRefLost (sRef s)
7775 {
7776   if (sRef_hasAliasInfoLoc (s))
7777     {
7778       llgenindentmsg (cstring_makeLiteral ("Original reference lost"),
7779 		      sRef_getAliasInfoLoc (s));
7780     }
7781 }
7782 
7783 void
sRef_showRefKilled(sRef s)7784 sRef_showRefKilled (sRef s)
7785 {
7786   if (sRef_isValid (s))
7787     {
7788       DPRINTF (("Killed: %s", sRef_unparseFull (s)));
7789       if (context_getLocIndentSpaces () == 0) {
7790 	stateInfo_display (s->definfo, message ("  Storage %q", sRef_unparseOpt (s)));
7791       } else {
7792 	stateInfo_display (s->definfo, message ("Storage %q", sRef_unparseOpt (s)));
7793       }
7794     }
7795 }
7796 
7797 void
sRef_showStateInconsistent(sRef s)7798 sRef_showStateInconsistent (sRef s)
7799 {
7800   if (sRef_hasStateInfoLoc (s))
7801     {
7802       llgenindentmsg
7803 	(message ("Storage %qbecomes inconsistent (released on one branch)",
7804 		  sRef_unparseOpt (s)),
7805 	 sRef_getStateInfoLoc (s));
7806     }
7807 }
7808 
7809 void
sRef_showStateInfo(sRef s)7810 sRef_showStateInfo (sRef s)
7811 {
7812   if (sRef_isValid (s)) {
7813     if (context_getLocIndentSpaces () == 0) {
7814       stateInfo_display (s->definfo, message ("   Storage %q", sRef_unparseOpt (s)));
7815     } else {
7816       stateInfo_display (s->definfo, message ("Storage %q", sRef_unparseOpt (s)));
7817     }
7818   }
7819 }
7820 
7821 void
sRef_showExpInfo(sRef s)7822 sRef_showExpInfo (sRef s)
7823 {
7824   if (sRef_isValid (s)) {
7825     if (context_getLocIndentSpaces () == 0) {
7826       stateInfo_display (s->expinfo, message ("   Storage %q", sRef_unparseOpt (s)));
7827     } else {
7828       stateInfo_display (s->expinfo, message ("Storage %q", sRef_unparseOpt (s)));
7829     }
7830   }
7831 }
7832 
7833 void
sRef_showMetaStateInfo(sRef s,cstring key)7834 sRef_showMetaStateInfo (sRef s, cstring key)
7835 {
7836   stateValue val;
7837   metaStateInfo minfo = context_lookupMetaStateInfo (key);
7838 
7839   llassert (sRef_isReasonable (s));
7840   llassert (valueTable_isDefined (s->state));
7841   llassert (metaStateInfo_isDefined (minfo));
7842 
7843   val = valueTable_lookup (s->state, key);
7844 
7845   if (stateValue_hasLoc (val))
7846     {
7847       llgenindentmsg
7848 	(message ("%qbecomes %q", sRef_unparseOpt (s),
7849 		  stateValue_unparseValue (val, minfo)),
7850 	 stateValue_getLoc (val));
7851     }
7852 }
7853 
7854 void
sRef_showNullInfo(sRef s)7855 sRef_showNullInfo (sRef s)
7856 {
7857   DPRINTF (("Show null info: %s", sRef_unparseFull (s)));
7858 
7859   if (sRef_hasNullInfoLoc (s) && sRef_isKnown (s))
7860     {
7861       DPRINTF (("has null info: %s",
7862 		fileloc_unparse (sRef_getNullInfoLoc (s))));
7863 
7864       switch (sRef_getNullState (s))
7865 	{
7866 	case NS_CONSTNULL:
7867 	  {
7868 	    fileloc loc = sRef_getNullInfoLoc (s);
7869 
7870 	    if (fileloc_isDefined (loc) && !fileloc_isLib (loc))
7871 	      {
7872 		llgenindentmsg
7873 		  (message ("Storage %qbecomes null", sRef_unparseOpt (s)),
7874 		   loc);
7875 	      }
7876 	    break;
7877 	  }
7878 	case NS_DEFNULL:
7879 	  {
7880 	    fileloc loc = sRef_getNullInfoLoc (s);
7881 
7882 	    if (fileloc_isDefined (loc) && !fileloc_isLib (loc))
7883 	      {
7884 		llgenindentmsg (message ("Storage %qbecomes null", sRef_unparseOpt (s)),
7885 				loc);
7886 	      }
7887 	    break;
7888 	  }
7889 	case NS_ABSNULL:
7890 	case NS_POSNULL:
7891 	  llgenindentmsg
7892 	    (message ("Storage %qmay become null", sRef_unparseOpt (s)),
7893 	     sRef_getNullInfoLoc (s));
7894 	  break;
7895 	case NS_NOTNULL:
7896 	case NS_MNOTNULL:
7897 	  llgenindentmsg
7898 	    (message ("Storage %qbecomes not null", sRef_unparseOpt (s)),
7899 	     sRef_getNullInfoLoc (s));
7900 	  break;
7901 	case NS_UNKNOWN:
7902 	  llgenindentmsg
7903 	    (message ("Storage %qnull state becomes unknown",
7904 		      sRef_unparseOpt (s)),
7905 	     sRef_getNullInfoLoc (s));
7906 	  break;
7907 
7908 	case NS_ERROR:
7909 	  BADBRANCHCONT;
7910 	  break;
7911 
7912 	default:
7913 	  llgenindentmsg
7914 	    (message ("<error case> Storage %q becomes %s",
7915 		      sRef_unparse (s),
7916 		      nstate_unparse (sRef_getNullState (s))),
7917 	     sRef_getNullInfoLoc (s));
7918 
7919 	  break;
7920 	}
7921     }
7922 }
7923 
7924 void
sRef_showAliasInfo(sRef s)7925 sRef_showAliasInfo (sRef s)
7926 {
7927   if (sRef_isValid (s))
7928     {
7929       if (sRef_isFresh (s))
7930 	{
7931 	  if (context_getLocIndentSpaces () == 0) {
7932 	    stateInfo_display (s->aliasinfo, message ("   Fresh storage %q", sRef_unparseOpt (s)));
7933 	  } else {
7934 	    stateInfo_display (s->aliasinfo, message ("Fresh storage %q", sRef_unparseOpt (s)));
7935 	  }
7936 	}
7937       else
7938 	{
7939 	  if (context_getLocIndentSpaces () == 0) {
7940 	    stateInfo_display (s->aliasinfo, message ("   Storage %q", sRef_unparseOpt (s)));
7941 	  } else {
7942 	    stateInfo_display (s->aliasinfo, message ("Storage %q", sRef_unparseOpt (s)));
7943 	  }
7944 	}
7945     }
7946 }
7947 
7948 void
sRef_mergeNullState(sRef s,nstate n)7949 sRef_mergeNullState (sRef s, nstate n)
7950 {
7951   if (sRef_isReasonable (s))
7952     {
7953       nstate old;
7954 
7955       old = sRef_getNullState (s);
7956 
7957       if (n != old && n != NS_UNKNOWN)
7958 	{
7959 	  sRef_setNullState (s, n, g_currentloc);
7960 	}
7961     }
7962   else
7963     {
7964       llbuglit ("sRef_mergeNullState: invalid");
7965     }
7966 }
7967 
7968 bool
sRef_possiblyNull(sRef s)7969 sRef_possiblyNull (sRef s)
7970 {
7971   if (sRef_isReasonable (s))
7972     {
7973       if (sRef_getNullState (s) == NS_ABSNULL)
7974 	{
7975 	  ctype rct = ctype_realType (s->type);
7976 
7977 	  if (ctype_isAbstract (rct))
7978 	    {
7979 	      return FALSE;
7980 	    }
7981 	  else
7982 	    {
7983 	      if (ctype_isUser (rct))
7984 		{
7985 		  uentry ue = usymtab_getTypeEntry (ctype_typeId (rct));
7986 
7987 		  return (nstate_possiblyNull
7988 			  (sRef_getNullState (uentry_getSref (ue))));
7989 		}
7990 	      else
7991 		{
7992 		  return FALSE;
7993 		}
7994 	    }
7995 	}
7996       else
7997 	{
7998 	  return nstate_possiblyNull (sRef_getNullState (s));
7999 	}
8000     }
8001 
8002   return FALSE;
8003 }
8004 
8005 cstring
sRef_getScopeName(sRef s)8006 sRef_getScopeName (sRef s)
8007 {
8008   sRef base = sRef_getRootBase (s);
8009 
8010   if (sRef_isRealGlobal (base))
8011     {
8012       return (cstring_makeLiteralTemp ("Global"));
8013     }
8014   else if (sRef_isFileStatic (base))
8015     {
8016       return (cstring_makeLiteralTemp ("Static"));
8017     }
8018   else
8019     {
8020       return (cstring_makeLiteralTemp ("Local"));
8021     }
8022 }
8023 
8024 cstring
sRef_unparseScope(sRef s)8025 sRef_unparseScope (sRef s)
8026 {
8027   sRef base = sRef_getRootBase (s);
8028 
8029   if (sRef_isRealGlobal (base))
8030     {
8031       return (cstring_makeLiteralTemp ("global"));
8032     }
8033   else if (sRef_isFileStatic (base))
8034     {
8035       return (cstring_makeLiteralTemp ("file static"));
8036     }
8037   else
8038     {
8039       BADEXIT;
8040     }
8041 }
8042 
8043 int
sRef_getScope(sRef s)8044 sRef_getScope (sRef s)
8045 {
8046   llassert (sRef_isReasonable (s));
8047 
8048   if (sRef_isCvar (s))
8049     {
8050       return s->info->cvar->lexlevel;
8051     }
8052   else if (sRef_isParam (s))
8053     {
8054       return paramsScope;
8055     }
8056   else
8057     {
8058       return fileScope;
8059     }
8060 }
8061 
8062 bool
sRef_isDead(sRef s)8063 sRef_isDead (sRef s)
8064 {
8065   return (sRef_isReasonable (s) && (s)->defstate == SS_DEAD);
8066 }
8067 
8068 bool
sRef_isDeadStorage(sRef s)8069 sRef_isDeadStorage (sRef s)
8070 {
8071   if (sRef_isReasonable (s))
8072     {
8073       if (s->defstate == SS_DEAD
8074 	  || s->defstate == SS_UNUSEABLE
8075 	  || s->defstate == SS_UNDEFINED
8076 	  || s->defstate == SS_UNKNOWN)
8077 	{
8078 	  return TRUE;
8079 	}
8080       else
8081 	{
8082 	  return (sRef_isDefinitelyNull (s));
8083 	}
8084     }
8085   else
8086     {
8087       return FALSE;
8088     }
8089 }
8090 
8091 bool
sRef_isPossiblyDead(sRef s)8092 sRef_isPossiblyDead (sRef s)
8093 {
8094   return (sRef_isReasonable (s) && s->defstate == SS_HOFFA);
8095 }
8096 
sRef_isStateLive(sRef s)8097 bool sRef_isStateLive (sRef s)
8098 {
8099   if (sRef_isReasonable (s))
8100     {
8101       sstate ds = s->defstate;
8102 
8103       return (!(ds == SS_UNDEFINED
8104 		|| ds == SS_DEAD
8105 		|| ds == SS_UNUSEABLE
8106 		|| ds == SS_HOFFA));
8107     }
8108   else
8109     {
8110       return FALSE;
8111     }
8112 }
8113 
8114 
sRef_isStateUndefined(sRef s)8115 bool sRef_isStateUndefined (sRef s)
8116 {
8117   return ((sRef_isReasonable(s)) && ((s)->defstate == SS_UNDEFINED));
8118 }
8119 
sRef_isJustAllocated(sRef s)8120 bool sRef_isJustAllocated (sRef s)
8121 {
8122   if (sRef_isAllocated (s))
8123     {
8124       sRefSet_allElements (s->deriv, el)
8125 	{
8126 	  if (!(sRef_isStateUndefined (el) || sRef_isUnuseable (el)))
8127 	    {
8128 	      return FALSE;
8129 	    }
8130 	} end_sRefSet_allElements ;
8131 
8132       return TRUE;
8133     }
8134 
8135   return FALSE;
8136 }
8137 
8138 static bool
sRef_isAllocatedStorage(sRef s)8139 sRef_isAllocatedStorage (sRef s)
8140 {
8141   if (sRef_isReasonable (s) && ynm_toBoolStrict (sRef_isValidLvalue (s)))
8142     {
8143       return (ctype_isVisiblySharable (sRef_getType (s)));
8144     }
8145   else
8146     {
8147       return FALSE;
8148     }
8149 }
8150 
8151 bool
sRef_isUnuseable(sRef s)8152 sRef_isUnuseable (sRef s)
8153 {
8154   return ((sRef_isValid(s)) && ((s)->defstate == SS_UNUSEABLE));
8155 }
8156 
8157 bool
sRef_perhapsNull(sRef s)8158 sRef_perhapsNull (sRef s)
8159 {
8160   if (sRef_isReasonable (s))
8161     {
8162       if (sRef_getNullState (s) == NS_ABSNULL)
8163 	{
8164 	  ctype rct = ctype_realType (s->type);
8165 
8166 	  if (ctype_isAbstract (rct))
8167 	    {
8168 	      return FALSE;
8169 	    }
8170 	  else
8171 	    {
8172 	      if (ctype_isUser (rct))
8173 		{
8174 		  uentry ue = usymtab_getTypeEntry (ctype_typeId (rct));
8175 
8176 		  return (nstate_perhapsNull
8177 			  (sRef_getNullState (uentry_getSref (ue))));
8178 		}
8179 	      else
8180 		{
8181 		  return FALSE;
8182 		}
8183 	    }
8184 	}
8185       else
8186 	{
8187 	  return nstate_perhapsNull (sRef_getNullState (s));
8188 	}
8189     }
8190 
8191   return FALSE;
8192 }
8193 
8194 /*
8195 ** definitelyNull --- called when TRUE is good
8196 */
8197 
8198 bool
sRef_definitelyNull(sRef s)8199 sRef_definitelyNull (sRef s)
8200 {
8201   return (sRef_isReasonable (s)
8202 	  && (sRef_getNullState (s) == NS_DEFNULL || sRef_getNullState (s) == NS_CONSTNULL));
8203 }
8204 
8205 /*
8206 ** based on sRef_similar
8207 */
8208 
8209 void
sRef_setDerivNullState(sRef set,sRef guide,nstate ns)8210 sRef_setDerivNullState (sRef set, sRef guide, nstate ns)
8211 {
8212   if (sRef_isReasonable (set))
8213     {
8214       sRef deriv = sRef_getDeriv (set, guide);
8215 
8216       if (sRef_isReasonable (deriv))
8217 	{
8218 	  sRef_setNullStateN (deriv, ns);
8219 	}
8220     }
8221 }
8222 
8223 static /*@exposed@*/ sRef
sRef_getDeriv(sRef set,sRef guide)8224 sRef_getDeriv (/*@returned@*/ /*@notnull@*/ sRef set, sRef guide)
8225 {
8226   llassert (sRef_isReasonable (set));
8227   llassert (sRef_isReasonable (guide));
8228 
8229   switch (guide->kind)
8230     {
8231     case SK_CVAR:
8232       llassert (set->kind == SK_CVAR);
8233       return set;
8234 
8235     case SK_PARAM:
8236       llassert (set->kind == guide->kind);
8237       llassert (set->info->paramno == guide->info->paramno);
8238       return set;
8239 
8240     case SK_ARRAYFETCH:
8241 
8242       if (set->kind == SK_ARRAYFETCH
8243 	  && (sRef_similar (set->info->arrayfetch->arr,
8244 			    guide->info->arrayfetch->arr)))
8245 	{
8246 	  return set;
8247 	}
8248       else
8249 	{
8250 	  return (sRef_makeAnyArrayFetch
8251 		  (sRef_getDeriv (set, guide->info->arrayfetch->arr)));
8252 	}
8253 
8254     case SK_PTR:
8255 
8256       if (set->kind == SK_PTR && sRef_similar (set->info->ref, guide->info->ref))
8257 	{
8258 	  return set;
8259 	}
8260       else
8261 	{
8262 	  return (sRef_makePointer (sRef_getDeriv (set, guide->info->ref)));
8263 	}
8264 
8265     case SK_FIELD:
8266 
8267       if ((set->kind == SK_FIELD &&
8268 	   (sRef_similar (set->info->field->rec, guide->info->field->rec) &&
8269 	    cstring_equal (set->info->field->field, guide->info->field->field))))
8270 	{
8271 	  return set;
8272 	}
8273       else
8274 	{
8275 	  return (sRef_makeField (sRef_getDeriv (set, guide->info->field->rec),
8276 				  guide->info->field->field));
8277 	}
8278     case SK_ADR:
8279 
8280       if ((set->kind == SK_ADR) && sRef_similar (set->info->ref, guide->info->ref))
8281 	{
8282 	  return set;
8283 	}
8284       else
8285 	{
8286 	  return (sRef_makeAddress (sRef_getDeriv (set, guide->info->ref)));
8287 	}
8288 
8289     case SK_CONJ:
8290 
8291             return sRef_undefined;
8292 
8293     case SK_RESULT:
8294     case SK_SPECIAL:
8295     case SK_UNCONSTRAINED:
8296     case SK_TYPE:
8297     case SK_CONST:
8298     case SK_NEW:
8299     case SK_UNKNOWN:
8300     case SK_OBJECT:
8301     case SK_DERIVED:
8302     case SK_EXTERNAL:
8303       return sRef_undefined;
8304     }
8305 
8306   BADEXIT;
8307 }
8308 
8309 /*
8310 ** sRef_aliasCheckPred
8311 **
8312 ** A confusing but spiffy function:
8313 **
8314 **    Calls predf (s, e, text, <alias>) on s and all of s's aliases
8315 **    (unless checkAliases (s) is FALSE).
8316 **
8317 **    For alias calls, calls as
8318 **          predf (alias, e, text, s)
8319 */
8320 
8321 void
sRef_aliasCheckPred(bool (predf)(sRef,exprNode,sRef,exprNode),bool (checkAliases)(sRef),sRef s,exprNode e,exprNode err)8322 sRef_aliasCheckPred (bool (predf) (sRef, exprNode, sRef, exprNode),
8323 		     /*@null@*/ bool (checkAliases) (sRef),
8324 		     sRef s, exprNode e, exprNode err)
8325 {
8326   bool error = (*predf)(s, e, sRef_undefined, err);
8327 
8328 
8329   if (checkAliases != NULL && !(checkAliases (s)))
8330     {
8331       /* don't check aliases */
8332     }
8333   else
8334     {
8335       sRefSet aliases = usymtab_allAliases (s);
8336 
8337       sRefSet_realElements (aliases, current)
8338 	{
8339 	  if (sRef_isReasonable (current))
8340 	    {
8341 	      if (sRef_isReasonable (current))
8342 		{
8343 		  if (!sRef_similar (current, s)
8344 		      || (error && sRef_sameName (current, s)))
8345 		    {
8346 		      (void) (*predf)(current, e, s, err);
8347 		    }
8348 		}
8349 	      else
8350 		{
8351 		  llcontbug (message ("Invalid sRef as alias field of %s", sRef_unparse (s)));
8352 		}
8353 	    }
8354 	} end_sRefSet_realElements;
8355 
8356       sRefSet_free (aliases);
8357     }
8358 }
8359 
8360 /*
8361 ** return TRUE iff predf (s) is true for s or any alias of s
8362 */
8363 
8364 bool
sRef_aliasCheckSimplePred(sRefTest predf,sRef s)8365 sRef_aliasCheckSimplePred (sRefTest predf, sRef s)
8366 {
8367 
8368   if ((*predf)(s))
8369     {
8370       return TRUE;
8371     }
8372   else
8373     {
8374       sRefSet aliases;
8375 
8376       aliases = usymtab_allAliases (s);
8377 
8378       sRefSet_realElements (aliases, current)
8379 	{
8380 	  if (sRef_isReasonable (current))
8381 	    {
8382 	      sRef cref = sRef_updateSref (current);
8383 
8384 	      /* Whoa! a very kludgey way to make sure the right sref is used
8385 	      ** where there is a conditional symbol table.  I am beginning
8386 	      ** to think that having a conditional symbol table wasn't such
8387 	      ** a great idea.  ;(
8388 	      */
8389 
8390 	      if ((*predf)(cref))
8391 		{
8392 		  DPRINTF (("Checking alias: %s", sRef_unparseFull (cref)));
8393 		  sRefSet_free (aliases);
8394 		  return TRUE;
8395 		}
8396 	    }
8397 	} end_sRefSet_realElements;
8398 
8399       sRefSet_free (aliases);
8400     }
8401   return FALSE;
8402 }
8403 
8404 bool
sRef_aliasCompleteSimplePred(bool (predf)(sRef),sRef s)8405 sRef_aliasCompleteSimplePred (bool (predf) (sRef), sRef s)
8406 {
8407   sRefSet aliases;
8408   bool result = FALSE;
8409 
8410 
8411   aliases = usymtab_allAliases (s);
8412 
8413   if ((*predf)(s)) result = TRUE;
8414 
8415 
8416   sRefSet_realElements (aliases, current)
8417     {
8418       if (sRef_isReasonable (current))
8419 	{
8420 	  current = sRef_updateSref (current);
8421 	  if ((*predf)(current)) result = TRUE;
8422 	}
8423     } end_sRefSet_realElements;
8424 
8425   sRefSet_free (aliases);
8426   return result;
8427 }
8428 
8429 void
sRef_aliasSetComplete(void (predf)(sRef,fileloc),sRef s,fileloc loc)8430 sRef_aliasSetComplete (void (predf) (sRef, fileloc), sRef s, fileloc loc)
8431 {
8432   sRefSet aliases;
8433 
8434   aliases = usymtab_allAliases (s);
8435 
8436   DPRINTF (("All aliases: %s --> %s", sRef_unparseFull (s), sRefSet_unparseFull (aliases)));
8437 
8438   (*predf)(s, loc);
8439 
8440   sRefSet_realElements (aliases, current)
8441     {
8442       if (sRef_isReasonable (current))
8443 	{
8444 	  DPRINTF (("Update: %s", sRef_unparseFull (current)));
8445 	  current = sRef_updateSref (current);
8446 	  DPRINTF (("Updated ==> %s", sRef_unparseFull (current)));
8447 	  ((*predf)(current, loc));
8448 	  DPRINTF (("Killed: %s", sRef_unparseFull (current)));
8449 	}
8450     } end_sRefSet_realElements;
8451 
8452   sRefSet_free (aliases);
8453 }
8454 
8455 void
sRef_aliasSetCompleteParam(void (predf)(sRef,int,fileloc),sRef s,int kind,fileloc loc)8456 sRef_aliasSetCompleteParam (void (predf) (sRef, int, fileloc), sRef s,
8457 			    int kind, fileloc loc)
8458 {
8459   sRefSet aliases;
8460 
8461   if (sRef_isDeep (s))
8462     {
8463       aliases = usymtab_allAliases (s);
8464     }
8465   else
8466     {
8467       aliases = usymtab_aliasedBy (s);
8468     }
8469 
8470   (*predf)(s, kind, loc);
8471 
8472   sRefSet_realElements (aliases, current)
8473     {
8474       if (sRef_isReasonable (current))
8475 	{
8476 	  current = sRef_updateSref (current);
8477 	  ((*predf)(current, kind, loc));
8478 	}
8479     } end_sRefSet_realElements;
8480 
8481   sRefSet_free (aliases);
8482 }
8483 
8484 /*
8485 ** Version of aliasSetCompleteParam for alkind parameters
8486 */
8487 
8488 void
sRef_aliasSetCompleteAlkParam(void (predf)(sRef,alkind,fileloc),sRef s,alkind kind,fileloc loc)8489 sRef_aliasSetCompleteAlkParam (void (predf) (sRef, alkind, fileloc), sRef s,
8490 			       alkind kind, fileloc loc)
8491 {
8492   sRefSet aliases;
8493 
8494   if (sRef_isDeep (s))
8495     {
8496       aliases = usymtab_allAliases (s);
8497     }
8498   else
8499     {
8500       aliases = usymtab_aliasedBy (s);
8501     }
8502 
8503   (*predf)(s, kind, loc);
8504 
8505   sRefSet_realElements (aliases, current)
8506     {
8507       if (sRef_isReasonable (current))
8508 	{
8509 	  current = sRef_updateSref (current);
8510 	  ((*predf)(current, kind, loc));
8511 	}
8512     } end_sRefSet_realElements;
8513 
8514   sRefSet_free (aliases);
8515 }
8516 
8517 static void
sRef_innerAliasSetComplete(void (predf)(sRef,fileloc),sRef s,fileloc loc)8518 sRef_innerAliasSetComplete (void (predf) (sRef, fileloc), sRef s, fileloc loc)
8519 {
8520   sRef inner;
8521   sRefSet aliases;
8522   ctype ct;
8523 
8524   if (!sRef_isReasonable (s)) return;
8525 
8526   /*
8527   ** Type equivalence checking is necessary --- there might be casting.
8528   */
8529 
8530   (*predf)(s, loc);
8531 
8532   switch (s->kind)
8533     {
8534     case SK_UNCONSTRAINED:
8535     case SK_CVAR:
8536     case SK_PARAM:
8537       break;
8538     case SK_PTR:
8539       inner = s->info->ref;
8540       aliases = usymtab_allAliases (inner);
8541       ct = sRef_getType (inner);
8542 
8543       sRefSet_realElements (aliases, current)
8544 	{
8545 	  if (sRef_isReasonable (current))
8546 	    {
8547 	      current = sRef_updateSref (current);
8548 
8549 	      if (ctype_equal (ct, sRef_getType (current)))
8550 		{
8551 		  sRef ptr = sRef_makePointer (current);
8552 		  ((*predf)(ptr, loc));
8553 		}
8554 	    }
8555 	} end_sRefSet_realElements;
8556 
8557       sRefSet_free (aliases);
8558       break;
8559     case SK_ARRAYFETCH:
8560       inner = s->info->arrayfetch->arr;
8561       aliases = usymtab_allAliases (inner);
8562       ct = sRef_getType (inner);
8563 
8564       DPRINTF (("Array fetch: %s", sRefSet_unparse (aliases)));
8565 
8566       sRefSet_realElements (aliases, current)
8567 	{
8568 	  if (sRef_isReasonable (current))
8569 	    {
8570 	      current = sRef_updateSref (current);
8571 	      DPRINTF (("Current: %s", sRef_unparseFull (current)));
8572 
8573 	      if (ctype_equal (ct, sRef_getType (current)))
8574 		{
8575 		  if (s->info->arrayfetch->indknown)
8576 		    {
8577 		      sRef af = sRef_makeArrayFetchKnown (current, s->info->arrayfetch->ind);
8578 		      DPRINTF (("Defining: %s", sRef_unparseFull (af)));
8579 		      /* evans 2001-08-27 This isn't true:
8580 			   llassert (af->info->arrayfetch->arr == current);
8581 			 see comments in buildArrayFetchKnown
8582 		      */
8583 		      ((*predf)(af, loc));
8584 		    }
8585 		  else
8586 		    {
8587 		      sRef af = sRef_makeArrayFetch (current);
8588 		      /* evans 2001-08-27 This isn't true:
8589 			 llassert (af->info->arrayfetch->arr == current);
8590 			 see comments in buildArrayFetch
8591 		      */
8592 		      DPRINTF (("Defining: %s", sRef_unparseFull (af)));
8593 		      ((*predf)(af, loc));
8594 		    }
8595 		}
8596 	      else
8597 		{
8598 		  DPRINTF (("Type mismatch: %s / %s",
8599 			    ctype_unparse (ct),
8600 			    ctype_unparse (sRef_getType (current))));
8601 		}
8602 	    }
8603 	} end_sRefSet_realElements;
8604 
8605       sRefSet_free (aliases);
8606       break;
8607     case SK_FIELD:
8608       inner = s->info->field->rec;
8609       aliases = usymtab_allAliases (inner);
8610       ct = sRef_getType (inner);
8611 
8612       sRefSet_realElements (aliases, current)
8613 	{
8614 	  if (sRef_isReasonable (current))
8615 	    {
8616 	      current = sRef_updateSref (current);
8617 
8618 	      if (ctype_equal (ct, sRef_getType (current)))
8619 		{
8620 		  sRef f = sRef_makeField (current, s->info->field->field);
8621 
8622 		  ((*predf)(f, loc));
8623 		}
8624 	    }
8625 	} end_sRefSet_realElements;
8626 
8627       sRefSet_free (aliases);
8628       break;
8629     case SK_CONJ:
8630       sRef_innerAliasSetComplete (predf, s->info->conj->a, loc);
8631       sRef_innerAliasSetComplete (predf, s->info->conj->b, loc);
8632       break;
8633     case SK_SPECIAL:
8634     case SK_ADR:
8635     case SK_TYPE:
8636     case SK_CONST:
8637     case SK_NEW:
8638     case SK_UNKNOWN:
8639     case SK_OBJECT:
8640     case SK_DERIVED:
8641     case SK_EXTERNAL:
8642     case SK_RESULT:
8643       break;
8644     }
8645 }
8646 
8647 static void
sRef_innerAliasSetCompleteParam(void (predf)(sRef,sRef),sRef s,sRef t)8648 sRef_innerAliasSetCompleteParam (void (predf) (sRef, sRef), sRef s, sRef t)
8649 {
8650   sRef inner;
8651   sRefSet aliases;
8652   ctype ct;
8653 
8654   if (!sRef_isReasonable (s)) return;
8655 
8656   /*
8657   ** Type equivalence checking is necessary --- there might be casting.
8658   */
8659 
8660   (*predf)(s, t);
8661 
8662   switch (s->kind)
8663     {
8664     case SK_UNCONSTRAINED:
8665     case SK_CVAR:
8666     case SK_PARAM:
8667       break;
8668     case SK_PTR:
8669       inner = s->info->ref;
8670       aliases = usymtab_allAliases (inner);
8671       ct = sRef_getType (inner);
8672 
8673       sRefSet_realElements (aliases, current)
8674 	{
8675 	  if (sRef_isReasonable (current))
8676 	    {
8677 	      current = sRef_updateSref (current);
8678 
8679 	      if (ctype_equal (ct, sRef_getType (current)))
8680 		{
8681 		  sRef ptr = sRef_makePointer (current);
8682 
8683 		  ((*predf)(ptr, t));
8684 		}
8685 	    }
8686 	} end_sRefSet_realElements;
8687 
8688       sRefSet_free (aliases);
8689       break;
8690     case SK_ARRAYFETCH:
8691       inner = s->info->arrayfetch->arr;
8692       aliases = usymtab_allAliases (inner);
8693       ct = sRef_getType (inner);
8694 
8695       sRefSet_realElements (aliases, current)
8696 	{
8697 	  if (sRef_isReasonable (current))
8698 	    {
8699 	      current = sRef_updateSref (current);
8700 
8701 	      if (ctype_equal (ct, sRef_getType (current)))
8702 		{
8703 
8704 		  if (s->info->arrayfetch->indknown)
8705 		    {
8706 		      sRef af = sRef_makeArrayFetchKnown (current, s->info->arrayfetch->ind);
8707 
8708 		      ((*predf)(af, t));
8709 		    }
8710 		  else
8711 		    {
8712 		      sRef af = sRef_makeArrayFetch (current);
8713 
8714 		      ((*predf)(af, t));
8715 		    }
8716 		}
8717 	    }
8718 	} end_sRefSet_realElements;
8719 
8720       sRefSet_free (aliases);
8721       break;
8722     case SK_FIELD:
8723       inner = s->info->field->rec;
8724       aliases = usymtab_allAliases (inner);
8725       ct = sRef_getType (inner);
8726 
8727 
8728       sRefSet_realElements (aliases, current)
8729 	{
8730 	  if (sRef_isReasonable (current))
8731 	    {
8732 	      current = sRef_updateSref (current);
8733 
8734 	      if (ctype_equal (ct, sRef_getType (current)))
8735 		{
8736 		  sRef f = sRef_makeField (current, s->info->field->field);
8737 
8738 		  ((*predf)(f, t));
8739 		}
8740 	    }
8741 	} end_sRefSet_realElements;
8742 
8743       sRefSet_free (aliases);
8744       break;
8745     case SK_CONJ:
8746       sRef_innerAliasSetCompleteParam (predf, s->info->conj->a, t);
8747       sRef_innerAliasSetCompleteParam (predf, s->info->conj->b, t);
8748       break;
8749     case SK_SPECIAL:
8750     case SK_ADR:
8751     case SK_TYPE:
8752     case SK_CONST:
8753     case SK_NEW:
8754     case SK_UNKNOWN:
8755     case SK_OBJECT:
8756     case SK_DERIVED:
8757     case SK_EXTERNAL:
8758     case SK_RESULT:
8759       break;
8760     }
8761 }
8762 
sRef_combineExKinds(sRef res,sRef other)8763 static void sRef_combineExKinds (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other)
8764 {
8765   exkind a1 = sRef_getExKind (res);
8766   exkind a2 = sRef_getExKind (other);
8767 
8768   if (a1 == a2 || a2 == XO_UNKNOWN)
8769     {
8770       ;
8771     }
8772   else if (a1 == XO_UNKNOWN)
8773     {
8774       res->expinfo = stateInfo_update (res->expinfo, other->expinfo);
8775       res->expkind = a2;
8776     }
8777   else
8778     {
8779       res->expkind = XO_OBSERVER;
8780     }
8781 }
8782 
8783 /*
8784 ** Currently, this is a very ad hoc implementation, with lots of fixes to
8785 ** make real code work okay.  I need to come up with some more general
8786 ** rules or principles here.
8787 */
8788 
8789 static void
sRef_combineAliasKindsError(sRef res,sRef other,clause cl,fileloc loc)8790   sRef_combineAliasKindsError (/*@notnull@*/ sRef res,
8791 			       /*@notnull@*/ sRef other,
8792 			       clause cl, fileloc loc)
8793 {
8794   bool hasError = FALSE;
8795   alkind ares = sRef_getAliasKind (res);
8796   alkind aother = sRef_getAliasKind (other);
8797 
8798   sRef_checkMutable (res);
8799 
8800   if (alkind_isDependent (ares))
8801     {
8802       if (aother == AK_KEPT)
8803 	{
8804 	  res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8805 	  res->aliaskind = AK_KEPT;
8806 	}
8807       else
8808 	{
8809 	  if (aother == AK_LOCAL || aother == AK_STATIC
8810 	      || alkind_isTemp (aother))
8811 	    {
8812 	      DPRINTF (("Setting dependent: %s", sRef_unparseFull (res)));
8813 	      res->aliaskind = AK_DEPENDENT;
8814 	    }
8815 	}
8816     }
8817   else if (alkind_isDependent (aother))
8818     {
8819       if (ares == AK_KEPT)
8820 	{
8821 	  res->aliaskind = AK_KEPT;
8822 	}
8823       else
8824 	{
8825 	  if (ares == AK_LOCAL || ares == AK_STATIC || alkind_isTemp (ares))
8826 	    {
8827 	      DPRINTF (("Setting dependent: %s", sRef_unparseFull (res)));
8828 	      res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8829 	      res->aliaskind = AK_DEPENDENT;
8830 	    }
8831 	}
8832     }
8833   else if ((ares == AK_LOCAL || ares == AK_UNIQUE
8834 	    || ares == AK_STATIC || alkind_isTemp (ares))
8835 	   && sRef_isFresh (other))
8836     {
8837       /*
8838       ** cases like: if (s == NULL) s = malloc...;
8839       **    don't generate errors
8840       */
8841 
8842       if (usymtab_isAltDefinitelyNullDeep (res))
8843 	{
8844 	  res->aliaskind = ares;
8845 	}
8846       else
8847 	{
8848 	  hasError = TRUE;
8849 	}
8850     }
8851   else if ((aother == AK_LOCAL || aother == AK_UNIQUE
8852 	    || aother == AK_STATIC || alkind_isTemp (aother))
8853 	   && sRef_isFresh (res))
8854     {
8855       /*
8856       ** cases like: if (s == NULL) s = malloc...;
8857       **    don't generate errors
8858       */
8859 
8860       if (usymtab_isDefinitelyNullDeep (other))
8861 	{
8862 	  res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8863 	  res->aliaskind = aother;
8864 	}
8865       else
8866 	{
8867 	  hasError = TRUE;
8868 	}
8869     }
8870   else if (ares == AK_NEWREF && aother == AK_REFCOUNTED
8871 	   && sRef_isConst (other))
8872     {
8873       res->aliaskind = AK_NEWREF;
8874     }
8875   else if (aother == AK_NEWREF && ares == AK_REFCOUNTED
8876 	   && sRef_isConst (res))
8877     {
8878       res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8879       res->aliaskind = AK_NEWREF;
8880     }
8881   else if (sRef_isLocalVar (res)
8882 	   && ((ares == AK_KEPT && aother == AK_LOCAL)
8883 	       || (aother == AK_KEPT && ares == AK_LOCAL)))
8884     {
8885       res->aliaskind = AK_KEPT;
8886     }
8887   else if ((ares == AK_OWNED && aother == AK_ONLY)
8888 	   || (aother == AK_OWNED && ares == AK_ONLY))
8889     {
8890       res->aliaskind = AK_OWNED;
8891 
8892       if (aother == AK_OWNED)
8893 	{
8894 	  res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8895 	}
8896     }
8897   else
8898     {
8899       hasError = TRUE;
8900     }
8901 
8902   if (hasError)
8903     {
8904       if (sRef_isThroughArrayFetch (res))
8905 	{
8906 	  if (optgenerror2
8907 	      (FLG_BRANCHSTATE, FLG_STRICTBRANCHSTATE,
8908 	       message
8909 	       ("Clauses exit with %q possibly referencing %s storage %s, "
8910 		"%s storage %s",
8911 		sRef_unparse (res),
8912 		alkind_unparse (aother),
8913 		clause_nameTaken (cl),
8914 		alkind_unparse (ares),
8915 		clause_nameAlternate (cl)),
8916 	       loc))
8917 	    {
8918 	      sRef_showAliasInfo (res);
8919 	      sRef_showAliasInfo (other);
8920 	      res->aliaskind = AK_ERROR;
8921 	    }
8922 	  else
8923 	    {
8924 	      if (ares == AK_KEPT || aother == AK_KEPT)
8925 		{
8926 		  sRef_maybeKill (res, loc);
8927 		}
8928 	    }
8929 	}
8930       else
8931 	{
8932 	  if (optgenerror
8933 	      (FLG_BRANCHSTATE,
8934 	       message ("Clauses exit with %q referencing %s storage %s, "
8935 			"%s storage %s",
8936 			sRef_unparse (res),
8937 			alkind_unparse (aother),
8938 			clause_nameTaken (cl),
8939 			alkind_unparse (ares),
8940 			clause_nameAlternate (cl)),
8941 	       loc))
8942 	    {
8943 	      sRef_showAliasInfo (res);
8944 	      sRef_showAliasInfo (other);
8945 
8946 	      res->aliaskind = AK_ERROR;
8947 	    }
8948 	}
8949 
8950       res->aliaskind = (sRef_isLocalVar (res) ? AK_LOCAL : AK_UNKNOWN);
8951     }
8952 }
8953 
8954 static void
sRef_combineAliasKinds(sRef res,sRef other,clause cl,fileloc loc)8955   sRef_combineAliasKinds (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other,
8956 			  clause cl, fileloc loc)
8957 {
8958   alkind ares = sRef_getAliasKind (res);
8959   alkind aother = sRef_getAliasKind (other);
8960 
8961   sRef_checkMutable (res);
8962 
8963   DPRINTF (("Combine alias kinds: \n\t%s / \n\t%s",
8964 	    sRef_unparseFull (res), sRef_unparseFull (other)));
8965   if (alkind_equal (ares, aother)
8966       || aother == AK_UNKNOWN
8967       || aother == AK_ERROR)
8968     {
8969       ; /* keep current state */
8970     }
8971   else if (sRef_isDead (res) || sRef_isDead (other))
8972     {
8973       /* dead error reported (or storage is dead) */
8974       res ->aliaskind = AK_ERROR;
8975     }
8976   else if (ares == AK_UNKNOWN || ares == AK_ERROR
8977 	   || sRef_isStateUndefined (res)
8978 	   || sRef_isDefinitelyNull (res))
8979     {
8980       res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8981       res->aliaskind = aother;
8982     }
8983   else if (sRef_isStateUndefined (other)
8984 	   || sRef_isDefinitelyNull (other))
8985     {
8986       ;
8987     }
8988   else if (((ares == AK_UNIQUE || alkind_isTemp (ares))
8989 	    && aother == AK_LOCAL)
8990 	   || ((aother == AK_UNIQUE || alkind_isTemp (aother))
8991 	       && ares == AK_LOCAL))
8992     {
8993       if (ares != AK_LOCAL)
8994 	{
8995 	  res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
8996 	}
8997 
8998       res->aliaskind = AK_LOCAL;
8999     }
9000   else if ((ares == AK_OWNED && aother == AK_FRESH)
9001 	   || (aother == AK_OWNED && ares == AK_FRESH))
9002     {
9003       if (ares != AK_FRESH)
9004 	{
9005 	  res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
9006 	}
9007 
9008       res->aliaskind = AK_FRESH;
9009     }
9010   else if ((ares == AK_KEEP && aother == AK_FRESH) ||
9011 	   (aother == AK_KEEP && ares == AK_FRESH))
9012     {
9013       if (ares != AK_KEEP)
9014 	{
9015 	  res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
9016 	}
9017 
9018       res->aliaskind = AK_KEEP;
9019     }
9020   else if ((ares == AK_LOCAL && aother == AK_STACK) ||
9021 	   (aother == AK_LOCAL && ares == AK_STACK))
9022     {
9023       if (ares != AK_STACK)
9024 	{
9025 	  res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
9026 	}
9027 
9028       res->aliaskind = AK_STACK;
9029     }
9030   else if ((ares == AK_LOCAL
9031 	    && (aother == AK_OWNED && sRef_isLocalVar (other)))
9032 	   || (aother == AK_LOCAL
9033 	       && (ares == AK_OWNED && sRef_isLocalVar (res))))
9034     {
9035       if (ares != AK_LOCAL)
9036 	{
9037 	  res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
9038 	}
9039 
9040       res->aliaskind = AK_LOCAL;
9041     }
9042   else if ((ares == AK_FRESH && alkind_isOnly (aother))
9043 	   || (aother == AK_FRESH && alkind_isOnly (ares)))
9044     {
9045       res->aliaskind = AK_FRESH;
9046     }
9047   else if ((aother == AK_FRESH && sRef_definitelyNull (res))
9048 	   || (ares == AK_FRESH && sRef_definitelyNull (other)))
9049     {
9050       if (ares != AK_FRESH)
9051 	{
9052 	  res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
9053 	  res->aliaskind = AK_FRESH;
9054 	}
9055     }
9056   else if ((sRef_isFresh (res) && sRef_isConst (other))
9057 	   || (sRef_isFresh (other) && sRef_isConst (res)))
9058     {
9059       /*
9060       ** for NULL constantants
9061       ** this is bogus!
9062       */
9063 
9064       if (!sRef_isFresh (res))
9065 	{
9066 	  res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
9067 	}
9068 
9069       res->aliaskind = AK_FRESH;
9070     }
9071   else if ((alkind_isStatic (aother) && sRef_isConst (res))
9072 	   || (alkind_isStatic (ares) && sRef_isConst (other)))
9073     {
9074       if (!alkind_isStatic (ares))
9075 	{
9076 	  res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
9077 	  res->aliaskind = AK_STATIC;
9078 	}
9079     }
9080   else
9081     {
9082       sRef_combineAliasKindsError (res, other, cl, loc);
9083     }
9084 }
9085 
sRef_combineDefState(sRef res,sRef other)9086 static void sRef_combineDefState (/*@notnull@*/ sRef res,
9087 				  /*@notnull@*/ sRef other)
9088 {
9089   sstate s1 = res->defstate;
9090   sstate s2 = other->defstate;
9091   bool flip = FALSE;
9092 
9093   sRef_checkMutable (res);
9094 
9095   if (s1 == s2 || s2 == SS_UNKNOWN)
9096     {
9097       ;
9098     }
9099   else if (s1 == SS_UNKNOWN)
9100     {
9101       flip = TRUE;
9102     }
9103   else
9104     {
9105       switch (s1)
9106 	{
9107 	case SS_FIXED:
9108 	  if (s2 == SS_DEFINED)
9109 	    {
9110 	      break;
9111 	    }
9112 	  else
9113 	    {
9114 	      llcontbuglit ("ssfixed: not implemented");
9115 	      flip = TRUE;
9116 	    }
9117 	  break;
9118 	case SS_DEFINED:
9119 	  flip = TRUE;
9120 	  break;
9121 	case SS_PDEFINED:
9122 	case SS_ALLOCATED:
9123 	  flip = (s2 != SS_DEFINED);
9124 	  break;
9125 	case SS_HOFFA:
9126 	case SS_RELDEF:
9127 	case SS_UNUSEABLE:
9128 	case SS_UNDEFINED:
9129 	case SS_PARTIAL:
9130 	case SS_UNDEFGLOB:
9131 	case SS_KILLED:
9132 	case SS_DEAD:
9133 	case SS_SPECIAL:
9134 	  break;
9135 	BADDEFAULT;
9136 	}
9137     }
9138 
9139   if (flip)
9140     {
9141       res->definfo = stateInfo_update (res->definfo, other->definfo);
9142       res->defstate = s2;
9143     }
9144 }
9145 
sRef_getConjA(sRef s)9146 extern /*@notnull@*/ sRef sRef_getConjA (sRef s)
9147 {
9148   sRef ret;
9149   llassert (sRef_isConj (s));
9150 
9151   ret = s->info->conj->a;
9152   llassert (ret != NULL);
9153   return ret;
9154 }
9155 
sRef_getConjB(sRef s)9156 extern /*@notnull@*/ sRef sRef_getConjB (sRef s)
9157 {
9158   sRef ret;
9159   llassert (sRef_isConj (s));
9160 
9161   ret = s->info->conj->b;
9162   llassert (ret != NULL);
9163   return ret;
9164 }
9165 
sRef_makeArrow(sRef s,cstring f)9166 extern /*@exposed@*/ sRef sRef_makeArrow (sRef s, /*@dependent@*/ cstring f)
9167 {
9168   sRef p;
9169   sRef ret;
9170 
9171   p = sRef_makePointer (s);
9172   ret = sRef_makeField (p, f);
9173   DPRINTF (("Arrow: %s => %s",
9174 	    sRef_unparseFull (s), sRef_unparseFull (ret)));
9175   return ret;
9176 }
9177 
sRef_buildArrow(sRef s,cstring f)9178 extern /*@exposed@*/ sRef sRef_buildArrow (sRef s, cstring f)
9179 {
9180   sRef p;
9181   sRef ret;
9182 
9183   p = sRef_buildPointer (s);
9184   ret = sRef_buildField (p, f);
9185 
9186   return ret;
9187 }
9188 
sinfo_copy(sRef s)9189 static /*@null@*/ sinfo sinfo_copy (/*@notnull@*/ sRef s)
9190 {
9191   sinfo ret;
9192 
9193   switch (s->kind)
9194     {
9195     case SK_CVAR:
9196       ret = (sinfo) dmalloc (sizeof (*ret));
9197       ret->cvar = (cref) dmalloc (sizeof (*ret->cvar));
9198       ret->cvar->lexlevel = s->info->cvar->lexlevel;
9199       ret->cvar->index = s->info->cvar->index;
9200       break;
9201 
9202     case SK_PARAM:
9203       ret = (sinfo) dmalloc (sizeof (*ret));
9204       ret->paramno = s->info->paramno;
9205       llassert (ret->paramno >= -1);
9206       break;
9207 
9208     case SK_ARRAYFETCH:
9209       ret = (sinfo) dmalloc (sizeof (*ret));
9210       ret->arrayfetch = (ainfo) dmalloc (sizeof (*ret->arrayfetch));
9211       ret->arrayfetch->indknown = s->info->arrayfetch->indknown;
9212       ret->arrayfetch->ind = s->info->arrayfetch->ind;
9213       ret->arrayfetch->arr = s->info->arrayfetch->arr;
9214       break;
9215 
9216     case SK_FIELD:
9217       ret = (sinfo) dmalloc (sizeof (*ret));
9218       ret->field = (fldinfo) dmalloc (sizeof (*ret->field));
9219       ret->field->rec = s->info->field->rec;
9220       ret->field->field = s->info->field->field;
9221       break;
9222 
9223     case SK_OBJECT:
9224       ret = (sinfo) dmalloc (sizeof (*ret));
9225       ret->object = s->info->object;
9226       break;
9227 
9228     case SK_PTR:
9229     case SK_ADR:
9230     case SK_DERIVED:
9231     case SK_EXTERNAL:
9232       ret = (sinfo) dmalloc (sizeof (*ret));
9233       ret->ref = s->info->ref; /* Ref_copy (s->info->ref); */
9234       break;
9235 
9236     case SK_CONJ:
9237       ret = (sinfo) dmalloc (sizeof (*ret));
9238       ret->conj = (cjinfo) dmalloc (sizeof (*ret->conj));
9239       ret->conj->a = s->info->conj->a; /* sRef_copy (s->info->conj->a); */
9240       ret->conj->b = s->info->conj->b; /* sRef_copy (s->info->conj->b);*/
9241       break;
9242     case SK_SPECIAL:
9243       ret = (sinfo) dmalloc (sizeof (*ret));
9244       ret->spec = s->info->spec;
9245       break;
9246 
9247     case SK_UNCONSTRAINED:
9248     case SK_NEW:
9249       ret = (sinfo) dmalloc (sizeof (*ret));
9250       ret->fname = s->info->fname;
9251       break;
9252 
9253     case SK_RESULT:
9254     case SK_CONST:
9255     case SK_TYPE:
9256     case SK_UNKNOWN:
9257       llassertprint (s->info == NULL, ("s = %s", sRef_unparse (s)));
9258       ret = NULL;
9259       break;
9260     }
9261 
9262   return ret;
9263 }
9264 
sinfo_fullCopy(sRef s)9265 static /*@null@*/ sinfo sinfo_fullCopy (/*@notnull@*/ sRef s)
9266 {
9267   sinfo ret;
9268 
9269   /*
9270   ** Since its a full copy, only storage is assigned
9271   ** to dependent fields.
9272   */
9273   /*@-onlytrans@*/
9274 
9275   switch (s->kind)
9276     {
9277     case SK_CVAR:
9278       ret = (sinfo) dmalloc (sizeof (*ret));
9279       ret->cvar = (cref) dmalloc (sizeof (*ret->cvar));
9280       ret->cvar->lexlevel = s->info->cvar->lexlevel;
9281       ret->cvar->index = s->info->cvar->index;
9282       break;
9283 
9284     case SK_PARAM:
9285       ret = (sinfo) dmalloc (sizeof (*ret));
9286       ret->paramno = s->info->paramno;
9287       llassert (ret->paramno >= -1);
9288       break;
9289 
9290     case SK_ARRAYFETCH:
9291       ret = (sinfo) dmalloc (sizeof (*ret));
9292       ret->arrayfetch = (ainfo) dmalloc (sizeof (*ret->arrayfetch));
9293       ret->arrayfetch->indknown = s->info->arrayfetch->indknown;
9294       ret->arrayfetch->ind = s->info->arrayfetch->ind;
9295       ret->arrayfetch->arr = sRef_saveCopy (s->info->arrayfetch->arr);
9296       break;
9297 
9298     case SK_FIELD:
9299       ret = (sinfo) dmalloc (sizeof (*ret));
9300       ret->field = (fldinfo) dmalloc (sizeof (*ret->field));
9301       ret->field->rec = sRef_saveCopy (s->info->field->rec);
9302       ret->field->field = s->info->field->field;
9303       break;
9304 
9305     case SK_OBJECT:
9306       ret = (sinfo) dmalloc (sizeof (*ret));
9307       ret->object = s->info->object;
9308       break;
9309 
9310     case SK_PTR:
9311     case SK_ADR:
9312     case SK_DERIVED:
9313     case SK_EXTERNAL:
9314       ret = (sinfo) dmalloc (sizeof (*ret));
9315       ret->ref = sRef_saveCopy (s->info->ref);
9316       break;
9317 
9318     case SK_CONJ:
9319       ret = (sinfo) dmalloc (sizeof (*ret));
9320       ret->conj = (cjinfo) dmalloc (sizeof (*ret->conj));
9321       ret->conj->a = sRef_saveCopy (s->info->conj->a);
9322       ret->conj->b = sRef_saveCopy (s->info->conj->b);
9323       break;
9324     case SK_SPECIAL:
9325       ret = (sinfo) dmalloc (sizeof (*ret));
9326       ret->spec = s->info->spec;
9327       break;
9328     case SK_NEW:
9329     case SK_UNCONSTRAINED:
9330       ret = (sinfo) dmalloc (sizeof (*ret));
9331       ret->fname = s->info->fname;
9332       break;
9333     case SK_CONST:
9334     case SK_TYPE:
9335     case SK_RESULT:
9336     case SK_UNKNOWN:
9337       llassert (s->info == NULL);
9338       ret = NULL;
9339       break;
9340     }
9341   /*@=onlytrans@*/
9342   return ret;
9343 }
9344 
9345 
9346 static void
sinfo_update(sRef res,sRef other)9347   sinfo_update (/*@notnull@*/ /*@exposed@*/ sRef res,
9348 		/*@notnull@*/ /*@exposed@*/ sRef other)
9349 {
9350   llassert (res->kind == other->kind);
9351 
9352   switch (res->kind)
9353     {
9354     case SK_CVAR:
9355       res->info->cvar->lexlevel = other->info->cvar->lexlevel;
9356       res->info->cvar->index = other->info->cvar->index;
9357       break;
9358 
9359     case SK_PARAM:
9360       res->info->paramno = other->info->paramno;
9361       llassert (res->info->paramno >= -1);
9362       break;
9363 
9364     case SK_ARRAYFETCH:
9365       res->info->arrayfetch->indknown = other->info->arrayfetch->indknown;
9366       res->info->arrayfetch->ind = other->info->arrayfetch->ind;
9367       res->info->arrayfetch->arr = other->info->arrayfetch->arr;
9368       break;
9369 
9370     case SK_FIELD:
9371       res->info->field->rec = other->info->field->rec;
9372       res->info->field->field = other->info->field->field;
9373       break;
9374 
9375     case SK_OBJECT:
9376       res->info->object = other->info->object;
9377       break;
9378 
9379     case SK_PTR:
9380     case SK_ADR:
9381     case SK_DERIVED:
9382     case SK_EXTERNAL:
9383       res->info->ref = other->info->ref;
9384       break;
9385 
9386     case SK_CONJ:
9387       res->info->conj->a = other->info->conj->a;
9388       res->info->conj->b = other->info->conj->b;
9389       break;
9390 
9391     case SK_SPECIAL:
9392       res->info->spec = other->info->spec;
9393       break;
9394 
9395     case SK_NEW:
9396     case SK_UNCONSTRAINED:
9397       res->info->fname = other->info->fname;
9398       break;
9399 
9400     case SK_CONST:
9401     case SK_TYPE:
9402     case SK_UNKNOWN:
9403     case SK_RESULT:
9404       llassert (res->info == NULL);
9405       break;
9406     }
9407 }
9408 
sinfo_free(sRef s)9409 static void sinfo_free (/*@special@*/ /*@temp@*/ /*@notnull@*/ sRef s)
9410    /*@uses s->kind, s->info@*/
9411    /*@releases s->info@*/
9412 {
9413   switch (s->kind)
9414     {
9415     case SK_CVAR:
9416       DPRINTF (("Free sinfo: [%p]", s->info->cvar));
9417       sfree (s->info->cvar);
9418       break;
9419 
9420     case SK_PARAM:
9421       break;
9422 
9423     case SK_ARRAYFETCH:
9424       DPRINTF (("Free sinfo: [%p]", s->info->arrayfetch));
9425       sfree (s->info->arrayfetch);
9426       break;
9427 
9428     case SK_FIELD:
9429       DPRINTF (("Free sinfo: [%p]", s->info->field));
9430       sfree (s->info->field);
9431       break;
9432 
9433     case SK_OBJECT:
9434       break;
9435 
9436     case SK_PTR:
9437     case SK_ADR:
9438     case SK_DERIVED:
9439     case SK_EXTERNAL: /* is copy now! */
9440       break;
9441 
9442     case SK_CONJ:
9443       DPRINTF (("Free sinfo: [%p]", s->info->conj));
9444       sfree (s->info->conj);
9445       break;
9446 
9447     case SK_UNCONSTRAINED:
9448     case SK_SPECIAL:
9449     case SK_CONST:
9450     case SK_NEW:
9451     case SK_TYPE:
9452     case SK_UNKNOWN:
9453     case SK_RESULT:
9454       break;
9455     }
9456 
9457   if (s->info != NULL) {
9458       DPRINTF (("Free sinfo: [%p]", s->info));
9459   }
9460 
9461   sfree (s->info);
9462 }
9463 
sRef_isNSLocalVar(sRef s)9464 bool sRef_isNSLocalVar (sRef s)
9465 {
9466   if (sRef_isLocalVar (s))
9467     {
9468       uentry ue = sRef_getUentry (s);
9469 
9470       return (!uentry_isStatic (ue));
9471     }
9472   else
9473     {
9474       return FALSE;
9475     }
9476 }
9477 
sRef_isLocalVar(sRef s)9478 bool sRef_isLocalVar (sRef s)
9479 {
9480   if (sRef_isValid(s))
9481     {
9482       return (s->kind == SK_CVAR
9483 	      && (s->info->cvar->lexlevel > fileScope));
9484     }
9485 
9486   return FALSE;
9487 }
9488 
sRef_isRealLocalVar(sRef s)9489 bool sRef_isRealLocalVar (sRef s)
9490 {
9491   if (sRef_isValid(s))
9492     {
9493       if (s->kind == SK_CVAR)
9494 	{
9495 	  if (s->info->cvar->lexlevel == functionScope)
9496 	    {
9497 	      uentry ue = sRef_getUentry (s);
9498 
9499 	      if (uentry_isAnyParam (ue)
9500 		  || uentry_isRefParam (ue))
9501 		{
9502 		  return FALSE;
9503 		}
9504 	      else
9505 		{
9506 		  return TRUE;
9507 		}
9508 	    }
9509 	  else
9510 	    {
9511 	      return (s->info->cvar->lexlevel > functionScope);
9512 	    }
9513 	}
9514     }
9515 
9516   return FALSE;
9517 }
9518 
sRef_isLocalParamVar(sRef s)9519 bool sRef_isLocalParamVar (sRef s)
9520 {
9521   if (sRef_isValid(s))
9522     {
9523       return (s->kind == SK_PARAM
9524 	      || (s->kind == SK_CVAR
9525 		  && (s->info->cvar->lexlevel > fileScope)));
9526     }
9527 
9528   return FALSE;
9529 }
9530 
speckind_fromInt(int i)9531 static speckind speckind_fromInt (int i)
9532 {
9533   /*@+enumint@*/
9534   llassert (i >= SR_NOTHING && i <= SR_SYSTEM);
9535   /*@=enumint@*/
9536 
9537   return ((speckind) i);
9538 }
9539 
9540 
sRef_updateNullState(sRef res,sRef other)9541 static void sRef_updateNullState (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other)
9542      /*@modifies res@*/
9543 {
9544   res->nullstate = other->nullstate;
9545   DPRINTF (("update null state==> %s", sRef_unparseFull (res)));
9546   res->nullinfo = stateInfo_update (res->nullinfo, other->nullinfo);
9547   sRef_resetAliasKind (res);
9548 }
9549 
sRef_combineNullState(sRef res,sRef other)9550 void sRef_combineNullState (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other)
9551 {
9552   nstate n1 = sRef_getNullState (res);
9553   nstate n2 = sRef_getNullState (other);
9554   bool flip = FALSE;
9555   nstate nn = n1;
9556 
9557   if (n1 == n2 || n2 == NS_UNKNOWN)
9558     {
9559       ;
9560     }
9561   else
9562     {
9563       /* note: n2 is not unknown or defnull */
9564 
9565       switch (n1)
9566 	{
9567 	case NS_ERROR:   nn = NS_ERROR; break;
9568 	case NS_UNKNOWN: flip = TRUE; nn = n2; break;
9569 	case NS_POSNULL: break;
9570 	case NS_DEFNULL: nn = NS_POSNULL; break;
9571 	case NS_RELNULL: break;
9572 	case NS_NOTNULL:
9573 	  if (n2 == NS_MNOTNULL)
9574 	    {
9575 	      ;
9576 	    }
9577 	  else
9578 	    {
9579 	      flip = TRUE;
9580 	      nn = NS_POSNULL;
9581 	    }
9582 	  break;
9583 	case NS_MNOTNULL:
9584 	  if (n2 == NS_NOTNULL)
9585 	    {
9586 	      nn = NS_NOTNULL;
9587 	    }
9588 	  else
9589 	    {
9590 	      flip = TRUE;
9591 	      nn = NS_POSNULL;
9592 	    }
9593 	  break;
9594 	case NS_CONSTNULL:
9595 	case NS_ABSNULL:
9596 	  flip = TRUE;
9597 	  nn = n2;
9598 	}
9599     }
9600 
9601   if (flip)
9602     {
9603       res->nullinfo = stateInfo_update (res->nullinfo, other->nullinfo);
9604     }
9605 
9606   res->nullstate = nn;
9607   DPRINTF (("update null state==> %s", sRef_unparseFull (res)));
9608   sRef_resetAliasKind (res);
9609 }
9610 
sRef_nullMessage(sRef s)9611 cstring sRef_nullMessage (sRef s)
9612 {
9613   llassert (sRef_isReasonable (s));
9614 
9615   switch (sRef_getNullState (s))
9616     {
9617     case NS_DEFNULL:
9618     case NS_CONSTNULL:
9619       return (cstring_makeLiteralTemp ("null"));
9620     default:
9621       return (cstring_makeLiteralTemp ("possibly null"));
9622     }
9623   BADEXIT;
9624 }
9625 
sRef_ntMessage(sRef s)9626 /*@observer@*/ cstring sRef_ntMessage (sRef s)
9627 {
9628   llassert (sRef_isReasonable (s));
9629 
9630   switch (s->nullstate)
9631     {
9632     case NS_DEFNULL:
9633     case NS_CONSTNULL:
9634       return (cstring_makeLiteralTemp ("not nullterminated"));
9635     default:
9636       return (cstring_makeLiteralTemp ("possibly non-nullterminated"));
9637     }
9638   BADEXIT;
9639 }
9640 
9641 
9642 
sRef_fixResultType(sRef s,ctype typ,uentry ue)9643 sRef sRef_fixResultType (/*@returned@*/ sRef s, ctype typ, uentry ue)
9644 {
9645   sRef tmp = sRef_undefined;
9646   sRef ret;
9647 
9648   llassert (sRef_isReasonable (s));
9649 
9650   switch (s->kind)
9651     {
9652     case SK_RESULT:
9653       s->type = typ;
9654       ret = s;
9655       break;
9656     case SK_ARRAYFETCH:
9657       {
9658 	ctype ct;
9659 	tmp = sRef_fixResultType (s->info->arrayfetch->arr, typ, ue);
9660 
9661 	ct = ctype_realType (sRef_getType (tmp));
9662 
9663 
9664 	if (ctype_isKnown (ct))
9665 	  {
9666 	    if (ctype_isAP (ct))
9667 	      {
9668 		;
9669 	      }
9670 	    else
9671 	      {
9672 		voptgenerror
9673 		  (FLG_TYPE,
9674 		   message
9675 		   ("Special clause indexes non-array (%t): *%q",
9676 		    ct, sRef_unparse (s->info->arrayfetch->arr)),
9677 		   uentry_whereLast (ue));
9678 	      }
9679 	  }
9680 
9681 	tmp = sRef_fixResultType (s->info->arrayfetch->arr, typ, ue);
9682 
9683 	if (s->info->arrayfetch->indknown)
9684 	  {
9685 	    ret = sRef_makeArrayFetchKnown (tmp, s->info->arrayfetch->ind);
9686 	  }
9687 	else
9688 	  {
9689 	    ret = sRef_makeArrayFetch (tmp);
9690 	  }
9691       }
9692       break;
9693     case SK_FIELD:
9694       {
9695 	sRef rec = sRef_fixResultType (s->info->field->rec, typ, ue);
9696 	ctype ct = ctype_realType (sRef_getType (rec));
9697 
9698 	if (ctype_isKnown (ct))
9699 	  {
9700 	    if (ctype_isSU (ct))
9701 	      {
9702 		if (uentry_isValid (uentryList_lookupField (ctype_getFields (ct),
9703 							    s->info->field->field)))
9704 		  {
9705 		    ;
9706 		  }
9707 		else
9708 		  {
9709 		    voptgenerror
9710 		      (FLG_TYPE,
9711 		       message
9712 		       ("Special clause accesses non-existent field of result: %q.%s",
9713 			sRef_unparse (rec), s->info->field->field),
9714 		       uentry_whereLast (ue));
9715 		  }
9716 	      }
9717 	    else
9718 	      {
9719 		voptgenerror
9720 		  (FLG_TYPE,
9721 		   message
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));
9725 	      }
9726 	  }
9727 
9728 	ret = sRef_makeField (tmp, s->info->field->field);
9729 	break;
9730       }
9731     case SK_PTR:
9732       {
9733 	ctype ct;
9734 	tmp = sRef_fixResultType (s->info->ref, typ, ue);
9735 
9736 	ct = ctype_realType (sRef_getType (tmp));
9737 
9738 	if (ctype_isKnown (ct))
9739 	  {
9740 	    if (ctype_isAP (ct))
9741 	      {
9742 		;
9743 	      }
9744 	    else
9745 	      {
9746 		voptgenerror
9747 		  (FLG_TYPE,
9748 		   message
9749 		   ("Special clause dereferences non-pointer (%t): *%q",
9750 		    ct, sRef_unparse (s->info->ref)),
9751 		   uentry_whereLast (ue));
9752 	      }
9753 	  }
9754 
9755 	ret = sRef_makePointer (tmp);
9756 	break;
9757       }
9758     case SK_ADR:
9759       voptgenerror
9760 	(FLG_TYPE,
9761 	 message
9762 	 ("Special clause uses & operator (not allowed): &%q", sRef_unparse (s->info->ref)),
9763 	 uentry_whereLast (ue));
9764       ret = s;
9765       break;
9766     BADDEFAULT;
9767     }
9768 
9769   return ret;
9770 }
9771 
sRef_isOnly(sRef s)9772 bool sRef_isOnly (sRef s)
9773 {
9774   return (sRef_isValid(s) && alkind_isOnly (s->aliaskind));
9775 }
9776 
sRef_isDependent(sRef s)9777 bool sRef_isDependent (sRef s)
9778 {
9779   return (sRef_isValid(s) && alkind_isDependent (s->aliaskind));
9780 }
9781 
sRef_isOwned(sRef s)9782 bool sRef_isOwned (sRef s)
9783 {
9784   return (sRef_isReasonable (s) && (s->aliaskind == AK_OWNED));
9785 }
9786 
sRef_isKeep(sRef s)9787 bool sRef_isKeep (sRef s)
9788 {
9789   return (sRef_isReasonable (s) && (s->aliaskind == AK_KEEP));
9790 }
9791 
sRef_isTemp(sRef s)9792 bool sRef_isTemp (sRef s)
9793 {
9794   return (sRef_isReasonable (s) && alkind_isTemp (s->aliaskind));
9795 }
9796 
sRef_isLocalState(sRef s)9797 bool sRef_isLocalState (sRef s)
9798 {
9799   return (sRef_isReasonable (s) && (s->aliaskind == AK_LOCAL));
9800 }
9801 
sRef_isUnique(sRef s)9802 bool sRef_isUnique (sRef s)
9803 {
9804   return (sRef_isReasonable (s) && (s->aliaskind == AK_UNIQUE));
9805 }
9806 
sRef_isShared(sRef s)9807 bool sRef_isShared (sRef s)
9808 {
9809   return (sRef_isReasonable (s) && (s->aliaskind == AK_SHARED));
9810 }
9811 
sRef_isExposed(sRef s)9812 bool sRef_isExposed (sRef s)
9813 {
9814   return (sRef_isReasonable (s) && (s->expkind == XO_EXPOSED));
9815 }
9816 
sRef_isObserver(sRef s)9817 bool sRef_isObserver (sRef s)
9818 {
9819   return (sRef_isReasonable (s) && (s->expkind == XO_OBSERVER));
9820 }
9821 
sRef_isFresh(sRef s)9822 bool sRef_isFresh (sRef s)
9823 {
9824   return (sRef_isReasonable (s) && (s->aliaskind == AK_FRESH));
9825 }
9826 
sRef_isDefinitelyNull(sRef s)9827 bool sRef_isDefinitelyNull (sRef s)
9828 {
9829   return (sRef_isReasonable (s) && (sRef_getNullState (s) == NS_DEFNULL
9830 			       || sRef_getNullState (s) == NS_CONSTNULL));
9831 }
9832 
sRef_isAllocated(sRef s)9833 bool sRef_isAllocated (sRef s)
9834 {
9835   return (sRef_isReasonable (s) && (s->defstate == SS_ALLOCATED));
9836 }
9837 
sRef_isStack(sRef s)9838 bool sRef_isStack (sRef s)
9839 {
9840   return (sRef_isReasonable (s) && (s->aliaskind == AK_STACK));
9841 }
9842 
sRef_isNotNull(sRef s)9843 bool sRef_isNotNull (sRef s)
9844 {
9845   return (sRef_isValid(s) && (sRef_getNullState (s) == NS_MNOTNULL
9846 			      || sRef_getNullState (s) == NS_NOTNULL));
9847 }
9848 
sRef_getAliasKind(sRef s)9849 alkind sRef_getAliasKind (sRef s)
9850 {
9851   if (sRef_isValid(s)) {
9852     llassert (alkind_isValid (s->aliaskind));
9853     return s->aliaskind;
9854   }
9855 
9856   return AK_ERROR;
9857 }
9858 
sRef_getNullState(sRef s)9859 nstate sRef_getNullState (sRef s)
9860 {
9861   if (sRef_isReasonable (s)) {
9862     llassert (nstate_isValid (s->nullstate));
9863     return s->nullstate;
9864   }
9865 
9866   return NS_UNKNOWN;
9867 }
9868 
sRef_reflectAnnotation(sRef s,annotationInfo a,fileloc loc)9869 void sRef_reflectAnnotation (sRef s, annotationInfo a, fileloc loc)
9870 {
9871   if (sRef_isReasonable (s))
9872     {
9873       if (!valueTable_isDefined (s->state))
9874 	{
9875 	  s->state = valueTable_create (1);
9876 	  valueTable_insert
9877 	    (s->state,
9878 	     cstring_copy (metaStateInfo_getName (annotationInfo_getState (a))),
9879 	     stateValue_create (annotationInfo_getValue (a),
9880 				stateInfo_makeLoc (loc, SA_DECLARED)));
9881 	}
9882       else
9883 	{
9884 	  DPRINTF (("reflect loc: %s", fileloc_unparse (loc)));
9885 	  valueTable_update
9886 	    (s->state,
9887 	     metaStateInfo_getName (annotationInfo_getState (a)),
9888 	     stateValue_create (annotationInfo_getValue (a),
9889 				stateInfo_makeLoc (loc, SA_DECLARED)));
9890 
9891 	  DPRINTF (("sref: %s", sRef_unparse (s)));
9892 	  DPRINTF (("sref: %s", sRef_unparseFull (s)));
9893 	}
9894     }
9895 }
9896 
sRef_setMetaStateValueComplete(sRef s,cstring key,int value,fileloc loc)9897 void sRef_setMetaStateValueComplete (sRef s, cstring key, int value, fileloc loc)
9898 {
9899   sRefSet aliases = usymtab_allAliases (s);
9900 
9901   sRef_setMetaStateValue (s, key, value, loc);
9902 
9903   sRefSet_realElements (aliases, current)
9904     {
9905       if (sRef_isReasonable (current))
9906 	{
9907 	  current = sRef_updateSref (current);
9908 	  sRef_setMetaStateValue (current, key, value, loc);
9909 	}
9910     } end_sRefSet_realElements ;
9911 
9912   sRefSet_free (aliases);
9913 }
9914 
sRef_setMetaStateValue(sRef s,cstring key,int value,fileloc loc)9915 void sRef_setMetaStateValue (sRef s, cstring key, int value, fileloc loc)
9916 {
9917   sRef_checkMutable (s);
9918 
9919   if (sRef_isReasonable (s))
9920     {
9921       if (!valueTable_isDefined (s->state))
9922 	{
9923 	  DPRINTF (("inserting state: %s: %s %d", sRef_unparse (s), key, value));
9924 	  s->state = valueTable_create (1);
9925 	  valueTable_insert (s->state, cstring_copy (key),
9926 			     stateValue_create (value,
9927 						stateInfo_makeLoc (loc, SA_CHANGED)));
9928 	}
9929       else
9930 	{
9931 	  DPRINTF (("Updating state: %s: %s %d / %s", sRef_unparse (s), key, value,
9932 		    fileloc_unparse (loc)));
9933 	  if (valueTable_contains (s->state, key))
9934 	    {
9935 	      valueTable_update
9936 		(s->state, key, stateValue_create (value,
9937 						   stateInfo_makeLoc (loc, SA_CHANGED)));
9938 	    }
9939 	  else
9940 	    {
9941 	      valueTable_insert
9942 		(s->state, cstring_copy (key),
9943 		 stateValue_create (value, stateInfo_makeLoc (loc, SA_CHANGED)));
9944 	    }
9945 
9946 	  DPRINTF (("After: %s", sRef_unparseFull (s)));
9947 	}
9948     }
9949 }
9950 
sRef_checkMetaStateValue(sRef s,cstring key,int value)9951 bool sRef_checkMetaStateValue (sRef s, cstring key, int value)
9952 {
9953   if (sRef_isReasonable (s))
9954     {
9955       if (valueTable_isDefined (s->state))
9956 	{
9957 	  stateValue val;
9958 
9959 	  DPRINTF (("check state: %s: %s %d", sRef_unparse (s), key, value));
9960 
9961 	  val = valueTable_lookup (s->state, key);
9962 	  llassert (stateValue_isDefined (val));
9963 	  return (stateValue_isError (val)
9964 		  || stateValue_getValue (val) == value);
9965 	}
9966       else
9967 	{
9968 	  return TRUE;
9969 	}
9970     }
9971   else
9972     {
9973       return TRUE;
9974     }
9975 }
9976 
sRef_getMetaStateValue(sRef s,cstring key)9977 /*@observer@*/ stateValue sRef_getMetaStateValue (sRef s, cstring key)
9978 {
9979   if (sRef_isReasonable (s))
9980     {
9981       if (valueTable_isDefined (s->state))
9982 	{
9983 	  stateValue val;
9984 
9985 	  val = valueTable_lookup (s->state, key);
9986 	  /* Okay if its not defined, just returns stateValue_undefined */
9987 	  return val;
9988 	}
9989       else
9990 	{
9991 	  return stateValue_undefined;
9992 	}
9993     }
9994   else
9995     {
9996       return stateValue_undefined;
9997     }
9998 }
9999 
sRef_getValueTable(sRef s)10000 /*@observer@*/ valueTable sRef_getValueTable (sRef s)
10001 {
10002   DPRINTF (("Get value table: %s", sRef_unparse (s)));
10003 
10004   if (sRef_isReasonable (s))
10005     {
10006       llassert (sRef_isReasonable (s));
10007       DPRINTF (("Value table: %s", valueTable_unparse (s->state)));
10008       return s->state;
10009     }
10010   else
10011     {
10012       DPRINTF (("No value table!"));
10013       return valueTable_undefined;
10014     }
10015 }
10016 
sRef_makeStateSpecial(sRef s)10017 bool sRef_makeStateSpecial (sRef s)
10018 {
10019   /*
10020   ** Default defined state can be made special.
10021   */
10022 
10023   llassert (sRef_isReasonable (s));
10024 
10025   if (s->defstate == SS_UNKNOWN || s->defstate == SS_DEFINED || s->defstate == SS_SPECIAL)
10026     {
10027       /* s->aliaskind = AK_IMPTEMP; */ /* evans 2001-07-23 shouldn't effect alias state */
10028       s->defstate = SS_SPECIAL;
10029       DPRINTF (("Made special: %s", sRef_unparseFull (s)));
10030       return TRUE;
10031     }
10032   else
10033     {
10034       /* s->aliaskind = AK_IMPTEMP; */
10035       s->defstate = SS_SPECIAL;
10036       return FALSE;
10037     }
10038 }
10039 
sRef_markImmutable(sRef s)10040 void sRef_markImmutable (sRef s)
10041 {
10042   if (sRef_isReasonable (s))
10043     {
10044       DPRINTF (("Mark immutable: %s", sRef_unparseFull (s)));
10045       s->immut = TRUE;
10046     }
10047 }
10048 
sRef_definitelyNullContext(sRef s)10049 bool sRef_definitelyNullContext (sRef s)
10050 {
10051   return (sRef_definitelyNull (s)
10052 	  || usymtab_isDefinitelyNullDeep (s));
10053 }
10054 
sRef_definitelyNullAltContext(sRef s)10055 bool sRef_definitelyNullAltContext (sRef s)
10056 {
10057   return (sRef_definitelyNull (s)
10058 	  || usymtab_isAltDefinitelyNullDeep (s));
10059 }
10060 
10061 
10062 /* start modifications */
sRef_getNullTerminatedState(sRef p_s)10063 struct s_bbufinfo sRef_getNullTerminatedState (sRef p_s) {
10064    struct s_bbufinfo BUFSTATE_UNKNOWN;
10065    BUFSTATE_UNKNOWN.bufstate = BB_NOTNULLTERMINATED;
10066    BUFSTATE_UNKNOWN.size = 0;
10067    BUFSTATE_UNKNOWN.len = 0;
10068 
10069    if (sRef_isValid(p_s))
10070       return p_s->bufinfo;
10071    return BUFSTATE_UNKNOWN;
10072 }
10073 
sRef_setNullTerminatedState(sRef p_s)10074 void sRef_setNullTerminatedState(sRef p_s) {
10075    if(sRef_isReasonable (p_s)) {
10076       p_s->bufinfo.bufstate = BB_NULLTERMINATED;
10077    } else {
10078       llfatalbug( message("sRef_setNT passed a invalid sRef\n"));
10079    }
10080 }
10081 
10082 
sRef_setPossiblyNullTerminatedState(sRef p_s)10083 void sRef_setPossiblyNullTerminatedState(sRef p_s) {
10084    if( sRef_isReasonable (p_s)) {
10085       p_s->bufinfo.bufstate = BB_POSSIBLYNULLTERMINATED;
10086    } else {
10087       llfatalbug( message("sRef_setPossNT passed a invalid sRef\n"));
10088    }
10089 }
10090 
sRef_setNotNullTerminatedState(sRef p_s)10091 void sRef_setNotNullTerminatedState(sRef p_s) {
10092    if( sRef_isReasonable (p_s)) {
10093       p_s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
10094    } else {
10095       llfatalbug( message("sRef_unsetNT passed a invalid sRef\n"));
10096    }
10097 }
10098 
sRef_setLen(sRef p_s,int len)10099 void sRef_setLen(sRef p_s, int len) {
10100    if (sRef_isReasonable (p_s) && sRef_isNullTerminated(p_s))
10101      {
10102        p_s->bufinfo.len = len;
10103      }
10104    else
10105      {
10106        llfatalbug( message("sRef_setLen passed an invalid sRef\n"));
10107      }
10108 }
10109 
10110 
sRef_setSize(sRef p_s,int size)10111 void sRef_setSize(sRef p_s, int size) {
10112    if( sRef_isValid(p_s))
10113      {
10114        p_s->bufinfo.size = size;
10115      }
10116    else
10117      {
10118        llfatalbug( message("sRef_setSize passed a invalid sRef\n"));
10119      }
10120 }
10121 
sRef_resetLen(sRef p_s)10122 void sRef_resetLen(sRef p_s) {
10123   if (sRef_isReasonable (p_s))
10124     {
10125       p_s->bufinfo.len = 0;
10126     }
10127   else
10128     {
10129       llfatalbug (message ("sRef_setLen passed an invalid sRef\n"));
10130     }
10131 }
10132 
10133 /*drl7x 11/28/2000 */
10134 
sRef_isFixedArray(sRef p_s)10135 bool sRef_isFixedArray (sRef p_s) /*@*/ {
10136   ctype c;
10137   c = sRef_getType (p_s);
10138   return ( ctype_isFixedArray (c) );
10139 }
10140 
sRef_getArraySize(sRef p_s)10141 size_t sRef_getArraySize (sRef p_s) /*@*/
10142 {
10143   ctype c;
10144   llassert (sRef_isFixedArray(p_s) );
10145   DPRINTF (( message ("sRef_getArraySize getting array size for %s", sRef_unparse(p_s) )  ));
10146 
10147   c = sRef_getType (p_s);
10148   return (ctype_getArraySize (c));
10149 }
10150 
sRef_setValue(sRef s,multiVal val)10151 void sRef_setValue (sRef s, multiVal val)
10152 {
10153   if (!sRef_isReasonable (s))
10154     {
10155       llcontbuglit ("Unreasonable sRef");
10156       llcontbug (message ("sRef: %s", sRef_unparse (s)));
10157       return;
10158     }
10159 
10160   multiVal_free (s->val);
10161   s->val = val;
10162 }
10163 
sRef_hasValue(sRef s)10164 bool sRef_hasValue (sRef s)
10165 {
10166   return (sRef_isReasonable (s)
10167 	  && multiVal_isDefined (s->val));
10168 }
10169 
sRef_getValue(sRef s)10170 multiVal sRef_getValue (sRef s)
10171 {
10172   if (sRef_isReasonable (s))
10173     {
10174       return s->val;
10175     }
10176 
10177   return multiVal_undefined;
10178 }
10179