2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 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 splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
28 # include "splintMacros.nf"
31 static bool cprim_isReal (cprim c)
33 return (cprim_isAnyReal (c));
36 static bool cprim_isNumeric (cprim c)
38 return (cprim_isReal (c) || cprim_isInt (c));
44 if (i < CTX_UNKNOWN || i > CTX_LAST)
46 llcontbug (message ("cprim_fromInt: out of range: %d", i));
54 ** not symmetric: c1 := c2 or c2 is passed as c1
55 ** (if RELAXQUALS, c1 must be "bigger" than c2)
58 static bool cprim_closeEnoughAux (cprim p_c1, cprim p_c2, bool p_deep);
61 cprim_closeEnoughDeep (cprim c1, cprim c2)
64 ** If * c2 is passed as * c1
65 ** Comparison is slightly different since it is safe to pass int as long,
66 ** but not to pass int * as long *!
68 ** For deep comparisons, +relaxquals does not permit the long/int break.
71 return cprim_closeEnoughAux (c1, c2, TRUE);
75 cprim_closeEnough (cprim c1, cprim c2)
77 return cprim_closeEnoughAux (c1, c2, FALSE);
81 cprim_closeEnoughAux (cprim c1, cprim c2, bool deep)
83 if (c1 == c2) return TRUE;
85 DPRINTF (("cprim close: %s / %s", cprim_unparse (c1), cprim_unparse (c2)));
87 if (c1 == CTX_ANYINTEGRAL)
89 if (context_getFlag (FLG_MATCHANYINTEGRAL)
90 || context_getFlag (FLG_IGNOREQUALS))
92 return (cprim_isAnyInt (c2)
93 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
95 else if (context_getFlag (FLG_LONGINTEGRAL))
97 return (cprim_closeEnough (CTX_LINT, c2));
99 else if (context_getFlag (FLG_LONGUNSIGNEDINTEGRAL))
101 return (cprim_closeEnough (CTX_ULINT, c2));
109 if (c1 == CTX_UNSIGNEDINTEGRAL)
111 if (context_getFlag (FLG_MATCHANYINTEGRAL)
112 || context_getFlag (FLG_IGNOREQUALS))
114 if (context_getFlag (FLG_IGNORESIGNS))
116 return (cprim_isAnyUnsignedInt (c2)
117 || (cprim_isUnsignedChar (c2) && context_msgCharInt ()));
121 return (cprim_isAnyInt (c2)
122 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
125 else if (context_getFlag (FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL))
127 return (cprim_closeEnough (CTX_ULINT, c2));
135 if (c1 == CTX_SIGNEDINTEGRAL)
137 if (context_getFlag (FLG_MATCHANYINTEGRAL)
138 || context_getFlag (FLG_IGNOREQUALS))
140 return (cprim_isAnyInt (c2)
141 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
143 else if (context_getFlag (FLG_LONGSIGNEDINTEGRAL))
145 return (cprim_closeEnough (CTX_LINT, c2));
153 if (c2 == CTX_ANYINTEGRAL)
155 if (context_getFlag (FLG_MATCHANYINTEGRAL))
157 return (cprim_isAnyInt (c1)
158 || (cprim_isAnyChar (c1) && context_msgCharInt ()));
160 else if (context_getFlag (FLG_LONGINTEGRAL))
162 return (cprim_closeEnough (c1, CTX_LINT));
164 else if (context_getFlag (FLG_LONGUNSIGNEDINTEGRAL))
166 return (cprim_closeEnough (c1, CTX_ULINT));
174 if (c2 == CTX_UNSIGNEDINTEGRAL)
176 if (context_getFlag (FLG_MATCHANYINTEGRAL))
178 return (cprim_isAnyInt (c1)
179 || (cprim_isAnyChar (c1) && context_msgCharInt ()));
181 else if (context_getFlag (FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL))
183 return (cprim_closeEnough (c1, CTX_ULINT));
191 if (c2 == CTX_SIGNEDINTEGRAL)
193 if (context_getFlag (FLG_MATCHANYINTEGRAL))
195 return (cprim_isAnyInt (c2)
196 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
198 else if (context_getFlag (FLG_LONGSIGNEDINTEGRAL))
200 return (cprim_closeEnough (c1, CTX_LINT));
209 DPRINTF (("cprim close: %s / %s", cprim_unparse (c1), cprim_unparse (c2)));
211 if (context_getFlag (FLG_RELAXTYPES))
213 if (cprim_isNumeric (c1) && cprim_isNumeric (c2)) return TRUE;
216 if (context_getFlag (FLG_IGNOREQUALS))
222 if (cprim_isAnyChar (c2)
223 || (cprim_isAnyInt (c2) && (context_msgCharInt ()))) {
230 if (c2 == CTX_DOUBLE || c2 == CTX_FLOAT || c2 == CTX_LDOUBLE) {
242 if (cprim_isAnyInt (c2)
243 || (cprim_isAnyChar (c2) && context_msgCharInt ())) {
252 if (context_getFlag (FLG_IGNORESIGNS))
258 else if (c1 == CTX_UINT)
262 else if (c1 == CTX_ULINT)
266 /* 2001-06-10: This fix provided by Jim Zelenka: */
267 else if (c1 == CTX_ULLINT)
272 else if (c1 == CTX_USINT)
285 else if (c2 == CTX_UINT)
289 else if (c2 == CTX_ULINT)
293 /* 2001-06-10: This fix provided by Jim Zelenka: */
294 else if (c2 == CTX_ULLINT)
299 else if (c2 == CTX_USINT)
309 if (c1 == c2) return TRUE;
311 if (context_getFlag (FLG_FLOATDOUBLE))
313 if (c1 == CTX_FLOAT && c2 == CTX_DOUBLE)
317 if (c2 == CTX_FLOAT && c1 == CTX_DOUBLE)
323 DPRINTF (("cprim close: %s / %s", cprim_unparse (c1), cprim_unparse (c2)));
325 if (!deep && context_getFlag (FLG_RELAXQUALS))
330 return (c2 == CTX_FLOAT);
332 return (c2 == CTX_DOUBLE || c2 == CTX_FLOAT);
334 return ((c2 == CTX_CHAR && context_msgCharInt ())
335 || (c2 == CTX_INT && context_msgShortInt ())
336 || (c2 == CTX_LINT && context_msgShortInt () && context_msgLongInt ()));
339 return ((c2 == CTX_SINT
340 || (cprim_isAnyChar (c2) && context_msgCharInt ())
341 || (c2 == CTX_LINT && context_msgLongInt ())));
344 return (c2 == CTX_SINT
347 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
349 return (c2 == CTX_USINT
352 /* 2001-06-10: This fix provided by Jim Zelenka: */
353 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
355 return (c2 == CTX_SINT
357 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
359 return (c2 == CTX_USINT
360 || (c2 == CTX_UCHAR && context_msgCharInt ()));
362 return (c2 == CTX_UCHAR && context_msgCharInt ());
364 /* 2001-06-10: This fix provided by Jim Zelenka: */
365 return (c2 == CTX_UINT || c2 == CTX_USINT
366 || (c2 == CTX_UCHAR && context_msgCharInt()));
368 return (c2 == CTX_UINT && context_msgCharInt ());
370 return ((c2 == CTX_INT || c2 == CTX_SINT)
371 && context_msgCharInt ());
384 if (c2 == CTX_INT && context_msgShortInt ()) {
389 if (c2 == CTX_INT && context_msgLongInt ()) {
393 if (c2 == CTX_SINT && context_msgShortInt ()) {
398 if (c2 == CTX_INT && context_msgLongInt ()) {
403 return (c2 == CTX_CHAR && context_msgCharInt ());
408 return (c2 == CTX_UCHAR && context_msgCharInt ());
410 return (c2 == CTX_UINT && context_msgCharInt ());
412 return ((c2 == CTX_INT || c2 == CTX_SINT)
413 && context_msgCharInt ());
421 cprim_unparse (cprim c)
426 return cstring_makeLiteral ("-");
428 return cstring_makeLiteral ("void");
430 return cstring_makeLiteral ("char");
432 return cstring_makeLiteral ("unsigned char");
434 return cstring_makeLiteral ("double");
436 return cstring_makeLiteral ("long double");
438 return cstring_makeLiteral ("float");
440 return cstring_makeLiteral ("int");
442 return cstring_makeLiteral ("long int");
444 return cstring_makeLiteral ("long long");
446 return cstring_makeLiteral ("unsigned long long");
448 return cstring_makeLiteral ("short int");
450 return cstring_makeLiteral ("unsigned int");
452 return cstring_makeLiteral ("unsigned long int");
454 return cstring_makeLiteral ("unsigned short int");
455 case CTX_UNSIGNEDINTEGRAL:
456 return cstring_makeLiteral ("arbitrary unsigned integral type");
457 case CTX_SIGNEDINTEGRAL:
458 return cstring_makeLiteral ("arbitrary signed integral type");
459 case CTX_ANYINTEGRAL:
460 return cstring_makeLiteral ("arbitrary integral type");
462 return cstring_makeLiteral ("unknown prim");
466 bool cprim_isInt (cprim c)
468 return (cprim_isAnyInt (c)
469 || (cprim_isAnyChar (c) && context_msgCharInt ()));
472 int cprim_getExpectedBits (cprim c)
474 /* Any basis to these numbers? Just guesses for now..., check ISO spec */
507 case CTX_UNSIGNEDINTEGRAL:
509 case CTX_SIGNEDINTEGRAL:
511 case CTX_ANYINTEGRAL: