]> andersk Git - splint.git/blame - src/cprim.c
Added the FAQ and a document on using realloc to CVS.
[splint.git] / src / cprim.c
CommitLineData
616915dd 1/*
11db3170 2** Splint - annotation-assisted static program checker
c59f5181 3** Copyright (C) 1994-2003 University of Virginia,
616915dd 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
616915dd 23*/
24/*
25** cprim.c
26*/
27
1b8ae690 28# include "splintMacros.nf"
616915dd 29# include "basic.h"
30
31static bool cprim_isReal (cprim c)
32{
33 return (cprim_isAnyReal (c));
34}
35
36static bool cprim_isNumeric (cprim c)
37{
38 return (cprim_isReal (c) || cprim_isInt (c));
39}
40
41cprim
42cprim_fromInt (int i)
43{
44 if (i < CTX_UNKNOWN || i > CTX_LAST)
45 {
46 llcontbug (message ("cprim_fromInt: out of range: %d", i));
47 return CTX_UNKNOWN;
48 }
49 return (cprim) i;
50}
51
52
53/*
54** not symmetric: c1 := c2 or c2 is passed as c1
55** (if RELAXQUALS, c1 must be "bigger" than c2)
56*/
57
58static bool cprim_closeEnoughAux (cprim p_c1, cprim p_c2, bool p_deep);
59
60bool
61cprim_closeEnoughDeep (cprim c1, cprim c2)
62{
63 /*
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 *!
67 **
68 ** For deep comparisons, +relaxquals does not permit the long/int break.
69 */
70
71 return cprim_closeEnoughAux (c1, c2, TRUE);
72}
73
74bool
75cprim_closeEnough (cprim c1, cprim c2)
76{
77 return cprim_closeEnoughAux (c1, c2, FALSE);
78}
79
80static bool
81cprim_closeEnoughAux (cprim c1, cprim c2, bool deep)
82{
83 if (c1 == c2) return TRUE;
84
81fc136a 85 DPRINTF (("cprim close: %s / %s", cprim_unparse (c1), cprim_unparse (c2)));
86
616915dd 87 if (c1 == CTX_ANYINTEGRAL)
88 {
89 if (context_getFlag (FLG_MATCHANYINTEGRAL)
90 || context_getFlag (FLG_IGNOREQUALS))
91 {
92 return (cprim_isAnyInt (c2)
93 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
94 }
95 else if (context_getFlag (FLG_LONGINTEGRAL))
96 {
97 return (cprim_closeEnough (CTX_LINT, c2));
98 }
99 else if (context_getFlag (FLG_LONGUNSIGNEDINTEGRAL))
100 {
101 return (cprim_closeEnough (CTX_ULINT, c2));
102 }
103 else
104 {
105 return FALSE;
106 }
107 }
108
109 if (c1 == CTX_UNSIGNEDINTEGRAL)
110 {
111 if (context_getFlag (FLG_MATCHANYINTEGRAL)
112 || context_getFlag (FLG_IGNOREQUALS))
113 {
6fcd0b1e 114 if (context_getFlag (FLG_IGNORESIGNS))
115 {
116 return (cprim_isAnyUnsignedInt (c2)
117 || (cprim_isUnsignedChar (c2) && context_msgCharInt ()));
118 }
119 else
120 {
121 return (cprim_isAnyInt (c2)
122 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
123 }
616915dd 124 }
125 else if (context_getFlag (FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL))
126 {
127 return (cprim_closeEnough (CTX_ULINT, c2));
128 }
129 else
130 {
131 return FALSE;
132 }
133 }
134
135 if (c1 == CTX_SIGNEDINTEGRAL)
136 {
137 if (context_getFlag (FLG_MATCHANYINTEGRAL)
138 || context_getFlag (FLG_IGNOREQUALS))
139 {
140 return (cprim_isAnyInt (c2)
141 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
142 }
143 else if (context_getFlag (FLG_LONGSIGNEDINTEGRAL))
144 {
145 return (cprim_closeEnough (CTX_LINT, c2));
146 }
147 else
148 {
149 return FALSE;
150 }
151 }
152
153 if (c2 == CTX_ANYINTEGRAL)
154 {
155 if (context_getFlag (FLG_MATCHANYINTEGRAL))
156 {
157 return (cprim_isAnyInt (c1)
158 || (cprim_isAnyChar (c1) && context_msgCharInt ()));
159 }
160 else if (context_getFlag (FLG_LONGINTEGRAL))
161 {
162 return (cprim_closeEnough (c1, CTX_LINT));
163 }
164 else if (context_getFlag (FLG_LONGUNSIGNEDINTEGRAL))
165 {
166 return (cprim_closeEnough (c1, CTX_ULINT));
167 }
168 else
169 {
170 return FALSE;
171 }
172 }
173
174 if (c2 == CTX_UNSIGNEDINTEGRAL)
175 {
176 if (context_getFlag (FLG_MATCHANYINTEGRAL))
177 {
178 return (cprim_isAnyInt (c1)
179 || (cprim_isAnyChar (c1) && context_msgCharInt ()));
180 }
181 else if (context_getFlag (FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL))
182 {
183 return (cprim_closeEnough (c1, CTX_ULINT));
184 }
185 else
186 {
187 return FALSE;
188 }
189 }
190
191 if (c2 == CTX_SIGNEDINTEGRAL)
192 {
193 if (context_getFlag (FLG_MATCHANYINTEGRAL))
194 {
195 return (cprim_isAnyInt (c2)
196 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
197 }
198 else if (context_getFlag (FLG_LONGSIGNEDINTEGRAL))
199 {
200 return (cprim_closeEnough (c1, CTX_LINT));
201 }
202 else
203 {
204 return FALSE;
205 }
206 }
207
81fc136a 208
209 DPRINTF (("cprim close: %s / %s", cprim_unparse (c1), cprim_unparse (c2)));
210
616915dd 211 if (context_getFlag (FLG_RELAXTYPES))
212 {
213 if (cprim_isNumeric (c1) && cprim_isNumeric (c2)) return TRUE;
214 }
215
216 if (context_getFlag (FLG_IGNOREQUALS))
217 {
218 switch (c1)
219 {
220 case CTX_CHAR:
221 case CTX_UCHAR:
81fc136a 222 if (cprim_isAnyChar (c2)
223 || (cprim_isAnyInt (c2) && (context_msgCharInt ()))) {
224 return TRUE;
225 }
226 break;
616915dd 227 case CTX_DOUBLE:
228 case CTX_FLOAT:
229 case CTX_LDOUBLE:
81fc136a 230 if (c2 == CTX_DOUBLE || c2 == CTX_FLOAT || c2 == CTX_LDOUBLE) {
231 return TRUE;
232 }
233 break;
616915dd 234 case CTX_INT:
235 case CTX_LINT:
236 case CTX_LLINT:
237 case CTX_ULLINT:
238 case CTX_SINT:
239 case CTX_UINT:
240 case CTX_ULINT:
241 case CTX_USINT:
81fc136a 242 if (cprim_isAnyInt (c2)
243 || (cprim_isAnyChar (c2) && context_msgCharInt ())) {
244 return TRUE;
245 }
53306cab 246 /*@fallthrough@*/
616915dd 247 default:
81fc136a 248 ;
616915dd 249 }
250 }
81fc136a 251
252 if (context_getFlag (FLG_IGNORESIGNS))
616915dd 253 {
81fc136a 254 if (c1 == CTX_UCHAR)
616915dd 255 {
81fc136a 256 c1 = CTX_CHAR;
616915dd 257 }
81fc136a 258 else if (c1 == CTX_UINT)
616915dd 259 {
81fc136a 260 c1 = CTX_INT;
261 }
262 else if (c1 == CTX_ULINT)
263 {
264 c1 = CTX_LINT;
265 }
266 /* 2001-06-10: This fix provided by Jim Zelenka: */
267 else if (c1 == CTX_ULLINT)
268 {
269 c1 = CTX_LLINT;
270 }
271 /* End fix */
272 else if (c1 == CTX_USINT)
273 {
274 c1 = CTX_SINT;
275 }
276 else
277 {
278 ;
279 }
280
281 if (c2 == CTX_UCHAR)
282 {
283 c2 = CTX_CHAR;
284 }
285 else if (c2 == CTX_UINT)
286 {
287 c2 = CTX_INT;
288 }
289 else if (c2 == CTX_ULINT)
290 {
291 c2 = CTX_LINT;
292 }
293 /* 2001-06-10: This fix provided by Jim Zelenka: */
294 else if (c2 == CTX_ULLINT)
295 {
296 c2 = CTX_LLINT;
297 }
298 /* End fix */
299 else if (c2 == CTX_USINT)
300 {
301 c2 = CTX_SINT;
616915dd 302 }
81fc136a 303 else
304 {
305 ;
306 }
307 }
616915dd 308
81fc136a 309 if (c1 == c2) return TRUE;
310
311 if (context_getFlag (FLG_FLOATDOUBLE))
312 {
313 if (c1 == CTX_FLOAT && c2 == CTX_DOUBLE)
616915dd 314 {
81fc136a 315 return TRUE;
316 }
317 if (c2 == CTX_FLOAT && c1 == CTX_DOUBLE)
318 {
319 return TRUE;
320 }
321 }
322
323 DPRINTF (("cprim close: %s / %s", cprim_unparse (c1), cprim_unparse (c2)));
324
325 if (!deep && context_getFlag (FLG_RELAXQUALS))
326 {
327 switch (c1)
328 {
329 case CTX_DOUBLE:
330 return (c2 == CTX_FLOAT);
331 case CTX_LDOUBLE:
332 return (c2 == CTX_DOUBLE || c2 == CTX_FLOAT);
333 case CTX_SINT:
334 return ((c2 == CTX_CHAR && context_msgCharInt ())
335 || (c2 == CTX_INT && context_msgShortInt ())
336 || (c2 == CTX_LINT && context_msgShortInt () && context_msgLongInt ()));
337
338 case CTX_INT:
339 return ((c2 == CTX_SINT
340 || (cprim_isAnyChar (c2) && context_msgCharInt ())
341 || (c2 == CTX_LINT && context_msgLongInt ())));
342
343 case CTX_LLINT:
344 return (c2 == CTX_SINT
345 || c2 == CTX_INT
616915dd 346 || c2 == CTX_LINT
81fc136a 347 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
348 case CTX_ULLINT:
349 return (c2 == CTX_USINT
350 || c2 == CTX_UINT
351 || c2 == CTX_ULINT
352 /* 2001-06-10: This fix provided by Jim Zelenka: */
353 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
354 case CTX_LINT:
355 return (c2 == CTX_SINT
356 || c2 == CTX_INT
357 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
358 case CTX_UINT:
359 return (c2 == CTX_USINT
360 || (c2 == CTX_UCHAR && context_msgCharInt ()));
361 case CTX_USINT:
362 return (c2 == CTX_UCHAR && context_msgCharInt ());
363 case CTX_ULINT:
364 /* 2001-06-10: This fix provided by Jim Zelenka: */
365 return (c2 == CTX_UINT || c2 == CTX_USINT
366 || (c2 == CTX_UCHAR && context_msgCharInt()));
367 case CTX_UCHAR:
368 return (c2 == CTX_UINT && context_msgCharInt ());
369 case CTX_CHAR:
370 return ((c2 == CTX_INT || c2 == CTX_SINT)
371 && context_msgCharInt ());
372 default:
373 return FALSE;
616915dd 374 }
81fc136a 375 }
376 else
377 {
378 switch (c1)
616915dd 379 {
81fc136a 380 case CTX_DOUBLE:
381 case CTX_LDOUBLE:
382 return FALSE;
383 case CTX_SINT:
384 if (c2 == CTX_INT && context_msgShortInt ()) {
385 return TRUE;
386 }
387 /*@fallthrough@*/
388 case CTX_INT:
389 if (c2 == CTX_INT && context_msgLongInt ()) {
390 return TRUE;
391 }
392
393 if (c2 == CTX_SINT && context_msgShortInt ()) {
394 return TRUE;
395 }
396 /*@fallthrough@*/
397 case CTX_LINT:
398 if (c2 == CTX_INT && context_msgLongInt ()) {
399 return TRUE;
400 }
401 /*@fallthrough@*/
402 case CTX_LLINT:
403 return (c2 == CTX_CHAR && context_msgCharInt ());
404 case CTX_UINT:
405 case CTX_USINT:
406 case CTX_ULINT:
407 case CTX_ULLINT:
408 return (c2 == CTX_UCHAR && context_msgCharInt ());
409 case CTX_UCHAR:
410 return (c2 == CTX_UINT && context_msgCharInt ());
411 case CTX_CHAR:
412 return ((c2 == CTX_INT || c2 == CTX_SINT)
413 && context_msgCharInt ());
414 default:
415 return FALSE;
616915dd 416 }
417 }
418}
419
420/*@only@*/ cstring
421cprim_unparse (cprim c)
422{
423 switch (c)
424 {
425 case CTX_UNKNOWN:
426 return cstring_makeLiteral ("-");
427 case CTX_VOID:
428 return cstring_makeLiteral ("void");
429 case CTX_CHAR:
430 return cstring_makeLiteral ("char");
431 case CTX_UCHAR:
432 return cstring_makeLiteral ("unsigned char");
433 case CTX_DOUBLE:
434 return cstring_makeLiteral ("double");
435 case CTX_LDOUBLE:
436 return cstring_makeLiteral ("long double");
437 case CTX_FLOAT:
438 return cstring_makeLiteral ("float");
439 case CTX_INT:
440 return cstring_makeLiteral ("int");
441 case CTX_LINT:
442 return cstring_makeLiteral ("long int");
443 case CTX_LLINT:
444 return cstring_makeLiteral ("long long");
445 case CTX_ULLINT:
446 return cstring_makeLiteral ("unsigned long long");
447 case CTX_SINT:
448 return cstring_makeLiteral ("short int");
449 case CTX_UINT:
450 return cstring_makeLiteral ("unsigned int");
451 case CTX_ULINT:
452 return cstring_makeLiteral ("unsigned long int");
453 case CTX_USINT:
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");
461 default:
462 return cstring_makeLiteral ("unknown prim");
463 }
464}
465
466bool cprim_isInt (cprim c)
467{
468 return (cprim_isAnyInt (c)
469 || (cprim_isAnyChar (c) && context_msgCharInt ()));
470}
471
e5081f8c 472int cprim_getExpectedBits (cprim c)
473{
474 /* Any basis to these numbers? Just guesses for now..., check ISO spec */
475 switch (c)
476 {
477 case CTX_UNKNOWN:
478 return 0;
479 case CTX_VOID:
480 return 0;
481 case CTX_CHAR:
482 return 8;
483 case CTX_UCHAR:
484 return 8;
485 case CTX_DOUBLE:
486 return 64;
487 case CTX_LDOUBLE:
488 return 128;
489 case CTX_FLOAT:
490 return 32;
491 case CTX_INT:
492 return 32;
493 case CTX_LINT:
494 return 64;
495 case CTX_LLINT:
496 return 128;
497 case CTX_ULLINT:
498 return 128;
499 case CTX_SINT:
500 return 8;
501 case CTX_UINT:
502 return 32;
503 case CTX_ULINT:
504 return 64;
505 case CTX_USINT:
506 return 8;
507 case CTX_UNSIGNEDINTEGRAL:
508 return 64;
509 case CTX_SIGNEDINTEGRAL:
510 return 64;
511 case CTX_ANYINTEGRAL:
512 return 64;
513 default:
514 return 0;
515 }
516}
This page took 0.147947 seconds and 5 git commands to generate.