comparison: handle preops like "if (++a == b)"
[smatch.git] / smatch_sval.c
blobdb647d1902b7431cf30884a856506cb2dd367de7
1 /*
2 * Copyright (C) 2012 Oracle.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
19 * Basically the point of sval is that it can hold both ULLONG_MAX and
20 * LLONG_MIN. If it is an unsigned type then we use sval.uvalue or if it is
21 * signed we use sval.value.
23 * I considered just using one bit to store whether the value was signed vs
24 * unsigned but I think it might help to have the type information so we know
25 * how to do type promotion.
29 #include "smatch.h"
30 #include "smatch_slist.h"
31 #include "smatch_extra.h"
33 __ALLOCATOR(sval_t, "svals", sval);
35 sval_t *sval_alloc(sval_t sval)
37 sval_t *ret;
39 ret = __alloc_sval(0);
40 *ret = sval;
41 return ret;
44 sval_t *sval_alloc_permanent(sval_t sval)
46 sval_t *ret;
48 ret = malloc(sizeof(*ret));
49 *ret = sval;
50 return ret;
53 sval_t sval_blank(struct expression *expr)
55 sval_t ret;
57 ret.type = get_type(expr);
58 if (!ret.type)
59 ret.type = &int_ctype;
60 ret.value = 123456789;
62 return ret;
65 sval_t sval_type_val(struct symbol *type, long long val)
67 sval_t ret;
69 if (!type)
70 type = &int_ctype;
72 ret.type = type;
73 ret.value = val;
74 return ret;
77 sval_t sval_from_val(struct expression *expr, long long val)
79 sval_t ret;
81 ret = sval_blank(expr);
82 ret.value = val;
83 ret = sval_cast(get_type(expr), ret);
85 return ret;
88 int sval_unsigned(sval_t sval)
90 return type_unsigned(sval.type);
93 int sval_signed(sval_t sval)
95 return !type_unsigned(sval.type);
98 int sval_bits(sval_t sval)
100 return type_bits(sval.type);
103 int sval_positive_bits(sval_t sval)
105 return type_positive_bits(sval.type);
108 int sval_bits_used(sval_t sval)
110 int i;
112 for (i = 64; i >= 1; i--) {
113 if (sval.uvalue & (1ULL << (i - 1)))
114 return i;
116 return 0;
119 int sval_is_negative(sval_t sval)
121 if (type_unsigned(sval.type))
122 return 0;
123 if (sval.value < 0)
124 return 1;
125 return 0;
128 int sval_is_positive(sval_t sval)
130 return !sval_is_negative(sval);
133 int sval_is_min(sval_t sval)
135 sval_t min = sval_type_min(sval.type);
137 if (sval_unsigned(sval)) {
138 if (sval.uvalue == 0)
139 return 1;
140 return 0;
142 /* return true for less than min as well */
143 return (sval.value <= min.value);
146 int sval_is_max(sval_t sval)
148 sval_t max = sval_type_max(sval.type);
150 if (sval_unsigned(sval))
151 return (sval.uvalue >= max.value);
152 return (sval.value >= max.value);
155 int sval_is_a_min(sval_t sval)
157 if (sval_signed(sval) && sval.value == SHRT_MIN)
158 return 1;
159 if (sval_signed(sval) && sval.value == INT_MIN)
160 return 1;
161 if (sval_signed(sval) && sval.value == LLONG_MIN)
162 return 1;
163 return 0;
166 int sval_is_a_max(sval_t sval)
168 if (sval.uvalue == SHRT_MAX)
169 return 1;
170 if (sval.uvalue == INT_MAX)
171 return 1;
172 if (sval.uvalue == LLONG_MAX)
173 return 1;
174 if (sval.uvalue == USHRT_MAX)
175 return 1;
176 if (sval.uvalue == UINT_MAX)
177 return 1;
178 if (sval_unsigned(sval) && sval.uvalue == ULLONG_MAX)
179 return 1;
180 if (sval.value > valid_ptr_max - 1000 &&
181 sval.value < valid_ptr_max + 1000)
182 return 1;
183 return 0;
186 int sval_is_negative_min(sval_t sval)
188 if (!sval_is_negative(sval))
189 return 0;
190 return sval_is_min(sval);
194 * Returns -1 if one is smaller, 0 if they are the same and 1 if two is larger.
196 int sval_cmp(sval_t one, sval_t two)
198 struct symbol *type;
200 type = one.type;
201 if (sval_positive_bits(two) > sval_positive_bits(one))
202 type = two.type;
203 if (type_bits(type) < 31)
204 type = &int_ctype;
206 one = sval_cast(type, one);
207 two = sval_cast(type, two);
209 if (type_unsigned(type)) {
210 if (one.uvalue < two.uvalue)
211 return -1;
212 if (one.uvalue == two.uvalue)
213 return 0;
214 return 1;
216 /* fix me handle type promotion and unsigned values */
217 if (one.value < two.value)
218 return -1;
219 if (one.value == two.value)
220 return 0;
221 return 1;
224 int sval_cmp_t(struct symbol *type, sval_t one, sval_t two)
226 sval_t one_cast, two_cast;
228 one_cast = sval_cast(type, one);
229 two_cast = sval_cast(type, two);
230 return sval_cmp(one_cast, two_cast);
233 int sval_cmp_val(sval_t one, long long val)
235 sval_t sval;
237 sval = sval_type_val(&llong_ctype, val);
238 return sval_cmp(one, sval);
241 sval_t sval_min(sval_t one, sval_t two)
243 if (sval_cmp(one, two) > 0)
244 return two;
245 return one;
248 sval_t sval_max(sval_t one, sval_t two)
250 if (sval_cmp(one, two) < 0)
251 return two;
252 return one;
255 int sval_too_low(struct symbol *type, sval_t sval)
257 if (sval_is_negative(sval) && type_unsigned(type))
258 return 1;
259 if (type_signed(type) && sval_unsigned(sval))
260 return 0;
261 if (sval_cmp(sval, sval_type_min(type)) < 0)
262 return 1;
263 return 0;
266 int sval_too_high(struct symbol *type, sval_t sval)
268 if (sval_is_negative(sval))
269 return 0;
270 if (sval.uvalue > sval_type_max(type).uvalue)
271 return 1;
272 return 0;
275 int sval_fits(struct symbol *type, sval_t sval)
277 if (sval_too_low(type, sval))
278 return 0;
279 if (sval_too_high(type, sval))
280 return 0;
281 return 1;
284 sval_t sval_cast(struct symbol *type, sval_t sval)
286 sval_t ret;
288 if (!type)
289 type = &int_ctype;
291 ret.type = type;
292 switch (sval_bits(ret)) {
293 case 8:
294 if (sval_unsigned(ret))
295 ret.value = (long long)(unsigned char)sval.value;
296 else
297 ret.value = (long long)(char)sval.value;
298 break;
299 case 16:
300 if (sval_unsigned(ret))
301 ret.value = (long long)(unsigned short)sval.value;
302 else
303 ret.value = (long long)(short)sval.value;
304 break;
305 case 32:
306 if (sval_unsigned(ret))
307 ret.value = (long long)(unsigned int)sval.value;
308 else
309 ret.value = (long long)(int)sval.value;
310 break;
311 default:
312 ret.value = sval.value;
314 return ret;
318 sval_t sval_preop(sval_t sval, int op)
320 switch (op) {
321 case '!':
322 sval.value = !sval.value;
323 break;
324 case '~':
325 sval.value = ~sval.value;
326 sval = sval_cast(sval.type, sval);
327 break;
328 case '-':
329 sval.value = -sval.value;
330 sval = sval_cast(sval.type, sval);
331 break;
333 return sval;
336 static sval_t sval_binop_unsigned(struct symbol *type, sval_t left, int op, sval_t right)
338 sval_t ret;
340 ret.type = type;
341 switch (op) {
342 case '*':
343 ret.uvalue = left.uvalue * right.uvalue;
344 break;
345 case '/':
346 if (right.uvalue == 0) {
347 sm_msg("debug: %s: divide by zero", __func__);
348 ret.uvalue = 123456789;
349 } else {
350 ret.uvalue = left.uvalue / right.uvalue;
352 break;
353 case '+':
354 ret.uvalue = left.uvalue + right.uvalue;
355 break;
356 case '-':
357 ret.uvalue = left.uvalue - right.uvalue;
358 break;
359 case '%':
360 if (right.uvalue == 0) {
361 sm_msg("internal error: %s: MOD by zero", __func__);
362 ret.uvalue = 123456789;
363 } else {
364 ret.uvalue = left.uvalue % right.uvalue;
366 break;
367 case '|':
368 ret.uvalue = left.uvalue | right.uvalue;
369 break;
370 case '&':
371 ret.uvalue = left.uvalue & right.uvalue;
372 break;
373 case SPECIAL_RIGHTSHIFT:
374 ret.uvalue = left.uvalue >> right.uvalue;
375 break;
376 case SPECIAL_LEFTSHIFT:
377 ret.uvalue = left.uvalue << right.uvalue;
378 break;
379 case '^':
380 ret.uvalue = left.uvalue ^ right.uvalue;
381 break;
382 default:
383 sm_msg("internal error: %s: unhandled binop %s", __func__,
384 show_special(op));
385 ret.uvalue = 1234567;
387 return ret;
391 static sval_t sval_binop_signed(struct symbol *type, sval_t left, int op, sval_t right)
393 sval_t ret;
395 ret.type = type;
396 switch (op) {
397 case '*':
398 ret.value = left.value * right.value;
399 break;
400 case '/':
401 if (right.value == 0) {
402 sm_msg("debug: %s: divide by zero", __func__);
403 ret.value = 123456789;
404 } else if (left.value == LLONG_MIN && right.value == -1) {
405 sm_msg("debug: %s: invalid divide LLONG_MIN/-1", __func__);
406 ret.value = 12345678;
407 } else {
408 ret.value = left.value / right.value;
410 break;
411 case '+':
412 ret.value = left.value + right.value;
413 break;
414 case '-':
415 ret.value = left.value - right.value;
416 break;
417 case '%':
418 if (right.value == 0) {
419 sm_msg("internal error: %s: MOD by zero", __func__);
420 ret.value = 123456789;
421 } else {
422 ret.value = left.value % right.value;
424 break;
425 case '|':
426 ret.value = left.value | right.value;
427 break;
428 case '&':
429 ret.value = left.value & right.value;
430 break;
431 case SPECIAL_RIGHTSHIFT:
432 ret.value = left.value >> right.value;
433 break;
434 case SPECIAL_LEFTSHIFT:
435 ret.value = left.value << right.value;
436 break;
437 case '^':
438 ret.value = left.value ^ right.value;
439 break;
440 default:
441 sm_msg("internal error: %s: unhandled binop %s", __func__,
442 show_special(op));
443 ret.value = 1234567;
445 return ret;
448 sval_t sval_binop(sval_t left, int op, sval_t right)
450 struct symbol *type;
451 sval_t ret;
453 type = left.type;
454 if (sval_positive_bits(right) > sval_positive_bits(left))
455 type = right.type;
456 if (type_positive_bits(type) < 31)
457 type = &int_ctype;
459 if (type_unsigned(type))
460 ret = sval_binop_unsigned(type, left, op, right);
461 else
462 ret = sval_binop_signed(type, left, op, right);
463 return ret;
466 int sval_unop_overflows(sval_t sval, int op)
468 if (op != '-')
469 return 0;
470 if (sval_positive_bits(sval) == 32 && sval.value == INT_MIN)
471 return 1;
472 if (sval_positive_bits(sval) == 64 && sval.value == LLONG_MIN)
473 return 1;
474 if (sval_is_negative(sval))
475 return 0;
476 if (sval_signed(sval))
477 return 0;
478 if (sval_bits(sval) == 32 && sval.uvalue > INT_MAX)
479 return 1;
480 if (sval_bits(sval) == 64 && sval.uvalue > LLONG_MAX)
481 return 1;
482 return 0;
485 int sval_binop_overflows(sval_t left, int op, sval_t right)
487 struct symbol *type;
488 sval_t max, min;
490 type = left.type;
491 if (type_positive_bits(right.type) > type_positive_bits(left.type))
492 type = right.type;
493 if (type_positive_bits(type) < 31)
494 type = &int_ctype;
496 max = sval_type_max(type);
497 min = sval_type_min(type);
499 switch (op) {
500 case '+':
501 if (sval_is_negative(right)) {
502 if (left.value < min.value - right.value)
503 return 1;
504 } else {
505 if (left.uvalue > max.uvalue - right.uvalue)
506 return 1;
508 return 0;
509 case '*':
510 return right.uvalue != 0 && left.uvalue > max.uvalue / right.uvalue;
511 case '-':
512 if (type_unsigned(type)) {
513 if (sval_cmp(left, right) < 0)
514 return 1;
515 return 0;
518 if (sval_unop_overflows(right, '-'))
519 return 1;
520 right = sval_preop(right, '-');
521 if (sval_binop_overflows(left, '+', right))
522 return 1;
523 return 0;
525 return 0;
528 const char *sval_to_str(sval_t sval)
530 char buf[30];
532 if (sval_unsigned(sval) && sval.value == ULLONG_MAX)
533 return "u64max";
534 if (sval_unsigned(sval) && sval.value == UINT_MAX)
535 return "u32max";
536 if (sval_unsigned(sval) && sval.value == USHRT_MAX)
537 return "u16max";
539 if (sval_signed(sval) && sval.value == LLONG_MAX)
540 return "s64max";
541 if (sval_signed(sval) && sval.value == INT_MAX)
542 return "s32max";
543 if (sval_signed(sval) && sval.value == SHRT_MAX)
544 return "s16max";
546 if (sval_signed(sval) && sval.value == SHRT_MIN)
547 return "s16min";
548 if (sval_signed(sval) && sval.value == INT_MIN)
549 return "s32min";
550 if (sval_signed(sval) && sval.value == LLONG_MIN)
551 return "s64min";
553 if (sval_unsigned(sval))
554 snprintf(buf, sizeof(buf), "%llu", sval.value);
555 else if (sval.value < 0)
556 snprintf(buf, sizeof(buf), "(%lld)", sval.value);
557 else
558 snprintf(buf, sizeof(buf), "%lld", sval.value);
560 return alloc_sname(buf);
563 const char *sval_to_numstr(sval_t sval)
565 char buf[30];
567 if (sval_unsigned(sval))
568 snprintf(buf, sizeof(buf), "%llu", sval.value);
569 else if (sval.value < 0)
570 snprintf(buf, sizeof(buf), "(%lld)", sval.value);
571 else
572 snprintf(buf, sizeof(buf), "%lld", sval.value);
574 return alloc_sname(buf);
577 sval_t ll_to_sval(long long val)
579 sval_t ret;
581 ret.type = &llong_ctype;
582 ret.value = val;
583 return ret;
586 static void free_svals(struct symbol *sym)
588 if (__inline_fn)
589 return;
590 clear_sval_alloc();
593 void register_sval(int my_id)
595 add_hook(&free_svals, END_FUNC_HOOK);