flow: hooks: fix MACRO_ASSIGNMENT_HOOK
[smatch.git] / smatch_math.c
blob92385156da1f6a8f1fa4f4ed715aa0e150432433
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 enum {
24 NOTIMPLIED,
25 IMPLIED,
26 IMPLIED_MIN,
27 IMPLIED_MAX,
28 FUZZY_MAX,
29 FUZZY_MIN,
30 ABSOLUTE_MIN,
31 ABSOLUTE_MAX,
32 HARD_MAX,
35 static int opposite_implied(int implied)
37 if (implied == IMPLIED_MIN)
38 return IMPLIED_MAX;
39 if (implied == IMPLIED_MAX)
40 return IMPLIED_MIN;
41 if (implied == FUZZY_MIN)
42 return FUZZY_MAX;
43 if (implied == FUZZY_MAX)
44 return FUZZY_MIN;
45 if (implied == ABSOLUTE_MIN)
46 return ABSOLUTE_MAX;
47 if (implied == ABSOLUTE_MAX)
48 return ABSOLUTE_MIN;
50 return implied;
53 static int last_stmt_sval(struct statement *stmt, sval_t *sval)
55 struct expression *expr;
57 if (!stmt)
58 return 0;
60 stmt = last_ptr_list((struct ptr_list *)stmt->stmts);
61 if (stmt->type != STMT_EXPRESSION)
62 return 0;
63 expr = stmt->expression;
64 if (!get_value(expr, sval))
65 return 0;
66 return 1;
69 static sval_t handle_expression_statement(struct expression *expr, int *undefined, int implied)
71 struct statement *stmt;
72 sval_t ret;
74 stmt = get_expression_statement(expr);
75 if (!last_stmt_sval(stmt, &ret)) {
76 *undefined = 1;
77 ret.value = BOGUS;
80 return ret;
83 static sval_t handle_ampersand(int *undefined, int implied)
85 sval_t ret;
87 ret.type = &ptr_ctype;
88 ret.value = BOGUS;
90 if (implied == IMPLIED_MIN || implied == FUZZY_MIN || implied == ABSOLUTE_MIN)
91 return valid_ptr_min_sval;
92 if (implied == IMPLIED_MAX || implied == FUZZY_MAX || implied == ABSOLUTE_MAX)
93 return valid_ptr_max_sval;
95 *undefined = 1;
96 return ret;
99 static sval_t handle_negate(struct expression *expr, int *undefined, int implied)
101 sval_t ret;
103 ret = sval_blank(expr->unop);
104 if (implied_condition_true(expr->unop)) {
105 ret.value = 0;
106 return ret;
108 if (implied_condition_false(expr->unop)) {
109 ret.value = 1;
110 return ret;
112 if (implied == IMPLIED_MIN || implied == FUZZY_MIN || implied == ABSOLUTE_MIN) {
113 ret.value = 0;
114 return ret;
116 if (implied == IMPLIED_MAX || implied == FUZZY_MAX || implied == ABSOLUTE_MAX) {
117 ret.value = 1;
118 return ret;
120 *undefined = 1;
121 return bogus;
124 static sval_t handle_preop(struct expression *expr, int *undefined, int implied)
126 sval_t ret;
128 switch (expr->op) {
129 case '&':
130 ret = handle_ampersand(undefined, implied);
131 break;
132 case '!':
133 ret = handle_negate(expr, undefined, implied);
134 break;
135 case '~':
136 ret = _get_value(expr->unop, undefined, implied);
137 ret = sval_preop(ret, '~');
138 ret = sval_cast(get_type(expr->unop), ret);
139 break;
140 case '-':
141 ret = _get_value(expr->unop, undefined, implied);
142 ret = sval_preop(ret, '-');
143 break;
144 case '*':
145 ret = _get_implied_value(expr, undefined, implied);
146 break;
147 case '(':
148 ret = handle_expression_statement(expr, undefined, implied);
149 break;
150 default:
151 *undefined = 1;
152 ret = sval_blank(expr);
154 ret = sval_cast(get_type(expr), ret);
155 return ret;
158 static sval_t handle_divide(struct expression *expr, int *undefined, int implied)
160 sval_t left, right;
162 left = _get_value(expr->left, undefined, implied);
163 right = _get_value(expr->right, undefined, opposite_implied(implied));
165 if (right.value == 0) {
166 *undefined = 1;
167 return bogus;
170 return sval_binop(left, '/', right);
173 static sval_t handle_subtract(struct expression *expr, int *undefined, int implied)
175 sval_t left, right;
177 left = _get_value(expr->left, undefined, implied);
178 right = _get_value(expr->right, undefined, opposite_implied(implied));
180 return sval_binop(left, '-', right);
183 static sval_t handle_binop(struct expression *expr, int *undefined, int implied)
185 sval_t left, right;
186 sval_t ret = {.type = &int_ctype, .value = 123456};
187 int local_undef = 0;
189 switch (expr->op) {
190 case '%':
191 left = _get_value(expr->left, &local_undef, implied);
192 if (local_undef) {
193 if (implied == ABSOLUTE_MIN) {
194 ret = sval_blank(expr->left);
195 ret.value = 0;
196 return ret;
198 if (implied != ABSOLUTE_MAX)
199 *undefined = 1;
200 if (!get_absolute_max(expr->left, &left))
201 *undefined = 1;
203 right = _get_value(expr->right, undefined, implied);
204 if (right.value == 0)
205 *undefined = 1;
206 if (*undefined)
207 return bogus;
208 return sval_binop(left, '%', right);
210 case '&':
211 left = _get_value(expr->left, &local_undef, implied);
212 if (local_undef) {
213 if (implied == ABSOLUTE_MIN) {
214 ret = sval_blank(expr->left);
215 ret.value = 0;
216 return ret;
218 if (implied != ABSOLUTE_MAX)
219 *undefined = 1;
220 if (!get_absolute_max(expr->left, &left))
221 *undefined = 1;
223 right = _get_value(expr->right, undefined, implied);
224 if (*undefined)
225 return bogus;
226 return sval_binop(left, '&', right);
228 case SPECIAL_RIGHTSHIFT:
229 left = _get_value(expr->left, &local_undef, implied);
230 if (local_undef) {
231 if (implied == ABSOLUTE_MIN) {
232 ret = sval_blank(expr->left);
233 ret.value = 0;
234 return ret;
236 if (implied != ABSOLUTE_MAX)
237 *undefined = 1;
238 if (!get_absolute_max(expr->left, &left))
239 *undefined = 1;
241 right = _get_value(expr->right, undefined, implied);
242 if (*undefined)
243 return bogus;
244 return sval_binop(left, SPECIAL_RIGHTSHIFT, right);
247 left = _get_value(expr->left, undefined, implied);
248 right = _get_value(expr->right, undefined, implied);
250 if (*undefined)
251 return bogus;
253 switch (expr->op) {
254 case '/':
255 return handle_divide(expr, undefined, implied);
256 case '%':
257 if (right.value == 0) {
258 *undefined = 1;
259 return bogus;
260 } else {
261 return sval_binop(left, '%', right);
263 case '-':
264 ret = handle_subtract(expr, undefined, implied);
265 break;
266 default:
267 ret = sval_binop(left, expr->op, right);
269 return ret;
272 static int do_comparison(struct expression *expr)
274 struct range_list *left_ranges = NULL;
275 struct range_list *right_ranges = NULL;
276 int poss_true, poss_false;
278 get_implied_range_list(expr->left, &left_ranges);
279 get_implied_range_list(expr->right, &right_ranges);
281 poss_true = possibly_true_range_lists(left_ranges, expr->op, right_ranges);
282 poss_false = possibly_false_range_lists(left_ranges, expr->op, right_ranges);
284 free_range_list(&left_ranges);
285 free_range_list(&right_ranges);
287 if (!poss_true && !poss_false)
288 return 0;
289 if (poss_true && !poss_false)
290 return 1;
291 if (!poss_true && poss_false)
292 return 2;
293 return 3;
296 static sval_t handle_comparison(struct expression *expr, int *undefined, int implied)
298 sval_t left, right;
299 int res;
301 if (get_value(expr->left, &left) && get_value(expr->right, &right)) {
302 struct data_range tmp_left, tmp_right;
304 tmp_left.min = left;
305 tmp_left.max = left;
306 tmp_right.min = right;
307 tmp_right.max = right;
308 if (true_comparison_range(&tmp_left, expr->op, &tmp_right))
309 return one;
310 return zero;
313 if (implied == NOTIMPLIED) {
314 *undefined = 1;
315 return bogus;
318 res = do_comparison(expr);
319 if (res == 1)
320 return one;
321 if (res == 2)
322 return zero;
324 if (implied == IMPLIED_MIN || implied == FUZZY_MIN || implied == ABSOLUTE_MIN)
325 return zero;
326 if (implied == IMPLIED_MAX || implied == FUZZY_MAX || implied == ABSOLUTE_MAX)
327 return one;
329 *undefined = 1;
330 return bogus;
333 static sval_t handle_logical(struct expression *expr, int *undefined, int implied)
335 sval_t left, right;
337 if ((implied == NOTIMPLIED && get_value(expr->left, &left) &&
338 get_value(expr->right, &right)) ||
339 (implied != NOTIMPLIED && get_implied_value(expr->left, &left) &&
340 get_implied_value(expr->right, &right))) {
341 switch (expr->op) {
342 case SPECIAL_LOGICAL_OR:
343 if (left.value || right.value)
344 return one;
345 return zero;
346 case SPECIAL_LOGICAL_AND:
347 if (left.value && right.value)
348 return one;
349 return zero;
350 default:
351 *undefined = 1;
352 return bogus;
356 if (implied == IMPLIED_MIN || implied == FUZZY_MIN || implied == ABSOLUTE_MIN)
357 return zero;
358 if (implied == IMPLIED_MAX || implied == FUZZY_MAX || implied == ABSOLUTE_MAX)
359 return one;
361 *undefined = 1;
362 return bogus;
365 static sval_t handle_conditional(struct expression *expr, int *undefined, int implied)
367 if (known_condition_true(expr->conditional))
368 return _get_value(expr->cond_true, undefined, implied);
369 if (known_condition_false(expr->conditional))
370 return _get_value(expr->cond_false, undefined, implied);
372 if (implied == NOTIMPLIED) {
373 *undefined = 1;
374 return bogus;
377 if (implied_condition_true(expr->conditional))
378 return _get_value(expr->cond_true, undefined, implied);
379 if (implied_condition_false(expr->conditional))
380 return _get_value(expr->cond_false, undefined, implied);
382 *undefined = 1;
383 return bogus;
386 static int get_implied_value_helper(struct expression *expr, sval_t *sval, int implied)
388 struct smatch_state *state;
389 struct symbol *sym;
390 char *name;
392 /* fixme: this should return the casted value */
394 expr = strip_expr(expr);
396 if (get_value(expr, sval))
397 return 1;
399 name = get_variable_from_expr(expr, &sym);
400 if (!name)
401 return 0;
402 *sval = sval_blank(expr);
403 state = get_state(SMATCH_EXTRA, name, sym);
404 free_string(name);
405 if (!state || !state->data)
406 return 0;
407 if (implied == IMPLIED) {
408 if (estate_get_single_value(state, sval))
409 return 1;
410 return 0;
412 if (implied == HARD_MAX) {
413 if (estate_get_hard_max(state, sval))
414 return 1;
415 return 0;
417 if (implied == IMPLIED_MAX) {
418 *sval = estate_max(state);
419 if (sval_is_max(*sval)) /* this means just guessing. fixme. not really */
420 return 0;
421 return 1;
423 *sval = estate_min(state);
424 if (sval_is_min(*sval)) /* fixme */
425 return 0;
426 return 1;
429 static int get_fuzzy_max_helper(struct expression *expr, sval_t *max)
431 struct sm_state *sm;
432 struct sm_state *tmp;
433 sval_t sval;
435 if (get_hard_max(expr, &sval)) {
436 *max = sval;
437 return 1;
440 sm = get_sm_state_expr(SMATCH_EXTRA, expr);
441 if (!sm)
442 return 0;
444 sval = sval_type_min(estate_type(sm->state));
445 FOR_EACH_PTR(sm->possible, tmp) {
446 sval_t new_min;
448 new_min = estate_min(tmp->state);
449 if (sval_cmp(new_min, sval) > 0)
450 sval = new_min;
451 } END_FOR_EACH_PTR(tmp);
453 if (sval_is_min(sval))
454 return 0;
456 *max = sval_cast(get_type(expr), sval);
457 return 1;
460 static int get_fuzzy_min_helper(struct expression *expr, sval_t *min)
462 struct sm_state *sm;
463 struct sm_state *tmp;
464 sval_t sval;
466 if (get_implied_min(expr, min))
467 return 1;
469 sm = get_sm_state_expr(SMATCH_EXTRA, expr);
470 if (!sm)
471 return 0;
473 sval = sval_type_max(estate_type(sm->state));
474 FOR_EACH_PTR(sm->possible, tmp) {
475 sval_t new_max;
477 new_max = estate_max(tmp->state);
478 if (sval_cmp(new_max, sval) < 0)
479 sval = new_max;
480 } END_FOR_EACH_PTR(tmp);
482 if (sval_is_max(sval))
483 return 0;
484 *min = sval_cast(get_type(expr), sval);
485 return 1;
488 static sval_t _get_implied_value(struct expression *expr, int *undefined, int implied)
490 sval_t ret;
492 ret = sval_blank(expr);
494 switch (implied) {
495 case IMPLIED:
496 case IMPLIED_MAX:
497 case IMPLIED_MIN:
498 case HARD_MAX:
499 if (!get_implied_value_helper(expr, &ret, implied))
500 *undefined = 1;
501 break;
502 case ABSOLUTE_MIN:
503 if (!get_absolute_min_helper(expr, &ret))
504 *undefined = 1;
505 break;
506 case ABSOLUTE_MAX:
507 if (!get_absolute_max_helper(expr, &ret))
508 *undefined = 1;
509 break;
510 case FUZZY_MAX:
511 if (!get_fuzzy_max_helper(expr, &ret))
512 *undefined = 1;
513 break;
514 case FUZZY_MIN:
515 if (!get_fuzzy_min_helper(expr, &ret))
516 *undefined = 1;
517 break;
518 default:
519 *undefined = 1;
521 return ret;
524 static int get_const_value(struct expression *expr, sval_t *sval)
526 struct symbol *sym;
527 sval_t right;
529 if (expr->type != EXPR_SYMBOL || !expr->symbol)
530 return 0;
531 sym = expr->symbol;
532 if (!(sym->ctype.modifiers & MOD_CONST))
533 return 0;
534 if (get_value(sym->initializer, &right)) {
535 *sval = sval_cast(get_type(expr), right);
536 return 1;
538 return 0;
541 static sval_t _get_value(struct expression *expr, int *undefined, int implied)
543 sval_t ret;
545 if (!expr) {
546 *undefined = 1;
547 return bogus;
549 if (*undefined)
550 return bogus;
552 expr = strip_parens(expr);
554 switch (expr->type) {
555 case EXPR_VALUE:
556 ret = sval_from_val(expr, expr->value);
557 break;
558 case EXPR_PREOP:
559 ret = handle_preop(expr, undefined, implied);
560 break;
561 case EXPR_POSTOP:
562 ret = _get_value(expr->unop, undefined, implied);
563 break;
564 case EXPR_CAST:
565 case EXPR_FORCE_CAST:
566 case EXPR_IMPLIED_CAST:
567 ret = _get_value(expr->cast_expression, undefined, implied);
568 ret = sval_cast(get_type(expr), ret);
569 break;
570 case EXPR_BINOP:
571 ret = handle_binop(expr, undefined, implied);
572 break;
573 case EXPR_COMPARE:
574 ret = handle_comparison(expr, undefined, implied);
575 break;
576 case EXPR_LOGICAL:
577 ret = handle_logical(expr, undefined, implied);
578 break;
579 case EXPR_PTRSIZEOF:
580 case EXPR_SIZEOF:
581 ret = sval_blank(expr);
582 ret.value = get_expression_value_nomod(expr);
583 break;
584 case EXPR_SYMBOL:
585 if (get_const_value(expr, &ret)) {
586 break;
588 ret = _get_implied_value(expr, undefined, implied);
589 break;
590 case EXPR_SELECT:
591 case EXPR_CONDITIONAL:
592 ret = handle_conditional(expr, undefined, implied);
593 break;
594 default:
595 ret = _get_implied_value(expr, undefined, implied);
597 if (*undefined)
598 return bogus;
599 return ret;
602 /* returns 1 if it can get a value literal or else returns 0 */
603 int get_value(struct expression *expr, sval_t *sval)
605 int undefined = 0;
606 sval_t ret;
608 ret = _get_value(expr, &undefined, NOTIMPLIED);
609 if (undefined)
610 return 0;
611 *sval = ret;
612 return 1;
615 int get_implied_value(struct expression *expr, sval_t *sval)
617 int undefined = 0;
618 sval_t ret;
620 ret = _get_value(expr, &undefined, IMPLIED);
621 if (undefined)
622 return 0;
623 *sval = ret;
624 return 1;
627 int get_implied_min(struct expression *expr, sval_t *sval)
629 int undefined = 0;
630 sval_t ret;
632 ret = _get_value(expr, &undefined, IMPLIED_MIN);
633 if (undefined)
634 return 0;
635 *sval = ret;
636 return 1;
639 int get_implied_max(struct expression *expr, sval_t *sval)
641 int undefined = 0;
642 sval_t ret;
644 ret = _get_value(expr, &undefined, IMPLIED_MAX);
645 if (undefined)
646 return 0;
647 *sval = ret;
648 return 1;
651 int get_hard_max(struct expression *expr, sval_t *sval)
653 int undefined = 0;
654 sval_t ret;
656 ret = _get_value(expr, &undefined, HARD_MAX);
657 if (undefined)
658 return 0;
659 *sval = ret;
660 return 1;
663 int get_fuzzy_min(struct expression *expr, sval_t *sval)
665 int undefined = 0;
666 sval_t ret;
668 ret = _get_value(expr, &undefined, FUZZY_MIN);
669 if (undefined)
670 return 0;
671 *sval = ret;
672 return 1;
675 int get_fuzzy_max(struct expression *expr, sval_t *sval)
677 int undefined = 0;
678 sval_t ret;
680 ret = _get_value(expr, &undefined, FUZZY_MAX);
681 if (undefined)
682 return 0;
683 *sval = ret;
684 return 1;
687 int get_absolute_min(struct expression *expr, sval_t *sval)
689 int undefined = 0;
690 struct symbol *type;
692 type = get_type(expr);
693 if (!type)
694 type = &llong_ctype; // FIXME: this is wrong but places assume get type can't fail.
695 *sval = _get_value(expr, &undefined, ABSOLUTE_MIN);
696 if (undefined) {
697 *sval = sval_type_min(type);
698 return 1;
701 if (sval_cmp(*sval, sval_type_min(type)) < 0)
702 *sval = sval_type_min(type);
703 return 1;
706 int get_absolute_max(struct expression *expr, sval_t *sval)
708 int undefined = 0;
709 struct symbol *type;
711 type = get_type(expr);
712 if (!type)
713 type = &llong_ctype;
714 *sval = _get_value(expr, &undefined, ABSOLUTE_MAX);
715 if (undefined) {
716 *sval = sval_type_max(type);
717 return 1;
720 if (sval_cmp(sval_type_max(type), *sval) < 0)
721 *sval = sval_type_max(type);
722 return 1;
725 int known_condition_true(struct expression *expr)
727 sval_t tmp;
729 if (!expr)
730 return 0;
732 if (get_value(expr, &tmp) && tmp.value)
733 return 1;
735 return 0;
738 int known_condition_false(struct expression *expr)
740 if (!expr)
741 return 0;
743 if (is_zero(expr))
744 return 1;
746 if (expr->type == EXPR_CALL) {
747 if (sym_name_is("__builtin_constant_p", expr->fn))
748 return 1;
750 return 0;
753 int implied_condition_true(struct expression *expr)
755 sval_t tmp;
757 if (!expr)
758 return 0;
760 if (known_condition_true(expr))
761 return 1;
762 if (get_implied_value(expr, &tmp) && tmp.value)
763 return 1;
765 if (expr->type == EXPR_POSTOP)
766 return implied_condition_true(expr->unop);
768 if (expr->type == EXPR_PREOP && expr->op == SPECIAL_DECREMENT)
769 return implied_not_equal(expr->unop, 1);
770 if (expr->type == EXPR_PREOP && expr->op == SPECIAL_INCREMENT)
771 return implied_not_equal(expr->unop, -1);
773 expr = strip_expr(expr);
774 switch (expr->type) {
775 case EXPR_COMPARE:
776 if (do_comparison(expr) == 1)
777 return 1;
778 break;
779 case EXPR_PREOP:
780 if (expr->op == '!') {
781 if (implied_condition_false(expr->unop))
782 return 1;
783 break;
785 break;
786 default:
787 if (implied_not_equal(expr, 0) == 1)
788 return 1;
789 break;
791 return 0;
794 int implied_condition_false(struct expression *expr)
796 struct expression *tmp;
797 sval_t sval;
799 if (!expr)
800 return 0;
802 if (known_condition_false(expr))
803 return 1;
805 switch (expr->type) {
806 case EXPR_COMPARE:
807 if (do_comparison(expr) == 2)
808 return 1;
809 case EXPR_PREOP:
810 if (expr->op == '!') {
811 if (implied_condition_true(expr->unop))
812 return 1;
813 break;
815 tmp = strip_expr(expr);
816 if (tmp != expr)
817 return implied_condition_false(tmp);
818 break;
819 default:
820 if (get_implied_value(expr, &sval) && sval.value == 0)
821 return 1;
822 break;
824 return 0;