type: include smatch_slist.h to prevent a segfault
[smatch.git] / smatch_extra.c
blobe79c174c96d991282823e007a716230fc4181681
1 /*
2 * Copyright (C) 2008 Dan Carpenter.
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 * smatch_extra.c is supposed to track the value of every variable.
23 #include <stdlib.h>
24 #include <errno.h>
25 #ifndef __USE_ISOC99
26 #define __USE_ISOC99
27 #endif
28 #include <limits.h>
29 #include "parse.h"
30 #include "smatch.h"
31 #include "smatch_slist.h"
32 #include "smatch_extra.h"
34 static int my_id;
36 struct string_list *__ignored_macros = NULL;
37 static int in_warn_on_macro(void)
39 struct statement *stmt;
40 char *tmp;
41 char *macro;
43 stmt = get_current_statement();
44 if (!stmt)
45 return 0;
46 macro = get_macro_name(stmt->pos);
47 if (!macro)
48 return 0;
50 FOR_EACH_PTR(__ignored_macros, tmp) {
51 if (!strcmp(tmp, macro))
52 return 1;
53 } END_FOR_EACH_PTR(tmp);
54 return 0;
57 typedef void (mod_hook)(const char *name, struct symbol *sym, struct smatch_state *state);
58 DECLARE_PTR_LIST(void_fn_list, mod_hook *);
59 static struct void_fn_list *extra_mod_hooks;
60 void add_extra_mod_hook(mod_hook *fn)
62 mod_hook **p = malloc(sizeof(mod_hook *));
63 *p = fn;
64 add_ptr_list(&extra_mod_hooks, p);
67 void call_extra_mod_hooks(const char *name, struct symbol *sym, struct smatch_state *state)
69 mod_hook **fn;
71 FOR_EACH_PTR(extra_mod_hooks, fn) {
72 (*fn)(name, sym, state);
73 } END_FOR_EACH_PTR(fn);
76 struct sm_state *set_extra_mod_helper(const char *name, struct symbol *sym, struct smatch_state *state)
78 remove_from_equiv(name, sym);
79 call_extra_mod_hooks(name, sym, state);
80 if (__in_fake_assign && estate_is_unknown(state) && !get_state(SMATCH_EXTRA, name, sym))
81 return NULL;
82 return set_state(SMATCH_EXTRA, name, sym, state);
85 static char *get_other_name_sym(const char *name, struct symbol *sym, struct symbol **new_sym)
87 struct expression *assigned;
88 char *orig_name = NULL;
89 char buf[256];
90 char *ret = NULL;
91 int skip;
93 *new_sym = NULL;
95 if (!sym->ident)
96 return NULL;
98 skip = strlen(sym->ident->name);
99 if (name[skip] != '-' || name[skip + 1] != '>')
100 return NULL;
101 skip += 2;
103 assigned = get_assigned_expr_name_sym(sym->ident->name, sym);
104 if (!assigned)
105 return NULL;
106 if (assigned->type == EXPR_PREOP || assigned->op == '&') {
108 orig_name = expr_to_var_sym(assigned, new_sym);
109 if (!orig_name || !*new_sym)
110 goto free;
112 snprintf(buf, sizeof(buf), "%s.%s", orig_name + 1, name + skip);
113 ret = alloc_string(buf);
114 free_string(orig_name);
115 return ret;
118 if (assigned->type != EXPR_DEREF)
119 goto free;
121 orig_name = expr_to_var_sym(assigned, new_sym);
122 if (!orig_name || !*new_sym)
123 goto free;
125 snprintf(buf, sizeof(buf), "%s->%s", orig_name, name + skip);
126 ret = alloc_string(buf);
127 free_string(orig_name);
128 return ret;
130 free:
131 free_string(orig_name);
132 return NULL;
135 struct sm_state *set_extra_mod(const char *name, struct symbol *sym, struct smatch_state *state)
137 char *new_name;
138 struct symbol *new_sym;
139 struct sm_state *sm;
141 if (in_warn_on_macro())
142 return NULL;
143 sm = set_extra_mod_helper(name, sym, state);
144 new_name = get_other_name_sym(name, sym, &new_sym);
145 if (new_name && new_sym)
146 set_extra_mod_helper(new_name, new_sym, state);
147 free_string(new_name);
148 return sm;
151 struct sm_state *set_extra_expr_mod(struct expression *expr, struct smatch_state *state)
153 struct symbol *sym;
154 char *name;
155 struct sm_state *ret = NULL;
157 expr = strip_expr(expr);
158 name = expr_to_var_sym(expr, &sym);
159 if (!name || !sym)
160 goto free;
161 ret = set_extra_mod(name, sym, state);
162 free:
163 free_string(name);
164 return ret;
167 void set_extra_nomod(const char *name, struct symbol *sym, struct smatch_state *state)
169 char *new_name;
170 struct symbol *new_sym;
171 struct relation *rel;
172 struct smatch_state *orig_state;
174 orig_state = get_state(SMATCH_EXTRA, name, sym);
176 new_name = get_other_name_sym(name, sym, &new_sym);
177 if (new_name && new_sym)
178 set_state(SMATCH_EXTRA, new_name, new_sym, state);
179 free_string(new_name);
181 if (!estate_related(orig_state)) {
182 set_state(SMATCH_EXTRA, name, sym, state);
183 return;
186 set_related(state, estate_related(orig_state));
187 FOR_EACH_PTR(estate_related(orig_state), rel) {
188 if (option_debug_related)
189 sm_msg("%s updating related %s to %s", name, rel->name, state->name);
190 set_state(SMATCH_EXTRA, rel->name, rel->sym, state);
191 } END_FOR_EACH_PTR(rel);
195 * This is for return_implies_state() hooks which modify a SMATCH_EXTRA state
197 void set_extra_expr_nomod(struct expression *expr, struct smatch_state *state)
199 char *name;
200 struct symbol *sym;
202 name = expr_to_var_sym(expr, &sym);
203 if (!name || !sym)
204 goto free;
205 set_extra_nomod(name, sym, state);
206 free:
207 free_string(name);
211 static void set_extra_true_false(const char *name, struct symbol *sym,
212 struct smatch_state *true_state,
213 struct smatch_state *false_state)
215 char *new_name;
216 struct symbol *new_sym;
217 struct relation *rel;
218 struct smatch_state *orig_state;
220 if (in_warn_on_macro())
221 return;
223 new_name = get_other_name_sym(name, sym, &new_sym);
224 if (new_name && new_sym)
225 set_true_false_states(SMATCH_EXTRA, new_name, new_sym, true_state, false_state);
226 free_string(new_name);
228 orig_state = get_state(SMATCH_EXTRA, name, sym);
230 if (!estate_related(orig_state)) {
231 set_true_false_states(SMATCH_EXTRA, name, sym, true_state, false_state);
232 return;
235 if (true_state)
236 set_related(true_state, estate_related(orig_state));
237 if (false_state)
238 set_related(false_state, estate_related(orig_state));
240 FOR_EACH_PTR(estate_related(orig_state), rel) {
241 set_true_false_states(SMATCH_EXTRA, rel->name, rel->sym,
242 true_state, false_state);
243 } END_FOR_EACH_PTR(rel);
246 static void set_extra_expr_true_false(struct expression *expr,
247 struct smatch_state *true_state,
248 struct smatch_state *false_state)
250 char *name;
251 struct symbol *sym;
253 expr = strip_expr(expr);
254 name = expr_to_var_sym(expr, &sym);
255 if (!name || !sym)
256 goto free;
257 set_extra_true_false(name, sym, true_state, false_state);
258 free:
259 free_string(name);
262 static struct sm_state *handle_canonical_while_count_down(struct statement *loop)
264 struct expression *iter_var;
265 struct expression *condition;
266 struct sm_state *sm;
267 struct smatch_state *estate;
268 sval_t start;
270 condition = strip_expr(loop->iterator_pre_condition);
271 if (!condition)
272 return NULL;
273 if (condition->type != EXPR_PREOP && condition->type != EXPR_POSTOP)
274 return NULL;
275 if (condition->op != SPECIAL_DECREMENT)
276 return NULL;
278 iter_var = condition->unop;
279 sm = get_sm_state_expr(SMATCH_EXTRA, iter_var);
280 if (!sm)
281 return NULL;
282 if (sval_cmp_val(estate_min(sm->state), 0) < 0)
283 return NULL;
284 start = estate_max(sm->state);
285 if (sval_cmp_val(start, 0) <= 0)
286 return NULL;
287 if (!sval_is_max(start))
288 start.value--;
290 if (condition->type == EXPR_PREOP) {
291 estate = alloc_estate_range(sval_type_val(start.type, 1), start);
292 if (estate_has_hard_max(sm->state))
293 estate_set_hard_max(estate);
294 estate_copy_fuzzy_max(estate, sm->state);
295 set_extra_expr_mod(iter_var, estate);
297 if (condition->type == EXPR_POSTOP) {
298 estate = alloc_estate_range(sval_type_val(start.type, 0), start);
299 if (estate_has_hard_max(sm->state))
300 estate_set_hard_max(estate);
301 estate_copy_fuzzy_max(estate, sm->state);
302 set_extra_expr_mod(iter_var, estate);
304 return get_sm_state_expr(SMATCH_EXTRA, iter_var);
307 static struct sm_state *handle_canonical_for_inc(struct expression *iter_expr,
308 struct expression *condition)
310 struct expression *iter_var;
311 struct sm_state *sm;
312 struct smatch_state *estate;
313 sval_t start, end, max;
315 iter_var = iter_expr->unop;
316 sm = get_sm_state_expr(SMATCH_EXTRA, iter_var);
317 if (!sm)
318 return NULL;
319 if (!estate_get_single_value(sm->state, &start))
320 return NULL;
321 if (get_implied_max(condition->right, &end))
322 end = sval_cast(get_type(iter_var), end);
323 else
324 end = sval_type_max(get_type(iter_var));
326 if (get_sm_state_expr(SMATCH_EXTRA, condition->left) != sm)
327 return NULL;
329 switch (condition->op) {
330 case SPECIAL_UNSIGNED_LT:
331 case SPECIAL_NOTEQUAL:
332 case '<':
333 if (!sval_is_min(end))
334 end.value--;
335 break;
336 case SPECIAL_UNSIGNED_LTE:
337 case SPECIAL_LTE:
338 break;
339 default:
340 return NULL;
342 if (sval_cmp(end, start) < 0)
343 return NULL;
344 estate = alloc_estate_range(start, end);
345 if (get_hard_max(condition->right, &max)) {
346 estate_set_hard_max(estate);
347 if (condition->op == '<' ||
348 condition->op == SPECIAL_UNSIGNED_LT ||
349 condition->op == SPECIAL_NOTEQUAL)
350 max.value--;
351 estate_set_fuzzy_max(estate, max);
353 set_extra_expr_mod(iter_var, estate);
354 return get_sm_state_expr(SMATCH_EXTRA, iter_var);
357 static struct sm_state *handle_canonical_for_dec(struct expression *iter_expr,
358 struct expression *condition)
360 struct expression *iter_var;
361 struct sm_state *sm;
362 struct smatch_state *estate;
363 sval_t start, end;
365 iter_var = iter_expr->unop;
366 sm = get_sm_state_expr(SMATCH_EXTRA, iter_var);
367 if (!sm)
368 return NULL;
369 if (!estate_get_single_value(sm->state, &start))
370 return NULL;
371 if (!get_implied_min(condition->right, &end))
372 end = sval_type_min(get_type(iter_var));
373 if (get_sm_state_expr(SMATCH_EXTRA, condition->left) != sm)
374 return NULL;
376 switch (condition->op) {
377 case SPECIAL_NOTEQUAL:
378 case '>':
379 if (!sval_is_min(end) && !sval_is_max(end))
380 end.value++;
381 break;
382 case SPECIAL_GTE:
383 break;
384 default:
385 return NULL;
387 if (sval_cmp(end, start) > 0)
388 return NULL;
389 estate = alloc_estate_range(end, start);
390 estate_set_hard_max(estate);
391 estate_set_fuzzy_max(estate, estate_get_fuzzy_max(estate));
392 set_extra_expr_mod(iter_var, estate);
393 return get_sm_state_expr(SMATCH_EXTRA, iter_var);
396 static struct sm_state *handle_canonical_for_loops(struct statement *loop)
398 struct expression *iter_expr;
399 struct expression *condition;
401 if (!loop->iterator_post_statement)
402 return NULL;
403 if (loop->iterator_post_statement->type != STMT_EXPRESSION)
404 return NULL;
405 iter_expr = loop->iterator_post_statement->expression;
406 if (!loop->iterator_pre_condition)
407 return NULL;
408 if (loop->iterator_pre_condition->type != EXPR_COMPARE)
409 return NULL;
410 condition = loop->iterator_pre_condition;
412 if (iter_expr->op == SPECIAL_INCREMENT)
413 return handle_canonical_for_inc(iter_expr, condition);
414 if (iter_expr->op == SPECIAL_DECREMENT)
415 return handle_canonical_for_dec(iter_expr, condition);
416 return NULL;
419 struct sm_state *__extra_handle_canonical_loops(struct statement *loop, struct stree **stree)
421 struct sm_state *ret;
423 __push_fake_cur_stree();
424 if (!loop->iterator_post_statement)
425 ret = handle_canonical_while_count_down(loop);
426 else
427 ret = handle_canonical_for_loops(loop);
428 *stree = __pop_fake_cur_stree();
429 return ret;
432 int __iterator_unchanged(struct sm_state *sm)
434 if (!sm)
435 return 0;
436 if (get_sm_state(my_id, sm->name, sm->sym) == sm)
437 return 1;
438 return 0;
441 static void while_count_down_after(struct sm_state *sm, struct expression *condition)
443 sval_t after_value;
445 /* paranoid checking. prolly not needed */
446 condition = strip_expr(condition);
447 if (!condition)
448 return;
449 if (condition->type != EXPR_PREOP && condition->type != EXPR_POSTOP)
450 return;
451 if (condition->op != SPECIAL_DECREMENT)
452 return;
453 after_value = estate_min(sm->state);
454 after_value.value--;
455 set_extra_mod(sm->name, sm->sym, alloc_estate_sval(after_value));
458 void __extra_pre_loop_hook_after(struct sm_state *sm,
459 struct statement *iterator,
460 struct expression *condition)
462 struct expression *iter_expr;
463 sval_t limit;
464 struct smatch_state *state;
466 if (!iterator) {
467 while_count_down_after(sm, condition);
468 return;
471 iter_expr = iterator->expression;
473 if (condition->type != EXPR_COMPARE)
474 return;
475 if (iter_expr->op == SPECIAL_INCREMENT) {
476 limit = sval_binop(estate_max(sm->state), '+',
477 sval_type_val(estate_type(sm->state), 1));
478 } else {
479 limit = sval_binop(estate_min(sm->state), '-',
480 sval_type_val(estate_type(sm->state), 1));
482 if (!estate_has_hard_max(sm->state) && !__has_breaks()) {
483 if (iter_expr->op == SPECIAL_INCREMENT)
484 state = alloc_estate_range(estate_min(sm->state), limit);
485 else
486 state = alloc_estate_range(limit, estate_max(sm->state));
487 } else {
488 state = alloc_estate_sval(limit);
490 if (!estate_has_hard_max(sm->state)) {
491 estate_clear_hard_max(state);
493 if (estate_has_fuzzy_max(sm->state)) {
494 sval_t hmax = estate_get_fuzzy_max(sm->state);
495 sval_t max = estate_max(sm->state);
497 if (sval_cmp(hmax, max) != 0)
498 estate_clear_fuzzy_max(state);
499 } else if (!estate_has_fuzzy_max(sm->state)) {
500 estate_clear_fuzzy_max(state);
503 set_extra_mod(sm->name, sm->sym, state);
506 static struct stree *unmatched_stree;
507 static struct smatch_state *unmatched_state(struct sm_state *sm)
509 struct smatch_state *state;
511 if (unmatched_stree) {
512 state = get_state_stree(unmatched_stree, SMATCH_EXTRA, sm->name, sm->sym);
513 if (state)
514 return state;
516 if (parent_is_gone_var_sym(sm->name, sm->sym))
517 return alloc_estate_empty();
518 return alloc_estate_whole(estate_type(sm->state));
521 static void clear_the_pointed_at(struct expression *expr)
523 struct stree *stree;
524 char *name;
525 struct symbol *sym;
526 struct sm_state *tmp;
528 name = expr_to_var_sym(expr, &sym);
529 if (!name || !sym)
530 goto free;
532 stree = __get_cur_stree();
533 FOR_EACH_MY_SM(SMATCH_EXTRA, stree, tmp) {
534 if (tmp->name[0] != '*')
535 continue;
536 if (tmp->sym != sym)
537 continue;
538 if (strcmp(tmp->name + 1, name) != 0)
539 continue;
540 set_extra_mod(tmp->name, tmp->sym, alloc_estate_whole(estate_type(tmp->state)));
541 } END_FOR_EACH_SM(tmp);
543 free:
544 free_string(name);
547 static void match_function_call(struct expression *expr)
549 struct expression *arg;
550 struct expression *tmp;
552 /* if we have the db this is handled in smatch_function_hooks.c */
553 if (!option_no_db)
554 return;
555 if (inlinable(expr->fn))
556 return;
558 FOR_EACH_PTR(expr->args, arg) {
559 tmp = strip_expr(arg);
560 if (tmp->type == EXPR_PREOP && tmp->op == '&')
561 set_extra_expr_mod(tmp->unop, alloc_estate_whole(get_type(tmp->unop)));
562 else
563 clear_the_pointed_at(tmp);
564 } END_FOR_EACH_PTR(arg);
567 static int types_equiv_or_pointer(struct symbol *one, struct symbol *two)
569 if (!one || !two)
570 return 0;
571 if (one->type == SYM_PTR && two->type == SYM_PTR)
572 return 1;
573 return types_equiv(one, two);
576 static bool is_non_null_array(struct expression *expr)
578 struct symbol *type;
579 struct symbol *sym;
580 struct symbol *tmp;
581 char *name;
582 int i;
584 type = get_type(expr);
585 if (!type || type->type != SYM_ARRAY)
586 return 0;
587 if (expr->type == EXPR_SYMBOL)
588 return 1;
589 if (implied_not_equal(expr, 0))
590 return 1;
592 /* verify that it's not the first member of the struct */
593 if (expr->type != EXPR_DEREF || !expr->member)
594 return 0;
595 name = expr_to_var_sym(expr, &sym);
596 free_string(name);
597 if (!name || !sym)
598 return 0;
599 type = get_real_base_type(sym);
600 if (!type || type->type != SYM_PTR)
601 return 0;
602 type = get_real_base_type(type);
603 if (type->type != SYM_STRUCT)
604 return 0;
606 i = 0;
607 FOR_EACH_PTR(type->symbol_list, tmp) {
608 i++;
609 if (!tmp->ident)
610 continue;
611 if (strcmp(expr->member->name, tmp->ident->name) == 0) {
612 if (i == 1)
613 return 0;
614 return 1;
616 } END_FOR_EACH_PTR(tmp);
618 return 0;
621 static void match_vanilla_assign(struct expression *left, struct expression *right)
623 struct range_list *rl = NULL;
624 struct symbol *right_sym;
625 struct symbol *left_type;
626 struct symbol *right_type;
627 char *right_name = NULL;
628 struct symbol *sym;
629 char *name;
630 sval_t max;
631 struct smatch_state *state;
633 if (is_struct(left))
634 return;
636 name = expr_to_var_sym(left, &sym);
637 if (!name)
638 return;
640 left_type = get_type(left);
641 right_type = get_type(right);
643 right_name = expr_to_var_sym(right, &right_sym);
645 if (!__in_fake_assign &&
646 !(right->type == EXPR_PREOP && right->op == '&') &&
647 right_name && right_sym &&
648 types_equiv_or_pointer(left_type, right_type) &&
649 !has_symbol(right, sym)) {
650 set_equiv(left, right);
651 goto free;
654 if (is_non_null_array(right)) {
655 state = alloc_estate_range(array_min_sval, array_max_sval);
656 } else if (get_implied_rl(right, &rl)) {
657 rl = cast_rl(left_type, rl);
658 state = alloc_estate_rl(rl);
659 if (get_hard_max(right, &max)) {
660 estate_set_hard_max(state);
661 estate_set_fuzzy_max(state, max);
663 } else {
664 rl = alloc_whole_rl(right_type);
665 rl = cast_rl(left_type, rl);
666 state = alloc_estate_rl(rl);
668 set_extra_mod(name, sym, state);
669 free:
670 free_string(right_name);
673 static int op_remove_assign(int op)
675 switch (op) {
676 case SPECIAL_ADD_ASSIGN:
677 return '+';
678 case SPECIAL_SUB_ASSIGN:
679 return '-';
680 case SPECIAL_MUL_ASSIGN:
681 return '*';
682 case SPECIAL_DIV_ASSIGN:
683 return '/';
684 case SPECIAL_MOD_ASSIGN:
685 return '%';
686 case SPECIAL_AND_ASSIGN:
687 return '&';
688 case SPECIAL_OR_ASSIGN:
689 return '|';
690 case SPECIAL_XOR_ASSIGN:
691 return '^';
692 case SPECIAL_SHL_ASSIGN:
693 return SPECIAL_LEFTSHIFT;
694 case SPECIAL_SHR_ASSIGN:
695 return SPECIAL_RIGHTSHIFT;
696 default:
697 return op;
701 static void match_assign(struct expression *expr)
703 struct range_list *rl = NULL;
704 struct expression *left;
705 struct expression *right;
706 struct expression *binop_expr;
707 struct symbol *left_type;
708 struct symbol *right_type;
709 struct symbol *sym;
710 char *name;
711 sval_t left_min, left_max;
712 sval_t right_min, right_max;
713 sval_t res_min, res_max;
715 left = strip_expr(expr->left);
717 right = strip_expr(expr->right);
718 while (right->type == EXPR_ASSIGNMENT && right->op == '=')
719 right = strip_expr(right->left);
721 if (expr->op == '=' && is_condition(expr->right))
722 return; /* handled in smatch_condition.c */
723 if (expr->op == '=' && right->type == EXPR_CALL)
724 return; /* handled in smatch_function_hooks.c */
725 if (expr->op == '=') {
726 match_vanilla_assign(left, right);
727 return;
730 name = expr_to_var_sym(left, &sym);
731 if (!name)
732 return;
734 left_type = get_type(left);
735 right_type = get_type(right);
737 res_min = sval_type_min(left_type);
738 res_max = sval_type_max(left_type);
740 switch (expr->op) {
741 case SPECIAL_ADD_ASSIGN:
742 get_absolute_max(left, &left_max);
743 get_absolute_max(right, &right_max);
744 if (sval_binop_overflows(left_max, '+', right_max))
745 break;
746 if (get_implied_min(left, &left_min) &&
747 !sval_is_negative_min(left_min) &&
748 get_implied_min(right, &right_min) &&
749 !sval_is_negative_min(right_min)) {
750 res_min = sval_binop(left_min, '+', right_min);
751 res_min = sval_cast(right_type, res_min);
753 if (inside_loop()) /* we are assuming loops don't lead to wrapping */
754 break;
755 res_max = sval_binop(left_max, '+', right_max);
756 res_max = sval_cast(right_type, res_max);
757 break;
758 case SPECIAL_SUB_ASSIGN:
759 if (get_implied_max(left, &left_max) &&
760 !sval_is_max(left_max) &&
761 get_implied_min(right, &right_min) &&
762 !sval_is_min(right_min)) {
763 res_max = sval_binop(left_max, '-', right_min);
764 res_max = sval_cast(right_type, res_max);
766 if (inside_loop())
767 break;
768 if (get_implied_min(left, &left_min) &&
769 !sval_is_min(left_min) &&
770 get_implied_max(right, &right_max) &&
771 !sval_is_max(right_max)) {
772 res_min = sval_binop(left_min, '-', right_max);
773 res_min = sval_cast(right_type, res_min);
775 break;
776 case SPECIAL_AND_ASSIGN:
777 case SPECIAL_MOD_ASSIGN:
778 case SPECIAL_SHL_ASSIGN:
779 case SPECIAL_SHR_ASSIGN:
780 case SPECIAL_OR_ASSIGN:
781 case SPECIAL_XOR_ASSIGN:
782 case SPECIAL_MUL_ASSIGN:
783 case SPECIAL_DIV_ASSIGN:
784 binop_expr = binop_expression(expr->left,
785 op_remove_assign(expr->op),
786 expr->right);
787 if (get_absolute_rl(binop_expr, &rl)) {
788 rl = cast_rl(left_type, rl);
789 set_extra_mod(name, sym, alloc_estate_rl(rl));
790 goto free;
792 break;
794 rl = cast_rl(left_type, alloc_rl(res_min, res_max));
795 set_extra_mod(name, sym, alloc_estate_rl(rl));
796 free:
797 free_string(name);
800 static struct smatch_state *increment_state(struct smatch_state *state)
802 sval_t min = estate_min(state);
803 sval_t max = estate_max(state);
805 if (!estate_rl(state))
806 return NULL;
808 if (inside_loop())
809 max = sval_type_max(max.type);
811 if (!sval_is_min(min) && !sval_is_max(min))
812 min.value++;
813 if (!sval_is_min(max) && !sval_is_max(max))
814 max.value++;
815 return alloc_estate_range(min, max);
818 static struct smatch_state *decrement_state(struct smatch_state *state)
820 sval_t min = estate_min(state);
821 sval_t max = estate_max(state);
823 if (!estate_rl(state))
824 return NULL;
826 if (inside_loop())
827 min = sval_type_min(min.type);
829 if (!sval_is_min(min) && !sval_is_max(min))
830 min.value--;
831 if (!sval_is_min(max) && !sval_is_max(max))
832 max.value--;
833 return alloc_estate_range(min, max);
836 static void unop_expr(struct expression *expr)
838 struct smatch_state *state;
840 if (expr->smatch_flags & Handled)
841 return;
843 switch (expr->op) {
844 case SPECIAL_INCREMENT:
845 state = get_state_expr(SMATCH_EXTRA, expr->unop);
846 state = increment_state(state);
847 if (!state)
848 state = alloc_estate_whole(get_type(expr));
849 set_extra_expr_mod(expr->unop, state);
850 break;
851 case SPECIAL_DECREMENT:
852 state = get_state_expr(SMATCH_EXTRA, expr->unop);
853 state = decrement_state(state);
854 if (!state)
855 state = alloc_estate_whole(get_type(expr));
856 set_extra_expr_mod(expr->unop, state);
857 break;
858 default:
859 return;
863 static void asm_expr(struct statement *stmt)
866 struct expression *expr;
867 struct symbol *type;
868 int state = 0;
870 FOR_EACH_PTR(stmt->asm_outputs, expr) {
871 switch (state) {
872 case 0: /* identifier */
873 case 1: /* constraint */
874 state++;
875 continue;
876 case 2: /* expression */
877 state = 0;
878 type = get_type(strip_expr(expr));
879 set_extra_expr_mod(expr, alloc_estate_whole(type));
880 continue;
882 } END_FOR_EACH_PTR(expr);
885 static void delete_state_tracker(struct tracker *t)
887 remove_from_equiv(t->name, t->sym);
888 delete_state(t->owner, t->name, t->sym);
891 static void scoped_state_extra(const char *name, struct symbol *sym)
893 struct tracker *t;
895 t = alloc_tracker(SMATCH_EXTRA, name, sym);
896 add_scope_hook((scope_hook *)&delete_state_tracker, t);
899 static void check_dereference(struct expression *expr)
901 if (outside_of_function())
902 return;
903 set_extra_expr_nomod(expr, alloc_estate_range(valid_ptr_min_sval, valid_ptr_max_sval));
906 static void match_dereferences(struct expression *expr)
908 if (expr->type != EXPR_PREOP)
909 return;
910 check_dereference(expr->unop);
913 static void match_pointer_as_array(struct expression *expr)
915 if (!is_array(expr))
916 return;
917 check_dereference(get_array_base(expr));
920 static void set_param_dereferenced(struct expression *arg, char *key, char *unused)
922 struct symbol *sym;
923 char *name;
925 name = get_variable_from_key(arg, key, &sym);
926 if (!name || !sym)
927 goto free;
929 set_extra_nomod(name, sym, alloc_estate_range(valid_ptr_min_sval, valid_ptr_max_sval));
931 free:
932 free_string(name);
935 static sval_t add_one(sval_t sval)
937 sval.value++;
938 return sval;
941 static sval_t sub_one(sval_t sval)
943 sval.value--;
944 return sval;
947 static void handle_comparison(struct symbol *type, struct expression *left, int op, struct expression *right)
949 struct range_list *left_orig;
950 struct range_list *left_true;
951 struct range_list *left_false;
952 struct range_list *right_orig;
953 struct range_list *right_true;
954 struct range_list *right_false;
955 struct smatch_state *left_true_state;
956 struct smatch_state *left_false_state;
957 struct smatch_state *right_true_state;
958 struct smatch_state *right_false_state;
959 sval_t min, max, dummy, hard_max;
960 int left_postop = 0;
961 int right_postop = 0;
963 if (left->op == SPECIAL_INCREMENT || left->op == SPECIAL_DECREMENT) {
964 if (left->type == EXPR_POSTOP) {
965 left->smatch_flags |= Handled;
966 left_postop = left->op;
968 left = strip_expr(left->unop);
970 while (left->type == EXPR_ASSIGNMENT)
971 left = strip_expr(left->left);
973 if (right->op == SPECIAL_INCREMENT || right->op == SPECIAL_DECREMENT) {
974 if (right->type == EXPR_POSTOP) {
975 right->smatch_flags |= Handled;
976 right_postop = right->op;
978 right = strip_expr(right->unop);
981 if (get_implied_rl(left, &left_orig)) {
982 left_orig = cast_rl(type, left_orig);
983 } else {
984 min = sval_type_min(get_type(left));
985 max = sval_type_max(get_type(left));
986 left_orig = cast_rl(type, alloc_rl(min, max));
989 if (get_implied_rl(right, &right_orig)) {
990 right_orig = cast_rl(type, right_orig);
991 } else {
992 min = sval_type_min(get_type(right));
993 max = sval_type_max(get_type(right));
994 right_orig = cast_rl(type, alloc_rl(min, max));
996 min = sval_type_min(type);
997 max = sval_type_max(type);
999 left_true = clone_rl(left_orig);
1000 left_false = clone_rl(left_orig);
1001 right_true = clone_rl(right_orig);
1002 right_false = clone_rl(right_orig);
1004 switch (op) {
1005 case '<':
1006 case SPECIAL_UNSIGNED_LT:
1007 left_true = remove_range(left_orig, rl_max(right_orig), max);
1008 if (!sval_is_min(rl_min(right_orig))) {
1009 left_false = remove_range(left_orig, min, sub_one(rl_min(right_orig)));
1012 right_true = remove_range(right_orig, min, rl_min(left_orig));
1013 if (!sval_is_max(rl_max(left_orig)))
1014 right_false = remove_range(right_orig, add_one(rl_max(left_orig)), max);
1015 break;
1016 case SPECIAL_UNSIGNED_LTE:
1017 case SPECIAL_LTE:
1018 if (!sval_is_max(rl_max(right_orig)))
1019 left_true = remove_range(left_orig, add_one(rl_max(right_orig)), max);
1020 left_false = remove_range(left_orig, min, rl_min(right_orig));
1022 if (!sval_is_min(rl_min(left_orig)))
1023 right_true = remove_range(right_orig, min, sub_one(rl_min(left_orig)));
1024 right_false = remove_range(right_orig, rl_max(left_orig), max);
1026 if (sval_cmp(rl_min(left_orig), rl_min(right_orig)) == 0)
1027 left_false = remove_range(left_false, rl_min(left_orig), rl_min(left_orig));
1028 if (sval_cmp(rl_max(left_orig), rl_max(right_orig)) == 0)
1029 right_false = remove_range(right_false, rl_max(left_orig), rl_max(left_orig));
1030 break;
1031 case SPECIAL_EQUAL:
1032 if (!sval_is_max(rl_max(right_orig))) {
1033 left_true = remove_range(left_true, add_one(rl_max(right_orig)), max);
1035 if (!sval_is_min(rl_min(right_orig))) {
1036 left_true = remove_range(left_true, min, sub_one(rl_min(right_orig)));
1038 if (sval_cmp(rl_min(right_orig), rl_max(right_orig)) == 0)
1039 left_false = remove_range(left_orig, rl_min(right_orig), rl_min(right_orig));
1041 if (!sval_is_max(rl_max(left_orig)))
1042 right_true = remove_range(right_true, add_one(rl_max(left_orig)), max);
1043 if (!sval_is_min(rl_min(left_orig)))
1044 right_true = remove_range(right_true, min, sub_one(rl_min(left_orig)));
1045 if (sval_cmp(rl_min(left_orig), rl_max(left_orig)) == 0)
1046 right_false = remove_range(right_orig, rl_min(left_orig), rl_min(left_orig));
1047 break;
1048 case SPECIAL_UNSIGNED_GTE:
1049 case SPECIAL_GTE:
1050 if (!sval_is_min(rl_min(right_orig)))
1051 left_true = remove_range(left_orig, min, sub_one(rl_min(right_orig)));
1052 left_false = remove_range(left_orig, rl_max(right_orig), max);
1054 if (!sval_is_max(rl_max(left_orig)))
1055 right_true = remove_range(right_orig, add_one(rl_max(left_orig)), max);
1056 right_false = remove_range(right_orig, min, rl_min(left_orig));
1058 if (sval_cmp(rl_min(left_orig), rl_min(right_orig)) == 0)
1059 right_false = remove_range(right_false, rl_min(left_orig), rl_min(left_orig));
1060 if (sval_cmp(rl_max(left_orig), rl_max(right_orig)) == 0)
1061 left_false = remove_range(left_false, rl_max(left_orig), rl_max(left_orig));
1062 break;
1063 case '>':
1064 case SPECIAL_UNSIGNED_GT:
1065 left_true = remove_range(left_orig, min, rl_min(right_orig));
1066 if (!sval_is_max(rl_max(right_orig)))
1067 left_false = remove_range(left_orig, add_one(rl_max(right_orig)), max);
1069 right_true = remove_range(right_orig, rl_max(left_orig), max);
1070 if (!sval_is_min(rl_min(left_orig)))
1071 right_false = remove_range(right_orig, min, sub_one(rl_min(left_orig)));
1072 break;
1073 case SPECIAL_NOTEQUAL:
1074 if (!sval_is_max(rl_max(right_orig)))
1075 left_false = remove_range(left_false, add_one(rl_max(right_orig)), max);
1076 if (!sval_is_min(rl_min(right_orig)))
1077 left_false = remove_range(left_false, min, sub_one(rl_min(right_orig)));
1078 if (sval_cmp(rl_min(right_orig), rl_max(right_orig)) == 0)
1079 left_true = remove_range(left_orig, rl_min(right_orig), rl_min(right_orig));
1081 if (!sval_is_max(rl_max(left_orig)))
1082 right_false = remove_range(right_false, add_one(rl_max(left_orig)), max);
1083 if (!sval_is_min(rl_min(left_orig)))
1084 right_false = remove_range(right_false, min, sub_one(rl_min(left_orig)));
1085 if (sval_cmp(rl_min(left_orig), rl_max(left_orig)) == 0)
1086 right_true = remove_range(right_orig, rl_min(left_orig), rl_min(left_orig));
1087 break;
1088 default:
1089 return;
1092 left_true = rl_truncate_cast(get_type(left), left_true);
1093 left_false = rl_truncate_cast(get_type(left), left_false);
1094 right_true = rl_truncate_cast(get_type(right), right_true);
1095 right_false = rl_truncate_cast(get_type(right), right_false);
1097 left_true_state = alloc_estate_rl(left_true);
1098 left_false_state = alloc_estate_rl(left_false);
1099 right_true_state = alloc_estate_rl(right_true);
1100 right_false_state = alloc_estate_rl(right_false);
1102 switch (op) {
1103 case '<':
1104 case SPECIAL_UNSIGNED_LT:
1105 case SPECIAL_UNSIGNED_LTE:
1106 case SPECIAL_LTE:
1107 if (get_hard_max(right, &dummy))
1108 estate_set_hard_max(left_true_state);
1109 if (get_hard_max(left, &dummy))
1110 estate_set_hard_max(right_false_state);
1111 break;
1112 case '>':
1113 case SPECIAL_UNSIGNED_GT:
1114 case SPECIAL_UNSIGNED_GTE:
1115 case SPECIAL_GTE:
1116 if (get_hard_max(left, &dummy))
1117 estate_set_hard_max(right_true_state);
1118 if (get_hard_max(right, &dummy))
1119 estate_set_hard_max(left_false_state);
1120 break;
1123 switch (op) {
1124 case '<':
1125 case SPECIAL_UNSIGNED_LT:
1126 case SPECIAL_UNSIGNED_LTE:
1127 case SPECIAL_LTE:
1128 if (get_hard_max(right, &hard_max)) {
1129 if (op == '<' || op == SPECIAL_UNSIGNED_LT)
1130 hard_max.value--;
1131 estate_set_fuzzy_max(left_true_state, hard_max);
1133 if (get_implied_value(right, &hard_max)) {
1134 if (op == SPECIAL_UNSIGNED_LTE ||
1135 op == SPECIAL_LTE)
1136 hard_max.value++;
1137 estate_set_fuzzy_max(left_false_state, hard_max);
1139 if (get_hard_max(left, &hard_max)) {
1140 if (op == SPECIAL_UNSIGNED_LTE ||
1141 op == SPECIAL_LTE)
1142 hard_max.value--;
1143 estate_set_fuzzy_max(right_false_state, hard_max);
1145 if (get_implied_value(left, &hard_max)) {
1146 if (op == '<' || op == SPECIAL_UNSIGNED_LT)
1147 hard_max.value++;
1148 estate_set_fuzzy_max(right_true_state, hard_max);
1150 break;
1151 case '>':
1152 case SPECIAL_UNSIGNED_GT:
1153 case SPECIAL_UNSIGNED_GTE:
1154 case SPECIAL_GTE:
1155 if (get_hard_max(left, &hard_max)) {
1156 if (op == '>' || op == SPECIAL_UNSIGNED_GT)
1157 hard_max.value--;
1158 estate_set_fuzzy_max(right_true_state, hard_max);
1160 if (get_implied_value(left, &hard_max)) {
1161 if (op == SPECIAL_UNSIGNED_GTE ||
1162 op == SPECIAL_GTE)
1163 hard_max.value++;
1164 estate_set_fuzzy_max(right_false_state, hard_max);
1166 if (get_hard_max(right, &hard_max)) {
1167 if (op == SPECIAL_UNSIGNED_LTE ||
1168 op == SPECIAL_LTE)
1169 hard_max.value--;
1170 estate_set_fuzzy_max(left_false_state, hard_max);
1172 if (get_implied_value(right, &hard_max)) {
1173 if (op == '>' ||
1174 op == SPECIAL_UNSIGNED_GT)
1175 hard_max.value++;
1176 estate_set_fuzzy_max(left_true_state, hard_max);
1178 break;
1179 case SPECIAL_EQUAL:
1180 if (get_hard_max(left, &hard_max))
1181 estate_set_fuzzy_max(right_true_state, hard_max);
1182 if (get_hard_max(right, &hard_max))
1183 estate_set_fuzzy_max(left_true_state, hard_max);
1184 break;
1187 if (get_hard_max(left, &hard_max)) {
1188 estate_set_hard_max(left_true_state);
1189 estate_set_hard_max(left_false_state);
1191 if (get_hard_max(right, &hard_max)) {
1192 estate_set_hard_max(right_true_state);
1193 estate_set_hard_max(right_false_state);
1196 if (left_postop == SPECIAL_INCREMENT) {
1197 left_true_state = increment_state(left_true_state);
1198 left_false_state = increment_state(left_false_state);
1200 if (left_postop == SPECIAL_DECREMENT) {
1201 left_true_state = decrement_state(left_true_state);
1202 left_false_state = decrement_state(left_false_state);
1204 if (right_postop == SPECIAL_INCREMENT) {
1205 right_true_state = increment_state(right_true_state);
1206 right_false_state = increment_state(right_false_state);
1208 if (right_postop == SPECIAL_DECREMENT) {
1209 right_true_state = decrement_state(right_true_state);
1210 right_false_state = decrement_state(right_false_state);
1213 if (estate_rl(left_true_state) && estates_equiv(left_true_state, left_false_state)) {
1214 left_true_state = NULL;
1215 left_false_state = NULL;
1218 if (estate_rl(right_true_state) && estates_equiv(right_true_state, right_false_state)) {
1219 right_true_state = NULL;
1220 right_false_state = NULL;
1223 set_extra_expr_true_false(left, left_true_state, left_false_state);
1224 set_extra_expr_true_false(right, right_true_state, right_false_state);
1227 static int is_simple_math(struct expression *expr)
1229 if (!expr)
1230 return 0;
1231 if (expr->type != EXPR_BINOP)
1232 return 0;
1233 switch (expr->op) {
1234 case '+':
1235 case '-':
1236 case '*':
1237 return 1;
1239 return 0;
1242 static void move_known_values(struct expression **left_p, struct expression **right_p)
1244 struct expression *left = *left_p;
1245 struct expression *right = *right_p;
1246 sval_t sval;
1248 if (get_implied_value(left, &sval)) {
1249 if (!is_simple_math(right))
1250 return;
1251 if (right->op == '*') {
1252 sval_t divisor;
1254 if (!get_value(right->right, &divisor))
1255 return;
1256 if (divisor.value == 0 && sval.value % divisor.value)
1257 return;
1258 *left_p = binop_expression(left, invert_op(right->op), right->right);
1259 *right_p = right->left;
1260 return;
1262 if (right->op == '+' && get_value(right->left, &sval)) {
1263 *left_p = binop_expression(left, invert_op(right->op), right->left);
1264 *right_p = right->right;
1265 return;
1267 if (get_value(right->right, &sval)) {
1268 *left_p = binop_expression(left, invert_op(right->op), right->right);
1269 *right_p = right->left;
1270 return;
1272 return;
1274 if (get_implied_value(right, &sval)) {
1275 if (!is_simple_math(left))
1276 return;
1277 if (left->op == '*') {
1278 sval_t divisor;
1280 if (!get_value(left->right, &divisor))
1281 return;
1282 if (divisor.value == 0 && sval.value % divisor.value)
1283 return;
1284 *right_p = binop_expression(right, invert_op(left->op), left->right);
1285 *left_p = left->left;
1286 return;
1288 if (left->op == '+' && get_value(left->left, &sval)) {
1289 *right_p = binop_expression(right, invert_op(left->op), left->left);
1290 *left_p = left->right;
1291 return;
1294 if (get_value(left->right, &sval)) {
1295 *right_p = binop_expression(right, invert_op(left->op), left->right);
1296 *left_p = left->left;
1297 return;
1299 return;
1303 static int match_func_comparison(struct expression *expr)
1305 struct expression *left = strip_expr(expr->left);
1306 struct expression *right = strip_expr(expr->right);
1307 sval_t sval;
1310 * fixme: think about this harder. We should always be trying to limit
1311 * the non-call side as well. If we can't determine the limitter does
1312 * that mean we aren't querying the database and are missing important
1313 * information?
1316 if (left->type == EXPR_CALL) {
1317 if (get_implied_value(left, &sval)) {
1318 handle_comparison(get_type(expr), left, expr->op, right);
1319 return 1;
1321 function_comparison(left, expr->op, right);
1322 return 1;
1325 if (right->type == EXPR_CALL) {
1326 if (get_implied_value(right, &sval)) {
1327 handle_comparison(get_type(expr), left, expr->op, right);
1328 return 1;
1330 function_comparison(left, expr->op, right);
1331 return 1;
1334 return 0;
1337 static void match_comparison(struct expression *expr)
1339 struct expression *left_orig = strip_expr(expr->left);
1340 struct expression *right_orig = strip_expr(expr->right);
1341 struct expression *left, *right;
1342 struct expression *prev;
1343 struct symbol *type;
1345 if (match_func_comparison(expr))
1346 return;
1348 type = get_type(expr);
1349 if (!type)
1350 type = &llong_ctype;
1352 left = left_orig;
1353 right = right_orig;
1354 move_known_values(&left, &right);
1355 handle_comparison(type, left, expr->op, right);
1357 prev = get_assigned_expr(left_orig);
1358 if (is_simple_math(prev) && has_variable(prev, left_orig) == 0) {
1359 left = prev;
1360 right = right_orig;
1361 move_known_values(&left, &right);
1362 handle_comparison(type, left, expr->op, right);
1365 prev = get_assigned_expr(right_orig);
1366 if (is_simple_math(prev) && has_variable(prev, right_orig) == 0) {
1367 left = left_orig;
1368 right = prev;
1369 move_known_values(&left, &right);
1370 handle_comparison(type, left, expr->op, right);
1374 static void handle_AND_condition(struct expression *expr)
1376 struct range_list *rl = NULL;
1377 sval_t known;
1379 if (get_implied_value(expr->left, &known) && known.value > 0) {
1380 known.value--;
1381 get_absolute_rl(expr->right, &rl);
1382 rl = remove_range(rl, sval_type_val(known.type, 0), known);
1383 set_extra_expr_true_false(expr->right, alloc_estate_rl(rl), NULL);
1384 return;
1387 if (get_implied_value(expr->right, &known) && known.value > 0) {
1388 known.value--;
1389 get_absolute_rl(expr->left, &rl);
1390 rl = remove_range(rl, sval_type_val(known.type, 0), known);
1391 set_extra_expr_true_false(expr->left, alloc_estate_rl(rl), NULL);
1392 return;
1396 /* this is actually hooked from smatch_implied.c... it's hacky, yes */
1397 void __extra_match_condition(struct expression *expr)
1399 struct symbol *sym;
1400 char *name;
1401 struct smatch_state *pre_state;
1402 struct smatch_state *true_state;
1403 struct smatch_state *false_state;
1405 expr = strip_expr(expr);
1406 switch (expr->type) {
1407 case EXPR_CALL:
1408 function_comparison(expr, SPECIAL_NOTEQUAL, zero_expr());
1409 return;
1410 case EXPR_PREOP:
1411 case EXPR_SYMBOL:
1412 case EXPR_DEREF: {
1413 sval_t zero;
1415 zero = sval_blank(expr);
1416 zero.value = 0;
1418 name = expr_to_var_sym(expr, &sym);
1419 if (!name)
1420 return;
1421 pre_state = get_state(my_id, name, sym);
1422 true_state = estate_filter_sval(pre_state, zero);
1423 if (possibly_true(expr, SPECIAL_EQUAL, zero_expr()))
1424 false_state = alloc_estate_sval(zero);
1425 else
1426 false_state = alloc_estate_empty();
1427 set_extra_true_false(name, sym, true_state, false_state);
1428 free_string(name);
1429 return;
1431 case EXPR_COMPARE:
1432 match_comparison(expr);
1433 return;
1434 case EXPR_ASSIGNMENT:
1435 __extra_match_condition(expr->left);
1436 return;
1437 case EXPR_BINOP:
1438 if (expr->op == '&')
1439 handle_AND_condition(expr);
1440 return;
1444 static void assume_indexes_are_valid(struct expression *expr)
1446 struct expression *array_expr;
1447 int array_size;
1448 struct expression *offset;
1449 struct symbol *offset_type;
1450 struct range_list *rl_before;
1451 struct range_list *rl_after;
1452 struct range_list *filter = NULL;
1453 sval_t size;
1455 expr = strip_expr(expr);
1456 if (!is_array(expr))
1457 return;
1459 offset = get_array_offset(expr);
1460 offset_type = get_type(offset);
1461 if (offset_type && type_signed(offset_type)) {
1462 filter = alloc_rl(sval_type_min(offset_type),
1463 sval_type_val(offset_type, -1));
1466 array_expr = get_array_base(expr);
1467 array_size = get_real_array_size(array_expr);
1468 if (array_size > 1) {
1469 size = sval_type_val(offset_type, array_size);
1470 add_range(&filter, size, sval_type_max(offset_type));
1473 if (!filter)
1474 return;
1475 get_absolute_rl(offset, &rl_before);
1476 rl_after = rl_filter(rl_before, filter);
1477 if (rl_equiv(rl_before, rl_after))
1478 return;
1479 set_extra_expr_nomod(offset, alloc_estate_rl(rl_after));
1482 /* returns 1 if it is not possible for expr to be value, otherwise returns 0 */
1483 int implied_not_equal(struct expression *expr, long long val)
1485 return !possibly_false(expr, SPECIAL_NOTEQUAL, value_expr(val));
1488 int implied_not_equal_name_sym(char *name, struct symbol *sym, long long val)
1490 struct smatch_state *estate;
1492 estate = get_state(SMATCH_EXTRA, name, sym);
1493 if (!estate)
1494 return 0;
1495 if (!rl_has_sval(estate_rl(estate), sval_type_val(estate_type(estate), 0)))
1496 return 1;
1497 return 0;
1500 int parent_is_null_var_sym(const char *name, struct symbol *sym)
1502 char buf[256];
1503 char *start;
1504 char *end;
1505 struct smatch_state *state;
1507 strncpy(buf, name, sizeof(buf) - 1);
1508 buf[sizeof(buf) - 1] = '\0';
1510 start = &buf[0];
1511 while (*start == '*') {
1512 start++;
1513 state = get_state(SMATCH_EXTRA, start, sym);
1514 if (!state)
1515 continue;
1516 if (!estate_rl(state))
1517 return 1;
1518 if (estate_min(state).value == 0 &&
1519 estate_max(state).value == 0)
1520 return 1;
1523 start = &buf[0];
1524 while (*start == '&')
1525 start++;
1527 while ((end = strrchr(start, '-'))) {
1528 *end = '\0';
1529 state = get_state(SMATCH_EXTRA, start, sym);
1530 if (!state)
1531 continue;
1532 if (estate_min(state).value == 0 &&
1533 estate_max(state).value == 0)
1534 return 1;
1536 return 0;
1539 int parent_is_null(struct expression *expr)
1541 struct symbol *sym;
1542 char *var;
1543 int ret = 0;
1545 expr = strip_expr(expr);
1546 var = expr_to_var_sym(expr, &sym);
1547 if (!var || !sym)
1548 goto free;
1549 ret = parent_is_null_var_sym(var, sym);
1550 free:
1551 free_string(var);
1552 return ret;
1555 static int param_used_callback(void *found, int argc, char **argv, char **azColName)
1557 *(int *)found = 1;
1558 return 0;
1561 static int filter_unused_kzalloc_info(struct expression *call, int param, char *printed_name, struct sm_state *sm)
1563 sval_t sval;
1564 int found = 0;
1566 /* for function pointers assume everything is used */
1567 if (call->fn->type != EXPR_SYMBOL)
1568 return 0;
1571 * kzalloc() information is treated as special because so there is just
1572 * a lot of stuff initialized to zero and it makes building the database
1573 * take hours and hours.
1575 * In theory, we should just remove this line and not pass any unused
1576 * information, but I'm not sure enough that this code works so I want
1577 * to hold off on that for now.
1579 if (!estate_get_single_value(sm->state, &sval) || sval.value != 0)
1580 return 0;
1582 run_sql(&param_used_callback, &found,
1583 "select * from call_implies where %s and type = %d and parameter = %d and key = '%s';",
1584 get_static_filter(call->fn->symbol), PARAM_USED, param, printed_name);
1585 if (found)
1586 return 0;
1588 /* If the database is not built yet, then assume everything is used */
1589 run_sql(&param_used_callback, &found,
1590 "select * from call_implies where %s and type = %d;",
1591 get_static_filter(call->fn->symbol), PARAM_USED);
1592 if (!found)
1593 return 0;
1595 return 1;
1598 static void struct_member_callback(struct expression *call, int param, char *printed_name, struct sm_state *sm)
1600 if (estate_is_whole(sm->state))
1601 return;
1602 if (filter_unused_kzalloc_info(call, param, printed_name, sm))
1603 return;
1604 sql_insert_caller_info(call, PARAM_VALUE, param, printed_name, sm->state->name);
1605 if (estate_has_fuzzy_max(sm->state))
1606 sql_insert_caller_info(call, FUZZY_MAX, param, printed_name,
1607 sval_to_str(estate_get_fuzzy_max(sm->state)));
1610 static void db_limited_before(void)
1612 unmatched_stree = clone_stree(__get_cur_stree());
1615 static void db_limited_after(void)
1617 free_stree(&unmatched_stree);
1620 static void db_param_limit_filter(struct expression *expr, int param, char *key, char *value, enum info_type op)
1622 struct expression *arg;
1623 char *name;
1624 struct symbol *sym;
1625 struct sm_state *sm;
1626 struct symbol *compare_type, *var_type;
1627 struct range_list *rl;
1628 struct range_list *limit;
1629 struct range_list *new;
1631 while (expr->type == EXPR_ASSIGNMENT)
1632 expr = strip_expr(expr->right);
1633 if (expr->type != EXPR_CALL)
1634 return;
1636 arg = get_argument_from_call_expr(expr->args, param);
1637 if (!arg)
1638 return;
1640 name = get_variable_from_key(arg, key, &sym);
1641 if (!name || !sym)
1642 goto free;
1644 if (strcmp(key, "$") == 0)
1645 compare_type = get_arg_type(expr->fn, param);
1646 else
1647 compare_type = get_member_type_from_key(arg, key);
1649 sm = get_sm_state(SMATCH_EXTRA, name, sym);
1650 if (sm)
1651 rl = estate_rl(sm->state);
1652 else
1653 rl = alloc_whole_rl(compare_type);
1655 call_results_to_rl(expr, compare_type, value, &limit);
1656 new = rl_intersection(rl, limit);
1658 var_type = get_member_type_from_key(arg, key);
1659 new = cast_rl(var_type, new);
1661 /* We want to preserve the implications here */
1662 if (sm && rl_equiv(estate_rl(sm->state), new))
1663 __set_sm(sm);
1664 else {
1665 if (op == PARAM_LIMIT)
1666 set_extra_nomod(name, sym, alloc_estate_rl(new));
1667 else
1668 set_extra_mod(name, sym, alloc_estate_rl(new));
1671 free:
1672 free_string(name);
1675 static void db_param_limit(struct expression *expr, int param, char *key, char *value)
1677 db_param_limit_filter(expr, param, key, value, PARAM_LIMIT);
1680 static void db_param_filter(struct expression *expr, int param, char *key, char *value)
1682 db_param_limit_filter(expr, param, key, value, PARAM_FILTER);
1685 static void db_param_add_set(struct expression *expr, int param, char *key, char *value, enum info_type op)
1687 struct expression *arg;
1688 char *name;
1689 struct symbol *sym;
1690 struct symbol *type;
1691 struct smatch_state *state;
1692 struct range_list *new = NULL;
1693 struct range_list *added = NULL;
1695 while (expr->type == EXPR_ASSIGNMENT)
1696 expr = strip_expr(expr->right);
1697 if (expr->type != EXPR_CALL)
1698 return;
1700 arg = get_argument_from_call_expr(expr->args, param);
1701 if (!arg)
1702 return;
1703 type = get_member_type_from_key(arg, key);
1704 name = get_variable_from_key(arg, key, &sym);
1705 if (!name || !sym)
1706 goto free;
1708 state = get_state(SMATCH_EXTRA, name, sym);
1709 if (state)
1710 new = estate_rl(state);
1712 call_results_to_rl(expr, type, value, &added);
1714 if (op == PARAM_SET)
1715 new = added;
1716 else
1717 new = rl_union(new, added);
1719 set_extra_mod(name, sym, alloc_estate_rl(new));
1720 free:
1721 free_string(name);
1724 static void db_param_add(struct expression *expr, int param, char *key, char *value)
1726 db_param_add_set(expr, param, key, value, PARAM_ADD);
1729 static void db_param_set(struct expression *expr, int param, char *key, char *value)
1731 db_param_add_set(expr, param, key, value, PARAM_SET);
1734 static void db_returned_member_info(struct expression *expr, int param, char *key, char *value)
1736 struct symbol *type;
1737 struct symbol *sym;
1738 char *name;
1739 struct range_list *rl;
1741 if (expr->type != EXPR_ASSIGNMENT)
1742 return;
1744 name = return_state_to_var_sym(expr, param, key, &sym);
1745 if (!name || !sym)
1746 goto free;
1747 type = get_member_type_from_key(expr->left, key);
1748 if (!type)
1749 return;
1750 call_results_to_rl(expr->right, type, value, &rl);
1751 set_extra_mod(name, sym, alloc_estate_rl(rl));
1753 free:
1754 free_string(name);
1757 static char *in_terms_of_param_math(struct expression *expr, char *printed_name)
1759 struct symbol *sym;
1760 char *var;
1761 char buf[256];
1762 char *ret = NULL;
1764 var = expr_to_var_sym(expr, &sym);
1765 if (!var || !sym)
1766 goto free;
1767 snprintf(buf, sizeof(buf), "%s%s", var, printed_name + 2);
1769 ret = get_value_in_terms_of_parameter_math_var_sym(buf, sym);
1771 free:
1772 free_string(var);
1773 return ret;
1776 static void returned_member_callback(int return_id, char *return_ranges, struct expression *expr, char *printed_name, struct smatch_state *state)
1778 char buf[256];
1779 char *math_str;
1780 sval_t sval;
1782 /* these are handled in smatch_param_filter/set/limit.c */
1783 if (printed_name[0] != '*' &&
1784 !strchr(printed_name, '.') && !strchr(printed_name, '-'))
1785 return;
1787 if (estate_get_single_value(state, &sval)) {
1788 sql_insert_return_states(return_id, return_ranges, RETURN_VALUE, -1,
1789 printed_name, sval_to_str(sval));
1790 return;
1793 math_str = in_terms_of_param_math(expr, printed_name);
1794 if (math_str) {
1795 snprintf(buf, sizeof(buf), "%s[%s]", state->name, math_str);
1796 sql_insert_return_states(return_id, return_ranges, RETURN_VALUE, -1,
1797 printed_name, buf);
1798 return;
1801 if (estate_is_whole(state))
1802 return;
1804 sql_insert_return_states(return_id, return_ranges, RETURN_VALUE, -1,
1805 printed_name, state->name);
1808 static void match_call_info(struct expression *expr)
1810 struct smatch_state *state;
1811 struct range_list *rl = NULL;
1812 struct expression *arg;
1813 struct symbol *type;
1814 int i = 0;
1816 FOR_EACH_PTR(expr->args, arg) {
1817 type = get_arg_type(expr->fn, i);
1819 if (get_implied_rl(arg, &rl))
1820 rl = cast_rl(type, rl);
1821 else
1822 rl = cast_rl(type, alloc_whole_rl(get_type(arg)));
1824 if (!is_whole_rl(rl))
1825 sql_insert_caller_info(expr, PARAM_VALUE, i, "$", show_rl(rl));
1826 state = get_state_expr(SMATCH_EXTRA, arg);
1827 if (estate_has_fuzzy_max(state)) {
1828 sql_insert_caller_info(expr, FUZZY_MAX, i, "$",
1829 sval_to_str(estate_get_fuzzy_max(state)));
1831 i++;
1832 } END_FOR_EACH_PTR(arg);
1835 static void set_param_value(const char *name, struct symbol *sym, char *key, char *value)
1837 struct range_list *rl = NULL;
1838 struct smatch_state *state;
1839 struct symbol *type;
1840 char fullname[256];
1842 if (strcmp(key, "*$") == 0)
1843 snprintf(fullname, sizeof(fullname), "*%s", name);
1844 else if (strncmp(key, "$", 1) == 0)
1845 snprintf(fullname, 256, "%s%s", name, key + 1);
1846 else
1847 return;
1849 type = get_member_type_from_key(symbol_expression(sym), key);
1850 str_to_rl(type, value, &rl);
1851 state = alloc_estate_rl(rl);
1852 set_state(SMATCH_EXTRA, fullname, sym, state);
1855 static void set_param_hard_max(const char *name, struct symbol *sym, char *key, char *value)
1857 struct range_list *rl = NULL;
1858 struct smatch_state *state;
1859 struct symbol *type;
1860 char fullname[256];
1861 sval_t max;
1863 if (strcmp(key, "*$") == 0)
1864 snprintf(fullname, sizeof(fullname), "*%s", name);
1865 else if (strncmp(key, "$", 1) == 0)
1866 snprintf(fullname, 256, "%s%s", name, key + 1);
1867 else
1868 return;
1870 state = get_state(SMATCH_EXTRA, fullname, sym);
1871 if (!state)
1872 return;
1873 type = get_member_type_from_key(symbol_expression(sym), key);
1874 str_to_rl(type, value, &rl);
1875 if (!rl_to_sval(rl, &max))
1876 return;
1877 estate_set_fuzzy_max(state, max);
1880 void register_smatch_extra(int id)
1882 my_id = id;
1884 add_merge_hook(my_id, &merge_estates);
1885 add_unmatched_state_hook(my_id, &unmatched_state);
1886 select_caller_info_hook(set_param_value, PARAM_VALUE);
1887 select_caller_info_hook(set_param_hard_max, FUZZY_MAX);
1888 select_return_states_hook(RETURN_VALUE, &db_returned_member_info);
1889 select_return_states_before(&db_limited_before);
1890 select_return_states_hook(PARAM_LIMIT, &db_param_limit);
1891 select_return_states_hook(PARAM_FILTER, &db_param_filter);
1892 select_return_states_hook(PARAM_ADD, &db_param_add);
1893 select_return_states_hook(PARAM_SET, &db_param_set);
1894 select_return_states_after(&db_limited_after);
1897 void register_smatch_extra_late(int id)
1899 add_hook(&match_dereferences, DEREF_HOOK);
1900 add_hook(&match_pointer_as_array, OP_HOOK);
1901 select_call_implies_hook(DEREFERENCE, &set_param_dereferenced);
1902 add_hook(&match_function_call, FUNCTION_CALL_HOOK);
1903 add_hook(&match_assign, ASSIGNMENT_HOOK);
1904 add_hook(&match_assign, GLOBAL_ASSIGNMENT_HOOK);
1905 add_hook(&unop_expr, OP_HOOK);
1906 add_hook(&asm_expr, ASM_HOOK);
1908 add_hook(&match_call_info, FUNCTION_CALL_HOOK);
1909 add_member_info_callback(my_id, struct_member_callback);
1910 add_returned_member_callback(my_id, returned_member_callback);
1912 add_hook(&assume_indexes_are_valid, OP_HOOK);