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 ** sRefSet.c
26 **
27 ** based on set_template.c
28 **
29 ** where T has T_equal (or change this) and T_unparse
30 */
31 
32 # include "splintMacros.nf"
33 # include "basic.h"
34 
35 sRefSet
sRefSet_new()36 sRefSet_new ()
37 {
38   return sRefSet_undefined;
39 }
40 
41 static /*@notnull@*/ /*@only@*/ sRefSet
sRefSet_newEmpty(void)42 sRefSet_newEmpty (void)
43 {
44   sRefSet s = (sRefSet) dmalloc (sizeof (*s));
45 
46   s->entries = 0;
47   s->nspace = sRefSetBASESIZE;
48   s->elements = (sRef *) dmalloc (sizeof (*s->elements) * sRefSetBASESIZE);
49 
50   return (s);
51 }
52 
53 /*@only@*/ sRefSet
sRefSet_single(sRef sr)54 sRefSet_single (/*@exposed@*/ sRef sr)
55 {
56   sRefSet s = (sRefSet) dmalloc (sizeof (*s));
57 
58   s->entries = 1;
59   s->nspace = sRefSetBASESIZE - 1;
60   s->elements = (sRef *) dmalloc (sizeof (*s->elements) * sRefSetBASESIZE);
61   s->elements[0] = sr;
62 
63   return (s);
64 }
65 
66 static void
sRefSet_grow(sRefSet s)67 sRefSet_grow (/*@notnull@*/ sRefSet s)
68 {
69   int i;
70   sRef *newelements;
71 
72   s->nspace = sRefSetBASESIZE;
73   newelements = (sRef *) dmalloc (sizeof (*newelements) * (s->entries + s->nspace));
74 
75   for (i = 0; i < s->entries; i++)
76     {
77       newelements[i] = s->elements[i];
78     }
79 
80   sfree (s->elements);
81   s->elements = newelements;
82 }
83 
84 sRefSet
sRefSet_insert(sRefSet s,sRef el)85 sRefSet_insert (sRefSet s, /*@exposed@*/ sRef el)
86 {
87   if (sRefSet_isUndefined (s))
88     {
89       s = sRefSet_newEmpty ();
90     }
91 
92 
93   if (!sRefSet_isSameMember (s, el))
94     {
95 
96       if (s->nspace <= 0)
97 	sRefSet_grow (s);
98 
99       s->nspace--;
100 
101       llassert (s->elements != NULL);
102       s->elements[s->entries] = el;
103       s->entries++;
104     }
105   else
106     {
107       ;
108     }
109 
110   return s;
111 }
112 
113 void
sRefSet_clear(sRefSet s)114 sRefSet_clear (sRefSet s)
115 {
116   if (sRefSet_isDefined (s))
117     {
118       s->nspace += s->entries;
119       s->entries = 0;
120     }
121 }
122 
123 /*
124 ** slow algorithm...but it doesn't matter
125 */
126 
127 void
sRefSet_clearStatics(sRefSet s)128 sRefSet_clearStatics (sRefSet s)
129 {
130   if (sRefSet_isDefined (s))
131     {
132       int i;
133 
134       for (i = 0; i < s->entries; i++)
135 	{
136 	  sRef current = s->elements[i];
137 
138 	  if (sRef_isFileStatic (sRef_getRootBase (current)))
139 	    {
140 	      int j;
141 
142 	      for (j = i; j < s->entries - 1; j++)
143 		{
144 		  s->elements[j] = s->elements[j+1];
145 		}
146 
147 	      s->entries--;
148 	      s->nspace++;
149 	      i--;
150 	    }
151 	}
152     }
153 }
154 
155 bool
sRefSet_delete(sRefSet s,sRef el)156 sRefSet_delete (sRefSet s, sRef el)
157 {
158   int i;
159 
160   if (sRefSet_isUndefined (s)) return FALSE;
161 
162   if (s->elements != NULL)
163     {
164       for (i = 0; i < s->entries; i++)
165 	{
166 	  sRef current = s->elements[i];
167 
168 	  if (sRef_realSame (el, current))
169 	    {
170 	      int j;
171 
172 	      for (j = i; j < s->entries - 1; j++)
173 		{
174 		  s->elements[j] = s->elements[j+1];
175 		}
176 
177 	      s->entries--;
178 	      s->nspace++;
179 	      return TRUE;
180 	    }
181 	}
182     }
183 
184   return FALSE;
185 }
186 
187 /*@exposed@*/ sRef
sRefSet_choose(sRefSet s)188 sRefSet_choose (sRefSet s)
189 {
190   llassert (sRefSet_isDefined (s));
191   llassert (s->entries > 0);
192   llassert (s->elements != NULL);
193 
194   return (s->elements[0]);
195 }
196 
197 /*@exposed@*/ sRef
sRefSet_mergeIntoOne(sRefSet s)198 sRefSet_mergeIntoOne (sRefSet s)
199 {
200   sRef res;
201   int i;
202 
203   if (sRefSet_isUndefined (s)) return sRef_undefined;
204   if (s->entries == 0) return sRef_undefined;
205 
206   llassert (s->elements != NULL);
207 
208   res = s->elements[0];
209 
210   for (i = 1; i < s->entries; i++)
211     {
212       sRef tmp;
213 
214       tmp = sRef_makeConj (res, s->elements[i]);
215       res = tmp;
216     }
217 
218   return res;
219 }
220 
221 /*
222 ** this is really yucky...but it works...
223 */
224 
225 bool
sRefSet_deleteBase(sRefSet s,sRef base)226 sRefSet_deleteBase (sRefSet s, sRef base)
227 {
228   int i = 0;
229   int offset = 0;
230 
231   if (sRefSet_isUndefined (s) || (s->elements == NULL))
232     {
233       return FALSE;
234     } ;
235 
236   while (i + offset < s->entries)
237     {
238       sRef current = s->elements[i + offset];
239 
240       while (sRef_includedBy (current, base))
241 	{
242 	  	  offset++;
243 	  if (i + offset >= s->entries) goto doneLoop;
244 	  current = s->elements [i + offset];
245 	}
246 
247       if (offset > 0)
248 	{
249 	  	  s->elements [i] = current;
250 	}
251 
252       i++;
253     }
254 
255  doneLoop:
256   s->entries -= offset;
257   s->nspace += offset;
258 
259   return (offset > 0);
260 }
261 
262 /*
263 ** modifies *s1
264 */
265 
266 sRefSet
sRefSet_unionFree(sRefSet s1,sRefSet s2)267 sRefSet_unionFree (/*@returned@*/ sRefSet s1, sRefSet s2)
268 {
269   sRefSet res = sRefSet_union (s1, s2);
270 
271   sRefSet_free (s2);
272   return res;
273 }
274 
275 sRefSet
sRefSet_union(sRefSet s1,sRefSet s2)276 sRefSet_union (/*@returned@*/ sRefSet s1, sRefSet s2)
277 {
278   if (s1 == s2)
279     {
280       return s1;
281     }
282 
283   if (sRefSet_isEmpty (s1))
284     {
285       s1 = sRefSet_copyInto (s1, s2);
286     }
287   else
288     {
289       sRefSet_allElements (s2, el)
290 	{
291 	  s1 = sRefSet_insert (s1, el);
292 	} end_sRefSet_allElements;
293     }
294 
295   return s1;
296 }
297 
298 /*
299 ** s1 <- s1 U (s2 - ex - params)
300 */
301 
302 sRefSet
sRefSet_unionExcept(sRefSet s1,sRefSet s2,sRef ex)303 sRefSet_unionExcept (/*@returned@*/ sRefSet s1, sRefSet s2, sRef ex)
304 {
305   if (s1 == s2) return s1;
306 
307   sRefSet_allElements (s2, el)
308     {
309       if (sRef_same (el, ex))
310 	{
311 	  ;
312 	}
313       else
314 	{
315 	  s1 = sRefSet_insert (s1, el);
316 	}
317     } end_sRefSet_allElements;
318 
319   return s1;
320 }
321 
322 /*@only@*/ sRefSet
sRefSet_realNewUnion(sRefSet s1,sRefSet s2)323 sRefSet_realNewUnion (sRefSet s1, sRefSet s2)
324 {
325   llassert (NOALIAS (s1, s2));
326 
327   if (sRefSet_isUndefined (s1))
328     {
329       return (sRefSet_newCopy (s2));
330     }
331   else
332     {
333       sRefSet ret = sRefSet_newCopy (s1);
334 
335       sRefSet_allElements (s2, el)
336 	{
337 	  ret = sRefSet_insert (ret, el);
338 	} end_sRefSet_allElements;
339 
340       return ret;
341     }
342 }
343 
344 /* slow! */
345 
346 /*@only@*/ sRefSet
sRefSet_intersect(sRefSet s1,sRefSet s2)347 sRefSet_intersect (sRefSet s1, sRefSet s2)
348 {
349   sRefSet s = sRefSet_new ();
350 
351   llassert (NOALIAS (s1, s2));
352 
353   sRefSet_allElements (s1, el)
354     {
355       if (sRefSet_member (s2, el))
356 	{
357 	  s = sRefSet_insert (s, el);
358 	}
359     } end_sRefSet_allElements;
360 
361     return s;
362 }
363 
364 sRefSet
sRefSet_levelUnion(sRefSet sr,sRefSet s,int lexlevel)365 sRefSet_levelUnion (/*@returned@*/ sRefSet sr, sRefSet s, int lexlevel)
366 {
367   llassert (NOALIAS (sr, s));
368 
369   sRefSet_allElements (s, el)
370     {
371       if (sRef_lexLevel (el) <= lexlevel)
372 	{
373 	  sr = sRefSet_insert (sr, el);
374 	}
375     } end_sRefSet_allElements;
376 
377   return sr;
378 }
379 
380 void
sRefSet_levelPrune(sRefSet s,int lexlevel)381 sRefSet_levelPrune (sRefSet s, int lexlevel)
382 {
383   if (sRefSet_isDefined (s))
384     {
385       int i;
386       int backcount = sRefSet_size (s) - 1;
387 
388       for (i = 0; i <= backcount; i++)
389 	{
390 	  sRef el = s->elements[i];
391 
392 	  if (sRef_lexLevel (el) > lexlevel)
393 	    {
394 	      int j;
395 
396 
397 	      for (j = backcount; j > i; j--)
398 		{
399 		  backcount--;
400 		  s->entries--;
401 		  s->nspace++;
402 
403 		  if (sRef_lexLevel (s->elements[j]) <= lexlevel)
404 		    {
405 		      s->elements[i] = s->elements[j];
406 
407 		      if (backcount == i) s->entries++;
408 		      /*@innerbreak@*/ break;
409 		    }
410 		}
411 
412 	      if (backcount == i)
413 		{
414 		  s->entries--;
415 		}
416 	    }
417 	}
418     }
419 }
420 
421 /*
422 ** s1 <- s2
423 */
424 
sRefSet_copyInto(sRefSet s1,sRefSet s2)425 sRefSet sRefSet_copyInto (/*@returned@*/ sRefSet s1, /*@exposed@*/ sRefSet s2)
426 {
427   int origentries;
428 
429   llassert (NOALIAS (s1, s2));
430 
431   if (sRefSet_isUndefined (s1))
432     {
433       if (sRefSet_isEmpty (s2))
434 	{
435 	  return s1;
436 	}
437       else
438 	{
439 	  s1 = sRefSet_newEmpty ();
440 	}
441     }
442 
443   origentries = s1->entries;
444 
445   s1->nspace = s1->entries + s1->nspace;
446   s1->entries = 0;
447 
448   sRefSet_allElements (s2, el)
449     {
450       if (s1->nspace == 0)
451 	{
452 	  sRefSet_grow (s1);
453 	}
454 
455       s1->elements[s1->entries] = el;
456       s1->nspace--;
457       s1->entries++;
458     } end_sRefSet_allElements;
459 
460   return s1;
461 }
462 
463 /*@only@*/ sRefSet
sRefSet_newCopy(sRefSet s)464   sRefSet_newCopy (/*@exposed@*/ sRefSet s)
465 {
466   if (sRefSet_isEmpty (s))
467     {
468       return sRefSet_undefined;
469     }
470   else
471     {
472       sRefSet r = (sRefSet) dmalloc (sizeof (*r));
473       int i;
474 
475       r->entries = s->entries;
476       r->nspace = s->nspace;
477       r->elements = (sRef *) dmalloc (sizeof (*r->elements) * (s->entries + s->nspace));
478 
479       for (i = 0; i < s->entries; i++)
480 	{
481 	  r->elements[i] = s->elements[i];
482 	}
483 
484       return r;
485     }
486 }
487 
488 /*@only@*/ sRefSet
sRefSet_levelCopy(sRefSet s,int lexlevel)489 sRefSet_levelCopy (/*@exposed@*/ sRefSet s, int lexlevel)
490 {
491   if (sRefSet_isEmpty (s))
492     {
493       return sRefSet_undefined;
494     }
495   else
496     {
497       sRefSet r = (sRefSet) dmalloc (sizeof (*r));
498       int i;
499 
500       r->nspace = s->entries;
501       r->entries = 0;
502       r->elements = (sRef *) dmalloc (sizeof (*r->elements) * (s->entries));
503 
504       for (i = 0; i < s->entries; i++)
505 	{
506 	  if (sRef_lexLevel (s->elements[i]) <= lexlevel)
507 	    {
508 	      r->elements[r->entries] = s->elements[i];
509 	      r->entries++;
510 	      r->nspace--;
511 	    }
512 	}
513 
514       return r;
515     }
516 }
517 
518 /*@only@*/ sRefSet
sRefSet_newDeepCopy(sRefSet s)519 sRefSet_newDeepCopy (sRefSet s)
520 {
521   if (sRefSet_isUndefined (s))
522     {
523       return sRefSet_newEmpty ();
524     }
525   else
526     {
527       sRefSet r = (sRefSet) dmalloc (sizeof (*r));
528       int i;
529 
530       r->entries = s->entries;
531       r->nspace = s->nspace;
532       r->elements = (sRef *) dmalloc (sizeof (*r->elements) * (s->entries + s->nspace));
533 
534       for (i = 0; i < s->entries; i++)
535 	{
536 	  r->elements[i] = sRef_copy (s->elements[i]);
537 	}
538 
539       return r;
540     }
541 }
542 
543 static bool
sRefSet_isElementCompare(bool (* test)(sRef,sRef),sRefSet s,sRef el)544 sRefSet_isElementCompare (bool (*test)(sRef, sRef), sRefSet s, sRef el)
545 {
546   sRefSet_allElements (s, e)
547     {
548       if ((test)(el, e))
549 	{
550 	  return TRUE;
551 	}
552     } end_sRefSet_allElements;
553 
554   return FALSE;
555 }
556 
557 static bool
sRefSet_isElementTest(bool (* test)(sRef),sRefSet s)558 sRefSet_isElementTest (bool (*test)(sRef), sRefSet s)
559 {
560   sRefSet_allElements (s, e)
561     {
562       if ((test)(e))
563 	{
564 	  return TRUE;
565 	}
566     } end_sRefSet_allElements;
567 
568   return FALSE;
569 }
570 
571 bool
sRefSet_hasRealElement(sRefSet s)572 sRefSet_hasRealElement (sRefSet s)
573 {
574   sRefSet_allElements (s, e)
575     {
576       if (sRef_isMeaningful (e) && !sRef_isUnconstrained (e))
577 	{
578 	  return TRUE;
579 	}
580     } end_sRefSet_allElements;
581 
582   return FALSE;
583 }
584 
585 bool
sRefSet_containsSameObject(sRefSet s,sRef el)586 sRefSet_containsSameObject (sRefSet s, sRef el)
587 {
588   return (sRefSet_isElementCompare (sRef_sameObject, s, el));
589 }
590 
591 bool
sRefSet_isSameMember(sRefSet s,sRef el)592 sRefSet_isSameMember (sRefSet s, sRef el)
593 {
594   return (sRefSet_isElementCompare (sRef_realSame, s, el));
595 }
596 
597 bool
sRefSet_isSameNameMember(sRefSet s,sRef el)598 sRefSet_isSameNameMember (sRefSet s, sRef el)
599 {
600   return (sRefSet_isElementCompare (sRef_sameName, s, el));
601 }
602 
603 bool
sRefSet_member(sRefSet s,sRef el)604 sRefSet_member (sRefSet s, sRef el)
605 {
606   return (sRefSet_isElementCompare (sRef_similar, s, el));
607 }
608 
609 bool
sRefSet_hasStatic(sRefSet s)610 sRefSet_hasStatic (sRefSet s)
611 {
612   return (sRefSet_isElementTest (sRef_isFileStatic, s));
613 }
614 
615 bool
sRefSet_hasUnconstrained(sRefSet s)616 sRefSet_hasUnconstrained (sRefSet s)
617 {
618   return (sRefSet_isElementTest (sRef_isUnconstrained, s));
619 }
620 
621 cstring
sRefSet_unparseUnconstrained(sRefSet s)622   sRefSet_unparseUnconstrained (sRefSet s)
623 {
624   int num = 0;
625   cstring res = cstring_undefined;
626 
627   sRefSet_allElements (s, el)
628     {
629       if (sRef_isUnconstrained (el))
630 	{
631 	  if (cstring_isUndefined (res))
632 	    {
633 	      res = cstring_copy (sRef_unconstrainedName (el));
634 	    }
635 	  else
636 	    {
637 	      res = message ("%q, %s", res, sRef_unconstrainedName (el));
638 	    }
639 
640 	  num++;
641 	}
642     } end_sRefSet_allElements ;
643 
644   if (num == 0)
645     {
646       llassert (cstring_isUndefined (res));
647       return (cstring_makeLiteral ("<ERROR: no unconstrained calls>"));
648     }
649   else if (num == 1)
650     {
651       return (message ("unconstrained function %q", res));
652     }
653   else
654     {
655       return (message ("unconstrained functions %q", res));
656     }
657 }
658 
659 cstring
sRefSet_unparseUnconstrainedPlain(sRefSet s)660 sRefSet_unparseUnconstrainedPlain (sRefSet s)
661 {
662   cstring res = cstring_undefined;
663 
664   sRefSet_allElements (s, el)
665     {
666       if (sRef_isUnconstrained (el))
667 	{
668 	  if (cstring_isUndefined (res))
669 	    {
670 	      res = cstring_copy (sRef_unconstrainedName (el));
671 	    }
672 	  else
673 	    {
674 	      res = message ("%q, %s", res, sRef_unconstrainedName (el));
675 	    }
676 	}
677     } end_sRefSet_allElements ;
678 
679   return res;
680 }
681 
682 bool
sRefSet_modifyMember(sRefSet s,sRef m)683 sRefSet_modifyMember (sRefSet s, sRef m)
684 {
685   bool ret = FALSE;
686 
687   sRefSet_allElements (s, e)
688     {
689       if (sRef_similar (m, e))
690 	{
691 	  sRef_setModified (e);
692 	  ret = TRUE;
693 	}
694     } end_sRefSet_allElements;
695 
696 
697   return ret;
698 }
699 
700 /*@exposed@*/ sRef
sRefSet_lookupMember(sRefSet s,sRef el)701 sRefSet_lookupMember (sRefSet s, sRef el)
702 {
703   sRefSet_allElements (s, e)
704     {
705       if (sRef_similar (el, e))
706 	{
707 	  return e;
708 	}
709     } end_sRefSet_allElements;
710 
711   return sRef_undefined;
712 }
713 
sRefSet_size(sRefSet s)714 int sRefSet_size (sRefSet s)
715 {
716   if (sRefSet_isUndefined (s)) return 0;
717   return s->entries;
718 }
719 
720 /*@only@*/ cstring
sRefSet_unparse(sRefSet s)721 sRefSet_unparse (sRefSet s)
722 {
723   int i;
724   cstring st = cstring_makeLiteral ("{");
725 
726   if (sRefSet_isDefined (s))
727     {
728       for (i = 0; i < sRefSet_size (s); i++)
729 	{
730 	  if (i == 0)
731 	    st = message ("%q %q", st, sRef_unparse (s->elements[i]));
732 	  else
733 	    st = message ("%q, %q", st, sRef_unparse (s->elements[i]));
734 	}
735     }
736 
737   st = message ("%q }", st);
738   return st;
739 }
740 
sRefSet_unparsePlain(sRefSet s)741 cstring sRefSet_unparsePlain (sRefSet s)
742 {
743   int i;
744   cstring st = cstring_undefined;
745 
746   if (sRefSet_isDefined (s))
747     {
748       for (i = 0; i < sRefSet_size (s); i++)
749 	{
750 	  if (i == 0)
751 	    st = sRef_unparse (s->elements[i]);
752 	  else
753 	    st = message ("%q, %q", st, sRef_unparse (s->elements[i]));
754 	}
755     }
756 
757   return st;
758 }
759 
760 cstring
sRefSet_unparseDebug(sRefSet s)761 sRefSet_unparseDebug (sRefSet s)
762 {
763   int i;
764   cstring st = cstring_makeLiteral ("{");
765 
766   if (sRefSet_isDefined (s))
767     {
768       for (i = 0; i < sRefSet_size (s); i++)
769 	{
770 	  if (i == 0)
771 	    {
772 	      st = message ("%q %q", st, sRef_unparseDebug (s->elements[i]));
773 	    }
774 	  else
775 	    {
776 	      st = message ("%q, %q", st, sRef_unparseDebug (s->elements[i]));
777 	    }
778 	}
779     }
780 
781   st = message ("%q }", st);
782   return st;
783 }
784 
785 cstring
sRefSet_unparseFull(sRefSet s)786 sRefSet_unparseFull (sRefSet s)
787 {
788   int i;
789   cstring st = cstring_makeLiteral ("{");
790 
791   if (sRefSet_isDefined (s))
792     {
793       for (i = 0; i < sRefSet_size (s); i++)
794 	{
795 	  if (i == 0)
796 	    {
797 	      st = message ("%q %q", st, sRef_unparseFull (s->elements[i]));
798 	    }
799 	  else
800 	    {
801 	      st = message ("%q, %q", st, sRef_unparseFull (s->elements[i]));
802 	    }
803 	}
804     }
805 
806   st = message ("%q }", st);
807   return st;
808 }
809 
810 void
sRefSet_fixSrefs(sRefSet s)811 sRefSet_fixSrefs (sRefSet s)
812 {
813   if (sRefSet_isDefined (s))
814     {
815       int i;
816 
817       for (i = 0; i < sRefSet_size (s); i++)
818 	{
819 	  sRef current = s->elements[i];
820 
821 	  if (sRef_isLocalVar (current))
822 	    {
823 	      s->elements[i] = uentry_getSref (sRef_getUentry (current));
824 	    }
825 	}
826     }
827 }
828 
829 void
sRefSet_free(sRefSet s)830 sRefSet_free (/*@only@*/ sRefSet s)
831 {
832   if (!sRefSet_isUndefined (s))
833     {
834       /* evans 2003-10-20: increase size sanity limit from 1000 */
835       llassertprint (s->entries < 99999, ("sRefSet free size: %d", s->entries));
836 
837       sfree (s->elements);
838       sfree (s);
839     }
840 }
841 
sRefSet_removeIndirection(sRefSet s)842 sRefSet sRefSet_removeIndirection (sRefSet s)
843 {
844   /*
845   ** returns a NEW sRefSet containing references to all sRef's in s
846   */
847 
848   sRefSet t = sRefSet_new ();
849 
850 
851   sRefSet_allElements (s, el)
852     {
853       if (!sRef_isAddress (el))
854 	{
855 	  t = sRefSet_insert (t, sRef_makeAddress (el));
856 	}
857     } end_sRefSet_allElements;
858 
859   return t;
860 }
861 
sRefSet_addIndirection(sRefSet s)862 sRefSet sRefSet_addIndirection (sRefSet s)
863 {
864   /*
865   ** returns a NEW sRefSet containing references to all sRef's in s
866   */
867 
868   sRefSet t = sRefSet_new ();
869 
870 
871   sRefSet_allElements (s, el)
872     {
873       ctype ct = ctype_realType (sRef_getType (el));
874 
875 
876       if ((ctype_isArrayPtr (ct)))
877 	{
878 
879 	  sRef a = sRef_constructPointer (el);
880 	  t = sRefSet_insert (t, a);
881 	}
882     } end_sRefSet_allElements;
883 
884     return t;
885 }
886 
sRefSet_accessField(sRefSet s,cstring f)887 sRefSet sRefSet_accessField (sRefSet s, /*@observer@*/ cstring f)
888 {
889   /*
890   ** returns a NEW sRefSet containing references to all sRef's in s
891   */
892 
893   sRefSet t = sRefSet_new ();
894 
895   sRefSet_allElements (s, el)
896     {
897       ctype ct = ctype_realType (sRef_getType (el));
898 
899       if ((ctype_isStruct (ct) || ctype_isUnion (ct))
900 	  && (!uentry_isUndefined (uentryList_lookupField (ctype_getFields (ct), f))))
901 	{
902 	  t = sRefSet_insert (t, sRef_makeNCField (el, f));
903 	}
904     } end_sRefSet_allElements;
905 
906     return t;
907 }
908 
sRefSet_fetchUnknown(sRefSet s)909 sRefSet sRefSet_fetchUnknown (sRefSet s)
910 {
911   sRefSet t = sRefSet_new ();
912 
913   sRefSet_allElements (s, el)
914     {
915       ctype ct = ctype_realType (sRef_getType (el));
916 
917       if (ctype_isArrayPtr (ct))
918 	{
919 	  t = sRefSet_insert (t, sRef_makeArrayFetch (el));
920 	}
921     } end_sRefSet_allElements;
922 
923   return t;
924 }
925 
sRefSet_fetchKnown(sRefSet s,int i)926 sRefSet sRefSet_fetchKnown (sRefSet s, int i)
927 {
928   sRefSet t = sRefSet_new ();
929 
930   sRefSet_allElements (s, el)
931     {
932       ctype ct = ctype_realType (sRef_getType (el));
933 
934       if (ctype_isArrayPtr (ct))
935 	{
936 	  t = sRefSet_insert (t, sRef_makeArrayFetchKnown (el, i));
937 	}
938     } end_sRefSet_allElements;
939 
940   return t;
941 }
942 
sRefSet_compare(sRefSet s1,sRefSet s2)943 int sRefSet_compare (sRefSet s1, sRefSet s2)
944 {
945   sRefSet_allElements (s1, el)
946     {
947       if (!sRefSet_isSameMember (s2, el))
948 	{
949 	  return -1;
950 	}
951     } end_sRefSet_allElements;
952 
953   sRefSet_allElements (s2, el)
954     {
955       if (!sRefSet_isSameMember (s1, el))
956 	{
957 	  return 1;
958 	}
959     } end_sRefSet_allElements;
960 
961   return 0;
962 }
963 
sRefSet_equal(sRefSet s1,sRefSet s2)964 bool sRefSet_equal (sRefSet s1, sRefSet s2)
965 {
966   sRefSet_allElements (s1, el)
967     {
968       if (!sRefSet_isSameMember (s2, el))
969 	{
970 	  return FALSE;
971 	}
972     } end_sRefSet_allElements;
973 
974   sRefSet_allElements (s2, el)
975     {
976       if (!sRefSet_isSameMember (s1, el))
977 	{
978 	  return FALSE;
979 	}
980     } end_sRefSet_allElements;
981 
982   return TRUE;
983 }
984 
985 /*@only@*/ sRefSet
sRefSet_undump(char ** s)986 sRefSet_undump (char **s)
987 {
988   char c;
989   sRefSet sl = sRefSet_new ();
990 
991   while ((c = **s) != '#' && c != '@' && c != '$' && c != '&')
992     {
993       sl = sRefSet_insert (sl, sRef_undump (s));
994 
995 
996       if (**s == ',')
997 	{
998 	  (*s)++;
999 	}
1000     }
1001 
1002     return sl;
1003 }
1004 
1005 /*@only@*/ cstring
sRefSet_dump(sRefSet sl)1006 sRefSet_dump (sRefSet sl)
1007 {
1008   cstring st = cstring_undefined;
1009   bool first = TRUE;
1010 
1011 
1012   sRefSet_allElements (sl, el)
1013     {
1014       if (!first)
1015 	{
1016 	  st = cstring_appendChar (st, ',');
1017 	}
1018       else
1019 	{
1020 	  first = FALSE;
1021 	}
1022 
1023       st = cstring_concatFree (st, sRef_dump (el));
1024     } end_sRefSet_allElements;
1025 
1026   return st;
1027 }
1028 
1029 void
sRefSet_markImmutable(sRefSet s)1030 sRefSet_markImmutable (sRefSet s)
1031 {
1032   sRefSet_allElements (s, el)
1033     {
1034       sRef_markImmutable (el);
1035     } end_sRefSet_allElements;
1036 }
1037 
1038