extra: cleanup set_related()
[smatch.git] / smatch_math.c
blobb558601c58ab54930234270534766037916d3e06
1 /*
2 * smatch/smatch_math.c
4 * Copyright (C) 2010 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
10 #include "smatch.h"
11 #include "smatch_slist.h"
12 #include "smatch_extra.h"
14 static sval_t _get_value(struct expression *expr, int *undefined, int implied);
15 static sval_t _get_implied_value(struct expression *expr, int *undefined, int implied);
17 #define BOGUS 12345
19 static sval_t zero = {.type = &int_ctype, .value = 0};
20 static sval_t one = {.type = &int_ctype, .value = 1};
21 static sval_t bogus = {.type = &int_ctype, .value = BOGUS};
23 #define NOTIMPLIED 0
24 #define IMPLIED 1
25 #define IMPLIED_MIN 2
26 #define IMPLIED_MAX 3
27 #define FUZZYMAX 4
28 #define FUZZYMIN 5
29 #define ABSOLUTE_MIN 6
30 #define ABSOLUTE_MAX 7
32 static int opposite_implied(int implied)
34 if (implied == IMPLIED_MIN)
35 return IMPLIED_MAX;
36 if (implied == IMPLIED_MAX)
37 return IMPLIED_MIN;
38 if (implied == ABSOLUTE_MIN)
39 return ABSOLUTE_MAX;
40 if (implied == ABSOLUTE_MAX)
41 return ABSOLUTE_MIN;
42 return implied;
45 static int last_stmt_sval(struct statement *stmt, sval_t *sval)
47 struct expression *expr;
49 if (!stmt)
50 return 0;
52 stmt = last_ptr_list((struct ptr_list *)stmt->stmts);
53 if (stmt->type != STMT_EXPRESSION)
54 return 0;
55 expr = stmt->expression;
56 if (!get_value_sval(expr, sval))
57 return 0;
58 return 1;
61 static sval_t handle_expression_statement(struct expression *expr, int *undefined, int implied)
63 struct statement *stmt;
64 sval_t ret;
66 stmt = get_expression_statement(expr);
67 if (!last_stmt_sval(stmt, &ret)) {
68 *undefined = 1;
69 ret.value = BOGUS;
72 return ret;
75 static sval_t handle_ampersand(int *undefined, int implied)
77 sval_t ret;
79 ret.type = &ptr_ctype;
80 ret.value = BOGUS;
82 if (implied == IMPLIED_MIN || implied == FUZZYMIN || implied == ABSOLUTE_MIN)
83 return valid_ptr_min_sval;
84 if (implied == IMPLIED_MAX || implied == FUZZYMAX || implied == ABSOLUTE_MAX)
85 return valid_ptr_max_sval;
87 *undefined = 1;
88 return ret;
91 static sval_t handle_preop(struct expression *expr, int *undefined, int implied)
93 sval_t ret;
95 switch (expr->op) {
96 case '&':
97 ret = handle_ampersand(undefined, implied);
98 break;
99 case '!':
100 ret = _get_value(expr->unop, undefined, implied);
101 ret = sval_preop(ret, '!');
102 break;
103 case '~':
104 ret = _get_value(expr->unop, undefined, implied);
105 ret = sval_preop(ret, '~');
106 ret = sval_cast(ret, get_type(expr->unop));
107 break;
108 case '-':
109 ret = _get_value(expr->unop, undefined, implied);
110 ret = sval_preop(ret, '-');
111 break;
112 case '*':
113 ret = _get_implied_value(expr, undefined, implied);
114 break;
115 case '(':
116 ret = handle_expression_statement(expr, undefined, implied);
117 break;
118 default:
119 *undefined = 1;
120 ret = sval_blank(expr);
122 ret = sval_cast(ret, get_type(expr));
123 return ret;
126 static sval_t handle_divide(struct expression *expr, int *undefined, int implied)
128 sval_t left, right;
130 left = _get_value(expr->left, undefined, implied);
131 right = _get_value(expr->right, undefined, opposite_implied(implied));
133 if (right.value == 0) {
134 *undefined = 1;
135 return bogus;
138 return sval_binop(left, '/', right);
141 static sval_t handle_subtract(struct expression *expr, int *undefined, int implied)
143 sval_t left, right;
145 left = _get_value(expr->left, undefined, implied);
146 right = _get_value(expr->right, undefined, opposite_implied(implied));
148 return sval_binop(left, '-', right);
151 static sval_t handle_binop(struct expression *expr, int *undefined, int implied)
153 sval_t left, right;
154 sval_t ret = {.type = &int_ctype, .value = 123456};
155 int local_undef = 0;
157 switch (expr->op) {
158 case '%':
159 left = _get_value(expr->left, &local_undef, implied);
160 if (local_undef) {
161 if (implied == ABSOLUTE_MIN) {
162 ret = sval_blank(expr->left);
163 ret.value = 0;
164 return ret;
166 if (implied != ABSOLUTE_MAX)
167 *undefined = 1;
168 if (!get_absolute_max_sval(expr->left, &left))
169 *undefined = 1;
171 right = _get_value(expr->right, undefined, implied);
172 if (right.value == 0)
173 *undefined = 1;
174 else
175 ret = sval_binop(left, '%', right);
176 return ret;
178 case '&':
179 left = _get_value(expr->left, &local_undef, implied);
180 if (local_undef) {
181 if (implied == ABSOLUTE_MIN) {
182 ret = sval_blank(expr->left);
183 ret.value = 0;
184 return ret;
186 if (implied != ABSOLUTE_MAX)
187 *undefined = 1;
188 if (!get_absolute_max_sval(expr->left, &left))
189 *undefined = 1;
191 right = _get_value(expr->right, undefined, implied);
192 return sval_binop(left, '&', right);
194 case SPECIAL_RIGHTSHIFT:
195 left = _get_value(expr->left, &local_undef, implied);
196 if (local_undef) {
197 if (implied == ABSOLUTE_MIN) {
198 ret = sval_blank(expr->left);
199 ret.value = 0;
200 return ret;
202 if (implied != ABSOLUTE_MAX)
203 *undefined = 1;
204 if (!get_absolute_max_sval(expr->left, &left))
205 *undefined = 1;
207 right = _get_value(expr->right, undefined, implied);
208 return sval_binop(left, SPECIAL_RIGHTSHIFT, right);
211 left = _get_value(expr->left, undefined, implied);
212 right = _get_value(expr->right, undefined, implied);
214 switch (expr->op) {
215 case '/':
216 return handle_divide(expr, undefined, implied);
217 case '%':
218 if (right.value == 0)
219 *undefined = 1;
220 else
221 ret = sval_binop(left, '%', right);
222 break;
223 case '-':
224 ret = handle_subtract(expr, undefined, implied);
225 break;
226 default:
227 ret = sval_binop(left, expr->op, right);
229 return ret;
232 static int do_comparison(struct expression *expr)
234 struct range_list_sval *left_ranges = NULL;
235 struct range_list_sval *right_ranges = NULL;
236 int poss_true, poss_false;
238 get_implied_range_list_sval(expr->left, &left_ranges);
239 get_implied_range_list_sval(expr->right, &right_ranges);
241 poss_true = possibly_true_range_lists_sval(left_ranges, expr->op, right_ranges);
242 poss_false = possibly_false_range_lists_sval(left_ranges, expr->op, right_ranges);
244 free_range_list_sval(&left_ranges);
245 free_range_list_sval(&right_ranges);
247 if (!poss_true && !poss_false)
248 return 0;
249 if (poss_true && !poss_false)
250 return 1;
251 if (!poss_true && poss_false)
252 return 2;
253 return 3;
256 static sval_t handle_comparison(struct expression *expr, int *undefined, int implied)
258 sval_t left, right;
259 int res;
261 if (get_value_sval(expr->left, &left) && get_value_sval(expr->right, &right)) {
262 struct data_range_sval tmp_left, tmp_right;
264 tmp_left.min = left;
265 tmp_left.max = left;
266 tmp_right.min = right;
267 tmp_right.max = right;
268 if (true_comparison_range_sval(&tmp_left, expr->op, &tmp_right))
269 return one;
270 return zero;
273 if (implied == NOTIMPLIED) {
274 *undefined = 1;
275 return bogus;
278 res = do_comparison(expr);
279 if (res == 1)
280 return one;
281 if (res == 2)
282 return zero;
284 if (implied == IMPLIED_MIN || implied == FUZZYMIN || implied == ABSOLUTE_MIN)
285 return zero;
286 if (implied == IMPLIED_MAX || implied == FUZZYMAX || implied == ABSOLUTE_MAX)
287 return one;
289 *undefined = 1;
290 return bogus;
293 static sval_t handle_logical(struct expression *expr, int *undefined, int implied)
295 sval_t left, right;
297 if ((implied == NOTIMPLIED && get_value_sval(expr->left, &left) &&
298 get_value_sval(expr->right, &right)) ||
299 (implied != NOTIMPLIED && get_implied_value_sval(expr->left, &left) &&
300 get_implied_value_sval(expr->right, &right))) {
301 switch (expr->op) {
302 case SPECIAL_LOGICAL_OR:
303 if (left.value || right.value)
304 return one;
305 return zero;
306 case SPECIAL_LOGICAL_AND:
307 if (left.value && right.value)
308 return one;
309 return zero;
310 default:
311 *undefined = 1;
312 return bogus;
316 if (implied == IMPLIED_MIN || implied == FUZZYMIN || implied == ABSOLUTE_MIN)
317 return zero;
318 if (implied == IMPLIED_MAX || implied == FUZZYMAX || implied == ABSOLUTE_MAX)
319 return one;
321 *undefined = 1;
322 return bogus;
325 static sval_t handle_conditional(struct expression *expr, int *undefined, int implied)
327 if (known_condition_true(expr->conditional))
328 return _get_value(expr->cond_true, undefined, implied);
329 if (known_condition_false(expr->conditional))
330 return _get_value(expr->cond_false, undefined, implied);
332 if (implied == NOTIMPLIED) {
333 *undefined = 1;
334 return bogus;
337 if (implied_condition_true(expr->conditional))
338 return _get_value(expr->cond_true, undefined, implied);
339 if (implied_condition_false(expr->conditional))
340 return _get_value(expr->cond_false, undefined, implied);
342 *undefined = 1;
343 return bogus;
346 static int get_implied_value_helper(struct expression *expr, sval_t *sval, int implied)
348 struct smatch_state *state;
349 struct symbol *sym;
350 char *name;
352 /* fixme: this should return the casted value */
354 expr = strip_expr(expr);
356 if (get_value_sval(expr, sval))
357 return 1;
359 name = get_variable_from_expr(expr, &sym);
360 if (!name)
361 return 0;
362 *sval = sval_blank(expr);
363 state = get_state(SMATCH_EXTRA, name, sym);
364 free_string(name);
365 if (!state || !state->data)
366 return 0;
367 if (implied == IMPLIED) {
368 if (estate_get_single_value_sval(state, sval))
369 return 1;
370 return 0;
372 if (implied == IMPLIED_MAX || implied == ABSOLUTE_MAX) {
373 *sval = estate_max_sval(state);
374 if (sval_is_max(*sval)) /* this means just guessing. fixme. not really */
375 return 0;
376 return 1;
378 *sval = estate_min_sval(state);
379 if (sval_is_min(*sval)) /* fixme */
380 return 0;
381 return 1;
384 static int is_some_kind_of_max(sval_t sval)
386 switch (sval.uvalue) {
387 case ULLONG_MAX:
388 case LLONG_MAX:
389 case UINT_MAX:
390 case INT_MAX:
391 case USHRT_MAX:
392 case SHRT_MAX:
393 return 1;
394 default:
395 return 0;
399 static int get_fuzzy_max_helper(struct expression *expr, sval_t *max)
401 struct sm_state *sm;
402 struct sm_state *tmp;
403 sval_t sval;
405 if (get_implied_max_sval(expr, &sval) && !is_some_kind_of_max(sval)) {
406 *max = sval;
407 return 1;
410 sm = get_sm_state_expr(SMATCH_EXTRA, expr);
411 if (!sm)
412 return 0;
414 sval = sval_type_min(estate_type(sm->state));
415 FOR_EACH_PTR(sm->possible, tmp) {
416 sval_t new_min;
418 new_min = estate_min_sval(tmp->state);
419 if (sval_cmp(new_min, sval) > 0)
420 sval = new_min;
421 } END_FOR_EACH_PTR(tmp);
423 if (sval_is_min(sval))
424 return 0;
426 *max = sval_cast(sval, get_type(expr));
427 return 1;
430 static int get_fuzzy_min_helper(struct expression *expr, sval_t *min)
432 struct sm_state *sm;
433 struct sm_state *tmp;
434 sval_t sval;
436 if (get_implied_min_sval(expr, min))
437 return 1;
439 sm = get_sm_state_expr(SMATCH_EXTRA, expr);
440 if (!sm)
441 return 0;
443 sval = sval_type_max(estate_type(sm->state));
444 FOR_EACH_PTR(sm->possible, tmp) {
445 sval_t new_max;
447 new_max = estate_max_sval(tmp->state);
448 if (sval_cmp(new_max, sval) < 0)
449 sval = new_max;
450 } END_FOR_EACH_PTR(tmp);
452 if (sval_is_max(sval))
453 return 0;
454 *min = sval_cast(sval, get_type(expr));
455 return 1;
458 static sval_t _get_implied_value(struct expression *expr, int *undefined, int implied)
460 sval_t ret;
462 ret = sval_blank(expr);
464 switch (implied) {
465 case IMPLIED:
466 case IMPLIED_MAX:
467 case IMPLIED_MIN:
468 if (!get_implied_value_helper(expr, &ret, implied))
469 *undefined = 1;
470 break;
471 case ABSOLUTE_MIN:
472 if (!get_absolute_min_helper(expr, &ret))
473 *undefined = 1;
474 break;
475 case ABSOLUTE_MAX:
476 if (!get_absolute_max_helper(expr, &ret))
477 *undefined = 1;
478 break;
479 case FUZZYMAX:
480 if (!get_fuzzy_max_helper(expr, &ret))
481 *undefined = 1;
482 break;
483 case FUZZYMIN:
484 if (!get_fuzzy_min_helper(expr, &ret))
485 *undefined = 1;
486 break;
487 default:
488 *undefined = 1;
490 return ret;
493 static int get_const_value(struct expression *expr, sval_t *sval)
495 struct symbol *sym;
496 sval_t right;
498 if (expr->type != EXPR_SYMBOL || !expr->symbol)
499 return 0;
500 sym = expr->symbol;
501 if (!(sym->ctype.modifiers & MOD_CONST))
502 return 0;
503 if (get_value_sval(sym->initializer, &right)) {
504 *sval = sval_cast(right, get_type(expr));
505 return 1;
507 return 0;
510 static sval_t _get_value(struct expression *expr, int *undefined, int implied)
512 sval_t tmp_ret;
514 if (!expr) {
515 *undefined = 1;
516 return bogus;
518 if (*undefined)
519 return bogus;
521 expr = strip_parens(expr);
523 switch (expr->type) {
524 case EXPR_VALUE:
525 tmp_ret = sval_from_val(expr, expr->value);
526 break;
527 case EXPR_PREOP:
528 tmp_ret = handle_preop(expr, undefined, implied);
529 break;
530 case EXPR_POSTOP:
531 tmp_ret = _get_value(expr->unop, undefined, implied);
532 break;
533 case EXPR_CAST:
534 case EXPR_FORCE_CAST:
535 case EXPR_IMPLIED_CAST:
536 tmp_ret = _get_value(expr->cast_expression, undefined, implied);
537 tmp_ret = sval_cast(tmp_ret, get_type(expr));
538 break;
539 case EXPR_BINOP:
540 tmp_ret = handle_binop(expr, undefined, implied);
541 break;
542 case EXPR_COMPARE:
543 tmp_ret = handle_comparison(expr, undefined, implied);
544 break;
545 case EXPR_LOGICAL:
546 tmp_ret = handle_logical(expr, undefined, implied);
547 break;
548 case EXPR_PTRSIZEOF:
549 case EXPR_SIZEOF:
550 tmp_ret = sval_blank(expr);
551 tmp_ret.value = get_expression_value_nomod(expr);
552 break;
553 case EXPR_SYMBOL:
554 if (get_const_value(expr, &tmp_ret)) {
555 break;
557 tmp_ret = _get_implied_value(expr, undefined, implied);
558 break;
559 case EXPR_SELECT:
560 case EXPR_CONDITIONAL:
561 tmp_ret = handle_conditional(expr, undefined, implied);
562 break;
563 default:
564 tmp_ret = _get_implied_value(expr, undefined, implied);
566 if (*undefined)
567 return bogus;
568 return tmp_ret;
571 /* returns 1 if it can get a value literal or else returns 0 */
572 int get_value_sval(struct expression *expr, sval_t *sval)
574 int undefined = 0;
575 sval_t ret;
577 ret = _get_value(expr, &undefined, NOTIMPLIED);
578 if (undefined)
579 return 0;
580 *sval = ret;
581 return 1;
584 int get_implied_value_sval(struct expression *expr, sval_t *sval)
586 int undefined = 0;
587 sval_t ret;
589 ret = _get_value(expr, &undefined, IMPLIED);
590 if (undefined)
591 return 0;
592 *sval = ret;
593 return 1;
596 int get_implied_min_sval(struct expression *expr, sval_t *sval)
598 int undefined = 0;
599 sval_t ret;
601 ret = _get_value(expr, &undefined, IMPLIED_MIN);
602 if (undefined)
603 return 0;
604 *sval = ret;
605 return 1;
608 int get_implied_max_sval(struct expression *expr, sval_t *sval)
610 int undefined = 0;
611 sval_t ret;
613 ret = _get_value(expr, &undefined, IMPLIED_MAX);
614 if (undefined)
615 return 0;
616 *sval = ret;
617 return 1;
620 int get_fuzzy_min_sval(struct expression *expr, sval_t *sval)
622 int undefined = 0;
623 sval_t ret;
625 ret = _get_value(expr, &undefined, FUZZYMIN);
626 if (undefined)
627 return 0;
628 *sval = ret;
629 return 1;
632 int get_fuzzy_max_sval(struct expression *expr, sval_t *sval)
634 int undefined = 0;
635 sval_t ret;
637 ret = _get_value(expr, &undefined, FUZZYMAX);
638 if (undefined)
639 return 0;
640 *sval = ret;
641 return 1;
644 int get_absolute_min_sval(struct expression *expr, sval_t *sval)
646 int undefined = 0;
647 struct symbol *type;
649 type = get_type(expr);
650 *sval = _get_value(expr, &undefined, ABSOLUTE_MIN);
651 if (undefined) {
652 *sval = sval_type_min(type);
653 return 1;
656 if (sval_cmp(*sval, sval_type_min(type)) < 0)
657 *sval = sval_type_min(type);
658 return 1;
661 int get_absolute_max_sval(struct expression *expr, sval_t *sval)
663 int undefined = 0;
664 struct symbol *type;
666 type = get_type(expr);
667 *sval = _get_value(expr, &undefined, ABSOLUTE_MAX);
668 if (undefined) {
669 *sval = sval_type_max(type);
670 return 1;
673 if (sval_cmp(sval_type_max(type), *sval) < 0)
674 *sval = sval_type_max(type);
675 return 1;
678 int known_condition_true(struct expression *expr)
680 sval_t tmp;
682 if (!expr)
683 return 0;
685 if (get_value_sval(expr, &tmp) && tmp.value)
686 return 1;
688 return 0;
691 int known_condition_false(struct expression *expr)
693 if (!expr)
694 return 0;
696 if (is_zero(expr))
697 return 1;
699 if (expr->type == EXPR_CALL) {
700 if (sym_name_is("__builtin_constant_p", expr->fn))
701 return 1;
703 return 0;
706 int implied_condition_true(struct expression *expr)
708 sval_t tmp;
710 if (!expr)
711 return 0;
713 if (known_condition_true(expr))
714 return 1;
715 if (get_implied_value_sval(expr, &tmp) && tmp.value)
716 return 1;
718 if (expr->type == EXPR_POSTOP)
719 return implied_condition_true(expr->unop);
721 if (expr->type == EXPR_PREOP && expr->op == SPECIAL_DECREMENT)
722 return implied_not_equal(expr->unop, 1);
723 if (expr->type == EXPR_PREOP && expr->op == SPECIAL_INCREMENT)
724 return implied_not_equal(expr->unop, -1);
726 expr = strip_expr(expr);
727 switch (expr->type) {
728 case EXPR_COMPARE:
729 if (do_comparison(expr) == 1)
730 return 1;
731 break;
732 case EXPR_PREOP:
733 if (expr->op == '!') {
734 if (implied_condition_false(expr->unop))
735 return 1;
736 break;
738 break;
739 default:
740 if (implied_not_equal(expr, 0) == 1)
741 return 1;
742 break;
744 return 0;
747 int implied_condition_false(struct expression *expr)
749 struct expression *tmp;
750 sval_t sval;
752 if (!expr)
753 return 0;
755 if (known_condition_false(expr))
756 return 1;
758 switch (expr->type) {
759 case EXPR_COMPARE:
760 if (do_comparison(expr) == 2)
761 return 1;
762 case EXPR_PREOP:
763 if (expr->op == '!') {
764 if (implied_condition_true(expr->unop))
765 return 1;
766 break;
768 tmp = strip_expr(expr);
769 if (tmp != expr)
770 return implied_condition_false(tmp);
771 break;
772 default:
773 if (get_implied_value_sval(expr, &sval) && sval.value == 0)
774 return 1;
775 break;
777 return 0;