2 ** vim
: set syntax
=c filetype
=c shiftwidth
=2 softtabstop
=2 expandtab
:
4 ** Splint
- annotation-assisted static program checker
5 ** Copyright
(C
) 1994-2003 University of Virginia
,
6 ** Massachusetts Institute of Technology
8 ** This program is free software
; you can redistribute it and
/or modify it
9 ** under the terms of the GNU General Public License as published by the
10 ** Free Software Foundation
; either version
2 of the License
, or
(at your
11 ** option
) any later version.
13 ** This program is distributed in the hope that it will be useful
, but
14 ** WITHOUT
ANY WARRANTY
; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU
16 ** General Public License for more details.
18 ** The GNU General Public License is available from http
://www.gnu.org
/ or
19 ** the Free Software Foundation
, Inc.
, 59 Temple Place
- Suite
330, Boston
,
20 ** MA
02111-1307, USA.
22 ** For information on splint
: info@splint.org
23 ** To report a bug
: splint-bug@splint.org
24 ** For more information
: http
://www.splint.org
29 ** NOTE
: This is not a stand-alone source file
, but is included in ctype.c.
30 ** (This is necessary becuase there is no other way in C to have a
31 ** hidden scope
, besides at the file level.
)
37 ** type definitions and forward declarations in ctbase.i
41 ctentry_free
(/*@only@
*/ ctentry c
)
43 ctbase_free
(c-
>ctbase
);
44 cstring_free
(c-
>unparse
);
48 static void cttable_reset
(void
)
52 if
(cttab.entries
!= NULL)
56 for
(i
= 0; i
< cttab.size
; i
++)
58 /*drl bee
: si
*/ ctentry_free
(cttab.entries
[i
]);
62 sfree
(cttab.entries
);
73 ctentry_makeNew
(ctkind ctk
, /*@only@
*/ ctbase c
)
76 return
(ctentry_make
(ctk
, c
, ctype_dne
, ctype_dne
, ctype_dne
, cstring_undefined
));
79 static
/*@only@
*/ ctentry
80 ctentry_make
(ctkind ctk
,
81 /*@keep@
*/ ctbase c
, ctype base
,
82 ctype ptr
, ctype array
,
83 /*@keep@
*/ cstring unparse
) /*@
*/
85 ctentry cte
= (ctentry
) dmalloc
(sizeof
(*cte
));
91 cte-
>unparse
= unparse
;
96 ctentry_unparse
(ctentry c
)
99 ("%20s [%d] [%d] [%d]",
100 (cstring_isDefined
(c-
>unparse
) ? c-
>unparse
: cstring_makeLiteral
("<no name>")),
107 ctentry_isInteresting
(ctentry c
)
109 return
(cstring_isNonEmpty
(c-
>unparse
));
112 static
/*@only@
*/ cstring
113 ctentry_dump
(ctentry c
)
115 DPRINTF
(("Dumping: %s", ctentry_unparse
(c
)));
117 if
(c-
>ptr
== ctype_dne
118 && c->array == ctype_dne
119 && c->base == ctype_dne)
121 return
(message
("%d %q&",
122 ctkind_toInt
(c-
>kind
),
123 ctbase_dump
(c-
>ctbase
)));
125 else if
(c-
>base
== ctype_undefined
126 && c->array == ctype_dne)
128 if
(c-
>ptr
== ctype_dne
)
130 return
(message
("%d %q!",
131 ctkind_toInt
(c-
>kind
),
132 ctbase_dump
(c-
>ctbase
)));
136 return
(message
("%d %q^%d",
137 ctkind_toInt
(c-
>kind
),
138 ctbase_dump
(c-
>ctbase
),
142 else if
(c-
>ptr
== ctype_dne
143 && c->array == ctype_dne)
145 return
(message
("%d %q%d&",
146 ctkind_toInt
(c-
>kind
),
147 ctbase_dump
(c-
>ctbase
),
152 return
(message
("%d %q%d %d %d",
153 ctkind_toInt
(c-
>kind
),
154 ctbase_dump
(c-
>ctbase
),
155 c-
>base
, c-
>ptr
, c-
>array
));
160 static
/*@only@
*/ ctentry
161 ctentry_undump
(/*@dependent@
*/ char
*s
) /*@requires maxRead
(s
) >= 2 @
*/
163 int base
, ptr
, array
;
167 kind
= ctkind_fromInt
(reader_getInt
(&s));
168 ct
= ctbase_undump
(&s);
170 if
(reader_optCheckChar
(&s, '&'))
176 else if
(reader_optCheckChar
(&s, '!'))
178 base
= ctype_undefined
;
182 else if
(reader_optCheckChar
(&s, '^'))
184 base
= ctype_undefined
;
185 ptr
= reader_getInt
(&s);
190 base
= reader_getInt
(&s);
192 if
(reader_optCheckChar
(&s, '&'))
199 ptr
= reader_getInt
(&s);
200 array
= reader_getInt
(&s);
204 /* can't unparse w
/o typeTable
*/
205 return
(ctentry_make
(kind
, ct
, base
, ptr
, array
, cstring_undefined
));
208 static
/*@observer@
*/ cstring
209 ctentry_doUnparse
(ctentry c
) /*@modifies c@
*/
211 if
(cstring_isDefined
(c-
>unparse
))
217 cstring s
= ctbase_unparse
(c-
>ctbase
);
219 if
(!cstring_isEmpty
(s
) && !cstring_containsChar (s, '<'))
225 cstring_markOwned
(s
);
232 static
/*@observer@
*/ cstring
233 ctentry_doUnparseDeep
(ctentry c
)
235 if
(cstring_isDefined
(c-
>unparse
))
241 c-
>unparse
= ctbase_unparseDeep
(c-
>ctbase
);
247 ** cttable operations
250 static
/*@only@
*/ cstring
251 cttable_unparse
(void
)
254 cstring s
= cstring_undefined
;
257 for
(i
= 0; i
< cttab.size
; i
++)
259 /*drl bee
: si
*/ ctentry cte
= cttab.entries
[i
];
260 if
(ctentry_isInteresting
(cte
))
262 if
(ctbase_isUA
(cte-
>ctbase
))
264 s
= message
("%s%d\t%q [%d]\n", s
, i
, ctentry_unparse
(cttab.entries
[i
]),
265 cte-
>ctbase-
>contents.tid
);
269 s
= message
("%s%d\t%q\n", s
, i
, ctentry_unparse
(cttab.entries
[i
]));
273 /*@noaccess ctbase@
*/
284 for
(i
= 0; i
< cttab.size
; i
++)
286 /*drl bee
: si
*/ ctentry cte
= cttab.entries
[i
];
288 if
(TRUE) /* ctentry_isInteresting
(cte
)) */
290 if
(ctbase_isUA
(cte-
>ctbase
))
292 fprintf
(g_warningstream
, "%3d: %s [%d]\n", i
,
293 cstring_toCharsSafe
(ctentry_doUnparse
(cttab.entries
[i
])),
294 cte-
>ctbase-
>contents.tid
);
298 fprintf
(g_warningstream
, "%3d: %s\n", i
,
299 cstring_toCharsSafe
(ctentry_doUnparse
(cttab.entries
[i
])));
304 /* fprintf
(g_warningstream
, "%3d: <no name>\n", i
); */
307 /*@noaccess ctbase@
*/
314 ** Output cttable for dump file
318 cttable_dump
(FILE *fout
)
320 bool showdots
= FALSE;
321 int showdotstride
= 0;
324 if
(context_getFlag
(FLG_SHOWSCAN
) && cttab.size > 5000)
327 displayScanOpen
(message
("Dumping type table (%d types)", cttab.size
));
328 showdotstride
= cttab.size
/ 5;
332 for
(i
= 0; i
< cttab.size
; i
++)
336 /*drl bee
: si
*/ s
= ctentry_dump
(cttab.entries
[i
]);
337 DPRINTF
(("[%d] = %s", i
, ctentry_unparse
(cttab.entries
[i
])));
338 llassert
(cstring_length
(s
) < MAX_DUMP_LINE_LENGTH
);
339 fputline
(fout
, cstring_toCharsSafe
(s
));
342 if
(showdots
&& (i != 0 && ((i - 1) % showdotstride == 0)))
344 (void
) fflush
(g_warningstream
);
345 displayScanContinue
(cstring_makeLiteralTemp
("."));
346 (void
) fflush
(stderr
);
353 displayScanOpen
(cstring_makeLiteral
("Continuing dump "));
359 ** load cttable from init file
362 static void cttable_load
(FILE *f
)
364 /*@modifies cttab
, f @
*/
366 char
*s
= mstring_create
(MAX_DUMP_LINE_LENGTH
);
373 DPRINTF
(("Loading cttable: "));
377 while
(reader_readLine
(f
, s
, MAX_DUMP_LINE_LENGTH
) != NULL && *s == ';')
382 if
(mstring_length
(s
) == (MAX_DUMP_LINE_LENGTH
- 1))
384 llbug
(message
("Library line too long: %s\n", cstring_fromChars
(s
)));
387 while
(s
!= NULL && *s != ';' && *s != '\0')
391 /*drl bee
: tcf
*/ cte
= ctentry_undump
(s
);
392 ct
= cttable_addFull
(cte
);
394 DPRINTF
(("Type: %d: %s", ct
, ctype_unparse
(ct
)));
396 if
(ctbase_isConj
(cte-
>ctbase
)
397 && !(ctbase_isExplicitConj (cte->ctbase)))
399 ctype_recordConj
(ct
);
402 s
= reader_readLine
(f
, s
, MAX_DUMP_LINE_LENGTH
);
408 DPRINTF
(("Done loading cttable: "));
416 ** fill up the cttable with basic types
, and first order derivations.
417 ** this is done without using our constructors for efficiency reasons
423 static void cttable_init
(void
)
424 /*@globals cttab@
*/ /*@modifies cttab@
*/
428 ctbase ct
= ctbase_undefined
;
430 llassert
(cttab.size
== 0);
432 /* do for plain
, pointer
, arrayof
*/
433 for
(i
= CTK_PLAIN
; i
<= CTK_ARRAY
; i
++)
435 for
(j
= CTX_UNKNOWN
; j
<= CTX_LAST
; j
++)
441 ct
= ctbase_createBool
(); /* why different?
*/
443 else if
(j
== CTX_UNKNOWN
)
445 ct
= ctbase_createUnknown
();
449 ct
= ctbase_createPrim
((cprim
)j
);
452 (void
) cttable_addFull
453 (ctentry_make
(CTK_PLAIN
,
455 j
+ CTK_PREDEFINED
, j
+ CTK_PREDEFINED2
,
456 ctbase_unparse
(ct
)));
463 ct
= ctbase_makePointer
(j
);
464 /*@switchbreak@
*/ break
;
466 ct
= ctbase_makeArray
(j
);
467 /*@switchbreak@
*/ break
;
469 llbugexitlit
("cttable_init: base case");
472 (void
) cttable_addDerived
(i
, ct
, j
);
477 /**** reserve a slot for userBool
****/
478 (void
) cttable_addFull
(ctentry_make
(CTK_INVALID
, ctbase_undefined
,
479 ctype_undefined
, ctype_dne
, ctype_dne
,
489 o_ctentry
*newentries
;
491 cttab.nspace
= CTK_BASESIZE
;
492 newentries
= (ctentry
*) dmalloc
(sizeof
(*newentries
) * (cttab.size
+ cttab.nspace
));
494 if
(newentries
== NULL)
496 llfatalerror
(message
("cttable_grow: out of memory. Size: %d",
500 for
(i
= 0; i
< cttab.size
; i
++)
502 /*drl bee
: dm
*/ /*drl bee
: si
*/ newentries
[i
] = cttab.entries
[i
];
506 sfree
(cttab.entries
);
509 cttab.entries
= newentries
;
514 cttable_addDerived
(ctkind ctk
, /*@keep@
*/ ctbase cnew
, ctype base
)
516 if
(cttab.nspace
== 0)
519 /*drl bee
: si
*/ cttab.entries
[cttab.size
] =
520 ctentry_make
(ctk
, cnew
, base
, ctype_dne
, ctype_dne
, cstring_undefined
);
524 return
(cttab.size
++);
528 cttable_addComplex
(/*@only@
*/ ctbase cnew
)
529 /*@modifies cttab
; @
*/
532 if
(cnew-
>type
!= CT_FCN
&& cnew->type != CT_EXPFCN)
535 int ctstop
= cttable_lastIndex
() - DEFAULT_OPTLEVEL
;
537 if
(ctstop
< LAST_PREDEFINED
)
539 ctstop
= LAST_PREDEFINED
;
542 for
(i
= cttable_lastIndex
(); i
>= ctstop
; i--
) /* better to go from back...
*/
546 ctb
= ctype_getCtbase
(i
);
548 /* is this optimization really worthwhile?
*/
550 if
(ctbase_isDefined
(ctb
) && ctbase_equivStrict (cnew, ctb))
552 DPRINTF
(("EQUIV!! %s / %s",
553 ctbase_unparse
(cnew
),
554 ctbase_unparse
(ctb
)));
562 if
(cttab.nspace
== 0)
565 /*drl bee
: si
*/ cttab.entries
[cttab.size
] = ctentry_make
(CTK_COMPLEX
, cnew
, ctype_undefined
,
566 ctype_dne
, ctype_dne
,
570 return
(cttab.size
++);
571 /*@noaccess ctbase@
*/
575 cttable_addFull
(ctentry cnew
)
577 if
(cttab.nspace
== 0)
582 /*drl bee
: si
*/ cttab.entries
[cttab.size
] = cnew
;
585 return
(cttab.size
++);
589 cttable_addFullSafe
(/*@only@
*/ ctentry cnew
)
592 ctbase cnewbase
= cnew-
>ctbase
;
594 llassert
(ctbase_isDefined
(cnewbase
));
596 for
(i
= cttable_lastIndex
(); i
>= CT_FIRST
; i--
)
598 ctbase ctb
= ctype_getCtbase
(i
);
600 if
(ctbase_isDefined
(ctb
)
601 && ctbase_equiv (cnewbase, ctype_getCtbaseSafe (i)))
608 if
(cttab.nspace
== 0)
611 /*drl bee
: si
*/ cttab.entries
[cttab.size
] = cnew
;
615 return
(cttab.size
++);