Some consistency changes to library & headers flags.
[splint-patched.git] / src / stateClauseList.c
blob8c58c3e15635a5346a53bd82bdeafec11565c2a3
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.
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
25 ** stateClauseList.c
28 # include "splintMacros.nf"
29 # include "basic.h"
31 /*@constant int stateClauseListBASESIZE;@*/
32 # define stateClauseListBASESIZE MIDBASESIZE
34 static /*@notnull@*/ stateClauseList stateClauseList_new (void)
36 stateClauseList s = (stateClauseList) dmalloc (sizeof (*s));
38 s->nelements = 0;
39 s->nspace = stateClauseListBASESIZE;
40 s->elements = (stateClause *)
41 dmalloc (sizeof (*s->elements) * stateClauseListBASESIZE);
43 return (s);
46 static void
47 stateClauseList_grow (stateClauseList s)
49 int i;
50 stateClause *newelements;
52 llassert (stateClauseList_isDefined (s));
54 s->nspace += stateClauseListBASESIZE;
56 newelements = (stateClause *)
57 dmalloc (sizeof (*newelements) * (s->nelements + s->nspace));
59 for (i = 0; i < s->nelements; i++)
61 newelements[i] = s->elements[i];
64 sfree (s->elements);
65 s->elements = newelements;
68 stateClauseList stateClauseList_add (stateClauseList s, stateClause el)
70 DPRINTF (("Adding: %s", stateClause_unparse (el)));
72 if (stateClauseList_isUndefined (s))
74 s = stateClauseList_new ();
76 else
78 stateClauseList_elements (s, cl)
80 if (stateClause_sameKind (cl, el))
82 voptgenerror
83 (FLG_SYNTAX,
84 message ("Multiple %q clauses for one function (ignoring second)",
85 stateClause_unparseKind (cl)),
86 g_currentloc);
88 stateClause_free (el);
89 return s;
91 } end_stateClauseList_elements ;
94 if (s->nspace <= 0)
96 stateClauseList_grow (s);
99 s->nspace--;
100 s->elements[s->nelements] = el;
101 s->nelements++;
103 return s;
106 cstring stateClauseList_unparse (stateClauseList s)
108 cstring st = cstring_undefined;
109 int i;
111 if (stateClauseList_isDefined (s))
113 for (i = 0; i < stateClauseList_size (s); i++)
115 if (i == 0)
117 st = message ("%q;", stateClause_unparse (s->elements[i]));
119 else
120 st = message ("%q %q;", st, stateClause_unparse (s->elements[i]));
124 return (st);
127 stateClauseList stateClauseList_copy (stateClauseList s)
129 if (stateClauseList_isDefined (s))
131 stateClauseList t = (stateClauseList) dmalloc (sizeof (*t));
132 int i;
134 t->nelements = s->nelements;
135 t->nspace = 0;
137 if (s->nelements > 0)
139 t->elements = (stateClause *) dmalloc (sizeof (*t->elements) * t->nelements);
140 for (i = 0; i < s->nelements; i++)
142 t->elements[i] = stateClause_copy (s->elements[i]);
145 else
147 t->elements = NULL;
150 return t;
152 else
154 return stateClauseList_undefined;
158 void
159 stateClauseList_free (stateClauseList s)
161 if (!stateClauseList_isUndefined (s))
163 int i;
165 for (i = 0; i < s->nelements; i++)
167 stateClause_free (s->elements[i]);
170 sfree (s->elements);
171 sfree (s);
175 cstring stateClauseList_dump (stateClauseList s)
177 cstring st = cstring_undefined;
179 if (stateClauseList_isUndefined (s)) return st;
181 stateClauseList_elements (s, current)
183 st = message ("%q%q$", st, stateClause_dump (current));
184 } end_stateClauseList_elements;
186 return st;
189 stateClauseList stateClauseList_undump (char **s)
191 char c;
192 stateClauseList pn = stateClauseList_new ();
193 int paramno = 0;
195 c = **s;
197 while (c != '#' && c != '@')
199 stateClause sc = stateClause_undump (s);
201 pn = stateClauseList_add (pn, sc);
202 reader_checkChar (s, '$');
203 c = **s;
204 paramno++;
207 return pn;
210 # ifdef DEADCODE
211 int stateClauseList_compare (stateClauseList s1, stateClauseList s2)
213 if (stateClauseList_isUndefined (s1)
214 && stateClauseList_isUndefined (s2))
216 return 0;
218 else
220 if (s1 - s2 > 0) /* evans 2001-08-21: was (int) s1 > (int) s2) */
222 return 1;
224 else
226 return -1;
230 # endif /* DEADCODE */
232 static /*@exposed@*/ sRefSet
233 stateClauseList_getClause (stateClauseList s, stateClause k)
235 stateClauseList_elements (s, el)
237 if (stateClause_matchKind (el, k))
239 return stateClause_getRefs (el);
241 } end_stateClauseList_elements ;
243 return sRefSet_undefined;
246 void stateClauseList_checkAll (uentry ue)
248 stateClauseList clauses = uentry_getStateClauseList (ue);
249 sRef res = uentry_getSref (ue);
250 bool specialResult = FALSE;
252 DPRINTF (("Check state clauses: %s", uentry_unparseFull (ue)));
254 stateClauseList_elements (clauses, cl)
256 bool isPre = stateClause_isBeforeOnly (cl);
258 if (stateClause_isGlobal (cl))
262 else
264 sRefSet refs = stateClause_getRefs (cl);
266 sRefSet_allElements (refs, el)
268 sRef rb = sRef_getRootBase (el);
270 DPRINTF (("Check: %s", sRef_unparse (el)));
272 if (sRef_isResult (rb))
275 ** The result type is now know, need to set it:
278 if (ctype_isUnknown (sRef_getType (rb)))
280 ctype utype = uentry_getType (ue);
281 llassert (ctype_isFunction (utype));
283 sRef_setTypeFull (rb, ctype_getReturnType (utype));
284 DPRINTF (("el: %s", sRef_unparseFull (el)));
288 if (stateClause_setsMetaState (cl))
290 qual q = stateClause_getMetaQual (cl);
291 annotationInfo qa = qual_getAnnotationInfo (q);
293 if (!annotationInfo_matchesContextRef (qa, el))
295 if (optgenerror
296 (FLG_ANNOTATIONERROR,
297 message ("Attribute annotation %s used on inappropriate reference %q in %q clause of %q: %q",
298 qual_unparse (q),
299 sRef_unparse (el),
300 stateClause_unparseKind (cl),
301 uentry_getName (ue),
302 stateClause_unparse (cl)),
303 uentry_whereLast (ue)))
305 /* annotationInfo_showContextError (ainfo, ue); */
310 if (sRef_isResult (rb))
312 if (isPre)
314 voptgenerror
315 (FLG_INCONDEFS,
316 message ("Function result is used in %q clause of %q "
317 "(%q applies to the state before function is "
318 "called, so should not use result): %q",
319 stateClause_unparseKind (cl),
320 uentry_getName (ue),
321 stateClause_unparseKind (cl),
322 sRef_unparse (el)),
323 uentry_whereLast (ue));
325 else
327 if (!sRef_isStateSpecial (res))
329 DPRINTF (("Here we are: %s", sRef_unparseFull (res)));
331 if (!specialResult)
333 sstate pstate = sRef_getDefState (res);
335 if (!sRef_makeStateSpecial (res))
337 if (optgenerror
338 (FLG_INCONDEFS,
339 message ("Function result is used in %q clause of %q "
340 "but was previously annotated with %s: %q",
341 stateClause_unparseKind (cl),
342 uentry_getName (ue),
343 sstate_unparse (pstate),
344 sRef_unparse (el)),
345 uentry_whereLast (ue)))
347 specialResult = TRUE;
353 DPRINTF (("Fixing result type! %s", sRef_unparseFull (el)));
354 (void) sRef_fixResultType (el, sRef_getType (res), ue);
357 else if (sRef_isParam (rb))
359 DPRINTF (("Make special: %s", sRef_unparseFull (rb)));
361 if (!sRef_makeStateSpecial (rb))
363 if (fileloc_isXHFile (uentry_whereLast (ue)))
365 ; /* Okay to override in .xh files */
367 else if (stateClause_isQual (cl))
369 ; /* qual clauses don't interfere with definition state */
371 else
373 voptgenerror
374 (FLG_INCONDEFS,
375 message ("Reference %q used in %q clause of %q, "
376 "but was previously annotated with %s: %q",
377 sRef_unparse (rb),
378 stateClause_unparseKind (cl),
379 uentry_getName (ue),
380 sstate_unparse (sRef_getDefState (res)),
381 sRef_unparse (el)),
382 uentry_whereLast (ue));
386 DPRINTF (("Made special: %s", sRef_unparseFull (rb)));
388 else if (sRef_isInvalid (rb))
390 /*@innercontinue@*/ continue;
392 else
394 BADBRANCHCONT;
395 /*@innercontinue@*/ continue;
398 if (stateClause_isMemoryAllocation (cl))
400 if (!ctype_isVisiblySharable (sRef_getType (el)))
402 voptgenerror
403 (FLG_ANNOTATIONERROR,
404 /*@-sefparams@*/ /* This is okay because its fresh storage. */
405 message
406 ("%q clauses includes %q of "
407 "non-dynamically allocated type %s",
408 cstring_capitalizeFree (stateClause_unparseKind (cl)),
409 sRef_unparse (el),
410 ctype_unparse (sRef_getType (el))),
411 uentry_whereLast (ue));
412 /*@=sefparams@*/
416 } end_sRefSet_allElements ;
418 } end_stateClauseList_elements ;
421 void stateClauseList_checkEqual (uentry old, uentry unew)
423 stateClauseList oldClauses = uentry_getStateClauseList (old);
424 stateClauseList newClauses = uentry_getStateClauseList (unew);
426 if (stateClauseList_isDefined (newClauses))
428 stateClauseList_elements (newClauses, cl)
430 if (stateClause_isGlobal (cl))
434 else
436 sRefSet sc = stateClauseList_getClause (oldClauses, cl);
438 if (!sRefSet_equal (sc, stateClause_getRefs (cl)))
440 if (optgenerror
441 (FLG_INCONDEFS,
442 message ("Function %q %rdeclared with inconsistent %q clause: %q",
443 uentry_getName (old),
444 uentry_isDeclared (old),
445 stateClause_unparseKind (cl),
446 sRefSet_unparsePlain (stateClause_getRefs (cl))),
447 g_currentloc))
449 uentry_showWhereLastExtra (old, sRefSet_unparsePlain (sc));
453 } end_stateClauseList_elements ;
455 stateClauseList_elements (oldClauses, cl)
457 if (stateClause_isGlobal (cl))
459 ; /* Don't handle globals for now */
461 else
463 sRefSet sc = stateClauseList_getClause (newClauses, cl);
465 if (sRefSet_isUndefined (sc) && !sRefSet_isEmpty (stateClause_getRefs (cl)))
467 if (optgenerror
468 (FLG_INCONDEFS,
469 message ("Function %q %rdeclared without %q clause (either "
470 "use no special clauses in redeclaration, or "
471 "they must match exactly: %q",
472 uentry_getName (old),
473 uentry_isDeclared (old),
474 stateClause_unparseKind (cl),
475 sRefSet_unparsePlain (stateClause_getRefs (cl))),
476 g_currentloc))
478 uentry_showWhereLastExtra (old, sRefSet_unparsePlain (sc));
482 } end_stateClauseList_elements ;