]> andersk Git - splint.git/blame - src/cprim.c
Fixed scanf %x problem.
[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;
e0a05ba9 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 {
e0a05ba9 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 ()));
115 }
116
117 if (context_getFlag (FLG_IGNOREQUALS))
616915dd 118 {
6fcd0b1e 119 if (context_getFlag (FLG_IGNORESIGNS))
120 {
121 return (cprim_isAnyUnsignedInt (c2)
122 || (cprim_isUnsignedChar (c2) && context_msgCharInt ()));
123 }
124 else
125 {
126 return (cprim_isAnyInt (c2)
127 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
128 }
616915dd 129 }
130 else if (context_getFlag (FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL))
131 {
132 return (cprim_closeEnough (CTX_ULINT, c2));
133 }
134 else
135 {
136 return FALSE;
137 }
138 }
139
140 if (c1 == CTX_SIGNEDINTEGRAL)
141 {
e0a05ba9 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 ()));
146 }
147
148 if (context_getFlag (FLG_IGNOREQUALS))
616915dd 149 {
150 return (cprim_isAnyInt (c2)
151 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
152 }
153 else if (context_getFlag (FLG_LONGSIGNEDINTEGRAL))
154 {
155 return (cprim_closeEnough (CTX_LINT, c2));
156 }
157 else
158 {
159 return FALSE;
160 }
161 }
162
163 if (c2 == CTX_ANYINTEGRAL)
164 {
165 if (context_getFlag (FLG_MATCHANYINTEGRAL))
166 {
167 return (cprim_isAnyInt (c1)
168 || (cprim_isAnyChar (c1) && context_msgCharInt ()));
169 }
170 else if (context_getFlag (FLG_LONGINTEGRAL))
171 {
172 return (cprim_closeEnough (c1, CTX_LINT));
173 }
174 else if (context_getFlag (FLG_LONGUNSIGNEDINTEGRAL))
175 {
176 return (cprim_closeEnough (c1, CTX_ULINT));
177 }
178 else
179 {
180 return FALSE;
181 }
182 }
183
184 if (c2 == CTX_UNSIGNEDINTEGRAL)
185 {
186 if (context_getFlag (FLG_MATCHANYINTEGRAL))
187 {
188 return (cprim_isAnyInt (c1)
189 || (cprim_isAnyChar (c1) && context_msgCharInt ()));
190 }
191 else if (context_getFlag (FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL))
192 {
193 return (cprim_closeEnough (c1, CTX_ULINT));
194 }
195 else
196 {
197 return FALSE;
198 }
199 }
200
201 if (c2 == CTX_SIGNEDINTEGRAL)
202 {
203 if (context_getFlag (FLG_MATCHANYINTEGRAL))
204 {
205 return (cprim_isAnyInt (c2)
206 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
207 }
208 else if (context_getFlag (FLG_LONGSIGNEDINTEGRAL))
209 {
210 return (cprim_closeEnough (c1, CTX_LINT));
211 }
212 else
213 {
214 return FALSE;
215 }
216 }
217
81fc136a 218
219 DPRINTF (("cprim close: %s / %s", cprim_unparse (c1), cprim_unparse (c2)));
220
616915dd 221 if (context_getFlag (FLG_RELAXTYPES))
222 {
223 if (cprim_isNumeric (c1) && cprim_isNumeric (c2)) return TRUE;
224 }
225
226 if (context_getFlag (FLG_IGNOREQUALS))
227 {
228 switch (c1)
229 {
230 case CTX_CHAR:
231 case CTX_UCHAR:
81fc136a 232 if (cprim_isAnyChar (c2)
233 || (cprim_isAnyInt (c2) && (context_msgCharInt ()))) {
234 return TRUE;
235 }
236 break;
616915dd 237 case CTX_DOUBLE:
238 case CTX_FLOAT:
239 case CTX_LDOUBLE:
81fc136a 240 if (c2 == CTX_DOUBLE || c2 == CTX_FLOAT || c2 == CTX_LDOUBLE) {
241 return TRUE;
242 }
243 break;
616915dd 244 case CTX_INT:
245 case CTX_LINT:
246 case CTX_LLINT:
247 case CTX_ULLINT:
248 case CTX_SINT:
249 case CTX_UINT:
250 case CTX_ULINT:
251 case CTX_USINT:
81fc136a 252 if (cprim_isAnyInt (c2)
253 || (cprim_isAnyChar (c2) && context_msgCharInt ())) {
254 return TRUE;
255 }
53306cab 256 /*@fallthrough@*/
616915dd 257 default:
81fc136a 258 ;
616915dd 259 }
260 }
81fc136a 261
262 if (context_getFlag (FLG_IGNORESIGNS))
616915dd 263 {
81fc136a 264 if (c1 == CTX_UCHAR)
616915dd 265 {
81fc136a 266 c1 = CTX_CHAR;
616915dd 267 }
81fc136a 268 else if (c1 == CTX_UINT)
616915dd 269 {
81fc136a 270 c1 = CTX_INT;
271 }
272 else if (c1 == CTX_ULINT)
273 {
274 c1 = CTX_LINT;
275 }
276 /* 2001-06-10: This fix provided by Jim Zelenka: */
277 else if (c1 == CTX_ULLINT)
278 {
279 c1 = CTX_LLINT;
280 }
281 /* End fix */
282 else if (c1 == CTX_USINT)
283 {
284 c1 = CTX_SINT;
285 }
286 else
287 {
288 ;
289 }
290
291 if (c2 == CTX_UCHAR)
292 {
293 c2 = CTX_CHAR;
294 }
295 else if (c2 == CTX_UINT)
296 {
297 c2 = CTX_INT;
298 }
299 else if (c2 == CTX_ULINT)
300 {
301 c2 = CTX_LINT;
302 }
303 /* 2001-06-10: This fix provided by Jim Zelenka: */
304 else if (c2 == CTX_ULLINT)
305 {
306 c2 = CTX_LLINT;
307 }
308 /* End fix */
309 else if (c2 == CTX_USINT)
310 {
311 c2 = CTX_SINT;
616915dd 312 }
81fc136a 313 else
314 {
315 ;
316 }
317 }
616915dd 318
81fc136a 319 if (c1 == c2) return TRUE;
320
321 if (context_getFlag (FLG_FLOATDOUBLE))
322 {
323 if (c1 == CTX_FLOAT && c2 == CTX_DOUBLE)
616915dd 324 {
81fc136a 325 return TRUE;
326 }
327 if (c2 == CTX_FLOAT && c1 == CTX_DOUBLE)
328 {
329 return TRUE;
330 }
331 }
332
333 DPRINTF (("cprim close: %s / %s", cprim_unparse (c1), cprim_unparse (c2)));
334
335 if (!deep && context_getFlag (FLG_RELAXQUALS))
336 {
337 switch (c1)
338 {
339 case CTX_DOUBLE:
340 return (c2 == CTX_FLOAT);
341 case CTX_LDOUBLE:
342 return (c2 == CTX_DOUBLE || c2 == CTX_FLOAT);
343 case CTX_SINT:
344 return ((c2 == CTX_CHAR && context_msgCharInt ())
345 || (c2 == CTX_INT && context_msgShortInt ())
346 || (c2 == CTX_LINT && context_msgShortInt () && context_msgLongInt ()));
347
348 case CTX_INT:
349 return ((c2 == CTX_SINT
350 || (cprim_isAnyChar (c2) && context_msgCharInt ())
351 || (c2 == CTX_LINT && context_msgLongInt ())));
352
353 case CTX_LLINT:
354 return (c2 == CTX_SINT
355 || c2 == CTX_INT
616915dd 356 || c2 == CTX_LINT
81fc136a 357 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
358 case CTX_ULLINT:
359 return (c2 == CTX_USINT
360 || c2 == CTX_UINT
361 || c2 == CTX_ULINT
362 /* 2001-06-10: This fix provided by Jim Zelenka: */
363 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
364 case CTX_LINT:
365 return (c2 == CTX_SINT
366 || c2 == CTX_INT
367 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
368 case CTX_UINT:
369 return (c2 == CTX_USINT
370 || (c2 == CTX_UCHAR && context_msgCharInt ()));
371 case CTX_USINT:
372 return (c2 == CTX_UCHAR && context_msgCharInt ());
373 case CTX_ULINT:
374 /* 2001-06-10: This fix provided by Jim Zelenka: */
375 return (c2 == CTX_UINT || c2 == CTX_USINT
376 || (c2 == CTX_UCHAR && context_msgCharInt()));
377 case CTX_UCHAR:
378 return (c2 == CTX_UINT && context_msgCharInt ());
379 case CTX_CHAR:
380 return ((c2 == CTX_INT || c2 == CTX_SINT)
381 && context_msgCharInt ());
382 default:
383 return FALSE;
616915dd 384 }
81fc136a 385 }
386 else
387 {
388 switch (c1)
616915dd 389 {
81fc136a 390 case CTX_DOUBLE:
391 case CTX_LDOUBLE:
392 return FALSE;
393 case CTX_SINT:
394 if (c2 == CTX_INT && context_msgShortInt ()) {
395 return TRUE;
396 }
397 /*@fallthrough@*/
398 case CTX_INT:
399 if (c2 == CTX_INT && context_msgLongInt ()) {
400 return TRUE;
401 }
402
403 if (c2 == CTX_SINT && context_msgShortInt ()) {
404 return TRUE;
405 }
406 /*@fallthrough@*/
407 case CTX_LINT:
408 if (c2 == CTX_INT && context_msgLongInt ()) {
409 return TRUE;
410 }
411 /*@fallthrough@*/
412 case CTX_LLINT:
413 return (c2 == CTX_CHAR && context_msgCharInt ());
414 case CTX_UINT:
415 case CTX_USINT:
416 case CTX_ULINT:
417 case CTX_ULLINT:
418 return (c2 == CTX_UCHAR && context_msgCharInt ());
419 case CTX_UCHAR:
420 return (c2 == CTX_UINT && context_msgCharInt ());
421 case CTX_CHAR:
422 return ((c2 == CTX_INT || c2 == CTX_SINT)
423 && context_msgCharInt ());
424 default:
425 return FALSE;
616915dd 426 }
427 }
428}
429
430/*@only@*/ cstring
431cprim_unparse (cprim c)
432{
433 switch (c)
434 {
435 case CTX_UNKNOWN:
436 return cstring_makeLiteral ("-");
437 case CTX_VOID:
438 return cstring_makeLiteral ("void");
439 case CTX_CHAR:
440 return cstring_makeLiteral ("char");
441 case CTX_UCHAR:
442 return cstring_makeLiteral ("unsigned char");
443 case CTX_DOUBLE:
444 return cstring_makeLiteral ("double");
445 case CTX_LDOUBLE:
446 return cstring_makeLiteral ("long double");
447 case CTX_FLOAT:
448 return cstring_makeLiteral ("float");
449 case CTX_INT:
450 return cstring_makeLiteral ("int");
451 case CTX_LINT:
452 return cstring_makeLiteral ("long int");
453 case CTX_LLINT:
454 return cstring_makeLiteral ("long long");
455 case CTX_ULLINT:
456 return cstring_makeLiteral ("unsigned long long");
457 case CTX_SINT:
458 return cstring_makeLiteral ("short int");
459 case CTX_UINT:
460 return cstring_makeLiteral ("unsigned int");
461 case CTX_ULINT:
462 return cstring_makeLiteral ("unsigned long int");
463 case CTX_USINT:
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");
471 default:
472 return cstring_makeLiteral ("unknown prim");
473 }
474}
475
476bool cprim_isInt (cprim c)
477{
478 return (cprim_isAnyInt (c)
479 || (cprim_isAnyChar (c) && context_msgCharInt ()));
480}
481
e5081f8c 482int cprim_getExpectedBits (cprim c)
483{
484 /* Any basis to these numbers? Just guesses for now..., check ISO spec */
485 switch (c)
486 {
487 case CTX_UNKNOWN:
488 return 0;
489 case CTX_VOID:
490 return 0;
491 case CTX_CHAR:
492 return 8;
493 case CTX_UCHAR:
494 return 8;
495 case CTX_DOUBLE:
496 return 64;
497 case CTX_LDOUBLE:
498 return 128;
499 case CTX_FLOAT:
500 return 32;
501 case CTX_INT:
502 return 32;
503 case CTX_LINT:
504 return 64;
505 case CTX_LLINT:
506 return 128;
507 case CTX_ULLINT:
508 return 128;
509 case CTX_SINT:
510 return 8;
511 case CTX_UINT:
512 return 32;
513 case CTX_ULINT:
514 return 64;
515 case CTX_USINT:
516 return 8;
517 case CTX_UNSIGNEDINTEGRAL:
518 return 64;
519 case CTX_SIGNEDINTEGRAL:
520 return 64;
521 case CTX_ANYINTEGRAL:
522 return 64;
523 default:
524 return 0;
525 }
526}
This page took 0.15665 seconds and 5 git commands to generate.