]> andersk Git - splint.git/blame - src/cprim.c
Moved doc/lclint.1 to doc/splint.1
[splint.git] / src / cprim.c
CommitLineData
616915dd 1/*
11db3170 2** Splint - annotation-assisted static program checker
77d37419 3** Copyright (C) 1994-2002 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
85 if (c1 == CTX_ANYINTEGRAL)
86 {
87 if (context_getFlag (FLG_MATCHANYINTEGRAL)
88 || context_getFlag (FLG_IGNOREQUALS))
89 {
90 return (cprim_isAnyInt (c2)
91 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
92 }
93 else if (context_getFlag (FLG_LONGINTEGRAL))
94 {
95 return (cprim_closeEnough (CTX_LINT, c2));
96 }
97 else if (context_getFlag (FLG_LONGUNSIGNEDINTEGRAL))
98 {
99 return (cprim_closeEnough (CTX_ULINT, c2));
100 }
101 else
102 {
103 return FALSE;
104 }
105 }
106
107 if (c1 == CTX_UNSIGNEDINTEGRAL)
108 {
109 if (context_getFlag (FLG_MATCHANYINTEGRAL)
110 || context_getFlag (FLG_IGNOREQUALS))
111 {
112 return (cprim_isAnyInt (c2)
113 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
114 }
115 else if (context_getFlag (FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL))
116 {
117 return (cprim_closeEnough (CTX_ULINT, c2));
118 }
119 else
120 {
121 return FALSE;
122 }
123 }
124
125 if (c1 == CTX_SIGNEDINTEGRAL)
126 {
127 if (context_getFlag (FLG_MATCHANYINTEGRAL)
128 || context_getFlag (FLG_IGNOREQUALS))
129 {
130 return (cprim_isAnyInt (c2)
131 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
132 }
133 else if (context_getFlag (FLG_LONGSIGNEDINTEGRAL))
134 {
135 return (cprim_closeEnough (CTX_LINT, c2));
136 }
137 else
138 {
139 return FALSE;
140 }
141 }
142
143 if (c2 == CTX_ANYINTEGRAL)
144 {
145 if (context_getFlag (FLG_MATCHANYINTEGRAL))
146 {
147 return (cprim_isAnyInt (c1)
148 || (cprim_isAnyChar (c1) && context_msgCharInt ()));
149 }
150 else if (context_getFlag (FLG_LONGINTEGRAL))
151 {
152 return (cprim_closeEnough (c1, CTX_LINT));
153 }
154 else if (context_getFlag (FLG_LONGUNSIGNEDINTEGRAL))
155 {
156 return (cprim_closeEnough (c1, CTX_ULINT));
157 }
158 else
159 {
160 return FALSE;
161 }
162 }
163
164 if (c2 == CTX_UNSIGNEDINTEGRAL)
165 {
166 if (context_getFlag (FLG_MATCHANYINTEGRAL))
167 {
168 return (cprim_isAnyInt (c1)
169 || (cprim_isAnyChar (c1) && context_msgCharInt ()));
170 }
171 else if (context_getFlag (FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL))
172 {
173 return (cprim_closeEnough (c1, CTX_ULINT));
174 }
175 else
176 {
177 return FALSE;
178 }
179 }
180
181 if (c2 == CTX_SIGNEDINTEGRAL)
182 {
183 if (context_getFlag (FLG_MATCHANYINTEGRAL))
184 {
185 return (cprim_isAnyInt (c2)
186 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
187 }
188 else if (context_getFlag (FLG_LONGSIGNEDINTEGRAL))
189 {
190 return (cprim_closeEnough (c1, CTX_LINT));
191 }
192 else
193 {
194 return FALSE;
195 }
196 }
197
198 if (context_getFlag (FLG_RELAXTYPES))
199 {
200 if (cprim_isNumeric (c1) && cprim_isNumeric (c2)) return TRUE;
201 }
202
203 if (context_getFlag (FLG_IGNOREQUALS))
204 {
205 switch (c1)
206 {
207 case CTX_CHAR:
208 case CTX_UCHAR:
209 return (cprim_isAnyChar (c2)
210 || (cprim_isAnyInt (c2) && (context_msgCharInt ())));
211 case CTX_DOUBLE:
212 case CTX_FLOAT:
213 case CTX_LDOUBLE:
214 return (c2 == CTX_DOUBLE || c2 == CTX_FLOAT || c2 == CTX_LDOUBLE);
215 case CTX_INT:
216 case CTX_LINT:
217 case CTX_LLINT:
218 case CTX_ULLINT:
219 case CTX_SINT:
220 case CTX_UINT:
221 case CTX_ULINT:
222 case CTX_USINT:
223 return (cprim_isAnyInt (c2)
224 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
225 default:
226 return FALSE;
227 }
228 }
229 else
230 {
231 if (context_getFlag (FLG_IGNORESIGNS))
232 {
233 if (c1 == CTX_UCHAR)
234 {
235 c1 = CTX_CHAR;
236 }
237 else if (c1 == CTX_UINT)
238 {
239 c1 = CTX_INT;
240 }
241 else if (c1 == CTX_ULINT)
242 {
243 c1 = CTX_LINT;
244 }
28bf4b0b 245 /* 2001-06-10: This fix provided by Jim Zelenka: */
246 else if (c1 == CTX_ULLINT)
247 {
248 c1 = CTX_LLINT;
249 }
250 /* End fix */
616915dd 251 else if (c1 == CTX_USINT)
252 {
253 c1 = CTX_SINT;
254 }
255 else
256 {
257 ;
258 }
259
260 if (c2 == CTX_UCHAR)
261 {
262 c2 = CTX_CHAR;
263 }
264 else if (c2 == CTX_UINT)
265 {
266 c2 = CTX_INT;
267 }
268 else if (c2 == CTX_ULINT)
269 {
270 c2 = CTX_LINT;
271 }
28bf4b0b 272 /* 2001-06-10: This fix provided by Jim Zelenka: */
273 else if (c2 == CTX_ULLINT)
274 {
275 c2 = CTX_LLINT;
276 }
277 /* End fix */
616915dd 278 else if (c2 == CTX_USINT)
279 {
280 c2 = CTX_SINT;
281 }
282 else
283 {
284 ;
285 }
286 }
287
288 if (c1 == c2) return TRUE;
289
290 if (context_getFlag (FLG_FLOATDOUBLE))
291 {
292 if (c1 == CTX_FLOAT && c2 == CTX_DOUBLE)
293 {
294 return TRUE;
295 }
296 if (c2 == CTX_FLOAT && c1 == CTX_DOUBLE)
297 {
298 return TRUE;
299 }
300 }
301
302 if (!deep && context_getFlag (FLG_RELAXQUALS))
303 {
304 switch (c1)
305 {
306 case CTX_DOUBLE:
307 return (c2 == CTX_FLOAT);
308 case CTX_LDOUBLE:
309 return (c2 == CTX_DOUBLE || c2 == CTX_FLOAT);
310 case CTX_SINT:
311 return (c2 == CTX_CHAR && context_msgCharInt ());
312 case CTX_INT:
313 return (c2 == CTX_SINT
314 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
315 case CTX_LLINT:
316 return (c2 == CTX_SINT
317 || c2 == CTX_INT
318 || c2 == CTX_LINT
319 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
320 case CTX_ULLINT:
321 return (c2 == CTX_USINT
322 || c2 == CTX_UINT
28bf4b0b 323 || c2 == CTX_ULINT
324 /* 2001-06-10: This fix provided by Jim Zelenka: */
325 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
616915dd 326 case CTX_LINT:
327 return (c2 == CTX_SINT
328 || c2 == CTX_INT
329 || (cprim_isAnyChar (c2) && context_msgCharInt ()));
330 case CTX_UINT:
331 return (c2 == CTX_USINT
332 || (c2 == CTX_UCHAR && context_msgCharInt ()));
333 case CTX_USINT:
334 return (c2 == CTX_UCHAR && context_msgCharInt ());
335 case CTX_ULINT:
28bf4b0b 336 /* 2001-06-10: This fix provided by Jim Zelenka: */
337 return (c2 == CTX_UINT || c2 == CTX_USINT
338 || (c2 == CTX_UCHAR && context_msgCharInt()));
616915dd 339 case CTX_UCHAR:
340 return (c2 == CTX_UINT && context_msgCharInt ());
341 case CTX_CHAR:
342 return ((c2 == CTX_INT || c2 == CTX_SINT)
343 && context_msgCharInt ());
344 default:
345 return FALSE;
346 }
347 }
348 else
349 {
350 switch (c1)
351 {
352 case CTX_DOUBLE:
353 case CTX_LDOUBLE:
354 return FALSE;
355 case CTX_SINT:
356 case CTX_INT:
357 case CTX_LINT:
358 case CTX_LLINT:
359 return (c2 == CTX_CHAR && context_msgCharInt ());
360 case CTX_UINT:
361 case CTX_USINT:
362 case CTX_ULINT:
363 case CTX_ULLINT:
364 return (c2 == CTX_UCHAR && context_msgCharInt ());
365 case CTX_UCHAR:
366 return (c2 == CTX_UINT && context_msgCharInt ());
367 case CTX_CHAR:
368 return ((c2 == CTX_INT || c2 == CTX_SINT)
369 && context_msgCharInt ());
370 default:
371 return FALSE;
372 }
373 }
374 }
375}
376
377/*@only@*/ cstring
378cprim_unparse (cprim c)
379{
380 switch (c)
381 {
382 case CTX_UNKNOWN:
383 return cstring_makeLiteral ("-");
384 case CTX_VOID:
385 return cstring_makeLiteral ("void");
386 case CTX_CHAR:
387 return cstring_makeLiteral ("char");
388 case CTX_UCHAR:
389 return cstring_makeLiteral ("unsigned char");
390 case CTX_DOUBLE:
391 return cstring_makeLiteral ("double");
392 case CTX_LDOUBLE:
393 return cstring_makeLiteral ("long double");
394 case CTX_FLOAT:
395 return cstring_makeLiteral ("float");
396 case CTX_INT:
397 return cstring_makeLiteral ("int");
398 case CTX_LINT:
399 return cstring_makeLiteral ("long int");
400 case CTX_LLINT:
401 return cstring_makeLiteral ("long long");
402 case CTX_ULLINT:
403 return cstring_makeLiteral ("unsigned long long");
404 case CTX_SINT:
405 return cstring_makeLiteral ("short int");
406 case CTX_UINT:
407 return cstring_makeLiteral ("unsigned int");
408 case CTX_ULINT:
409 return cstring_makeLiteral ("unsigned long int");
410 case CTX_USINT:
411 return cstring_makeLiteral ("unsigned short int");
412 case CTX_UNSIGNEDINTEGRAL:
413 return cstring_makeLiteral ("arbitrary unsigned integral type");
414 case CTX_SIGNEDINTEGRAL:
415 return cstring_makeLiteral ("arbitrary signed integral type");
416 case CTX_ANYINTEGRAL:
417 return cstring_makeLiteral ("arbitrary integral type");
418 default:
419 return cstring_makeLiteral ("unknown prim");
420 }
421}
422
423bool cprim_isInt (cprim c)
424{
425 return (cprim_isAnyInt (c)
426 || (cprim_isAnyChar (c) && context_msgCharInt ()));
427}
428
429
430
431
This page took 0.15004 seconds and 5 git commands to generate.