2 ** LCLint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2000 University of Virginia,
4 ** Massachusetts Institute of Technology
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
20 ** For information on lclint: lclint-request@cs.virginia.edu
21 ** To report a bug: lclint-bug@cs.virginia.edu
22 ** For more information: http://lclint.cs.virginia.edu
27 ** based on set_template.c
29 ** where T has T_equal (or change this) and T_unparse
32 # include "lclintMacros.nf"
38 return sRefSet_undefined;
41 static /*@notnull@*/ /*@only@*/ sRefSet
42 sRefSet_newEmpty (void)
44 sRefSet s = (sRefSet) dmalloc (sizeof (*s));
47 s->nspace = sRefSetBASESIZE;
48 s->elements = (sRef *) dmalloc (sizeof (*s->elements) * sRefSetBASESIZE);
54 sRefSet_single (/*@exposed@*/ sRef sr)
56 sRefSet s = (sRefSet) dmalloc (sizeof (*s));
59 s->nspace = sRefSetBASESIZE - 1;
60 s->elements = (sRef *) dmalloc (sizeof (*s->elements) * sRefSetBASESIZE);
67 sRefSet_grow (/*@notnull@*/ sRefSet s)
72 s->nspace = sRefSetBASESIZE;
73 newelements = (sRef *) dmalloc (sizeof (*newelements) * (s->entries + s->nspace));
75 for (i = 0; i < s->entries; i++)
77 newelements[i] = s->elements[i];
81 s->elements = newelements;
85 sRefSet_insert (sRefSet s, /*@exposed@*/ sRef el)
87 if (sRefSet_isUndefined (s))
89 s = sRefSet_newEmpty ();
93 if (!sRefSet_isSameMember (s, el))
101 llassert (s->elements != NULL);
102 s->elements[s->entries] = el;
114 sRefSet_clear (sRefSet s)
116 if (sRefSet_isDefined (s))
118 s->nspace += s->entries;
124 ** slow algorithm...but it doesn't matter
128 sRefSet_clearStatics (sRefSet s)
130 if (sRefSet_isDefined (s))
134 for (i = 0; i < s->entries; i++)
136 sRef current = s->elements[i];
138 if (sRef_isFileStatic (sRef_getRootBase (current)))
142 for (j = i; j < s->entries - 1; j++)
144 s->elements[j] = s->elements[j+1];
156 sRefSet_delete (sRefSet s, sRef el)
160 if (sRefSet_isUndefined (s)) return FALSE;
162 if (s->elements != NULL)
164 for (i = 0; i < s->entries; i++)
166 sRef current = s->elements[i];
168 if (sRef_realSame (el, current))
172 for (j = i; j < s->entries - 1; j++)
174 s->elements[j] = s->elements[j+1];
188 sRefSet_choose (sRefSet s)
190 llassert (sRefSet_isDefined (s));
191 llassert (s->entries > 0);
192 llassert (s->elements != NULL);
194 return (s->elements[0]);
198 sRefSet_mergeIntoOne (sRefSet s)
203 if (sRefSet_isUndefined (s)) return sRef_undefined;
204 if (s->entries == 0) return sRef_undefined;
206 llassert (s->elements != NULL);
208 res = s->elements[0];
210 for (i = 1; i < s->entries; i++)
214 tmp = sRef_makeConj (res, s->elements[i]);
222 ** this is really yucky...but it works...
226 sRefSet_deleteBase (sRefSet s, sRef base)
231 if (sRefSet_isUndefined (s) || (s->elements == NULL))
236 while (i + offset < s->entries)
238 sRef current = s->elements[i + offset];
240 while (sRef_includedBy (current, base))
243 if (i + offset >= s->entries) goto doneLoop;
244 current = s->elements [i + offset];
249 s->elements [i] = current;
256 s->entries -= offset;
267 sRefSet_unionFree (/*@returned@*/ sRefSet s1, sRefSet s2)
269 sRefSet res = sRefSet_union (s1, s2);
276 sRefSet_union (/*@returned@*/ sRefSet s1, sRefSet s2)
283 if (sRefSet_isEmpty (s1))
285 s1 = sRefSet_copy (s1, s2);
289 sRefSet_allElements (s2, el)
291 s1 = sRefSet_insert (s1, el);
292 } end_sRefSet_allElements;
299 ** s1 <- s1 U (s2 - ex - params)
303 sRefSet_unionExcept (/*@returned@*/ sRefSet s1, sRefSet s2, sRef ex)
305 if (s1 == s2) return s1;
307 sRefSet_allElements (s2, el)
309 if (sRef_same (el, ex))
314 s1 = sRefSet_insert (s1, el);
316 } end_sRefSet_allElements;
322 sRefSet_realNewUnion (sRefSet s1, sRefSet s2)
324 llassert (NOALIAS (s1, s2));
326 if (sRefSet_isUndefined (s1))
328 return (sRefSet_newCopy (s2));
332 sRefSet ret = sRefSet_newCopy (s1);
334 sRefSet_allElements (s2, el)
336 ret = sRefSet_insert (ret, el);
337 } end_sRefSet_allElements;
346 sRefSet_intersect (sRefSet s1, sRefSet s2)
348 sRefSet s = sRefSet_new ();
350 llassert (NOALIAS (s1, s2));
352 sRefSet_allElements (s1, el)
354 if (sRefSet_member (s2, el))
356 s = sRefSet_insert (s, el);
358 } end_sRefSet_allElements;
364 sRefSet_levelUnion (/*@returned@*/ sRefSet sr, sRefSet s, int lexlevel)
366 llassert (NOALIAS (sr, s));
368 sRefSet_allElements (s, el)
370 if (sRef_lexLevel (el) <= lexlevel)
372 sr = sRefSet_insert (sr, el);
374 } end_sRefSet_allElements;
380 sRefSet_levelPrune (sRefSet s, int lexlevel)
382 if (sRefSet_isDefined (s))
385 int backcount = sRefSet_size (s) - 1;
387 for (i = 0; i <= backcount; i++)
389 sRef el = s->elements[i];
391 if (sRef_lexLevel (el) > lexlevel)
396 for (j = backcount; j > i; j--)
402 if (sRef_lexLevel (s->elements[j]) <= lexlevel)
404 s->elements[i] = s->elements[j];
406 if (backcount == i) s->entries++;
407 /*@innerbreak@*/ break;
425 sRefSet_copy (/*@returned@*/ sRefSet s1, /*@exposed@*/ sRefSet s2)
429 llassert (NOALIAS (s1, s2));
431 if (sRefSet_isUndefined (s1))
433 if (sRefSet_isEmpty (s2))
439 s1 = sRefSet_newEmpty ();
443 origentries = s1->entries;
445 s1->nspace = s1->entries + s1->nspace;
448 sRefSet_allElements (s2, el)
455 s1->elements[s1->entries] = el;
458 } end_sRefSet_allElements;
464 sRefSet_newCopy (/*@exposed@*/ sRefSet s)
466 if (sRefSet_isEmpty (s))
468 return sRefSet_undefined;
472 sRefSet r = (sRefSet) dmalloc (sizeof (*r));
475 r->entries = s->entries;
476 r->nspace = s->nspace;
477 r->elements = (sRef *) dmalloc (sizeof (*r->elements) * (s->entries + s->nspace));
479 for (i = 0; i < s->entries; i++)
481 r->elements[i] = s->elements[i];
489 sRefSet_levelCopy (/*@exposed@*/ sRefSet s, int lexlevel)
491 if (sRefSet_isEmpty (s))
493 return sRefSet_undefined;
497 sRefSet r = (sRefSet) dmalloc (sizeof (*r));
500 r->nspace = s->entries;
502 r->elements = (sRef *) dmalloc (sizeof (*r->elements) * (s->entries));
504 for (i = 0; i < s->entries; i++)
506 if (sRef_lexLevel (s->elements[i]) <= lexlevel)
508 r->elements[r->entries] = s->elements[i];
519 sRefSet_newDeepCopy (sRefSet s)
521 if (sRefSet_isUndefined (s))
523 return sRefSet_newEmpty ();
527 sRefSet r = (sRefSet) dmalloc (sizeof (*r));
530 r->entries = s->entries;
531 r->nspace = s->nspace;
532 r->elements = (sRef *) dmalloc (sizeof (*r->elements) * (s->entries + s->nspace));
534 for (i = 0; i < s->entries; i++)
536 r->elements[i] = sRef_copy (s->elements[i]);
544 sRefSet_isElementCompare (bool (*test)(sRef, sRef), sRefSet s, sRef el)
546 sRefSet_allElements (s, e)
552 } end_sRefSet_allElements;
558 sRefSet_isElementTest (bool (*test)(sRef), sRefSet s)
560 sRefSet_allElements (s, e)
566 } end_sRefSet_allElements;
572 sRefSet_hasRealElement (sRefSet s)
574 sRefSet_allElements (s, e)
576 if (sRef_isMeaningful (e) && !sRef_isUnconstrained (e))
580 } end_sRefSet_allElements;
586 sRefSet_isSameMember (sRefSet s, sRef el)
588 return (sRefSet_isElementCompare (sRef_realSame, s, el));
592 sRefSet_isSameNameMember (sRefSet s, sRef el)
594 return (sRefSet_isElementCompare (sRef_sameName, s, el));
598 sRefSet_member (sRefSet s, sRef el)
600 return (sRefSet_isElementCompare (sRef_similar, s, el));
604 sRefSet_hasStatic (sRefSet s)
606 return (sRefSet_isElementTest (sRef_isFileStatic, s));
610 sRefSet_hasUnconstrained (sRefSet s)
612 return (sRefSet_isElementTest (sRef_isUnconstrained, s));
616 sRefSet_unparseUnconstrained (sRefSet s)
619 cstring res = cstring_undefined;
621 sRefSet_allElements (s, el)
623 if (sRef_isUnconstrained (el))
625 if (cstring_isUndefined (res))
627 res = cstring_copy (sRef_unconstrainedName (el));
631 res = message ("%q, %s", res, sRef_unconstrainedName (el));
636 } end_sRefSet_allElements ;
640 llassert (cstring_isUndefined (res));
641 return (cstring_makeLiteral ("<ERROR: no unconstrained calls>"));
645 return (message ("unconstrained function %q", res));
649 return (message ("unconstrained functions %q", res));
654 sRefSet_unparseUnconstrainedPlain (sRefSet s)
656 cstring res = cstring_undefined;
658 sRefSet_allElements (s, el)
660 if (sRef_isUnconstrained (el))
662 if (cstring_isUndefined (res))
664 res = cstring_copy (sRef_unconstrainedName (el));
668 res = message ("%q, %s", res, sRef_unconstrainedName (el));
671 } end_sRefSet_allElements ;
677 sRefSet_modifyMember (sRefSet s, sRef m)
681 sRefSet_allElements (s, e)
683 if (sRef_similar (m, e))
685 sRef_setModified (e);
688 } end_sRefSet_allElements;
695 sRefSet_lookupMember (sRefSet s, sRef el)
697 sRefSet_allElements (s, e)
699 if (sRef_similar (el, e))
703 } end_sRefSet_allElements;
705 return sRef_undefined;
708 int sRefSet_size (sRefSet s)
710 if (sRefSet_isUndefined (s)) return 0;
715 sRefSet_unparse (sRefSet s)
718 cstring st = cstring_makeLiteral ("{");
720 if (sRefSet_isDefined (s))
722 for (i = 0; i < sRefSet_size (s); i++)
725 st = message ("%q %q", st, sRef_unparse (s->elements[i]));
727 st = message ("%q, %q", st, sRef_unparse (s->elements[i]));
731 st = message ("%q }", st);
735 cstring sRefSet_unparsePlain (sRefSet s)
738 cstring st = cstring_undefined;
740 if (sRefSet_isDefined (s))
742 for (i = 0; i < sRefSet_size (s); i++)
745 st = sRef_unparse (s->elements[i]);
747 st = message ("%q, %q", st, sRef_unparse (s->elements[i]));
755 sRefSet_unparseDebug (sRefSet s)
758 cstring st = cstring_makeLiteral ("{");
760 if (sRefSet_isDefined (s))
762 for (i = 0; i < sRefSet_size (s); i++)
766 st = message ("%q %q", st, sRef_unparseDebug (s->elements[i]));
770 st = message ("%q, %q", st, sRef_unparseDebug (s->elements[i]));
775 st = message ("%q }", st);
780 sRefSet_fixSrefs (sRefSet s)
782 if (sRefSet_isDefined (s))
786 for (i = 0; i < sRefSet_size (s); i++)
788 sRef current = s->elements[i];
790 if (sRef_isLocalVar (current))
792 s->elements[i] = uentry_getSref (sRef_getUentry (current));
799 sRefSet_free (/*@only@*/ sRefSet s)
801 if (!sRefSet_isUndefined (s))
803 llassertprint (s->entries < 1000, ("sRefSet free size: %d", s->entries));
810 sRefSet sRefSet_removeIndirection (sRefSet s)
813 ** returns a NEW sRefSet containing references to all sRef's in s
816 sRefSet t = sRefSet_new ();
819 sRefSet_allElements (s, el)
821 if (!sRef_isAddress (el))
823 t = sRefSet_insert (t, sRef_makeAddress (el));
825 } end_sRefSet_allElements;
830 sRefSet sRefSet_addIndirection (sRefSet s)
833 ** returns a NEW sRefSet containing references to all sRef's in s
836 sRefSet t = sRefSet_new ();
839 sRefSet_allElements (s, el)
841 ctype ct = ctype_realType (sRef_getType (el));
844 if ((ctype_isArrayPtr (ct)))
847 sRef a = sRef_constructPointer (el);
849 t = sRefSet_insert (t, a);
851 } end_sRefSet_allElements;
856 sRefSet sRefSet_accessField (sRefSet s, /*@observer@*/ cstring f)
859 ** returns a NEW sRefSet containing references to all sRef's in s
862 sRefSet t = sRefSet_new ();
865 sRefSet_allElements (s, el)
867 ctype ct = ctype_realType (sRef_getType (el));
869 if ((ctype_isStruct (ct) || ctype_isUnion (ct))
870 && (!uentry_isUndefined (uentryList_lookupField (ctype_getFields (ct), f))))
872 t = sRefSet_insert (t, sRef_makeNCField (el, f));
874 } end_sRefSet_allElements;
879 sRefSet sRefSet_fetchUnknown (sRefSet s)
881 sRefSet t = sRefSet_new ();
883 sRefSet_allElements (s, el)
885 ctype ct = ctype_realType (sRef_getType (el));
887 if (ctype_isArrayPtr (ct))
889 t = sRefSet_insert (t, sRef_makeArrayFetch (el));
891 } end_sRefSet_allElements;
896 sRefSet sRefSet_fetchKnown (sRefSet s, int i)
898 sRefSet t = sRefSet_new ();
900 sRefSet_allElements (s, el)
902 ctype ct = ctype_realType (sRef_getType (el));
904 if (ctype_isArrayPtr (ct))
906 t = sRefSet_insert (t, sRef_makeArrayFetchKnown (el, i));
908 } end_sRefSet_allElements;
913 int sRefSet_compare (sRefSet s1, sRefSet s2)
915 sRefSet_allElements (s1, el)
917 if (!sRefSet_isSameMember (s2, el))
921 } end_sRefSet_allElements;
923 sRefSet_allElements (s2, el)
925 if (!sRefSet_isSameMember (s1, el))
929 } end_sRefSet_allElements;
934 bool sRefSet_equal (sRefSet s1, sRefSet s2)
936 sRefSet_allElements (s1, el)
938 if (!sRefSet_isSameMember (s2, el))
942 } end_sRefSet_allElements;
944 sRefSet_allElements (s2, el)
946 if (!sRefSet_isSameMember (s1, el))
950 } end_sRefSet_allElements;
956 sRefSet_undump (char **s)
959 sRefSet sl = sRefSet_new ();
961 while ((c = **s) != '#' && c != '@' && c != '$' && c != '&')
963 sl = sRefSet_insert (sl, sRef_undump (s));
976 sRefSet_dump (sRefSet sl)
978 cstring st = cstring_undefined;
982 sRefSet_allElements (sl, el)
986 st = cstring_appendChar (st, ',');
993 st = cstring_concatFree (st, sRef_dump (el));
994 } end_sRefSet_allElements;