]> andersk Git - splint.git/blame - src/stateInfo.c
Fixed all /*@i...@*/ tags (except 1).
[splint.git] / src / stateInfo.c
CommitLineData
28bf4b0b 1/*
11db3170 2** Splint - annotation-assisted static program checker
c59f5181 3** Copyright (C) 1994-2003 University of Virginia,
28bf4b0b 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**
155af98d 20** For information on splint: info@splint.org
21** To report a bug: splint-bug@splint.org
11db3170 22** For more information: http://www.splint.org
28bf4b0b 23*/
24
1b8ae690 25# include "splintMacros.nf"
28bf4b0b 26# include "basic.h"
27
16c024b5 28static /*@observer@*/ cstring stateAction_unparse (stateAction p_sa) /*@*/ ;
29
28bf4b0b 30void stateInfo_free (/*@only@*/ stateInfo a)
31{
32 if (a != NULL)
33 {
34 fileloc_free (a->loc);
35 sfree (a);
36 }
37}
38
39/*@only@*/ stateInfo stateInfo_update (/*@only@*/ stateInfo old, stateInfo newinfo)
40 /*
41 ** returns an stateInfo with the same value as new. May reuse the
42 ** storage of old. (i.e., same effect as copy, but more
43 ** efficient.)
44 */
45{
46 if (old == NULL)
47 {
16c024b5 48 DPRINTF (("Update state ==> %s", stateInfo_unparse (newinfo)));
6fcd0b1e 49 return stateInfo_copy (newinfo);
28bf4b0b 50 }
51 else if (newinfo == NULL)
52 {
53 stateInfo_free (old);
54 return NULL;
55 }
56 else
57 {
16c024b5 58 if (fileloc_equal (old->loc, newinfo->loc)
59 && old->action == newinfo->action
60 /*@-abstractcompare@*/ && old->ref == newinfo->ref /*@=abstractcompare@*/)
61 {
62 /*
63 ** Duplicate (change through alias most likely)
64 ** don't add this info
65 */
66
67 return old;
68 }
69 else
70 {
71 stateInfo snew = stateInfo_makeRefLoc (newinfo->ref,
72 newinfo->loc, newinfo->action);
73 llassert (snew->previous == NULL);
74 snew->previous = old;
75 DPRINTF (("Update state ==> %s", stateInfo_unparse (snew)));
76 return snew;
77 }
28bf4b0b 78 }
28bf4b0b 79}
80
16c024b5 81static /*@observer@*/ stateInfo stateInfo_sort (/*@temp@*/ stateInfo sinfo)
82 /* Sorts in reverse location order */
28bf4b0b 83{
16c024b5 84 DPRINTF (("Sorting: %s", stateInfo_unparse (sinfo)));
85
86 if (sinfo == NULL || sinfo->previous == NULL)
28bf4b0b 87 {
16c024b5 88 return sinfo;
28bf4b0b 89 }
90 else
91 {
16c024b5 92 stateInfo snext = stateInfo_sort (sinfo->previous);
93 stateInfo sfirst = snext;
28bf4b0b 94
16c024b5 95 DPRINTF (("sinfo/sext: %s // %s", stateInfo_unparse (sinfo), stateInfo_unparse (snext)));
96 llassert (snext != NULL);
97
98 if (!fileloc_lessthan (sinfo->loc, snext->loc))
99 {
b73d1009 100 /*@i2@*/ sinfo->previous = sfirst; /* spurious? */
16c024b5 101 DPRINTF (("Sorted ==> %s", stateInfo_unparse (sinfo)));
b73d1009 102 /*@i2@*/ return sinfo; /* spurious? */
16c024b5 103 }
104 else
105 {
106 while (snext != NULL && fileloc_lessthan (sinfo->loc, snext->loc))
107 {
108 /*
109 ** swap the order
110 */
111 fileloc tloc = snext->loc;
112 stateAction taction = snext->action;
113 sRef tref = snext->ref;
114
115 DPRINTF (("in while: sinfo/sext: %s // %s", stateInfo_unparse (sinfo), stateInfo_unparse (snext)));
116
117 snext->loc = sinfo->loc;
118 snext->action = sinfo->action;
b73d1009 119 /*@-modobserver@*/
120 snext->ref = sinfo->ref; /* Doesn't actually modifie sfirst */
121 /*@=modobserver@*/
16c024b5 122
123 sinfo->loc = tloc;
124 sinfo->action = taction;
125 sinfo->ref = tref;
b73d1009 126 /*@-mustfreeonly@*/
127 sinfo->previous = snext->previous;
128 /*@=mustfreeonly@*/
16c024b5 129 snext = snext->previous;
130 DPRINTF (("in while: sinfo/sext: %s // %s", stateInfo_unparse (sinfo), stateInfo_unparse (snext)));
131 }
132
133 DPRINTF (("Sorted ==> %s", stateInfo_unparse (sfirst)));
b73d1009 134 /*@-compmempass@*/
135 return sfirst;
136 /*@=compmempass@*/
16c024b5 137 }
138 }
28bf4b0b 139}
140
141/*@only@*/ stateInfo
16c024b5 142stateInfo_updateLoc (/*@only@*/ stateInfo old, stateAction action, fileloc loc)
28bf4b0b 143{
16c024b5 144 if (fileloc_isUndefined (loc)) {
145 loc = fileloc_copy (g_currentloc);
146 }
147
148 if (old != NULL && fileloc_equal (old->loc, loc) && old->action == action)
28bf4b0b 149 {
16c024b5 150 /*
151 ** Duplicate (change through alias most likely)
152 ** don't add this info
153 */
154
155 return old;
28bf4b0b 156 }
157 else
158 {
16c024b5 159 stateInfo snew = stateInfo_makeLoc (loc, action);
160 llassert (snew->previous == NULL);
161 snew->previous = old;
162 DPRINTF (("Update state ==> %s", stateInfo_unparse (snew)));
163 return snew;
28bf4b0b 164 }
16c024b5 165}
28bf4b0b 166
16c024b5 167/*@only@*/ stateInfo
168stateInfo_updateRefLoc (/*@only@*/ stateInfo old, /*@exposed@*/ sRef ref,
169 stateAction action, fileloc loc)
170{
171 if (fileloc_isUndefined (loc)) {
172 loc = fileloc_copy (g_currentloc);
173 }
174
175 if (old != NULL && fileloc_equal (old->loc, loc)
176 && old->action == action
177 /*@-abstractcompare*/ && old->ref == ref /*@=abstractcompare@*/)
178 {
179 /*
180 ** Duplicate (change through alias most likely)
181 ** don't add this info
182 */
183
184 return old;
185 }
186 else
187 {
188 stateInfo snew = stateInfo_makeRefLoc (ref, loc, action);
189 llassert (snew->previous == NULL);
190 snew->previous = old;
191 DPRINTF (("Update state ==> %s", stateInfo_unparse (snew)));
192 return snew;
193 }
28bf4b0b 194}
195
196/*@only@*/ stateInfo stateInfo_copy (stateInfo a)
197{
198 if (a == NULL)
199 {
200 return NULL;
201 }
202 else
203 {
204 stateInfo ret = (stateInfo) dmalloc (sizeof (*ret));
205
206 ret->loc = fileloc_copy (a->loc); /*< should report bug without copy! >*/
28bf4b0b 207 ret->ref = a->ref;
16c024b5 208 ret->action = a->action;
6fcd0b1e 209 ret->previous = stateInfo_copy (a->previous);
28bf4b0b 210
211 return ret;
212 }
213}
214
6970c11b 215/*@only@*/ /*@notnull@*/ stateInfo
216stateInfo_currentLoc (void)
217{
16c024b5 218 return stateInfo_makeLoc (g_currentloc, SA_DECLARED);
6970c11b 219}
220
28bf4b0b 221/*@only@*/ /*@notnull@*/ stateInfo
16c024b5 222stateInfo_makeLoc (fileloc loc, stateAction action)
28bf4b0b 223{
224 stateInfo ret = (stateInfo) dmalloc (sizeof (*ret));
225
16c024b5 226 if (fileloc_isUndefined (loc)) {
227 ret->loc = fileloc_copy (g_currentloc);
228 } else {
229 ret->loc = fileloc_copy (loc);
230 }
231
28bf4b0b 232 ret->ref = sRef_undefined;
16c024b5 233 ret->action = action;
6fcd0b1e 234 ret->previous = stateInfo_undefined;
235
16c024b5 236 DPRINTF (("Make loc ==> %s", stateInfo_unparse (ret)));
28bf4b0b 237 return ret;
238}
239
2f2892c2 240/*@only@*/ /*@notnull@*/ stateInfo
16c024b5 241stateInfo_makeRefLoc (/*@exposed@*/ sRef ref, fileloc loc, stateAction action)
6fcd0b1e 242 /*@post:isnull result->previous@*/
28bf4b0b 243{
244 stateInfo ret = (stateInfo) dmalloc (sizeof (*ret));
245
16c024b5 246 if (fileloc_isUndefined (loc)) {
247 ret->loc = fileloc_copy (g_currentloc);
248 } else {
249 ret->loc = fileloc_copy (loc);
250 }
251
28bf4b0b 252 ret->ref = ref;
16c024b5 253 ret->action = action;
6fcd0b1e 254 ret->previous = stateInfo_undefined;
255
28bf4b0b 256 return ret;
257}
258
259/*@only@*/ cstring
260stateInfo_unparse (stateInfo s)
261{
16c024b5 262 cstring res = cstring_makeLiteral ("");
263
264 while (stateInfo_isDefined (s)) {
265 res = message ("%q%q: ", res, fileloc_unparse (s->loc));
266 if (sRef_isValid (s->ref)) {
267 res = message ("%q through alias %q ", res, sRef_unparse (s->ref));
268 }
269
270 res = message ("%q%s; ", res, stateAction_unparse (s->action));
271 s = s->previous;
272 }
273
274 return res;
28bf4b0b 275}
276
277fileloc stateInfo_getLoc (stateInfo info)
278{
6fcd0b1e 279 if (stateInfo_isDefined (info))
280 {
28bf4b0b 281 return info->loc;
6fcd0b1e 282 }
283
284 return fileloc_undefined;
285}
286
16c024b5 287stateAction stateAction_fromNState (nstate ns)
288{
289 switch (ns)
290 {
291 case NS_ERROR:
292 case NS_UNKNOWN:
293 return SA_UNKNOWN;
294 case NS_NOTNULL:
295 case NS_MNOTNULL:
296 return SA_BECOMESNONNULL;
297 case NS_RELNULL:
298 case NS_CONSTNULL:
299 return SA_DECLARED;
300 case NS_POSNULL:
301 return SA_BECOMESPOSSIBLYNULL;
302 case NS_DEFNULL:
303 return SA_BECOMESNULL;
304 case NS_ABSNULL:
305 return SA_BECOMESPOSSIBLYNULL;
306 }
307}
308
309stateAction stateAction_fromExkind (exkind ex)
310{
311 switch (ex)
312 {
313 case XO_UNKNOWN:
314 case XO_NORMAL:
315 return SA_UNKNOWN;
316 case XO_EXPOSED:
317 return SA_EXPOSED;
318 case XO_OBSERVER:
319 return SA_OBSERVER;
320 }
321
322 BADBRANCH;
323 /*@notreached@*/ return SA_UNKNOWN;
324}
325
326stateAction stateAction_fromAlkind (alkind ak)
327{
328 switch (ak)
329 {
330 case AK_UNKNOWN:
331 case AK_ERROR:
332 return SA_UNKNOWN;
333 case AK_ONLY:
334 return SA_ONLY;
335 case AK_IMPONLY:
336 return SA_IMPONLY;
337 case AK_KEEP:
338 return SA_KEEP;
339 case AK_KEPT:
340 return SA_KEPT;
341 case AK_TEMP:
342 return SA_TEMP;
343 case AK_IMPTEMP:
344 return SA_IMPTEMP;
345 case AK_SHARED:
346 return SA_SHARED;
347 case AK_UNIQUE:
348 case AK_RETURNED:
349 return SA_DECLARED;
350 case AK_FRESH:
351 return SA_FRESH;
352 case AK_STACK:
353 return SA_XSTACK;
354 case AK_REFCOUNTED:
355 return SA_REFCOUNTED;
356 case AK_REFS:
357 return SA_REFS;
358 case AK_KILLREF:
359 return SA_KILLREF;
360 case AK_NEWREF:
361 return SA_NEWREF;
362 case AK_OWNED:
363 return SA_OWNED;
364 case AK_DEPENDENT:
365 return SA_DEPENDENT;
366 case AK_IMPDEPENDENT:
367 return SA_IMPDEPENDENT;
368 case AK_STATIC:
369 return SA_STATIC;
370 case AK_LOCAL:
371 return SA_LOCAL;
372 }
373
374 BADBRANCH;
375 /*@notreached@*/ return SA_UNKNOWN;
376}
377
378stateAction stateAction_fromSState (sstate ss)
379{
380 switch (ss)
381 {
382 case SS_UNKNOWN: return SA_DECLARED;
383 case SS_UNUSEABLE: return SA_KILLED;
384 case SS_UNDEFINED: return SA_UNDEFINED;
385 case SS_MUNDEFINED: return SA_MUNDEFINED;
386 case SS_ALLOCATED: return SA_ALLOCATED;
387 case SS_PDEFINED: return SA_PDEFINED;
388 case SS_DEFINED: return SA_DEFINED;
389 case SS_PARTIAL: return SA_PDEFINED;
390 case SS_DEAD: return SA_RELEASED;
391 case SS_HOFFA: return SA_PKILLED;
392 case SS_SPECIAL: return SA_DECLARED;
393 case SS_RELDEF: return SA_DECLARED;
394 case SS_FIXED:
395 case SS_UNDEFGLOB:
396 case SS_KILLED:
397 case SS_UNDEFKILLED:
398 case SS_LAST:
399 llbug (message ("Unexpected sstate: %s", sstate_unparse (ss)));
400 /*@notreached@*/ return SA_UNKNOWN;
401 }
402}
403
404static /*@observer@*/ cstring stateAction_unparse (stateAction sa)
405{
406 switch (sa)
407 {
408 case SA_UNKNOWN: return cstring_makeLiteralTemp ("changed <unknown modification>");
409 case SA_CHANGED: return cstring_makeLiteralTemp ("changed");
410
411 case SA_CREATED: return cstring_makeLiteralTemp ("created");
412 case SA_DECLARED: return cstring_makeLiteralTemp ("declared");
413 case SA_DEFINED: return cstring_makeLiteralTemp ("defined");
414 case SA_PDEFINED: return cstring_makeLiteralTemp ("partially defined");
415 case SA_RELEASED: return cstring_makeLiteralTemp ("released");
416 case SA_ALLOCATED: return cstring_makeLiteralTemp ("allocated");
417 case SA_KILLED: return cstring_makeLiteralTemp ("released");
418 case SA_PKILLED: return cstring_makeLiteralTemp ("possibly released");
419 case SA_MERGED: return cstring_makeLiteralTemp ("merged");
420 case SA_UNDEFINED: return cstring_makeLiteralTemp ("becomes undefined");
421 case SA_MUNDEFINED: return cstring_makeLiteralTemp ("possibly undefined");
422
423 case SA_SHARED: return cstring_makeLiteralTemp ("becomes shared");
424 case SA_ONLY: return cstring_makeLiteralTemp ("becomes only");
425 case SA_IMPONLY: return cstring_makeLiteralTemp ("becomes implicitly only");
426 case SA_OWNED: return cstring_makeLiteralTemp ("becomes owned");
427 case SA_DEPENDENT: return cstring_makeLiteralTemp ("becomes dependent");
428 case SA_IMPDEPENDENT: return cstring_makeLiteralTemp ("becomes implicitly dependent");
429 case SA_KEPT: return cstring_makeLiteralTemp ("becomes kept");
430 case SA_KEEP: return cstring_makeLiteralTemp ("becomes keep");
431 case SA_FRESH: return cstring_makeLiteralTemp ("becomes fresh");
432 case SA_TEMP: return cstring_makeLiteralTemp ("becomes temp");
433 case SA_IMPTEMP: return cstring_makeLiteralTemp ("becomes implicitly temp");
434 case SA_XSTACK: return cstring_makeLiteralTemp ("becomes stack-allocated storage");
435 case SA_STATIC: return cstring_makeLiteralTemp ("becomes static");
436 case SA_LOCAL: return cstring_makeLiteralTemp ("becomes local");
437
438 case SA_REFCOUNTED: return cstring_makeLiteralTemp ("becomes refcounted");
439 case SA_REFS: return cstring_makeLiteralTemp ("becomes refs");
440 case SA_NEWREF: return cstring_makeLiteralTemp ("becomes newref");
441 case SA_KILLREF: return cstring_makeLiteralTemp ("becomes killref");
442
443 case SA_OBSERVER: return cstring_makeLiteralTemp ("becomes observer");
444 case SA_EXPOSED: return cstring_makeLiteralTemp ("becomes exposed");
445
446 case SA_BECOMESNULL: return cstring_makeLiteralTemp ("becomes null");
447 case SA_BECOMESNONNULL: return cstring_makeLiteralTemp ("becomes non-null");
448 case SA_BECOMESPOSSIBLYNULL: return cstring_makeLiteralTemp ("becomes possibly null");
449 }
450
451 DPRINTF (("Bad state action: %d", sa));
452 BADBRANCH;
453}
454
6fcd0b1e 455void stateInfo_display (stateInfo s, cstring sname)
456{
16c024b5 457 bool showdeep = context_flagOn (FLG_SHOWDEEPHISTORY, g_currentloc);
458
459 s = stateInfo_sort (s);
460
6fcd0b1e 461 while (stateInfo_isDefined (s))
462 {
16c024b5 463 cstring msg = message ("%s%s", sname, stateAction_unparse (s->action));
464
6fcd0b1e 465 if (sRef_isValid (s->ref)) {
16c024b5 466 msg = message ("%q (through alias %q)", msg, sRef_unparse (s->ref));
6fcd0b1e 467 }
16c024b5 468
6fcd0b1e 469 llgenindentmsg (msg, s->loc);
16c024b5 470
471 if (!showdeep) {
472 break;
473 }
474
6fcd0b1e 475 s = s->previous;
28bf4b0b 476 }
477
6fcd0b1e 478 cstring_free (sname);
28bf4b0b 479}
480
6fcd0b1e 481
This page took 0.148267 seconds and 5 git commands to generate.