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 /* We allow signed ints to match any integral if matchanyintegral is set */
112 if (context_getFlag (FLG_MATCHANYINTEGRAL
)) {
113 return (cprim_isAnyInt (c2
)
114 || (cprim_isAnyChar (c2
) && context_msgCharInt ()));
117 if (context_getFlag (FLG_IGNOREQUALS
))
119 if (context_getFlag (FLG_IGNORESIGNS
))
121 return (cprim_isAnyUnsignedInt (c2
)
122 || (cprim_isUnsignedChar (c2
) && context_msgCharInt ()));
126 return (cprim_isAnyInt (c2
)
127 || (cprim_isAnyChar (c2
) && context_msgCharInt ()));
130 else if (context_getFlag (FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL
))
132 return (cprim_closeEnough (CTX_ULINT
, c2
));
140 if (c1
== CTX_SIGNEDINTEGRAL
)
142 /* We allow signed ints to match any integral if matchanyintegral is set */
143 if (context_getFlag (FLG_MATCHANYINTEGRAL
)) {
144 return (cprim_isAnyInt (c2
)
145 || (cprim_isAnyChar (c2
) && context_msgCharInt ()));
148 if (context_getFlag (FLG_IGNOREQUALS
))
150 return (cprim_isAnyInt (c2
)
151 || (cprim_isAnyChar (c2
) && context_msgCharInt ()));
153 else if (context_getFlag (FLG_LONGSIGNEDINTEGRAL
))
155 return (cprim_closeEnough (CTX_LINT
, c2
));
163 if (c2
== CTX_ANYINTEGRAL
)
165 if (context_getFlag (FLG_MATCHANYINTEGRAL
))
167 return (cprim_isAnyInt (c1
)
168 || (cprim_isAnyChar (c1
) && context_msgCharInt ()));
170 else if (context_getFlag (FLG_LONGINTEGRAL
))
172 return (cprim_closeEnough (c1
, CTX_LINT
));
174 else if (context_getFlag (FLG_LONGUNSIGNEDINTEGRAL
))
176 return (cprim_closeEnough (c1
, CTX_ULINT
));
184 if (c2
== CTX_UNSIGNEDINTEGRAL
)
186 if (context_getFlag (FLG_MATCHANYINTEGRAL
))
188 return (cprim_isAnyInt (c1
)
189 || (cprim_isAnyChar (c1
) && context_msgCharInt ()));
191 else if (context_getFlag (FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL
))
193 return (cprim_closeEnough (c1
, CTX_ULINT
));
201 if (c2
== CTX_SIGNEDINTEGRAL
)
203 if (context_getFlag (FLG_MATCHANYINTEGRAL
))
205 return (cprim_isAnyInt (c2
)
206 || (cprim_isAnyChar (c2
) && context_msgCharInt ()));
208 else if (context_getFlag (FLG_LONGSIGNEDINTEGRAL
))
210 return (cprim_closeEnough (c1
, CTX_LINT
));
219 DPRINTF (("cprim close: %s / %s", cprim_unparse (c1
), cprim_unparse (c2
)));
221 if (context_getFlag (FLG_RELAXTYPES
))
223 if (cprim_isNumeric (c1
) && cprim_isNumeric (c2
)) return TRUE
;
226 if (context_getFlag (FLG_IGNOREQUALS
))
232 if (cprim_isAnyChar (c2
)
233 || (cprim_isAnyInt (c2
) && (context_msgCharInt ()))) {
240 if (c2
== CTX_DOUBLE
|| c2
== CTX_FLOAT
|| c2
== CTX_LDOUBLE
) {
252 if (cprim_isAnyInt (c2
)
253 || (cprim_isAnyChar (c2
) && context_msgCharInt ())) {
262 if (context_getFlag (FLG_IGNORESIGNS
))
268 else if (c1
== CTX_UINT
)
272 else if (c1
== CTX_ULINT
)
276 /* 2001-06-10: This fix provided by Jim Zelenka: */
277 else if (c1
== CTX_ULLINT
)
282 else if (c1
== CTX_USINT
)
295 else if (c2
== CTX_UINT
)
299 else if (c2
== CTX_ULINT
)
303 /* 2001-06-10: This fix provided by Jim Zelenka: */
304 else if (c2
== CTX_ULLINT
)
309 else if (c2
== CTX_USINT
)
319 if (c1
== c2
) return TRUE
;
321 if (context_getFlag (FLG_FLOATDOUBLE
))
323 if (c1
== CTX_FLOAT
&& c2
== CTX_DOUBLE
)
327 if (c2
== CTX_FLOAT
&& c1
== CTX_DOUBLE
)
333 DPRINTF (("cprim close: %s / %s", cprim_unparse (c1
), cprim_unparse (c2
)));
335 if (!deep
&& context_getFlag (FLG_RELAXQUALS
))
340 return (c2
== CTX_FLOAT
);
342 return (c2
== CTX_DOUBLE
|| c2
== CTX_FLOAT
);
344 return ((c2
== CTX_CHAR
&& context_msgCharInt ())
345 || (c2
== CTX_INT
&& context_msgShortInt ())
346 || (c2
== CTX_LINT
&& context_msgShortInt () && context_msgLongInt ()));
349 return ((c2
== CTX_SINT
350 || (cprim_isAnyChar (c2
) && context_msgCharInt ())
351 || (c2
== CTX_LINT
&& context_msgLongInt ())));
354 return (c2
== CTX_SINT
357 || (cprim_isAnyChar (c2
) && context_msgCharInt ()));
359 return (c2
== CTX_USINT
362 /* 2001-06-10: This fix provided by Jim Zelenka: */
363 || (cprim_isAnyChar (c2
) && context_msgCharInt ()));
365 return (c2
== CTX_SINT
367 || (cprim_isAnyChar (c2
) && context_msgCharInt ()));
369 return (c2
== CTX_USINT
370 || (c2
== CTX_UCHAR
&& context_msgCharInt ()));
372 return (c2
== CTX_UCHAR
&& context_msgCharInt ());
374 /* 2001-06-10: This fix provided by Jim Zelenka: */
375 return (c2
== CTX_UINT
|| c2
== CTX_USINT
376 || (c2
== CTX_UCHAR
&& context_msgCharInt()));
378 return (c2
== CTX_UINT
&& context_msgCharInt ());
380 return ((c2
== CTX_INT
|| c2
== CTX_SINT
)
381 && context_msgCharInt ());
394 if (c2
== CTX_INT
&& context_msgShortInt ()) {
399 if (c2
== CTX_INT
&& context_msgLongInt ()) {
403 if (c2
== CTX_SINT
&& context_msgShortInt ()) {
408 if (c2
== CTX_INT
&& context_msgLongInt ()) {
413 return (c2
== CTX_CHAR
&& context_msgCharInt ());
418 return (c2
== CTX_UCHAR
&& context_msgCharInt ());
420 return (c2
== CTX_UINT
&& context_msgCharInt ());
422 return ((c2
== CTX_INT
|| c2
== CTX_SINT
)
423 && context_msgCharInt ());
431 cprim_unparse (cprim c
)
436 return cstring_makeLiteral ("-");
438 return cstring_makeLiteral ("void");
440 return cstring_makeLiteral ("char");
442 return cstring_makeLiteral ("unsigned char");
444 return cstring_makeLiteral ("double");
446 return cstring_makeLiteral ("long double");
448 return cstring_makeLiteral ("float");
450 return cstring_makeLiteral ("int");
452 return cstring_makeLiteral ("long int");
454 return cstring_makeLiteral ("long long");
456 return cstring_makeLiteral ("unsigned long long");
458 return cstring_makeLiteral ("short int");
460 return cstring_makeLiteral ("unsigned int");
462 return cstring_makeLiteral ("unsigned long int");
464 return cstring_makeLiteral ("unsigned short int");
465 case CTX_UNSIGNEDINTEGRAL
:
466 return cstring_makeLiteral ("arbitrary unsigned integral type");
467 case CTX_SIGNEDINTEGRAL
:
468 return cstring_makeLiteral ("arbitrary signed integral type");
469 case CTX_ANYINTEGRAL
:
470 return cstring_makeLiteral ("arbitrary integral type");
472 return cstring_makeLiteral ("unknown prim");
476 bool cprim_isInt (cprim c
)
478 return (cprim_isAnyInt (c
)
479 || (cprim_isAnyChar (c
) && context_msgCharInt ()));
482 int cprim_getExpectedBits (cprim c
)
484 /* Any basis to these numbers? Just guesses for now..., check ISO spec */
517 case CTX_UNSIGNEDINTEGRAL
:
519 case CTX_SIGNEDINTEGRAL
:
521 case CTX_ANYINTEGRAL
: