Print this page
11506 smatch resync


  19  * smatch_extra.c is supposed to track the value of every variable.
  20  *
  21  */
  22 
  23 #define _GNU_SOURCE
  24 #include <string.h>
  25 
  26 #include <stdlib.h>
  27 #include <errno.h>
  28 #ifndef __USE_ISOC99
  29 #define __USE_ISOC99
  30 #endif
  31 #include <limits.h>
  32 #include "parse.h"
  33 #include "smatch.h"
  34 #include "smatch_slist.h"
  35 #include "smatch_extra.h"
  36 
  37 static int my_id;
  38 static int link_id;

  39 
  40 static void match_link_modify(struct sm_state *sm, struct expression *mod_expr);
  41 
  42 struct string_list *__ignored_macros = NULL;
  43 static int in_warn_on_macro(void)
  44 {
  45         struct statement *stmt;
  46         char *tmp;
  47         char *macro;
  48 
  49         stmt = get_current_statement();
  50         if (!stmt)
  51                 return 0;
  52         macro = get_macro_name(stmt->pos);
  53         if (!macro)
  54                 return 0;
  55 
  56         FOR_EACH_PTR(__ignored_macros, tmp) {
  57                 if (!strcmp(tmp, macro))
  58                         return 1;
  59         } END_FOR_EACH_PTR(tmp);
  60         return 0;
  61 }
  62 
  63 typedef void (mod_hook)(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state);


 117 
 118 static char *get_pointed_at(const char *name, struct symbol *sym, struct symbol **new_sym)
 119 {
 120         struct expression *assigned;
 121 
 122         if (name[0] != '*')
 123                 return NULL;
 124         if (strcmp(name + 1, sym->ident->name) != 0)
 125                 return NULL;
 126 
 127         assigned = get_assigned_expr_name_sym(sym->ident->name, sym);
 128         if (!assigned)
 129                 return NULL;
 130         assigned = strip_parens(assigned);
 131         if (assigned->type != EXPR_PREOP || assigned->op != '&')
 132                 return NULL;
 133 
 134         return expr_to_var_sym(assigned->unop, new_sym);
 135 }
 136 
 137 char *get_other_name_sym(const char *name, struct symbol *sym, struct symbol **new_sym)
 138 {
 139         struct expression *assigned;
 140         char *orig_name = NULL;
 141         char buf[256];
 142         char *ret = NULL;
 143         int skip;
 144 
 145         *new_sym = NULL;
 146 
 147         if (!sym || !sym->ident)
 148                 return NULL;
 149 
 150         ret = get_pointed_at(name, sym, new_sym);
 151         if (ret)
 152                 return ret;
 153 
 154         skip = strlen(sym->ident->name);
 155         if (name[skip] != '-' || name[skip + 1] != '>')
 156                 return NULL;
 157         skip += 2;
 158 
 159         assigned = get_assigned_expr_name_sym(sym->ident->name, sym);
 160         if (!assigned)
 161                 return NULL;
 162         if (assigned->type == EXPR_CALL)
 163                 return map_call_to_other_name_sym(name, sym, new_sym);
 164         if (assigned->type == EXPR_PREOP || assigned->op == '&') {
 165 
 166                 orig_name = expr_to_var_sym(assigned, new_sym);
 167                 if (!orig_name || !*new_sym)
 168                         goto free;
 169 
 170                 snprintf(buf, sizeof(buf), "%s.%s", orig_name + 1, name + skip);
 171                 ret = alloc_string(buf);
 172                 free_string(orig_name);
 173                 return ret;
 174         }
 175 
 176         if (assigned->type != EXPR_DEREF)
 177                 goto free;
 178 
 179         orig_name = expr_to_var_sym(assigned, new_sym);
 180         if (!orig_name || !*new_sym)
 181                 goto free;
 182 
 183         snprintf(buf, sizeof(buf), "%s->%s", orig_name, name + skip);
 184         ret = alloc_string(buf);
 185         free_string(orig_name);
 186         return ret;
 187 
 188 free:
 189         free_string(orig_name);
 190         return NULL;
 191 }
 192 
















































































 193 void set_extra_mod(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
 194 {
 195         char *new_name;
 196         struct symbol *new_sym;
 197 
 198         set_extra_mod_helper(name, sym, expr, state);
 199         new_name = get_other_name_sym(name, sym, &new_sym);
 200         if (new_name && new_sym)
 201                 set_extra_mod_helper(new_name, new_sym, expr, state);
 202         free_string(new_name);
 203 }
 204 
 205 static struct expression *chunk_get_array_base(struct expression *expr)
 206 {
 207         /*
 208          * The problem with is_array() is that it only returns true for things
 209          * like foo[1] but not for foo[1].bar.
 210          *
 211          */
 212         expr = strip_expr(expr);


 284         orig_state = get_state(SMATCH_EXTRA, name, sym);
 285 
 286         /* don't save unknown states if leaving it blank is the same */
 287         if (!orig_state && estate_is_unknown(state))
 288                 return;
 289 
 290         new_name = get_other_name_sym(name, sym, &new_sym);
 291         if (new_name && new_sym)
 292                 set_extra_nomod_helper(new_name, new_sym, expr, state);
 293         free_string(new_name);
 294 
 295         if (!estate_related(orig_state)) {
 296                 set_extra_nomod_helper(name, sym, expr, state);
 297                 return;
 298         }
 299 
 300         set_related(state, estate_related(orig_state));
 301         FOR_EACH_PTR(estate_related(orig_state), rel) {
 302                 struct smatch_state *estate;
 303 
 304                 if (option_debug_related)
 305                         sm_msg("%s updating related %s to %s", name, rel->name, state->name);
 306                 estate = get_state(SMATCH_EXTRA, rel->name, rel->sym);
 307                 if (!estate)
 308                         continue;
 309                 set_extra_nomod_helper(rel->name, rel->sym, expr, clone_estate_cast(estate_type(estate), state));
 310         } END_FOR_EACH_PTR(rel);
 311 }
 312 
 313 void set_extra_nomod_vsl(const char *name, struct symbol *sym, struct var_sym_list *vsl, struct expression *expr, struct smatch_state *state)
 314 {
 315         struct var_sym *vs;
 316 
 317         FOR_EACH_PTR(vsl, vs) {
 318                 store_link(link_id, vs->var, vs->sym, name, sym);
 319         } END_FOR_EACH_PTR(vs);
 320 
 321         set_extra_nomod(name, sym, expr, state);
 322 }
 323 
 324 /*
 325  * This is for return_implies_state() hooks which modify a SMATCH_EXTRA state


 467                 *right = limit;
 468 
 469                 return 1;
 470         }
 471 
 472         if (condition->type != EXPR_PREOP && condition->type != EXPR_POSTOP)
 473                 return 0;
 474         if (condition->op != SPECIAL_DECREMENT)
 475                 return 0;
 476 
 477         *unop = condition;
 478         *op = '>';
 479 
 480         return 1;
 481 }
 482 
 483 static struct sm_state *handle_canonical_while_count_down(struct statement *loop)
 484 {
 485         struct expression *iter_var;
 486         struct expression *condition, *unop;

 487         struct sm_state *sm;
 488         struct smatch_state *estate;
 489         int op;
 490         sval_t start, right;
 491 
 492         right.type = &int_ctype;
 493         right.value = 0;
 494 
 495         condition = strip_expr(loop->iterator_pre_condition);
 496         if (!condition)
 497                 return NULL;
 498 
 499         if (!get_countdown_info(condition, &unop, &op, &right))
 500                 return NULL;
 501 
 502         iter_var = unop->unop;
 503 
 504         sm = get_sm_state_expr(SMATCH_EXTRA, iter_var);
 505         if (!sm)
 506                 return NULL;
 507         if (sval_cmp(estate_min(sm->state), right) < 0)
 508                 return NULL;
 509         start = estate_max(sm->state);





 510         if  (sval_cmp(start, right) <= 0)
 511                 return NULL;
 512         if (!sval_is_max(start))
 513                 start.value--;
 514 
 515         if (op == SPECIAL_GTE)
 516                 right.value--;
 517 
 518         if (unop->type == EXPR_PREOP) {
 519                 right.value++;
 520                 estate = alloc_estate_range(right, start);
 521                 if (estate_has_hard_max(sm->state))
 522                         estate_set_hard_max(estate);
 523                 estate_copy_fuzzy_max(estate, sm->state);
 524                 set_extra_expr_mod(iter_var, estate);
 525         }
 526         if (unop->type == EXPR_POSTOP) {
 527                 estate = alloc_estate_range(right, start);
 528                 if (estate_has_hard_max(sm->state))
 529                         estate_set_hard_max(estate);
 530                 estate_copy_fuzzy_max(estate, sm->state);
 531                 set_extra_expr_mod(iter_var, estate);
 532         }
 533         return get_sm_state_expr(SMATCH_EXTRA, iter_var);
 534 }
 535 
 536 static struct sm_state *handle_canonical_for_inc(struct expression *iter_expr,
 537                                                 struct expression *condition)
 538 {
 539         struct expression *iter_var;
 540         struct sm_state *sm;
 541         struct smatch_state *estate;
 542         sval_t start, end, max;

 543 
 544         iter_var = iter_expr->unop;
 545         sm = get_sm_state_expr(SMATCH_EXTRA, iter_var);
 546         if (!sm)
 547                 return NULL;
 548         if (!estate_get_single_value(sm->state, &start))
 549                 return NULL;
 550         if (get_implied_max(condition->right, &end))
 551                 end = sval_cast(get_type(iter_var), end);
 552         else
 553                 end = sval_type_max(get_type(iter_var));
 554 
 555         if (get_sm_state_expr(SMATCH_EXTRA, condition->left) != sm)
 556                 return NULL;
 557 
 558         switch (condition->op) {
 559         case SPECIAL_UNSIGNED_LT:
 560         case SPECIAL_NOTEQUAL:
 561         case '<':
 562                 if (!sval_is_min(end))
 563                         end.value--;
 564                 break;
 565         case SPECIAL_UNSIGNED_LTE:
 566         case SPECIAL_LTE:
 567                 break;
 568         default:
 569                 return NULL;
 570         }
 571         if (sval_cmp(end, start) < 0)
 572                 return NULL;



 573         estate = alloc_estate_range(start, end);
 574         if (get_hard_max(condition->right, &max)) {

 575                 estate_set_hard_max(estate);
 576                 if (condition->op == '<' ||
 577                     condition->op == SPECIAL_UNSIGNED_LT ||
 578                     condition->op == SPECIAL_NOTEQUAL)
 579                         max.value--;

 580                 estate_set_fuzzy_max(estate, max);
 581         }
 582         set_extra_expr_mod(iter_var, estate);
 583         return get_sm_state_expr(SMATCH_EXTRA, iter_var);
 584 }
 585 
 586 static struct sm_state *handle_canonical_for_dec(struct expression *iter_expr,
 587                                                 struct expression *condition)
 588 {
 589         struct expression *iter_var;
 590         struct sm_state *sm;
 591         struct smatch_state *estate;
 592         sval_t start, end;
 593 
 594         iter_var = iter_expr->unop;
 595         sm = get_sm_state_expr(SMATCH_EXTRA, iter_var);
 596         if (!sm)
 597                 return NULL;
 598         if (!estate_get_single_value(sm->state, &start))
 599                 return NULL;
 600         if (!get_implied_min(condition->right, &end))
 601                 end = sval_type_min(get_type(iter_var));

 602         if (get_sm_state_expr(SMATCH_EXTRA, condition->left) != sm)
 603                 return NULL;
 604 
 605         switch (condition->op) {
 606         case SPECIAL_NOTEQUAL:
 607         case '>':
 608                 if (!sval_is_min(end) && !sval_is_max(end))
 609                         end.value++;
 610                 break;
 611         case SPECIAL_GTE:
 612                 break;
 613         default:
 614                 return NULL;
 615         }
 616         if (sval_cmp(end, start) > 0)
 617                 return NULL;
 618         estate = alloc_estate_range(end, start);
 619         estate_set_hard_max(estate);
 620         estate_set_fuzzy_max(estate, estate_get_fuzzy_max(estate));
 621         set_extra_expr_mod(iter_var, estate);
 622         return get_sm_state_expr(SMATCH_EXTRA, iter_var);
 623 }
 624 
 625 static struct sm_state *handle_canonical_for_loops(struct statement *loop)
 626 {
 627         struct expression *iter_expr;
 628         struct expression *condition;


 697         struct expression *iter_expr;
 698         sval_t limit;
 699         struct smatch_state *state;
 700 
 701         if (!iterator) {
 702                 while_count_down_after(sm, condition);
 703                 return;
 704         }
 705 
 706         iter_expr = iterator->expression;
 707 
 708         if (condition->type != EXPR_COMPARE)
 709                 return;
 710         if (iter_expr->op == SPECIAL_INCREMENT) {
 711                 limit = sval_binop(estate_max(sm->state), '+',
 712                                    sval_type_val(estate_type(sm->state), 1));
 713         } else {
 714                 limit = sval_binop(estate_min(sm->state), '-',
 715                                    sval_type_val(estate_type(sm->state), 1));
 716         }

 717         if (!estate_has_hard_max(sm->state) && !__has_breaks()) {
 718                 if (iter_expr->op == SPECIAL_INCREMENT)
 719                         state = alloc_estate_range(estate_min(sm->state), limit);
 720                 else
 721                         state = alloc_estate_range(limit, estate_max(sm->state));
 722         } else {
 723                 state = alloc_estate_sval(limit);
 724         }
 725         if (!estate_has_hard_max(sm->state)) {
 726                 estate_clear_hard_max(state);
 727         }
 728         if (estate_has_fuzzy_max(sm->state)) {
 729                 sval_t hmax = estate_get_fuzzy_max(sm->state);
 730                 sval_t max = estate_max(sm->state);
 731 
 732                 if (sval_cmp(hmax, max) != 0)
 733                         estate_clear_fuzzy_max(state);
 734         } else if (!estate_has_fuzzy_max(sm->state)) {
 735                 estate_clear_fuzzy_max(state);
 736         }
 737 
 738         set_extra_mod(sm->name, sm->sym, iter_expr, state);
 739 }
 740 













 741 static struct stree *unmatched_stree;
 742 static struct smatch_state *unmatched_state(struct sm_state *sm)
 743 {
 744         struct smatch_state *state;

 745 
 746         if (unmatched_stree) {
 747                 state = get_state_stree(unmatched_stree, SMATCH_EXTRA, sm->name, sm->sym);
 748                 if (state)
 749                         return state;
 750         }
 751         if (parent_is_gone_var_sym(sm->name, sm->sym))
 752                 return alloc_estate_empty();


 753         return alloc_estate_whole(estate_type(sm->state));
 754 }
 755 
 756 static void clear_the_pointed_at(struct expression *expr)
 757 {
 758         struct stree *stree;
 759         char *name;
 760         struct symbol *sym;
 761         struct sm_state *tmp;
 762 
 763         name = expr_to_var_sym(expr, &sym);
 764         if (!name || !sym)
 765                 goto free;
 766 
 767         stree = __get_cur_stree();
 768         FOR_EACH_MY_SM(SMATCH_EXTRA, stree, tmp) {
 769                 if (tmp->name[0] != '*')
 770                         continue;
 771                 if (tmp->sym != sym)
 772                         continue;


 798         int param = -1;
 799 
 800         /* if we have the db this is handled in smatch_function_hooks.c */
 801         if (!option_no_db)
 802                 return;
 803         if (inlinable(expr->fn))
 804                 return;
 805 
 806         FOR_EACH_PTR(expr->args, arg) {
 807                 param++;
 808                 if (is_const_param(expr->fn, param))
 809                         continue;
 810                 tmp = strip_expr(arg);
 811                 if (tmp->type == EXPR_PREOP && tmp->op == '&')
 812                         set_extra_expr_mod(tmp->unop, alloc_estate_whole(get_type(tmp->unop)));
 813                 else
 814                         clear_the_pointed_at(tmp);
 815         } END_FOR_EACH_PTR(arg);
 816 }
 817 
 818 static int values_fit_type(struct expression *left, struct expression *right)
 819 {
 820         struct range_list *rl;
 821         struct symbol *type;
 822 
 823         type = get_type(left);
 824         if (!type)
 825                 return 0;
 826         get_absolute_rl(right, &rl);


 827         if (type_unsigned(type) && sval_is_negative(rl_min(rl)))
 828                 return 0;
 829         if (sval_cmp(sval_type_min(type), rl_min(rl)) > 0)
 830                 return 0;
 831         if (sval_cmp(sval_type_max(type), rl_max(rl)) < 0)
 832                 return 0;
 833         return 1;
 834 }
 835 
 836 static void save_chunk_info(struct expression *left, struct expression *right)
 837 {
 838         struct var_sym_list *vsl;
 839         struct var_sym *vs;
 840         struct expression *add_expr;
 841         struct symbol *type;
 842         sval_t sval;
 843         char *name;
 844         struct symbol *sym;
 845 
 846         if (right->type != EXPR_BINOP || right->op != '-')


 934                 struct smatch_state *right_state;
 935                 sval_t sval;
 936 
 937                 if (get_value(right, &sval)) {
 938                         sval = sval_cast(left_type, sval);
 939                         state = alloc_estate_sval(sval);
 940                         goto done;
 941                 }
 942 
 943                 right_state = get_state(SMATCH_EXTRA, right_name, right_sym);
 944                 if (right_state) {
 945                         /* simple assignment */
 946                         state = clone_estate(right_state);
 947                         goto done;
 948                 }
 949 
 950                 state = alloc_estate_rl(alloc_whole_rl(left_type));
 951                 goto done;
 952         }
 953 
 954         comparison = get_comparison(left, right);
 955         if (comparison) {
 956                 comparison = flip_comparison(comparison);
 957                 get_implied_rl(left, &orig_rl);
 958         }
 959 
 960         if (get_implied_rl(right, &rl)) {
 961                 rl = cast_rl(left_type, rl);
 962                 if (orig_rl)
 963                         filter_by_comparison(&rl, comparison, orig_rl);
 964                 state = alloc_estate_rl(rl);
 965                 if (get_hard_max(right, &max)) {
 966                         estate_set_hard_max(state);
 967                         estate_set_fuzzy_max(state, max);
 968                 }
 969         } else {
 970                 rl = alloc_whole_rl(right_type);
 971                 rl = cast_rl(left_type, rl);
 972                 if (orig_rl)
 973                         filter_by_comparison(&rl, comparison, orig_rl);
 974                 state = alloc_estate_rl(rl);
 975         }
 976 
 977 done:
 978         set_extra_mod(name, sym, left, state);
 979 free:
 980         free_string(right_name);
 981 }
 982 
 983 static int op_remove_assign(int op)
 984 {
 985         switch (op) {
 986         case SPECIAL_ADD_ASSIGN:
 987                 return '+';
 988         case SPECIAL_SUB_ASSIGN:
 989                 return '-';
 990         case SPECIAL_MUL_ASSIGN:
 991                 return '*';
 992         case SPECIAL_DIV_ASSIGN:
 993                 return '/';
 994         case SPECIAL_MOD_ASSIGN:
 995                 return '%';
 996         case SPECIAL_AND_ASSIGN:
 997                 return '&';
 998         case SPECIAL_OR_ASSIGN:
 999                 return '|';
1000         case SPECIAL_XOR_ASSIGN:
1001                 return '^';
1002         case SPECIAL_SHL_ASSIGN:
1003                 return SPECIAL_LEFTSHIFT;
1004         case SPECIAL_SHR_ASSIGN:
1005                 return SPECIAL_RIGHTSHIFT;
1006         default:
1007                 return op;
1008         }
1009 }
1010 
1011 static void match_assign(struct expression *expr)
1012 {
1013         struct range_list *rl = NULL;
1014         struct expression *left;
1015         struct expression *right;
1016         struct expression *binop_expr;
1017         struct symbol *left_type;
1018         struct symbol *sym;
1019         char *name;
1020         sval_t left_min, left_max;
1021         sval_t right_min, right_max;
1022         sval_t res_min, res_max;
1023 
1024         left = strip_expr(expr->left);
1025 
1026         right = strip_parens(expr->right);
1027         if (right->type == EXPR_CALL && sym_name_is("__builtin_expect", right->fn))
1028                 right = get_argument_from_call_expr(right->args, 0);
1029         while (right->type == EXPR_ASSIGNMENT && right->op == '=')
1030                 right = strip_parens(right->left);
1031 
1032         if (expr->op == '=' && is_condition(expr->right))
1033                 return; /* handled in smatch_condition.c */
1034         if (expr->op == '=' && right->type == EXPR_CALL)
1035                 return; /* handled in smatch_function_hooks.c */
1036         if (expr->op == '=') {
1037                 match_vanilla_assign(left, right);
1038                 return;
1039         }
1040 
1041         name = expr_to_var_sym(left, &sym);
1042         if (!name)
1043                 return;
1044 
1045         left_type = get_type(left);
1046 
1047         res_min = sval_type_min(left_type);
1048         res_max = sval_type_max(left_type);
1049 
1050         switch (expr->op) {
1051         case SPECIAL_ADD_ASSIGN:
1052                 get_absolute_max(left, &left_max);
1053                 get_absolute_max(right, &right_max);
1054                 if (sval_binop_overflows(left_max, '+', sval_cast(left_type, right_max)))
1055                         break;
1056                 if (get_implied_min(left, &left_min) &&
1057                     !sval_is_negative_min(left_min) &&
1058                     get_implied_min(right, &right_min) &&
1059                     !sval_is_negative_min(right_min)) {
1060                         res_min = sval_binop(left_min, '+', right_min);
1061                         res_min = sval_cast(left_type, res_min);
1062                 }
1063                 if (inside_loop())  /* we are assuming loops don't lead to wrapping */
1064                         break;
1065                 res_max = sval_binop(left_max, '+', right_max);
1066                 res_max = sval_cast(left_type, res_max);
1067                 break;
1068         case SPECIAL_SUB_ASSIGN:
1069                 if (get_implied_max(left, &left_max) &&
1070                     !sval_is_max(left_max) &&
1071                     get_implied_min(right, &right_min) &&
1072                     !sval_is_min(right_min)) {
1073                         res_max = sval_binop(left_max, '-', right_min);
1074                         res_max = sval_cast(left_type, res_max);
1075                 }
1076                 if (inside_loop())
1077                         break;
1078                 if (get_implied_min(left, &left_min) &&
1079                     !sval_is_min(left_min) &&
1080                     get_implied_max(right, &right_max) &&
1081                     !sval_is_max(right_max)) {
1082                         res_min = sval_binop(left_min, '-', right_max);
1083                         res_min = sval_cast(left_type, res_min);
1084                 }
1085                 break;
1086         case SPECIAL_AND_ASSIGN:
1087         case SPECIAL_MOD_ASSIGN:
1088         case SPECIAL_SHL_ASSIGN:
1089         case SPECIAL_SHR_ASSIGN:
1090         case SPECIAL_OR_ASSIGN:
1091         case SPECIAL_XOR_ASSIGN:
1092         case SPECIAL_MUL_ASSIGN:
1093         case SPECIAL_DIV_ASSIGN:
1094                 binop_expr = binop_expression(expr->left,
1095                                               op_remove_assign(expr->op),
1096                                               expr->right);
1097                 if (get_absolute_rl(binop_expr, &rl)) {
1098                         rl = cast_rl(left_type, rl);
1099                         set_extra_mod(name, sym, left, alloc_estate_rl(rl));
1100                         goto free;







1101                 }
1102                 break;
1103         }
1104         rl = cast_rl(left_type, alloc_rl(res_min, res_max));
1105         set_extra_mod(name, sym, left, alloc_estate_rl(rl));



1106 free:
1107         free_string(name);
1108 }
1109 
1110 static struct smatch_state *increment_state(struct smatch_state *state)
1111 {
1112         sval_t min = estate_min(state);
1113         sval_t max = estate_max(state);
1114 
1115         if (!estate_rl(state))
1116                 return NULL;
1117 
1118         if (inside_loop())
1119                 max = sval_type_max(max.type);
1120 
1121         if (!sval_is_min(min) && !sval_is_max(min))
1122                 min.value++;
1123         if (!sval_is_min(max) && !sval_is_max(max))
1124                 max.value++;
1125         return alloc_estate_range(min, max);


1217         } END_FOR_EACH_PTR(expr);
1218 }
1219 
1220 static void check_dereference(struct expression *expr)
1221 {
1222         struct smatch_state *state;
1223 
1224         if (__in_fake_assign)
1225                 return;
1226         if (outside_of_function())
1227                 return;
1228         state = get_extra_state(expr);
1229         if (state) {
1230                 struct range_list *rl;
1231 
1232                 rl = rl_intersection(estate_rl(state), valid_ptr_rl);
1233                 if (rl_equiv(rl, estate_rl(state)))
1234                         return;
1235                 set_extra_expr_nomod(expr, alloc_estate_rl(rl));
1236         } else {
1237                 set_extra_expr_nomod(expr, alloc_estate_range(valid_ptr_min_sval, valid_ptr_max_sval));







1238         }
1239 }
1240 
1241 static void match_dereferences(struct expression *expr)
1242 {
1243         if (expr->type != EXPR_PREOP)
1244                 return;
1245         /* it's saying that foo[1] = bar dereferences foo[1] */
1246         if (is_array(expr))
1247                 return;
1248         check_dereference(expr->unop);
1249 }
1250 
1251 static void match_pointer_as_array(struct expression *expr)
1252 {
1253         if (!is_array(expr))
1254                 return;
1255         check_dereference(get_array_base(expr));
1256 }
1257 


1285                 }
1286 
1287                 set_extra_nomod(name, sym, NULL, new);
1288         }
1289         free_string(name);
1290 
1291         find_dereferences(arg);
1292 }
1293 
1294 static sval_t add_one(sval_t sval)
1295 {
1296         sval.value++;
1297         return sval;
1298 }
1299 
1300 static int handle_postop_inc(struct expression *left, int op, struct expression *right)
1301 {
1302         struct statement *stmt;
1303         struct expression *cond;
1304         struct smatch_state *true_state, *false_state;

1305         sval_t start;
1306         sval_t limit;
1307 
1308         /*
1309          * If we're decrementing here then that's a canonical while count down
1310          * so it's handled already.  We're only handling loops like:
1311          * i = 0;
1312          * do { ... } while (i++ < 3);
1313          */
1314 
1315         if (left->type != EXPR_POSTOP || left->op != SPECIAL_INCREMENT)
1316                 return 0;
1317 
1318         stmt = __cur_stmt->parent;
1319         if (!stmt)
1320                 return 0;
1321         if (stmt->type == STMT_COMPOUND)
1322                 stmt = stmt->parent;
1323         if (!stmt || stmt->type != STMT_ITERATOR || !stmt->iterator_post_condition)
1324                 return 0;
1325 
1326         cond = strip_expr(stmt->iterator_post_condition);
1327         if (cond->type != EXPR_COMPARE || cond->op != op)
1328                 return 0;
1329         if (left != strip_expr(cond->left) || right != strip_expr(cond->right))
1330                 return 0;
1331 
1332         if (!get_implied_value(left->unop, &start))
1333                 return 0;
1334         if (!get_implied_value(right, &limit))
1335                 return 0;
1336 

1337         if (sval_cmp(start, limit) > 0)
1338                 return 0;
1339 
1340         switch (op) {
1341         case '<':
1342         case SPECIAL_UNSIGNED_LT:
1343                 break;
1344         case SPECIAL_LTE:
1345         case SPECIAL_UNSIGNED_LTE:
1346                 limit = add_one(limit);
1347         default:
1348                 return 0;
1349 
1350         }
1351 
1352         true_state = alloc_estate_range(add_one(start), limit);
1353         false_state = alloc_estate_range(add_one(limit), add_one(limit));
1354 
1355         /* Currently we just discard the false state but when two passes is
1356          * implimented correctly then it will use it.
1357          */
1358 
1359         set_extra_expr_true_false(left->unop, true_state, false_state);
1360 
1361         return 1;
1362 }
1363 
1364 bool is_impossible_variable(struct expression *expr)
1365 {
1366         struct smatch_state *state;
1367 
1368         state = get_extra_state(expr);
1369         if (state && !estate_rl(state))
1370                 return true;
1371         return false;
1372 }
1373 











1374 static void handle_comparison(struct symbol *type, struct expression *left, int op, struct expression *right)
1375 {
1376         struct range_list *left_orig;
1377         struct range_list *left_true;
1378         struct range_list *left_false;
1379         struct range_list *right_orig;
1380         struct range_list *right_true;
1381         struct range_list *right_false;
1382         struct smatch_state *left_true_state;
1383         struct smatch_state *left_false_state;
1384         struct smatch_state *right_true_state;
1385         struct smatch_state *right_false_state;
1386         sval_t dummy, hard_max;
1387         int left_postop = 0;
1388         int right_postop = 0;
1389 
1390         if (left->op == SPECIAL_INCREMENT || left->op == SPECIAL_DECREMENT) {
1391                 if (left->type == EXPR_POSTOP) {
1392                         left->smatch_flags |= Handled;
1393                         left_postop = left->op;


1436         if (!right_true || !right_false) {
1437                 struct range_list *tmp_true, *tmp_false;
1438 
1439                 split_comparison_rl(alloc_whole_rl(type), op, right_orig, NULL, NULL, &tmp_true, &tmp_false);
1440                 tmp_true = rl_truncate_cast(get_type(strip_expr(right)), tmp_true);
1441                 tmp_false = rl_truncate_cast(get_type(strip_expr(right)), tmp_false);
1442                 if (tmp_true && tmp_false)
1443                         __save_imaginary_state(right, tmp_true, tmp_false);
1444         }
1445 
1446         left_true_state = alloc_estate_rl(left_true);
1447         left_false_state = alloc_estate_rl(left_false);
1448         right_true_state = alloc_estate_rl(right_true);
1449         right_false_state = alloc_estate_rl(right_false);
1450 
1451         switch (op) {
1452         case '<':
1453         case SPECIAL_UNSIGNED_LT:
1454         case SPECIAL_UNSIGNED_LTE:
1455         case SPECIAL_LTE:
1456                 if (get_hard_max(right, &dummy))
1457                         estate_set_hard_max(left_true_state);
1458                 if (get_hard_max(left, &dummy))
1459                         estate_set_hard_max(right_false_state);
1460                 break;
1461         case '>':
1462         case SPECIAL_UNSIGNED_GT:
1463         case SPECIAL_UNSIGNED_GTE:
1464         case SPECIAL_GTE:
1465                 if (get_hard_max(left, &dummy))
1466                         estate_set_hard_max(right_true_state);
1467                 if (get_hard_max(right, &dummy))
1468                         estate_set_hard_max(left_false_state);
1469                 break;
1470         }
1471 
1472         switch (op) {
1473         case '<':
1474         case SPECIAL_UNSIGNED_LT:
1475         case SPECIAL_UNSIGNED_LTE:
1476         case SPECIAL_LTE:
1477                 if (get_hard_max(right, &hard_max)) {
1478                         if (op == '<' || op == SPECIAL_UNSIGNED_LT)
1479                                 hard_max.value--;
1480                         estate_set_fuzzy_max(left_true_state, hard_max);
1481                 }
1482                 if (get_implied_value(right, &hard_max)) {
1483                         if (op == SPECIAL_UNSIGNED_LTE ||
1484                             op == SPECIAL_LTE)
1485                                 hard_max.value++;
1486                         estate_set_fuzzy_max(left_false_state, hard_max);
1487                 }


1581 
1582         set_extra_expr_true_false(left, left_true_state, left_false_state);
1583         set_extra_expr_true_false(right, right_true_state, right_false_state);
1584 }
1585 
1586 static int is_simple_math(struct expression *expr)
1587 {
1588         if (!expr)
1589                 return 0;
1590         if (expr->type != EXPR_BINOP)
1591                 return 0;
1592         switch (expr->op) {
1593         case '+':
1594         case '-':
1595         case '*':
1596                 return 1;
1597         }
1598         return 0;
1599 }
1600 







































1601 static void move_known_values(struct expression **left_p, struct expression **right_p)
1602 {
1603         struct expression *left = *left_p;
1604         struct expression *right = *right_p;
1605         sval_t sval, dummy;
1606 
1607         if (get_implied_value(left, &sval)) {
1608                 if (!is_simple_math(right))
1609                         return;
1610                 if (get_implied_value(right, &dummy))
1611                         return;
1612                 if (right->op == '*') {
1613                         sval_t divisor;
1614 
1615                         if (!get_value(right->right, &divisor))
1616                                 return;
1617                         if (divisor.value == 0)
1618                                 return;
1619                         *left_p = binop_expression(left, invert_op(right->op), right->right);
1620                         *right_p = right->left;


1689             !is_whole_rl(rl)) {
1690                 *right_p = binop_expression(right, '-', left->left);
1691                 *left_p = left->right;
1692                 return 1;
1693         }
1694         if (!get_implied_value(left->right, &tmp) &&
1695             get_implied_rl(left->right, &rl) &&
1696             !is_whole_rl(rl)) {
1697                 *right_p = binop_expression(right, '-', left->right);
1698                 *left_p = left->left;
1699                 return 1;
1700         }
1701 
1702         return 0;
1703 }
1704 
1705 static int match_func_comparison(struct expression *expr)
1706 {
1707         struct expression *left = strip_expr(expr->left);
1708         struct expression *right = strip_expr(expr->right);
1709         sval_t sval;
1710 
1711         /*
1712          * fixme: think about this harder. We should always be trying to limit
1713          * the non-call side as well.  If we can't determine the limitter does
1714          * that mean we aren't querying the database and are missing important
1715          * information?
1716          */
1717 
1718         if (left->type == EXPR_CALL) {
1719                 if (get_implied_value(left, &sval)) {
1720                         handle_comparison(get_type(expr), left, expr->op, right);
1721                         return 1;
1722                 }
1723                 function_comparison(left, expr->op, right);
1724                 return 1;
1725         }
1726 
1727         if (right->type == EXPR_CALL) {
1728                 if (get_implied_value(right, &sval)) {
1729                         handle_comparison(get_type(expr), left, expr->op, right);
1730                         return 1;
1731                 }
1732                 function_comparison(left, expr->op, right);
1733                 return 1;
1734         }
1735 
1736         return 0;
1737 }
1738 
1739 /* Handle conditions like "if (foo + bar < foo) {" */
1740 static int handle_integer_overflow_test(struct expression *expr)
1741 {
1742         struct expression *left, *right;
1743         struct symbol *type;
1744         sval_t left_min, right_min, min, max;
1745 
1746         if (expr->op != '<' && expr->op != SPECIAL_UNSIGNED_LT)
1747                 return 0;
1748 
1749         left = strip_parens(expr->left);
1750         right = strip_parens(expr->right);
1751 
1752         if (left->op != '+')
1753                 return 0;
1754 
1755         type = get_type(expr);
1756         if (!type)
1757                 return 0;
1758         if (type_positive_bits(type) == 32) {
1759                 max.type = &uint_ctype;
1760                 max.uvalue = (unsigned int)-1;
1761         } else if (type_positive_bits(type) == 64) {
1762                 max.type = &ulong_ctype;
1763                 max.value = (unsigned long long)-1;
1764         } else {
1765                 return 0;
1766         }
1767 
1768         if (!expr_equiv(left->left, right) && !expr_equiv(left->right, right))
1769                 return 0;
1770 
1771         get_absolute_min(left->left, &left_min);
1772         get_absolute_min(left->right, &right_min);
1773         min = sval_binop(left_min, '+', right_min);
1774 




1775         set_extra_chunk_true_false(left, NULL, alloc_estate_range(min, max));
1776         return 1;
1777 }
1778 
1779 static void match_comparison(struct expression *expr)
1780 {
1781         struct expression *left_orig = strip_parens(expr->left);
1782         struct expression *right_orig = strip_parens(expr->right);
1783         struct expression *left, *right, *tmp;
1784         struct expression *prev;
1785         struct symbol *type;
1786         int redo, count;
1787 
1788         if (match_func_comparison(expr))
1789                 return;
1790 
1791         type = get_type(expr);
1792         if (!type)
1793                 type = &llong_ctype;
1794 


1853 }
1854 
1855 static sval_t get_high_mask(sval_t known)
1856 {
1857         sval_t ret;
1858         int i;
1859 
1860         ret = known;
1861         ret.value = 0;
1862 
1863         for (i = type_bits(known.type) - 1; i >= 0; i--) {
1864                 if (known.uvalue & (1ULL << i))
1865                         ret.uvalue |= (1ULL << i);
1866                 else
1867                         return ret;
1868 
1869         }
1870         return ret;
1871 }
1872 













































1873 static void handle_AND_op(struct expression *var, sval_t known)
1874 {
1875         struct range_list *orig_rl;
1876         struct range_list *true_rl = NULL;
1877         struct range_list *false_rl = NULL;
1878         int bit;
1879         sval_t low_mask = known;
1880         sval_t high_mask;
1881         sval_t max;
1882 
1883         get_absolute_rl(var, &orig_rl);
1884 
1885         if (known.value > 0) {
1886                 bit = ffsll(known.value) - 1;
1887                 low_mask.uvalue = (1ULL << bit) - 1;
1888                 true_rl = remove_range(orig_rl, sval_type_val(known.type, 0), low_mask);
1889         }
1890         high_mask = get_high_mask(known);
1891         if (high_mask.value) {
1892                 bit = ffsll(high_mask.value) - 1;


1899                 if (type_signed(high_mask.type) && type_unsigned(rl_type(false_rl))) {
1900                         false_rl = remove_range(false_rl,
1901                                                 sval_type_val(rl_type(false_rl), sval_type_max(known.type).uvalue),
1902                                         sval_type_val(rl_type(false_rl), -1));
1903                 }
1904         } else if (known.value == 1 &&
1905                    get_hard_max(var, &max) &&
1906                    sval_cmp(max, rl_max(orig_rl)) == 0 &&
1907                    max.value & 1) {
1908                 false_rl = remove_range(orig_rl, max, max);
1909         }
1910         set_extra_expr_true_false(var,
1911                                   true_rl ? alloc_estate_rl(true_rl) : NULL,
1912                                   false_rl ? alloc_estate_rl(false_rl) : NULL);
1913 }
1914 
1915 static void handle_AND_condition(struct expression *expr)
1916 {
1917         sval_t known;
1918 



1919         if (get_implied_value(expr->left, &known))
1920                 handle_AND_op(expr->right, known);
1921         else if (get_implied_value(expr->right, &known))
1922                 handle_AND_op(expr->left, known);
1923 }
1924 
1925 static void handle_MOD_condition(struct expression *expr)
1926 {
1927         struct range_list *orig_rl;
1928         struct range_list *true_rl;
1929         struct range_list *false_rl = NULL;
1930         sval_t right;
1931         sval_t zero;
1932 
1933         if (!get_implied_value(expr->right, &right) || right.value == 0)
1934                 return;
1935         get_absolute_rl(expr->left, &orig_rl);
1936 
1937         zero.value = 0;
1938         zero.type = rl_type(orig_rl);
1939 
1940         /* We're basically dorking around the min and max here */
1941         true_rl = remove_range(orig_rl, zero, zero);
1942         if (!sval_is_max(rl_max(true_rl)) &&
1943             !(rl_max(true_rl).value % right.value))
1944                 true_rl = remove_range(true_rl, rl_max(true_rl), rl_max(true_rl));
1945 
1946         if (rl_equiv(true_rl, orig_rl))
1947                 true_rl = NULL;
1948 
1949         if (sval_is_positive(rl_min(orig_rl)) &&
1950             (rl_max(orig_rl).value - rl_min(orig_rl).value) / right.value < 5) {
1951                 sval_t add;


1971 
1972                 if (!sval_is_max(rl_max(orig_rl)) &&
1973                     (rl_max(orig_rl).value % right.value)) {
1974                         sval_t chop = rl_max(orig_rl);
1975                         chop.value -= chop.value % right.value;
1976                         chop.value++;
1977                         if (!false_rl)
1978                                 false_rl = clone_rl(orig_rl);
1979                         false_rl = remove_range(false_rl, chop, rl_max(orig_rl));
1980                 }
1981         }
1982 
1983         set_extra_expr_true_false(expr->left,
1984                                   true_rl ? alloc_estate_rl(true_rl) : NULL,
1985                                   false_rl ? alloc_estate_rl(false_rl) : NULL);
1986 }
1987 
1988 /* this is actually hooked from smatch_implied.c...  it's hacky, yes */
1989 void __extra_match_condition(struct expression *expr)
1990 {
1991         struct smatch_state *pre_state;
1992         struct smatch_state *true_state;
1993         struct smatch_state *false_state;
1994         struct range_list *pre_rl;
1995 
1996         expr = strip_expr(expr);
1997         switch (expr->type) {
1998         case EXPR_CALL:
1999                 function_comparison(expr, SPECIAL_NOTEQUAL, zero_expr());
2000                 return;
2001         case EXPR_PREOP:
2002         case EXPR_SYMBOL:
2003         case EXPR_DEREF: {
2004                 sval_t zero;
2005 
2006                 zero = sval_blank(expr);
2007                 zero.value = 0;
2008 
2009                 pre_state = get_extra_state(expr);
2010                 if (estate_is_empty(pre_state))
2011                         return;
2012                 if (pre_state)
2013                         pre_rl = estate_rl(pre_state);
2014                 else
2015                         get_absolute_rl(expr, &pre_rl);
2016                 if (possibly_true_rl(pre_rl, SPECIAL_EQUAL, rl_zero()))
2017                         false_state = alloc_estate_sval(zero);
2018                 else
2019                         false_state = alloc_estate_empty();
2020                 true_state = alloc_estate_rl(remove_range(pre_rl, zero, zero));
2021                 set_extra_expr_true_false(expr, true_state, false_state);
2022                 return;
2023         }
2024         case EXPR_COMPARE:
2025                 match_comparison(expr);
2026                 return;
2027         case EXPR_ASSIGNMENT:
2028                 __extra_match_condition(expr->left);
2029                 return;
2030         case EXPR_BINOP:
2031                 if (expr->op == '&')
2032                         handle_AND_condition(expr);
2033                 if (expr->op == '%')
2034                         handle_MOD_condition(expr);
2035                 return;
2036         }
2037 }
2038 
2039 static void assume_indexes_are_valid(struct expression *expr)
2040 {
2041         struct expression *array_expr;
2042         int array_size;
2043         struct expression *offset;


2136         struct symbol *sym;
2137         char *var;
2138         int ret = 0;
2139 
2140         expr = strip_expr(expr);
2141         var = expr_to_var_sym(expr, &sym);
2142         if (!var || !sym)
2143                 goto free;
2144         ret = parent_is_null_var_sym(var, sym);
2145 free:
2146         free_string(var);
2147         return ret;
2148 }
2149 
2150 static int param_used_callback(void *found, int argc, char **argv, char **azColName)
2151 {
2152         *(int *)found = 1;
2153         return 0;
2154 }
2155 
2156 static int filter_unused_kzalloc_info(struct expression *call, int param, char *printed_name, struct sm_state *sm)
2157 {
2158         sval_t sval;




































2159         int found = 0;
2160 
2161         /* for function pointers assume everything is used */
2162         if (call->fn->type != EXPR_SYMBOL)
2163                 return 0;
2164 
2165         /*
2166          * This is to handle __builtin_mul_overflow().  In an ideal world we
2167          * would only need this for invalid code.
2168          *
2169          */
2170         if (!call->fn->symbol)
2171                 return 0;
2172 
2173         /*
2174          * kzalloc() information is treated as special because so there is just
2175          * a lot of stuff initialized to zero and it makes building the database
2176          * take hours and hours.
2177          *
2178          * In theory, we should just remove this line and not pass any unused
2179          * information, but I'm not sure enough that this code works so I want
2180          * to hold off on that for now.
2181          */
2182         if (!estate_get_single_value(sm->state, &sval) || sval.value != 0)
2183                 return 0;
2184 
2185         run_sql(&param_used_callback, &found,
2186                 "select * from return_implies where %s and type = %d and parameter = %d and key = '%s';",
2187                 get_static_filter(call->fn->symbol), PARAM_USED, param, printed_name);
2188         if (found)
2189                 return 0;
2190 
2191         /* If the database is not built yet, then assume everything is used */
2192         run_sql(&param_used_callback, &found,
2193                 "select * from return_implies where %s and type = %d;",
2194                 get_static_filter(call->fn->symbol), PARAM_USED);
2195         if (!found)
2196                 return 0;
2197 
2198         return 1;
2199 }
2200 
2201 struct range_list *intersect_with_real_abs_var_sym(const char *name, struct symbol *sym, struct range_list *start)
2202 {


2229 
2230         return rl_intersection(estate_rl(state), start);
2231 }
2232 
2233 struct range_list *intersect_with_real_abs_expr(struct expression *expr, struct range_list *start)
2234 {
2235         struct smatch_state *state;
2236         struct range_list *abs_rl;
2237 
2238         state = get_real_absolute_state(expr);
2239         if (!state || !estate_rl(state))
2240                 return start;
2241 
2242         abs_rl = cast_rl(rl_type(start), estate_rl(state));
2243         return rl_intersection(abs_rl, start);
2244 }
2245 
2246 static void struct_member_callback(struct expression *call, int param, char *printed_name, struct sm_state *sm)
2247 {
2248         struct range_list *rl;

2249 
2250         if (estate_is_whole(sm->state))
2251                 return;
2252         if (filter_unused_kzalloc_info(call, param, printed_name, sm))
2253                 return;
2254         rl = estate_rl(sm->state);
2255         rl = intersect_with_real_abs_var_sym(sm->name, sm->sym, rl);
2256         sql_insert_caller_info(call, PARAM_VALUE, param, printed_name, show_rl(rl));




2257         if (estate_has_fuzzy_max(sm->state))
2258                 sql_insert_caller_info(call, FUZZY_MAX, param, printed_name,
2259                                        sval_to_str(estate_get_fuzzy_max(sm->state)));

2260 }
2261 
2262 static void returned_struct_members(int return_id, char *return_ranges, struct expression *expr)
2263 {
2264         struct symbol *returned_sym;

2265         struct sm_state *sm;
2266         const char *param_name;
2267         char *compare_str;
2268         char buf[256];


2269 
2270         returned_sym = expr_to_sym(expr);
2271         if (!returned_sym)

2272                 return;
2273 





2274         FOR_EACH_MY_SM(my_id, __get_cur_stree(), sm) {
2275                 if (!estate_rl(sm->state))
2276                         continue;
2277                 if (returned_sym != sm->sym)
2278                         continue;
2279 
2280                 param_name = get_param_name(sm);
2281                 if (!param_name)
2282                         continue;
2283                 if (strcmp(param_name, "$") == 0)
2284                         continue;



2285                 compare_str = name_sym_to_param_comparison(sm->name, sm->sym);
2286                 if (!compare_str && estate_is_whole(sm->state))
2287                         continue;
2288                 snprintf(buf, sizeof(buf), "%s%s", sm->state->name, compare_str ?: "");
2289 
2290                 sql_insert_return_states(return_id, return_ranges, PARAM_VALUE,
2291                                          -1, param_name, buf);
2292         } END_FOR_EACH_SM(sm);



2293 }
2294 
2295 static void db_limited_before(void)
2296 {
2297         unmatched_stree = clone_stree(__get_cur_stree());
2298 }
2299 
2300 static void db_limited_after(void)
2301 {
2302         free_stree(&unmatched_stree);
2303 }
2304 
2305 static int rl_fits_in_type(struct range_list *rl, struct symbol *type)
2306 {
2307         if (type_bits(rl_type(rl)) <= type_bits(type))
2308                 return 1;
2309         if (sval_cmp(rl_max(rl), sval_type_max(type)) > 0)
2310                 return 0;
2311         if (sval_is_negative(rl_min(rl)) &&
2312             sval_cmp(rl_min(rl), sval_type_min(type)) < 0)
2313                 return 0;
2314         return 1;
2315 }
2316 
2317 static int basically_the_same(struct range_list *orig, struct range_list *new)
2318 {
2319         if (rl_equiv(orig, new))
2320                 return 1;
2321 
2322         /*
2323          * The whole range is essentially the same as 0,4096-27777777777 so
2324          * don't overwrite the implications just to store that.
2325          *
2326          */
2327         if (rl_type(orig)->type == SYM_PTR &&
2328             is_whole_rl(orig) &&
2329             rl_min(new).value == 0 &&
2330             rl_max(new).value == valid_ptr_max)
2331                 return 1;
2332         return 0;
2333 }
2334 
2335 static void db_param_limit_binops(struct expression *arg, char *key, struct range_list *rl)
2336 {


2346                 return;
2347 
2348         left_rl = rl_binop(rl, '/', alloc_rl(sval, sval));
2349         if (!rl_has_sval(rl, zero))
2350                 left_rl = remove_range(left_rl, zero, zero);
2351 
2352         set_extra_expr_nomod(arg->left, alloc_estate_rl(left_rl));
2353 }
2354 
2355 static void db_param_limit_filter(struct expression *expr, int param, char *key, char *value, enum info_type op)
2356 {
2357         struct expression *arg;
2358         char *name;
2359         struct symbol *sym;
2360         struct var_sym_list *vsl = NULL;
2361         struct sm_state *sm;
2362         struct symbol *compare_type, *var_type;
2363         struct range_list *rl;
2364         struct range_list *limit;
2365         struct range_list *new;
2366         char *tmp_name;
2367         struct symbol *tmp_sym;
2368 
2369         while (expr->type == EXPR_ASSIGNMENT)
2370                 expr = strip_expr(expr->right);
2371         if (expr->type != EXPR_CALL)
2372                 return;
2373 
2374         arg = get_argument_from_call_expr(expr->args, param);
2375         if (!arg)
2376                 return;
2377 








2378         name = get_chunk_from_key(arg, key, &sym, &vsl);
2379         if (!name)
2380                 return;
2381         if (op != PARAM_LIMIT && !sym)
2382                 goto free;
2383 
2384         if (strcmp(key, "$") == 0)
2385                 compare_type = get_arg_type(expr->fn, param);
2386         else
2387                 compare_type = get_member_type_from_key(arg, key);
2388 
2389         sm = get_sm_state(SMATCH_EXTRA, name, sym);
2390         if (sm)
2391                 rl = estate_rl(sm->state);
2392         else
2393                 rl = alloc_whole_rl(compare_type);
2394 
2395         if (op == PARAM_LIMIT && !rl_fits_in_type(rl, compare_type))
2396                 goto free;
2397 
2398         call_results_to_rl(expr, compare_type, value, &limit);
2399         new = rl_intersection(rl, limit);
2400 
2401         var_type = get_member_type_from_key(arg, key);
2402         new = cast_rl(var_type, new);
2403 
2404         /* We want to preserve the implications here */
2405         if (sm && basically_the_same(estate_rl(sm->state), new))
2406                 goto free;
2407         tmp_name = map_long_to_short_name_sym(name, sym, &tmp_sym);
2408         if (tmp_name && tmp_sym) {
2409                 free_string(name);
2410                 name = tmp_name;
2411                 sym = tmp_sym;
2412         }
2413 
2414         if (op == PARAM_LIMIT)
2415                 set_extra_nomod_vsl(name, sym, vsl, NULL, alloc_estate_rl(new));
2416         else
2417                 set_extra_mod(name, sym, NULL, alloc_estate_rl(new));
2418 







2419         if (op == PARAM_LIMIT && arg->type == EXPR_BINOP)
2420                 db_param_limit_binops(arg, key, new);
2421 free:
2422         free_string(name);
2423 }
2424 
2425 static void db_param_limit(struct expression *expr, int param, char *key, char *value)
2426 {
2427         db_param_limit_filter(expr, param, key, value, PARAM_LIMIT);
2428 }
2429 
2430 static void db_param_filter(struct expression *expr, int param, char *key, char *value)
2431 {
2432         db_param_limit_filter(expr, param, key, value, PARAM_FILTER);
2433 }
2434 
2435 static void db_param_add_set(struct expression *expr, int param, char *key, char *value, enum info_type op)
2436 {
2437         struct expression *arg;
2438         char *name, *tmp_name;
2439         struct symbol *sym, *tmp_sym;

2440         struct symbol *param_type, *arg_type;
2441         struct smatch_state *state;
2442         struct range_list *new = NULL;
2443         struct range_list *added = NULL;
2444 
2445         while (expr->type == EXPR_ASSIGNMENT)
2446                 expr = strip_expr(expr->right);
2447         if (expr->type != EXPR_CALL)
2448                 return;
2449 
2450         arg = get_argument_from_call_expr(expr->args, param);
2451         if (!arg)
2452                 return;
2453 
2454         arg_type = get_arg_type_from_key(expr->fn, param, arg, key);
2455         param_type = get_member_type_from_key(arg, key);
2456         name = get_variable_from_key(arg, key, &sym);
2457         if (!name || !sym)
2458                 goto free;
2459 
2460         state = get_state(SMATCH_EXTRA, name, sym);
2461         if (state)
2462                 new = estate_rl(state);
2463 
2464         call_results_to_rl(expr, arg_type, value, &added);
2465         added = cast_rl(param_type, added);
2466         if (op == PARAM_SET)
2467                 new = added;
2468         else
2469                 new = rl_union(new, added);
2470 
2471         tmp_name = map_long_to_short_name_sym_nostack(name, sym, &tmp_sym);
2472         if (tmp_name && tmp_sym) {
2473                 free_string(name);
2474                 name = tmp_name;
2475                 sym = tmp_sym;
2476         }
2477         set_extra_mod(name, sym, NULL, alloc_estate_rl(new));


2478 free:

2479         free_string(name);
2480 }
2481 
2482 static void db_param_add(struct expression *expr, int param, char *key, char *value)
2483 {
2484         in_param_set = true;
2485         db_param_add_set(expr, param, key, value, PARAM_ADD);
2486         in_param_set = false;
2487 }
2488 
2489 static void db_param_set(struct expression *expr, int param, char *key, char *value)
2490 {
2491         in_param_set = true;
2492         db_param_add_set(expr, param, key, value, PARAM_SET);
2493         in_param_set = false;
2494 }
2495 


















2496 static void db_param_value(struct expression *expr, int param, char *key, char *value)
2497 {
2498         struct expression *call;
2499         char *name;
2500         struct symbol *sym;
2501         struct symbol *type;
2502         struct range_list *rl = NULL;
2503 
2504         if (param != -1)
2505                 return;
2506 
2507         call = expr;
2508         while (call->type == EXPR_ASSIGNMENT)
2509                 call = strip_expr(call->right);
2510         if (call->type != EXPR_CALL)
2511                 return;
2512 
2513         type = get_member_type_from_key(expr->left, key);
2514         name = get_variable_from_key(expr->left, key, &sym);
2515         if (!name || !sym)
2516                 goto free;
2517 
2518         call_results_to_rl(call, type, value, &rl);
2519 
2520         set_extra_mod(name, sym, NULL, alloc_estate_rl(rl));
2521 free:
2522         free_string(name);
2523 }
2524 
2525 static void match_call_info(struct expression *expr)
2526 {
2527         struct smatch_state *state;
2528         struct range_list *rl = NULL;
2529         struct expression *arg;
2530         struct symbol *type;

2531         int i = 0;
2532 
2533         FOR_EACH_PTR(expr->args, arg) {
2534                 type = get_arg_type(expr->fn, i);
2535 
2536                 get_absolute_rl(arg, &rl);
2537                 rl = cast_rl(type, rl);
2538 
2539                 if (!is_whole_rl(rl)) {
2540                         rl = intersect_with_real_abs_expr(arg, rl);
2541                         sql_insert_caller_info(expr, PARAM_VALUE, i, "$", show_rl(rl));
2542                 }
2543                 state = get_state_expr(SMATCH_EXTRA, arg);




2544                 if (estate_has_fuzzy_max(state)) {
2545                         sql_insert_caller_info(expr, FUZZY_MAX, i, "$",
2546                                                sval_to_str(estate_get_fuzzy_max(state)));
2547                 }
2548                 i++;
2549         } END_FOR_EACH_PTR(arg);
2550 }
2551 
2552 static void set_param_value(const char *name, struct symbol *sym, char *key, char *value)
2553 {

2554         struct range_list *rl = NULL;
2555         struct smatch_state *state;
2556         struct symbol *type;
2557         char fullname[256];


2558         sval_t dummy;
2559 
2560         if (strcmp(key, "*$") == 0)
2561                 snprintf(fullname, sizeof(fullname), "*%s", name);
2562         else if (strncmp(key, "$", 1) == 0)
2563                 snprintf(fullname, 256, "%s%s", name, key + 1);
2564         else
2565                 return;
2566 
2567         type = get_member_type_from_key(symbol_expression(sym), key);



2568         str_to_rl(type, value, &rl);
2569         state = alloc_estate_rl(rl);
2570         if (estate_get_single_value(state, &dummy))
2571                 estate_set_hard_max(state);
2572         set_state(SMATCH_EXTRA, fullname, sym, state);
2573 }
2574 
2575 static void set_param_hard_max(const char *name, struct symbol *sym, char *key, char *value)
2576 {
2577         struct range_list *rl = NULL;
2578         struct smatch_state *state;
2579         struct symbol *type;
2580         char fullname[256];
2581         sval_t max;
2582 
2583         if (strcmp(key, "*$") == 0)
2584                 snprintf(fullname, sizeof(fullname), "*%s", name);
2585         else if (strncmp(key, "$", 1) == 0)
2586                 snprintf(fullname, 256, "%s%s", name, key + 1);
2587         else
2588                 return;
2589 
2590         state = get_state(SMATCH_EXTRA, fullname, sym);
2591         if (!state)
2592                 return;
2593         type = get_member_type_from_key(symbol_expression(sym), key);
2594         str_to_rl(type, value, &rl);
2595         if (!rl_to_sval(rl, &max))
2596                 return;
2597         estate_set_fuzzy_max(state, max);
2598 }
2599 


















2600 struct sm_state *get_extra_sm_state(struct expression *expr)
2601 {
2602         char *name;
2603         struct symbol *sym;
2604         struct sm_state *ret = NULL;
2605 
2606         name = expr_to_known_chunk_sym(expr, &sym);
2607         if (!name)
2608                 goto free;
2609 
2610         ret = get_sm_state(SMATCH_EXTRA, name, sym);
2611 free:
2612         free_string(name);
2613         return ret;
2614 }
2615 
2616 struct smatch_state *get_extra_state(struct expression *expr)
2617 {
2618         struct sm_state *sm;
2619 
2620         sm = get_extra_sm_state(expr);
2621         if (!sm)
2622                 return NULL;
2623         return sm->state;
2624 }
2625 
2626 void register_smatch_extra(int id)
2627 {
2628         my_id = id;
2629 

2630         add_merge_hook(my_id, &merge_estates);
2631         add_unmatched_state_hook(my_id, &unmatched_state);
2632         select_caller_info_hook(set_param_value, PARAM_VALUE);
2633         select_caller_info_hook(set_param_hard_max, FUZZY_MAX);

2634         select_return_states_before(&db_limited_before);
2635         select_return_states_hook(PARAM_LIMIT, &db_param_limit);
2636         select_return_states_hook(PARAM_FILTER, &db_param_filter);
2637         select_return_states_hook(PARAM_ADD, &db_param_add);
2638         select_return_states_hook(PARAM_SET, &db_param_set);

2639         select_return_states_hook(PARAM_VALUE, &db_param_value);
2640         select_return_states_after(&db_limited_after);
2641 }
2642 
2643 static void match_link_modify(struct sm_state *sm, struct expression *mod_expr)
2644 {
2645         struct var_sym_list *links;
2646         struct var_sym *tmp;
2647         struct smatch_state *state;
2648 
2649         links = sm->state->data;
2650 
2651         FOR_EACH_PTR(links, tmp) {
2652                 if (sm->sym == tmp->sym &&
2653                     strcmp(sm->name, tmp->var) == 0)
2654                         continue;
2655                 state = get_state(SMATCH_EXTRA, tmp->var, tmp->sym);
2656                 if (!state)
2657                         continue;
2658                 set_state(SMATCH_EXTRA, tmp->var, tmp->sym, alloc_estate_whole(estate_type(state)));
2659         } END_FOR_EACH_PTR(tmp);
2660         set_state(link_id, sm->name, sm->sym, &undefined);
2661 }
2662 
2663 void register_smatch_extra_links(int id)
2664 {
2665         link_id = id;

2666 }
2667 
2668 void register_smatch_extra_late(int id)
2669 {
2670         add_merge_hook(link_id, &merge_link_states);
2671         add_modification_hook(link_id, &match_link_modify);
2672         add_hook(&match_dereferences, DEREF_HOOK);
2673         add_hook(&match_pointer_as_array, OP_HOOK);
2674         select_return_implies_hook(DEREFERENCE, &set_param_dereferenced);
2675         add_hook(&match_function_call, FUNCTION_CALL_HOOK);
2676         add_hook(&match_assign, ASSIGNMENT_HOOK);
2677         add_hook(&match_assign, GLOBAL_ASSIGNMENT_HOOK);
2678         add_hook(&unop_expr, OP_HOOK);
2679         add_hook(&asm_expr, ASM_HOOK);
2680 
2681         add_hook(&match_call_info, FUNCTION_CALL_HOOK);
2682         add_member_info_callback(my_id, struct_member_callback);
2683         add_split_return_callback(&returned_struct_members);
2684 
2685 //      add_hook(&assume_indexes_are_valid, OP_HOOK);


  19  * smatch_extra.c is supposed to track the value of every variable.
  20  *
  21  */
  22 
  23 #define _GNU_SOURCE
  24 #include <string.h>
  25 
  26 #include <stdlib.h>
  27 #include <errno.h>
  28 #ifndef __USE_ISOC99
  29 #define __USE_ISOC99
  30 #endif
  31 #include <limits.h>
  32 #include "parse.h"
  33 #include "smatch.h"
  34 #include "smatch_slist.h"
  35 #include "smatch_extra.h"
  36 
  37 static int my_id;
  38 static int link_id;
  39 extern int check_assigned_expr_id;
  40 
  41 static void match_link_modify(struct sm_state *sm, struct expression *mod_expr);
  42 
  43 struct string_list *__ignored_macros = NULL;
  44 int in_warn_on_macro(void)
  45 {
  46         struct statement *stmt;
  47         char *tmp;
  48         char *macro;
  49 
  50         stmt = get_current_statement();
  51         if (!stmt)
  52                 return 0;
  53         macro = get_macro_name(stmt->pos);
  54         if (!macro)
  55                 return 0;
  56 
  57         FOR_EACH_PTR(__ignored_macros, tmp) {
  58                 if (!strcmp(tmp, macro))
  59                         return 1;
  60         } END_FOR_EACH_PTR(tmp);
  61         return 0;
  62 }
  63 
  64 typedef void (mod_hook)(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state);


 118 
 119 static char *get_pointed_at(const char *name, struct symbol *sym, struct symbol **new_sym)
 120 {
 121         struct expression *assigned;
 122 
 123         if (name[0] != '*')
 124                 return NULL;
 125         if (strcmp(name + 1, sym->ident->name) != 0)
 126                 return NULL;
 127 
 128         assigned = get_assigned_expr_name_sym(sym->ident->name, sym);
 129         if (!assigned)
 130                 return NULL;
 131         assigned = strip_parens(assigned);
 132         if (assigned->type != EXPR_PREOP || assigned->op != '&')
 133                 return NULL;
 134 
 135         return expr_to_var_sym(assigned->unop, new_sym);
 136 }
 137 
 138 char *get_other_name_sym_from_chunk(const char *name, const char *chunk, int len, struct symbol *sym, struct symbol **new_sym)
 139 {
 140         struct expression *assigned;
 141         char *orig_name = NULL;
 142         char buf[256];
 143         char *ret;

 144 
 145         assigned = get_assigned_expr_name_sym(chunk, sym);














 146         if (!assigned)
 147                 return NULL;
 148         if (assigned->type == EXPR_CALL)
 149                 return map_call_to_other_name_sym(name, sym, new_sym);
 150         if (assigned->type == EXPR_PREOP && assigned->op == '&') {
 151 
 152                 orig_name = expr_to_var_sym(assigned, new_sym);
 153                 if (!orig_name || !*new_sym)
 154                         goto free;
 155 
 156                 snprintf(buf, sizeof(buf), "%s.%s", orig_name + 1, name + len);
 157                 ret = alloc_string(buf);
 158                 free_string(orig_name);
 159                 return ret;
 160         }
 161 



 162         orig_name = expr_to_var_sym(assigned, new_sym);
 163         if (!orig_name || !*new_sym)
 164                 goto free;
 165 
 166         snprintf(buf, sizeof(buf), "%s->%s", orig_name, name + len);
 167         ret = alloc_string(buf);
 168         free_string(orig_name);
 169         return ret;

 170 free:
 171         free_string(orig_name);
 172         return NULL;
 173 }
 174 
 175 static char *get_long_name_sym(const char *name, struct symbol *sym, struct symbol **new_sym)
 176 {
 177         struct expression *tmp;
 178         struct sm_state *sm;
 179         char buf[256];
 180 
 181         /*
 182          * Just prepend the name with a different name/sym and return that.
 183          * For example, if we set "foo->bar = bar;" then we clamp "bar->baz",
 184          * that also clamps "foo->bar->baz".
 185          *
 186          */
 187 
 188         FOR_EACH_MY_SM(check_assigned_expr_id, __get_cur_stree(), sm) {
 189                 tmp = sm->state->data;
 190                 if (!tmp || tmp->type != EXPR_SYMBOL)
 191                         continue;
 192                 if (tmp->symbol == sym)
 193                         goto found;
 194         } END_FOR_EACH_SM(sm);
 195 
 196         return NULL;
 197 
 198 found:
 199         snprintf(buf, sizeof(buf), "%s%s", sm->name, name + tmp->symbol->ident->len);
 200         *new_sym = sm->sym;
 201         return alloc_string(buf);
 202 }
 203 
 204 char *get_other_name_sym_helper(const char *name, struct symbol *sym, struct symbol **new_sym, bool use_stack)
 205 {
 206         char buf[256];
 207         char *ret;
 208         int len;
 209 
 210         *new_sym = NULL;
 211 
 212         if (!sym || !sym->ident)
 213                 return NULL;
 214 
 215         ret = get_pointed_at(name, sym, new_sym);
 216         if (ret)
 217                 return ret;
 218 
 219         ret = map_long_to_short_name_sym(name, sym, new_sym, use_stack);
 220         if (ret)
 221                 return ret;
 222 
 223         len = snprintf(buf, sizeof(buf), "%s", name);
 224         if (len >= sizeof(buf) - 2)
 225                 return NULL;
 226 
 227         while (len >= 1) {
 228                 if (buf[len] == '>' && buf[len - 1] == '-') {
 229                         len--;
 230                         buf[len] = '\0';
 231                         ret = get_other_name_sym_from_chunk(name, buf, len + 2, sym, new_sym);
 232                         if (ret)
 233                                 return ret;
 234                 }
 235                 len--;
 236         }
 237 
 238         ret = get_long_name_sym(name, sym, new_sym);
 239         if (ret)
 240                 return ret;
 241 
 242         return NULL;
 243 }
 244 
 245 char *get_other_name_sym(const char *name, struct symbol *sym, struct symbol **new_sym)
 246 {
 247         return get_other_name_sym_helper(name, sym, new_sym, true);
 248 }
 249 
 250 char *get_other_name_sym_nostack(const char *name, struct symbol *sym, struct symbol **new_sym)
 251 {
 252         return get_other_name_sym_helper(name, sym, new_sym, false);
 253 }
 254 
 255 void set_extra_mod(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
 256 {
 257         char *new_name;
 258         struct symbol *new_sym;
 259 
 260         set_extra_mod_helper(name, sym, expr, state);
 261         new_name = get_other_name_sym(name, sym, &new_sym);
 262         if (new_name && new_sym)
 263                 set_extra_mod_helper(new_name, new_sym, expr, state);
 264         free_string(new_name);
 265 }
 266 
 267 static struct expression *chunk_get_array_base(struct expression *expr)
 268 {
 269         /*
 270          * The problem with is_array() is that it only returns true for things
 271          * like foo[1] but not for foo[1].bar.
 272          *
 273          */
 274         expr = strip_expr(expr);


 346         orig_state = get_state(SMATCH_EXTRA, name, sym);
 347 
 348         /* don't save unknown states if leaving it blank is the same */
 349         if (!orig_state && estate_is_unknown(state))
 350                 return;
 351 
 352         new_name = get_other_name_sym(name, sym, &new_sym);
 353         if (new_name && new_sym)
 354                 set_extra_nomod_helper(new_name, new_sym, expr, state);
 355         free_string(new_name);
 356 
 357         if (!estate_related(orig_state)) {
 358                 set_extra_nomod_helper(name, sym, expr, state);
 359                 return;
 360         }
 361 
 362         set_related(state, estate_related(orig_state));
 363         FOR_EACH_PTR(estate_related(orig_state), rel) {
 364                 struct smatch_state *estate;
 365 


 366                 estate = get_state(SMATCH_EXTRA, rel->name, rel->sym);
 367                 if (!estate)
 368                         continue;
 369                 set_extra_nomod_helper(rel->name, rel->sym, expr, clone_estate_cast(estate_type(estate), state));
 370         } END_FOR_EACH_PTR(rel);
 371 }
 372 
 373 void set_extra_nomod_vsl(const char *name, struct symbol *sym, struct var_sym_list *vsl, struct expression *expr, struct smatch_state *state)
 374 {
 375         struct var_sym *vs;
 376 
 377         FOR_EACH_PTR(vsl, vs) {
 378                 store_link(link_id, vs->var, vs->sym, name, sym);
 379         } END_FOR_EACH_PTR(vs);
 380 
 381         set_extra_nomod(name, sym, expr, state);
 382 }
 383 
 384 /*
 385  * This is for return_implies_state() hooks which modify a SMATCH_EXTRA state


 527                 *right = limit;
 528 
 529                 return 1;
 530         }
 531 
 532         if (condition->type != EXPR_PREOP && condition->type != EXPR_POSTOP)
 533                 return 0;
 534         if (condition->op != SPECIAL_DECREMENT)
 535                 return 0;
 536 
 537         *unop = condition;
 538         *op = '>';
 539 
 540         return 1;
 541 }
 542 
 543 static struct sm_state *handle_canonical_while_count_down(struct statement *loop)
 544 {
 545         struct expression *iter_var;
 546         struct expression *condition, *unop;
 547         struct symbol *type;
 548         struct sm_state *sm;
 549         struct smatch_state *estate;
 550         int op;
 551         sval_t start, right;
 552 
 553         right.type = &int_ctype;
 554         right.value = 0;
 555 
 556         condition = strip_expr(loop->iterator_pre_condition);
 557         if (!condition)
 558                 return NULL;
 559 
 560         if (!get_countdown_info(condition, &unop, &op, &right))
 561                 return NULL;
 562 
 563         iter_var = unop->unop;
 564 
 565         sm = get_sm_state_expr(SMATCH_EXTRA, iter_var);
 566         if (!sm)
 567                 return NULL;
 568         if (sval_cmp(estate_min(sm->state), right) < 0)
 569                 return NULL;
 570         start = estate_max(sm->state);
 571 
 572         type = get_type(iter_var);
 573         right = sval_cast(type, right);
 574         start = sval_cast(type, start);
 575 
 576         if  (sval_cmp(start, right) <= 0)
 577                 return NULL;
 578         if (!sval_is_max(start))
 579                 start.value--;
 580 
 581         if (op == SPECIAL_GTE)
 582                 right.value--;
 583 
 584         if (unop->type == EXPR_PREOP) {
 585                 right.value++;
 586                 estate = alloc_estate_range(right, start);
 587                 if (estate_has_hard_max(sm->state))
 588                         estate_set_hard_max(estate);
 589                 estate_copy_fuzzy_max(estate, sm->state);
 590                 set_extra_expr_mod(iter_var, estate);
 591         }
 592         if (unop->type == EXPR_POSTOP) {
 593                 estate = alloc_estate_range(right, start);
 594                 if (estate_has_hard_max(sm->state))
 595                         estate_set_hard_max(estate);
 596                 estate_copy_fuzzy_max(estate, sm->state);
 597                 set_extra_expr_mod(iter_var, estate);
 598         }
 599         return get_sm_state_expr(SMATCH_EXTRA, iter_var);
 600 }
 601 
 602 static struct sm_state *handle_canonical_for_inc(struct expression *iter_expr,
 603                                                 struct expression *condition)
 604 {
 605         struct expression *iter_var;
 606         struct sm_state *sm;
 607         struct smatch_state *estate;
 608         sval_t start, end, max;
 609         struct symbol *type;
 610 
 611         iter_var = iter_expr->unop;
 612         sm = get_sm_state_expr(SMATCH_EXTRA, iter_var);
 613         if (!sm)
 614                 return NULL;
 615         if (!estate_get_single_value(sm->state, &start))
 616                 return NULL;
 617         if (!get_implied_value(condition->right, &end))
 618                 return NULL;


 619 
 620         if (get_sm_state_expr(SMATCH_EXTRA, condition->left) != sm)
 621                 return NULL;
 622 
 623         switch (condition->op) {
 624         case SPECIAL_UNSIGNED_LT:
 625         case SPECIAL_NOTEQUAL:
 626         case '<':
 627                 if (!sval_is_min(end))
 628                         end.value--;
 629                 break;
 630         case SPECIAL_UNSIGNED_LTE:
 631         case SPECIAL_LTE:
 632                 break;
 633         default:
 634                 return NULL;
 635         }
 636         if (sval_cmp(end, start) < 0)
 637                 return NULL;
 638         type = get_type(iter_var);
 639         start = sval_cast(type, start);
 640         end = sval_cast(type, end);
 641         estate = alloc_estate_range(start, end);
 642         if (get_hard_max(condition->right, &max)) {
 643                 if (!get_macro_name(condition->pos))
 644                         estate_set_hard_max(estate);
 645                 if (condition->op == '<' ||
 646                     condition->op == SPECIAL_UNSIGNED_LT ||
 647                     condition->op == SPECIAL_NOTEQUAL)
 648                         max.value--;
 649                 max = sval_cast(type, max);
 650                 estate_set_fuzzy_max(estate, max);
 651         }
 652         set_extra_expr_mod(iter_var, estate);
 653         return get_sm_state_expr(SMATCH_EXTRA, iter_var);
 654 }
 655 
 656 static struct sm_state *handle_canonical_for_dec(struct expression *iter_expr,
 657                                                 struct expression *condition)
 658 {
 659         struct expression *iter_var;
 660         struct sm_state *sm;
 661         struct smatch_state *estate;
 662         sval_t start, end;
 663 
 664         iter_var = iter_expr->unop;
 665         sm = get_sm_state_expr(SMATCH_EXTRA, iter_var);
 666         if (!sm)
 667                 return NULL;
 668         if (!estate_get_single_value(sm->state, &start))
 669                 return NULL;
 670         if (!get_implied_min(condition->right, &end))
 671                 end = sval_type_min(get_type(iter_var));
 672         end = sval_cast(estate_type(sm->state), end);
 673         if (get_sm_state_expr(SMATCH_EXTRA, condition->left) != sm)
 674                 return NULL;
 675 
 676         switch (condition->op) {
 677         case SPECIAL_NOTEQUAL:
 678         case '>':
 679                 if (!sval_is_max(end))
 680                         end.value++;
 681                 break;
 682         case SPECIAL_GTE:
 683                 break;
 684         default:
 685                 return NULL;
 686         }
 687         if (sval_cmp(end, start) > 0)
 688                 return NULL;
 689         estate = alloc_estate_range(end, start);
 690         estate_set_hard_max(estate);
 691         estate_set_fuzzy_max(estate, estate_get_fuzzy_max(estate));
 692         set_extra_expr_mod(iter_var, estate);
 693         return get_sm_state_expr(SMATCH_EXTRA, iter_var);
 694 }
 695 
 696 static struct sm_state *handle_canonical_for_loops(struct statement *loop)
 697 {
 698         struct expression *iter_expr;
 699         struct expression *condition;


 768         struct expression *iter_expr;
 769         sval_t limit;
 770         struct smatch_state *state;
 771 
 772         if (!iterator) {
 773                 while_count_down_after(sm, condition);
 774                 return;
 775         }
 776 
 777         iter_expr = iterator->expression;
 778 
 779         if (condition->type != EXPR_COMPARE)
 780                 return;
 781         if (iter_expr->op == SPECIAL_INCREMENT) {
 782                 limit = sval_binop(estate_max(sm->state), '+',
 783                                    sval_type_val(estate_type(sm->state), 1));
 784         } else {
 785                 limit = sval_binop(estate_min(sm->state), '-',
 786                                    sval_type_val(estate_type(sm->state), 1));
 787         }
 788         limit = sval_cast(estate_type(sm->state), limit);
 789         if (!estate_has_hard_max(sm->state) && !__has_breaks()) {
 790                 if (iter_expr->op == SPECIAL_INCREMENT)
 791                         state = alloc_estate_range(estate_min(sm->state), limit);
 792                 else
 793                         state = alloc_estate_range(limit, estate_max(sm->state));
 794         } else {
 795                 state = alloc_estate_sval(limit);
 796         }
 797         if (!estate_has_hard_max(sm->state)) {
 798                 estate_clear_hard_max(state);
 799         }
 800         if (estate_has_fuzzy_max(sm->state)) {
 801                 sval_t hmax = estate_get_fuzzy_max(sm->state);
 802                 sval_t max = estate_max(sm->state);
 803 
 804                 if (sval_cmp(hmax, max) != 0)
 805                         estate_clear_fuzzy_max(state);
 806         } else if (!estate_has_fuzzy_max(sm->state)) {
 807                 estate_clear_fuzzy_max(state);
 808         }
 809 
 810         set_extra_mod(sm->name, sm->sym, iter_expr, state);
 811 }
 812 
 813 static bool get_global_rl(const char *name, struct symbol *sym, struct range_list **rl)
 814 {
 815         struct expression *expr;
 816 
 817         if (!sym || !(sym->ctype.modifiers & MOD_TOPLEVEL) || !sym->ident)
 818                 return false;
 819         if (strcmp(sym->ident->name, name) != 0)
 820                 return false;
 821 
 822         expr = symbol_expression(sym);
 823         return get_implied_rl(expr, rl);
 824 }
 825 
 826 static struct stree *unmatched_stree;
 827 static struct smatch_state *unmatched_state(struct sm_state *sm)
 828 {
 829         struct smatch_state *state;
 830         struct range_list *rl;
 831 
 832         if (unmatched_stree) {
 833                 state = get_state_stree(unmatched_stree, SMATCH_EXTRA, sm->name, sm->sym);
 834                 if (state)
 835                         return state;
 836         }
 837         if (parent_is_gone_var_sym(sm->name, sm->sym))
 838                 return alloc_estate_empty();
 839         if (get_global_rl(sm->name, sm->sym, &rl))
 840                 return alloc_estate_rl(rl);
 841         return alloc_estate_whole(estate_type(sm->state));
 842 }
 843 
 844 static void clear_the_pointed_at(struct expression *expr)
 845 {
 846         struct stree *stree;
 847         char *name;
 848         struct symbol *sym;
 849         struct sm_state *tmp;
 850 
 851         name = expr_to_var_sym(expr, &sym);
 852         if (!name || !sym)
 853                 goto free;
 854 
 855         stree = __get_cur_stree();
 856         FOR_EACH_MY_SM(SMATCH_EXTRA, stree, tmp) {
 857                 if (tmp->name[0] != '*')
 858                         continue;
 859                 if (tmp->sym != sym)
 860                         continue;


 886         int param = -1;
 887 
 888         /* if we have the db this is handled in smatch_function_hooks.c */
 889         if (!option_no_db)
 890                 return;
 891         if (inlinable(expr->fn))
 892                 return;
 893 
 894         FOR_EACH_PTR(expr->args, arg) {
 895                 param++;
 896                 if (is_const_param(expr->fn, param))
 897                         continue;
 898                 tmp = strip_expr(arg);
 899                 if (tmp->type == EXPR_PREOP && tmp->op == '&')
 900                         set_extra_expr_mod(tmp->unop, alloc_estate_whole(get_type(tmp->unop)));
 901                 else
 902                         clear_the_pointed_at(tmp);
 903         } END_FOR_EACH_PTR(arg);
 904 }
 905 
 906 int values_fit_type(struct expression *left, struct expression *right)
 907 {
 908         struct range_list *rl;
 909         struct symbol *type;
 910 
 911         type = get_type(left);
 912         if (!type)
 913                 return 0;
 914         get_absolute_rl(right, &rl);
 915         if (type == rl_type(rl))
 916                 return 1;
 917         if (type_unsigned(type) && sval_is_negative(rl_min(rl)))
 918                 return 0;
 919         if (sval_cmp(sval_type_min(type), rl_min(rl)) > 0)
 920                 return 0;
 921         if (sval_cmp(sval_type_max(type), rl_max(rl)) < 0)
 922                 return 0;
 923         return 1;
 924 }
 925 
 926 static void save_chunk_info(struct expression *left, struct expression *right)
 927 {
 928         struct var_sym_list *vsl;
 929         struct var_sym *vs;
 930         struct expression *add_expr;
 931         struct symbol *type;
 932         sval_t sval;
 933         char *name;
 934         struct symbol *sym;
 935 
 936         if (right->type != EXPR_BINOP || right->op != '-')


1024                 struct smatch_state *right_state;
1025                 sval_t sval;
1026 
1027                 if (get_value(right, &sval)) {
1028                         sval = sval_cast(left_type, sval);
1029                         state = alloc_estate_sval(sval);
1030                         goto done;
1031                 }
1032 
1033                 right_state = get_state(SMATCH_EXTRA, right_name, right_sym);
1034                 if (right_state) {
1035                         /* simple assignment */
1036                         state = clone_estate(right_state);
1037                         goto done;
1038                 }
1039 
1040                 state = alloc_estate_rl(alloc_whole_rl(left_type));
1041                 goto done;
1042         }
1043 
1044         comparison = get_comparison_no_extra(left, right);
1045         if (comparison) {
1046                 comparison = flip_comparison(comparison);
1047                 get_implied_rl(left, &orig_rl);
1048         }
1049 
1050         if (get_implied_rl(right, &rl)) {
1051                 rl = cast_rl(left_type, rl);
1052                 if (orig_rl)
1053                         filter_by_comparison(&rl, comparison, orig_rl);
1054                 state = alloc_estate_rl(rl);
1055                 if (get_hard_max(right, &max)) {
1056                         estate_set_hard_max(state);
1057                         estate_set_fuzzy_max(state, max);
1058                 }
1059         } else {
1060                 rl = alloc_whole_rl(right_type);
1061                 rl = cast_rl(left_type, rl);
1062                 if (orig_rl)
1063                         filter_by_comparison(&rl, comparison, orig_rl);
1064                 state = alloc_estate_rl(rl);
1065         }
1066 
1067 done:
1068         set_extra_mod(name, sym, left, state);
1069 free:
1070         free_string(right_name);
1071 }
1072 




























1073 static void match_assign(struct expression *expr)
1074 {
1075         struct range_list *rl = NULL;
1076         struct expression *left;
1077         struct expression *right;
1078         struct expression *binop_expr;
1079         struct symbol *left_type;
1080         struct symbol *sym;
1081         char *name;



1082 
1083         left = strip_expr(expr->left);
1084 
1085         right = strip_parens(expr->right);
1086         if (right->type == EXPR_CALL && sym_name_is("__builtin_expect", right->fn))
1087                 right = get_argument_from_call_expr(right->args, 0);
1088         while (right->type == EXPR_ASSIGNMENT && right->op == '=')
1089                 right = strip_parens(right->left);
1090 
1091         if (expr->op == '=' && is_condition(expr->right))
1092                 return; /* handled in smatch_condition.c */
1093         if (expr->op == '=' && right->type == EXPR_CALL)
1094                 return; /* handled in smatch_function_hooks.c */
1095         if (expr->op == '=') {
1096                 match_vanilla_assign(left, right);
1097                 return;
1098         }
1099 
1100         name = expr_to_var_sym(left, &sym);
1101         if (!name)
1102                 return;
1103 
1104         left_type = get_type(left);
1105 



1106         switch (expr->op) {
1107         case SPECIAL_ADD_ASSIGN:
















1108         case SPECIAL_SUB_ASSIGN:

















1109         case SPECIAL_AND_ASSIGN:
1110         case SPECIAL_MOD_ASSIGN:
1111         case SPECIAL_SHL_ASSIGN:
1112         case SPECIAL_SHR_ASSIGN:
1113         case SPECIAL_OR_ASSIGN:
1114         case SPECIAL_XOR_ASSIGN:
1115         case SPECIAL_MUL_ASSIGN:
1116         case SPECIAL_DIV_ASSIGN:
1117                 binop_expr = binop_expression(expr->left,
1118                                               op_remove_assign(expr->op),
1119                                               expr->right);
1120                 get_absolute_rl(binop_expr, &rl);
1121                 rl = cast_rl(left_type, rl);
1122                 if (inside_loop()) {
1123                         if (expr->op == SPECIAL_ADD_ASSIGN)
1124                                 add_range(&rl, rl_max(rl), sval_type_max(rl_type(rl)));
1125 
1126                         if (expr->op == SPECIAL_SUB_ASSIGN &&
1127                             !sval_is_negative(rl_min(rl))) {
1128                                 sval_t zero = { .type = rl_type(rl) };
1129 
1130                                 add_range(&rl, rl_min(rl), zero);
1131                         }

1132                 }

1133                 set_extra_mod(name, sym, left, alloc_estate_rl(rl));
1134                 goto free;
1135         }
1136         set_extra_mod(name, sym, left, alloc_estate_whole(left_type));
1137 free:
1138         free_string(name);
1139 }
1140 
1141 static struct smatch_state *increment_state(struct smatch_state *state)
1142 {
1143         sval_t min = estate_min(state);
1144         sval_t max = estate_max(state);
1145 
1146         if (!estate_rl(state))
1147                 return NULL;
1148 
1149         if (inside_loop())
1150                 max = sval_type_max(max.type);
1151 
1152         if (!sval_is_min(min) && !sval_is_max(min))
1153                 min.value++;
1154         if (!sval_is_min(max) && !sval_is_max(max))
1155                 max.value++;
1156         return alloc_estate_range(min, max);


1248         } END_FOR_EACH_PTR(expr);
1249 }
1250 
1251 static void check_dereference(struct expression *expr)
1252 {
1253         struct smatch_state *state;
1254 
1255         if (__in_fake_assign)
1256                 return;
1257         if (outside_of_function())
1258                 return;
1259         state = get_extra_state(expr);
1260         if (state) {
1261                 struct range_list *rl;
1262 
1263                 rl = rl_intersection(estate_rl(state), valid_ptr_rl);
1264                 if (rl_equiv(rl, estate_rl(state)))
1265                         return;
1266                 set_extra_expr_nomod(expr, alloc_estate_rl(rl));
1267         } else {
1268                 struct range_list *rl;
1269 
1270                 if (get_mtag_rl(expr, &rl))
1271                         rl = rl_intersection(rl, valid_ptr_rl);
1272                 else
1273                         rl = clone_rl(valid_ptr_rl);
1274 
1275                 set_extra_expr_nomod(expr, alloc_estate_rl(rl));
1276         }
1277 }
1278 
1279 static void match_dereferences(struct expression *expr)
1280 {
1281         if (expr->type != EXPR_PREOP)
1282                 return;
1283         /* it's saying that foo[1] = bar dereferences foo[1] */
1284         if (is_array(expr))
1285                 return;
1286         check_dereference(expr->unop);
1287 }
1288 
1289 static void match_pointer_as_array(struct expression *expr)
1290 {
1291         if (!is_array(expr))
1292                 return;
1293         check_dereference(get_array_base(expr));
1294 }
1295 


1323                 }
1324 
1325                 set_extra_nomod(name, sym, NULL, new);
1326         }
1327         free_string(name);
1328 
1329         find_dereferences(arg);
1330 }
1331 
1332 static sval_t add_one(sval_t sval)
1333 {
1334         sval.value++;
1335         return sval;
1336 }
1337 
1338 static int handle_postop_inc(struct expression *left, int op, struct expression *right)
1339 {
1340         struct statement *stmt;
1341         struct expression *cond;
1342         struct smatch_state *true_state, *false_state;
1343         struct symbol *type;
1344         sval_t start;
1345         sval_t limit;
1346 
1347         /*
1348          * If we're decrementing here then that's a canonical while count down
1349          * so it's handled already.  We're only handling loops like:
1350          * i = 0;
1351          * do { ... } while (i++ < 3);
1352          */
1353 
1354         if (left->type != EXPR_POSTOP || left->op != SPECIAL_INCREMENT)
1355                 return 0;
1356 
1357         stmt = __cur_stmt->parent;
1358         if (!stmt)
1359                 return 0;
1360         if (stmt->type == STMT_COMPOUND)
1361                 stmt = stmt->parent;
1362         if (!stmt || stmt->type != STMT_ITERATOR || !stmt->iterator_post_condition)
1363                 return 0;
1364 
1365         cond = strip_expr(stmt->iterator_post_condition);
1366         if (cond->type != EXPR_COMPARE || cond->op != op)
1367                 return 0;
1368         if (left != strip_expr(cond->left) || right != strip_expr(cond->right))
1369                 return 0;
1370 
1371         if (!get_implied_value(left->unop, &start))
1372                 return 0;
1373         if (!get_implied_value(right, &limit))
1374                 return 0;
1375         type = get_type(left->unop);
1376         limit = sval_cast(type, limit);
1377         if (sval_cmp(start, limit) > 0)
1378                 return 0;
1379 
1380         switch (op) {
1381         case '<':
1382         case SPECIAL_UNSIGNED_LT:
1383                 break;
1384         case SPECIAL_LTE:
1385         case SPECIAL_UNSIGNED_LTE:
1386                 limit = add_one(limit);
1387         default:
1388                 return 0;
1389 
1390         }
1391 
1392         true_state = alloc_estate_range(add_one(start), limit);
1393         false_state = alloc_estate_range(add_one(limit), add_one(limit));
1394 
1395         /* Currently we just discard the false state but when two passes is
1396          * implimented correctly then it will use it.
1397          */
1398 
1399         set_extra_expr_true_false(left->unop, true_state, false_state);
1400 
1401         return 1;
1402 }
1403 
1404 bool is_impossible_variable(struct expression *expr)
1405 {
1406         struct smatch_state *state;
1407 
1408         state = get_extra_state(expr);
1409         if (state && !estate_rl(state))
1410                 return true;
1411         return false;
1412 }
1413 
1414 static bool in_macro(struct expression *left, struct expression *right)
1415 {
1416         if (!left || !right)
1417                 return 0;
1418         if (left->pos.line != right->pos.line || left->pos.pos != right->pos.pos)
1419                 return 0;
1420         if (get_macro_name(left->pos))
1421                 return 1;
1422         return 0;
1423 }
1424 
1425 static void handle_comparison(struct symbol *type, struct expression *left, int op, struct expression *right)
1426 {
1427         struct range_list *left_orig;
1428         struct range_list *left_true;
1429         struct range_list *left_false;
1430         struct range_list *right_orig;
1431         struct range_list *right_true;
1432         struct range_list *right_false;
1433         struct smatch_state *left_true_state;
1434         struct smatch_state *left_false_state;
1435         struct smatch_state *right_true_state;
1436         struct smatch_state *right_false_state;
1437         sval_t dummy, hard_max;
1438         int left_postop = 0;
1439         int right_postop = 0;
1440 
1441         if (left->op == SPECIAL_INCREMENT || left->op == SPECIAL_DECREMENT) {
1442                 if (left->type == EXPR_POSTOP) {
1443                         left->smatch_flags |= Handled;
1444                         left_postop = left->op;


1487         if (!right_true || !right_false) {
1488                 struct range_list *tmp_true, *tmp_false;
1489 
1490                 split_comparison_rl(alloc_whole_rl(type), op, right_orig, NULL, NULL, &tmp_true, &tmp_false);
1491                 tmp_true = rl_truncate_cast(get_type(strip_expr(right)), tmp_true);
1492                 tmp_false = rl_truncate_cast(get_type(strip_expr(right)), tmp_false);
1493                 if (tmp_true && tmp_false)
1494                         __save_imaginary_state(right, tmp_true, tmp_false);
1495         }
1496 
1497         left_true_state = alloc_estate_rl(left_true);
1498         left_false_state = alloc_estate_rl(left_false);
1499         right_true_state = alloc_estate_rl(right_true);
1500         right_false_state = alloc_estate_rl(right_false);
1501 
1502         switch (op) {
1503         case '<':
1504         case SPECIAL_UNSIGNED_LT:
1505         case SPECIAL_UNSIGNED_LTE:
1506         case SPECIAL_LTE:
1507                 if (get_implied_value(right, &dummy) && !in_macro(left, right))
1508                         estate_set_hard_max(left_true_state);
1509                 if (get_implied_value(left, &dummy) && !in_macro(left, right))
1510                         estate_set_hard_max(right_false_state);
1511                 break;
1512         case '>':
1513         case SPECIAL_UNSIGNED_GT:
1514         case SPECIAL_UNSIGNED_GTE:
1515         case SPECIAL_GTE:
1516                 if (get_implied_value(left, &dummy) && !in_macro(left, right))
1517                         estate_set_hard_max(right_true_state);
1518                 if (get_implied_value(right, &dummy) && !in_macro(left, right))
1519                         estate_set_hard_max(left_false_state);
1520                 break;
1521         }
1522 
1523         switch (op) {
1524         case '<':
1525         case SPECIAL_UNSIGNED_LT:
1526         case SPECIAL_UNSIGNED_LTE:
1527         case SPECIAL_LTE:
1528                 if (get_hard_max(right, &hard_max)) {
1529                         if (op == '<' || op == SPECIAL_UNSIGNED_LT)
1530                                 hard_max.value--;
1531                         estate_set_fuzzy_max(left_true_state, hard_max);
1532                 }
1533                 if (get_implied_value(right, &hard_max)) {
1534                         if (op == SPECIAL_UNSIGNED_LTE ||
1535                             op == SPECIAL_LTE)
1536                                 hard_max.value++;
1537                         estate_set_fuzzy_max(left_false_state, hard_max);
1538                 }


1632 
1633         set_extra_expr_true_false(left, left_true_state, left_false_state);
1634         set_extra_expr_true_false(right, right_true_state, right_false_state);
1635 }
1636 
1637 static int is_simple_math(struct expression *expr)
1638 {
1639         if (!expr)
1640                 return 0;
1641         if (expr->type != EXPR_BINOP)
1642                 return 0;
1643         switch (expr->op) {
1644         case '+':
1645         case '-':
1646         case '*':
1647                 return 1;
1648         }
1649         return 0;
1650 }
1651 
1652 static int flip_op(int op)
1653 {
1654         /* We only care about simple math */
1655         switch (op) {
1656         case '+':
1657                 return '-';
1658         case '-':
1659                 return '+';
1660         case '*':
1661                 return '/';
1662         }
1663         return 0;
1664 }
1665 
1666 static void move_known_to_rl(struct expression **expr_p, struct range_list **rl_p)
1667 {
1668         struct expression *expr = *expr_p;
1669         struct range_list *rl = *rl_p;
1670         sval_t sval;
1671 
1672         if (!is_simple_math(expr))
1673                 return;
1674 
1675         if (get_implied_value(expr->right, &sval)) {
1676                 *expr_p = expr->left;
1677                 *rl_p = rl_binop(rl, flip_op(expr->op), alloc_rl(sval, sval));
1678                 move_known_to_rl(expr_p, rl_p);
1679                 return;
1680         }
1681         if (expr->op == '-')
1682                 return;
1683         if (get_implied_value(expr->left, &sval)) {
1684                 *expr_p = expr->right;
1685                 *rl_p = rl_binop(rl, flip_op(expr->op), alloc_rl(sval, sval));
1686                 move_known_to_rl(expr_p, rl_p);
1687                 return;
1688         }
1689 }
1690 
1691 static void move_known_values(struct expression **left_p, struct expression **right_p)
1692 {
1693         struct expression *left = *left_p;
1694         struct expression *right = *right_p;
1695         sval_t sval, dummy;
1696 
1697         if (get_implied_value(left, &sval)) {
1698                 if (!is_simple_math(right))
1699                         return;
1700                 if (get_implied_value(right, &dummy))
1701                         return;
1702                 if (right->op == '*') {
1703                         sval_t divisor;
1704 
1705                         if (!get_value(right->right, &divisor))
1706                                 return;
1707                         if (divisor.value == 0)
1708                                 return;
1709                         *left_p = binop_expression(left, invert_op(right->op), right->right);
1710                         *right_p = right->left;


1779             !is_whole_rl(rl)) {
1780                 *right_p = binop_expression(right, '-', left->left);
1781                 *left_p = left->right;
1782                 return 1;
1783         }
1784         if (!get_implied_value(left->right, &tmp) &&
1785             get_implied_rl(left->right, &rl) &&
1786             !is_whole_rl(rl)) {
1787                 *right_p = binop_expression(right, '-', left->right);
1788                 *left_p = left->left;
1789                 return 1;
1790         }
1791 
1792         return 0;
1793 }
1794 
1795 static int match_func_comparison(struct expression *expr)
1796 {
1797         struct expression *left = strip_expr(expr->left);
1798         struct expression *right = strip_expr(expr->right);

1799 
1800         if (left->type == EXPR_CALL || right->type == EXPR_CALL) {











1801                 function_comparison(left, expr->op, right);
1802                 return 1;
1803         }
1804 









1805         return 0;
1806 }
1807 
1808 /* Handle conditions like "if (foo + bar < foo) {" */
1809 static int handle_integer_overflow_test(struct expression *expr)
1810 {
1811         struct expression *left, *right;
1812         struct symbol *type;
1813         sval_t left_min, right_min, min, max;
1814 
1815         if (expr->op != '<' && expr->op != SPECIAL_UNSIGNED_LT)
1816                 return 0;
1817 
1818         left = strip_parens(expr->left);
1819         right = strip_parens(expr->right);
1820 
1821         if (left->op != '+')
1822                 return 0;
1823 
1824         type = get_type(expr);
1825         if (!type)
1826                 return 0;
1827         if (type_positive_bits(type) == 32) {
1828                 max.type = &uint_ctype;
1829                 max.uvalue = (unsigned int)-1;
1830         } else if (type_positive_bits(type) == 64) {
1831                 max.type = &ulong_ctype;
1832                 max.value = (unsigned long long)-1;
1833         } else {
1834                 return 0;
1835         }
1836 
1837         if (!expr_equiv(left->left, right) && !expr_equiv(left->right, right))
1838                 return 0;
1839 
1840         get_absolute_min(left->left, &left_min);
1841         get_absolute_min(left->right, &right_min);
1842         min = sval_binop(left_min, '+', right_min);
1843 
1844         type = get_type(left);
1845         min = sval_cast(type, min);
1846         max = sval_cast(type, max);
1847 
1848         set_extra_chunk_true_false(left, NULL, alloc_estate_range(min, max));
1849         return 1;
1850 }
1851 
1852 static void match_comparison(struct expression *expr)
1853 {
1854         struct expression *left_orig = strip_parens(expr->left);
1855         struct expression *right_orig = strip_parens(expr->right);
1856         struct expression *left, *right, *tmp;
1857         struct expression *prev;
1858         struct symbol *type;
1859         int redo, count;
1860 
1861         if (match_func_comparison(expr))
1862                 return;
1863 
1864         type = get_type(expr);
1865         if (!type)
1866                 type = &llong_ctype;
1867 


1926 }
1927 
1928 static sval_t get_high_mask(sval_t known)
1929 {
1930         sval_t ret;
1931         int i;
1932 
1933         ret = known;
1934         ret.value = 0;
1935 
1936         for (i = type_bits(known.type) - 1; i >= 0; i--) {
1937                 if (known.uvalue & (1ULL << i))
1938                         ret.uvalue |= (1ULL << i);
1939                 else
1940                         return ret;
1941 
1942         }
1943         return ret;
1944 }
1945 
1946 static bool handle_bit_test(struct expression *expr)
1947 {
1948         struct range_list *orig_rl, *rl;
1949         struct expression *shift, *mask, *var;
1950         struct bit_info *bit_info;
1951         sval_t sval;
1952         sval_t high = { .type = &int_ctype };
1953         sval_t low = { .type = &int_ctype };
1954 
1955         shift = strip_expr(expr->right);
1956         mask = strip_expr(expr->left);
1957         if (shift->type != EXPR_BINOP || shift->op != SPECIAL_LEFTSHIFT) {
1958                 shift = strip_expr(expr->left);
1959                 mask = strip_expr(expr->right);
1960                 if (shift->type != EXPR_BINOP || shift->op != SPECIAL_LEFTSHIFT)
1961                         return false;
1962         }
1963         if (!get_implied_value(shift->left, &sval) || sval.value != 1)
1964                 return false;
1965         var = strip_expr(shift->right);
1966 
1967         bit_info = get_bit_info(mask);
1968         if (!bit_info)
1969                 return false;
1970         if (!bit_info->possible)
1971                 return false;
1972 
1973         get_absolute_rl(var, &orig_rl);
1974         if (sval_is_negative(rl_min(orig_rl)) ||
1975             rl_max(orig_rl).uvalue > type_bits(get_type(shift->left)))
1976                 return false;
1977 
1978         low.value = ffsll(bit_info->possible);
1979         high.value = sm_fls64(bit_info->possible);
1980         rl = alloc_rl(low, high);
1981         rl = cast_rl(get_type(var), rl);
1982         rl = rl_intersection(orig_rl, rl);
1983         if (!rl)
1984                 return false;
1985 
1986         set_extra_expr_true_false(shift->right, alloc_estate_rl(rl), NULL);
1987 
1988         return true;
1989 }
1990 
1991 static void handle_AND_op(struct expression *var, sval_t known)
1992 {
1993         struct range_list *orig_rl;
1994         struct range_list *true_rl = NULL;
1995         struct range_list *false_rl = NULL;
1996         int bit;
1997         sval_t low_mask = known;
1998         sval_t high_mask;
1999         sval_t max;
2000 
2001         get_absolute_rl(var, &orig_rl);
2002 
2003         if (known.value > 0) {
2004                 bit = ffsll(known.value) - 1;
2005                 low_mask.uvalue = (1ULL << bit) - 1;
2006                 true_rl = remove_range(orig_rl, sval_type_val(known.type, 0), low_mask);
2007         }
2008         high_mask = get_high_mask(known);
2009         if (high_mask.value) {
2010                 bit = ffsll(high_mask.value) - 1;


2017                 if (type_signed(high_mask.type) && type_unsigned(rl_type(false_rl))) {
2018                         false_rl = remove_range(false_rl,
2019                                                 sval_type_val(rl_type(false_rl), sval_type_max(known.type).uvalue),
2020                                         sval_type_val(rl_type(false_rl), -1));
2021                 }
2022         } else if (known.value == 1 &&
2023                    get_hard_max(var, &max) &&
2024                    sval_cmp(max, rl_max(orig_rl)) == 0 &&
2025                    max.value & 1) {
2026                 false_rl = remove_range(orig_rl, max, max);
2027         }
2028         set_extra_expr_true_false(var,
2029                                   true_rl ? alloc_estate_rl(true_rl) : NULL,
2030                                   false_rl ? alloc_estate_rl(false_rl) : NULL);
2031 }
2032 
2033 static void handle_AND_condition(struct expression *expr)
2034 {
2035         sval_t known;
2036 
2037         if (handle_bit_test(expr))
2038                 return;
2039 
2040         if (get_implied_value(expr->left, &known))
2041                 handle_AND_op(expr->right, known);
2042         else if (get_implied_value(expr->right, &known))
2043                 handle_AND_op(expr->left, known);
2044 }
2045 
2046 static void handle_MOD_condition(struct expression *expr)
2047 {
2048         struct range_list *orig_rl;
2049         struct range_list *true_rl;
2050         struct range_list *false_rl = NULL;
2051         sval_t right;
2052         sval_t zero = { 0, };
2053 
2054         if (!get_implied_value(expr->right, &right) || right.value == 0)
2055                 return;
2056         get_absolute_rl(expr->left, &orig_rl);
2057 
2058         zero.value = 0;
2059         zero.type = rl_type(orig_rl);
2060 
2061         /* We're basically dorking around the min and max here */
2062         true_rl = remove_range(orig_rl, zero, zero);
2063         if (!sval_is_max(rl_max(true_rl)) &&
2064             !(rl_max(true_rl).value % right.value))
2065                 true_rl = remove_range(true_rl, rl_max(true_rl), rl_max(true_rl));
2066 
2067         if (rl_equiv(true_rl, orig_rl))
2068                 true_rl = NULL;
2069 
2070         if (sval_is_positive(rl_min(orig_rl)) &&
2071             (rl_max(orig_rl).value - rl_min(orig_rl).value) / right.value < 5) {
2072                 sval_t add;


2092 
2093                 if (!sval_is_max(rl_max(orig_rl)) &&
2094                     (rl_max(orig_rl).value % right.value)) {
2095                         sval_t chop = rl_max(orig_rl);
2096                         chop.value -= chop.value % right.value;
2097                         chop.value++;
2098                         if (!false_rl)
2099                                 false_rl = clone_rl(orig_rl);
2100                         false_rl = remove_range(false_rl, chop, rl_max(orig_rl));
2101                 }
2102         }
2103 
2104         set_extra_expr_true_false(expr->left,
2105                                   true_rl ? alloc_estate_rl(true_rl) : NULL,
2106                                   false_rl ? alloc_estate_rl(false_rl) : NULL);
2107 }
2108 
2109 /* this is actually hooked from smatch_implied.c...  it's hacky, yes */
2110 void __extra_match_condition(struct expression *expr)
2111 {





2112         expr = strip_expr(expr);
2113         switch (expr->type) {
2114         case EXPR_CALL:
2115                 function_comparison(expr, SPECIAL_NOTEQUAL, zero_expr());
2116                 return;
2117         case EXPR_PREOP:
2118         case EXPR_SYMBOL:
2119         case EXPR_DEREF:
2120                 handle_comparison(get_type(expr), expr, SPECIAL_NOTEQUAL, zero_expr());






2121                 return;












2122         case EXPR_COMPARE:
2123                 match_comparison(expr);
2124                 return;
2125         case EXPR_ASSIGNMENT:
2126                 __extra_match_condition(expr->left);
2127                 return;
2128         case EXPR_BINOP:
2129                 if (expr->op == '&')
2130                         handle_AND_condition(expr);
2131                 if (expr->op == '%')
2132                         handle_MOD_condition(expr);
2133                 return;
2134         }
2135 }
2136 
2137 static void assume_indexes_are_valid(struct expression *expr)
2138 {
2139         struct expression *array_expr;
2140         int array_size;
2141         struct expression *offset;


2234         struct symbol *sym;
2235         char *var;
2236         int ret = 0;
2237 
2238         expr = strip_expr(expr);
2239         var = expr_to_var_sym(expr, &sym);
2240         if (!var || !sym)
2241                 goto free;
2242         ret = parent_is_null_var_sym(var, sym);
2243 free:
2244         free_string(var);
2245         return ret;
2246 }
2247 
2248 static int param_used_callback(void *found, int argc, char **argv, char **azColName)
2249 {
2250         *(int *)found = 1;
2251         return 0;
2252 }
2253 
2254 static int is_kzalloc_info(struct sm_state *sm)
2255 {
2256         sval_t sval;
2257 
2258         /*
2259          * kzalloc() information is treated as special because so there is just
2260          * a lot of stuff initialized to zero and it makes building the database
2261          * take hours and hours.
2262          *
2263          * In theory, we should just remove this line and not pass any unused
2264          * information, but I'm not sure enough that this code works so I want
2265          * to hold off on that for now.
2266          */
2267         if (!estate_get_single_value(sm->state, &sval))
2268                 return 0;
2269         if (sval.value != 0)
2270                 return 0;
2271         return 1;
2272 }
2273 
2274 static int is_really_long(struct sm_state *sm)
2275 {
2276         const char *p;
2277         int cnt = 0;
2278 
2279         p = sm->name;
2280         while ((p = strstr(p, "->"))) {
2281                 p += 2;
2282                 cnt++;
2283         }
2284 
2285         if (cnt < 3 ||
2286             strlen(sm->name) < 40)
2287                 return 0;
2288         return 1;
2289 }
2290 
2291 static int filter_unused_param_value_info(struct expression *call, int param, char *printed_name, struct sm_state *sm)
2292 {
2293         int found = 0;
2294 
2295         /* for function pointers assume everything is used */
2296         if (call->fn->type != EXPR_SYMBOL)
2297                 return 0;
2298 
2299         /*
2300          * This is to handle __builtin_mul_overflow().  In an ideal world we
2301          * would only need this for invalid code.
2302          *
2303          */
2304         if (!call->fn->symbol)
2305                 return 0;
2306 
2307         if (!is_kzalloc_info(sm) && !is_really_long(sm))









2308                 return 0;
2309 
2310         run_sql(&param_used_callback, &found,
2311                 "select * from return_implies where %s and type = %d and parameter = %d and key = '%s';",
2312                 get_static_filter(call->fn->symbol), PARAM_USED, param, printed_name);
2313         if (found)
2314                 return 0;
2315 
2316         /* If the database is not built yet, then assume everything is used */
2317         run_sql(&param_used_callback, &found,
2318                 "select * from return_implies where %s and type = %d;",
2319                 get_static_filter(call->fn->symbol), PARAM_USED);
2320         if (!found)
2321                 return 0;
2322 
2323         return 1;
2324 }
2325 
2326 struct range_list *intersect_with_real_abs_var_sym(const char *name, struct symbol *sym, struct range_list *start)
2327 {


2354 
2355         return rl_intersection(estate_rl(state), start);
2356 }
2357 
2358 struct range_list *intersect_with_real_abs_expr(struct expression *expr, struct range_list *start)
2359 {
2360         struct smatch_state *state;
2361         struct range_list *abs_rl;
2362 
2363         state = get_real_absolute_state(expr);
2364         if (!state || !estate_rl(state))
2365                 return start;
2366 
2367         abs_rl = cast_rl(rl_type(start), estate_rl(state));
2368         return rl_intersection(abs_rl, start);
2369 }
2370 
2371 static void struct_member_callback(struct expression *call, int param, char *printed_name, struct sm_state *sm)
2372 {
2373         struct range_list *rl;
2374         sval_t dummy;
2375 
2376         if (estate_is_whole(sm->state))
2377                 return;
2378         if (filter_unused_param_value_info(call, param, printed_name, sm))
2379                 return;
2380         rl = estate_rl(sm->state);
2381         rl = intersect_with_real_abs_var_sym(sm->name, sm->sym, rl);
2382         sql_insert_caller_info(call, PARAM_VALUE, param, printed_name, show_rl(rl));
2383         if (!estate_get_single_value(sm->state, &dummy)) {
2384                 if (estate_has_hard_max(sm->state))
2385                         sql_insert_caller_info(call, HARD_MAX, param, printed_name,
2386                                                sval_to_str(estate_max(sm->state)));
2387                 if (estate_has_fuzzy_max(sm->state))
2388                         sql_insert_caller_info(call, FUZZY_MAX, param, printed_name,
2389                                                sval_to_str(estate_get_fuzzy_max(sm->state)));
2390         }
2391 }
2392 
2393 static void returned_struct_members(int return_id, char *return_ranges, struct expression *expr)
2394 {
2395         struct symbol *returned_sym;
2396         char *returned_name;
2397         struct sm_state *sm;

2398         char *compare_str;
2399         char name_buf[256];
2400         char val_buf[256];
2401         int len;
2402 
2403         // FIXME handle *$
2404 
2405         if (!is_pointer(expr))
2406                 return;
2407 
2408         returned_name = expr_to_var_sym(expr, &returned_sym);
2409         if (!returned_name || !returned_sym)
2410                 goto free;
2411         len = strlen(returned_name);
2412 
2413         FOR_EACH_MY_SM(my_id, __get_cur_stree(), sm) {
2414                 if (!estate_rl(sm->state))
2415                         continue;
2416                 if (returned_sym != sm->sym)
2417                         continue;
2418                 if (strncmp(returned_name, sm->name, len) != 0)


2419                         continue;
2420                 if (sm->name[len] != '-')
2421                         continue;
2422 
2423                 snprintf(name_buf, sizeof(name_buf), "$%s", sm->name + len);
2424 
2425                 compare_str = name_sym_to_param_comparison(sm->name, sm->sym);
2426                 if (!compare_str && estate_is_whole(sm->state))
2427                         continue;
2428                 snprintf(val_buf, sizeof(val_buf), "%s%s", sm->state->name, compare_str ?: "");
2429 
2430                 sql_insert_return_states(return_id, return_ranges, PARAM_VALUE,
2431                                          -1, name_buf, val_buf);
2432         } END_FOR_EACH_SM(sm);
2433 
2434 free:
2435         free_string(returned_name);
2436 }
2437 
2438 static void db_limited_before(void)
2439 {
2440         unmatched_stree = clone_stree(__get_cur_stree());
2441 }
2442 
2443 static void db_limited_after(void)
2444 {
2445         free_stree(&unmatched_stree);
2446 }
2447 












2448 static int basically_the_same(struct range_list *orig, struct range_list *new)
2449 {
2450         if (rl_equiv(orig, new))
2451                 return 1;
2452 
2453         /*
2454          * The whole range is essentially the same as 0,4096-27777777777 so
2455          * don't overwrite the implications just to store that.
2456          *
2457          */
2458         if (rl_type(orig)->type == SYM_PTR &&
2459             is_whole_rl(orig) &&
2460             rl_min(new).value == 0 &&
2461             rl_max(new).value == valid_ptr_max)
2462                 return 1;
2463         return 0;
2464 }
2465 
2466 static void db_param_limit_binops(struct expression *arg, char *key, struct range_list *rl)
2467 {


2477                 return;
2478 
2479         left_rl = rl_binop(rl, '/', alloc_rl(sval, sval));
2480         if (!rl_has_sval(rl, zero))
2481                 left_rl = remove_range(left_rl, zero, zero);
2482 
2483         set_extra_expr_nomod(arg->left, alloc_estate_rl(left_rl));
2484 }
2485 
2486 static void db_param_limit_filter(struct expression *expr, int param, char *key, char *value, enum info_type op)
2487 {
2488         struct expression *arg;
2489         char *name;
2490         struct symbol *sym;
2491         struct var_sym_list *vsl = NULL;
2492         struct sm_state *sm;
2493         struct symbol *compare_type, *var_type;
2494         struct range_list *rl;
2495         struct range_list *limit;
2496         struct range_list *new;
2497         char *other_name;
2498         struct symbol *other_sym;
2499 
2500         while (expr->type == EXPR_ASSIGNMENT)
2501                 expr = strip_expr(expr->right);
2502         if (expr->type != EXPR_CALL)
2503                 return;
2504 
2505         arg = get_argument_from_call_expr(expr->args, param);
2506         if (!arg)
2507                 return;
2508 
2509         if (strcmp(key, "$") == 0)
2510                 compare_type = get_arg_type(expr->fn, param);
2511         else
2512                 compare_type = get_member_type_from_key(arg, key);
2513 
2514         call_results_to_rl(expr, compare_type, value, &limit);
2515         if (strcmp(key, "$") == 0)
2516                 move_known_to_rl(&arg, &limit);
2517         name = get_chunk_from_key(arg, key, &sym, &vsl);
2518         if (!name)
2519                 return;
2520         if (op != PARAM_LIMIT && !sym)
2521                 goto free;
2522 





2523         sm = get_sm_state(SMATCH_EXTRA, name, sym);
2524         if (sm)
2525                 rl = estate_rl(sm->state);
2526         else
2527                 rl = alloc_whole_rl(compare_type);
2528 
2529         if (op == PARAM_LIMIT && !rl_fits_in_type(rl, compare_type))
2530                 goto free;
2531 

2532         new = rl_intersection(rl, limit);
2533 
2534         var_type = get_member_type_from_key(arg, key);
2535         new = cast_rl(var_type, new);
2536 
2537         /* We want to preserve the implications here */
2538         if (sm && basically_the_same(rl, new))
2539                 goto free;
2540         other_name = get_other_name_sym(name, sym, &other_sym);





2541 
2542         if (op == PARAM_LIMIT)
2543                 set_extra_nomod_vsl(name, sym, vsl, NULL, alloc_estate_rl(new));
2544         else
2545                 set_extra_mod(name, sym, NULL, alloc_estate_rl(new));
2546 
2547         if (other_name && other_sym) {
2548                 if (op == PARAM_LIMIT)
2549                         set_extra_nomod_vsl(other_name, other_sym, vsl, NULL, alloc_estate_rl(new));
2550                 else
2551                         set_extra_mod(other_name, other_sym, NULL, alloc_estate_rl(new));
2552         }
2553 
2554         if (op == PARAM_LIMIT && arg->type == EXPR_BINOP)
2555                 db_param_limit_binops(arg, key, new);
2556 free:
2557         free_string(name);
2558 }
2559 
2560 static void db_param_limit(struct expression *expr, int param, char *key, char *value)
2561 {
2562         db_param_limit_filter(expr, param, key, value, PARAM_LIMIT);
2563 }
2564 
2565 static void db_param_filter(struct expression *expr, int param, char *key, char *value)
2566 {
2567         db_param_limit_filter(expr, param, key, value, PARAM_FILTER);
2568 }
2569 
2570 static void db_param_add_set(struct expression *expr, int param, char *key, char *value, enum info_type op)
2571 {
2572         struct expression *arg;
2573         char *name;
2574         char *other_name = NULL;
2575         struct symbol *sym, *other_sym;
2576         struct symbol *param_type, *arg_type;
2577         struct smatch_state *state;
2578         struct range_list *new = NULL;
2579         struct range_list *added = NULL;
2580 
2581         while (expr->type == EXPR_ASSIGNMENT)
2582                 expr = strip_expr(expr->right);
2583         if (expr->type != EXPR_CALL)
2584                 return;
2585 
2586         arg = get_argument_from_call_expr(expr->args, param);
2587         if (!arg)
2588                 return;
2589 
2590         arg_type = get_arg_type_from_key(expr->fn, param, arg, key);
2591         param_type = get_member_type_from_key(arg, key);
2592         name = get_variable_from_key(arg, key, &sym);
2593         if (!name || !sym)
2594                 goto free;
2595 
2596         state = get_state(SMATCH_EXTRA, name, sym);
2597         if (state)
2598                 new = estate_rl(state);
2599 
2600         call_results_to_rl(expr, arg_type, value, &added);
2601         added = cast_rl(param_type, added);
2602         if (op == PARAM_SET)
2603                 new = added;
2604         else
2605                 new = rl_union(new, added);
2606 
2607         other_name = get_other_name_sym_nostack(name, sym, &other_sym);





2608         set_extra_mod(name, sym, NULL, alloc_estate_rl(new));
2609         if (other_name && other_sym)
2610                 set_extra_mod(other_name, other_sym, NULL, alloc_estate_rl(new));
2611 free:
2612         free_string(other_name);
2613         free_string(name);
2614 }
2615 
2616 static void db_param_add(struct expression *expr, int param, char *key, char *value)
2617 {
2618         in_param_set = true;
2619         db_param_add_set(expr, param, key, value, PARAM_ADD);
2620         in_param_set = false;
2621 }
2622 
2623 static void db_param_set(struct expression *expr, int param, char *key, char *value)
2624 {
2625         in_param_set = true;
2626         db_param_add_set(expr, param, key, value, PARAM_SET);
2627         in_param_set = false;
2628 }
2629 
2630 static void match_lost_param(struct expression *call, int param)
2631 {
2632         struct expression *arg;
2633 
2634         if (is_const_param(call->fn, param))
2635                 return;
2636 
2637         arg = get_argument_from_call_expr(call->args, param);
2638         if (!arg)
2639                 return;
2640 
2641         arg = strip_expr(arg);
2642         if (arg->type == EXPR_PREOP && arg->op == '&')
2643                 set_extra_expr_mod(arg->unop, alloc_estate_whole(get_type(arg->unop)));
2644         else
2645                 ; /* if pointer then set struct members, maybe?*/
2646 }
2647 
2648 static void db_param_value(struct expression *expr, int param, char *key, char *value)
2649 {
2650         struct expression *call;
2651         char *name;
2652         struct symbol *sym;
2653         struct symbol *type;
2654         struct range_list *rl = NULL;
2655 
2656         if (param != -1)
2657                 return;
2658 
2659         call = expr;
2660         while (call->type == EXPR_ASSIGNMENT)
2661                 call = strip_expr(call->right);
2662         if (call->type != EXPR_CALL)
2663                 return;
2664 
2665         type = get_member_type_from_key(expr->left, key);
2666         name = get_variable_from_key(expr->left, key, &sym);
2667         if (!name || !sym)
2668                 goto free;
2669 
2670         call_results_to_rl(call, type, value, &rl);
2671 
2672         set_extra_mod(name, sym, NULL, alloc_estate_rl(rl));
2673 free:
2674         free_string(name);
2675 }
2676 
2677 static void match_call_info(struct expression *expr)
2678 {
2679         struct smatch_state *state;
2680         struct range_list *rl = NULL;
2681         struct expression *arg;
2682         struct symbol *type;
2683         sval_t dummy;
2684         int i = 0;
2685 
2686         FOR_EACH_PTR(expr->args, arg) {
2687                 type = get_arg_type(expr->fn, i);
2688 
2689                 get_absolute_rl(arg, &rl);
2690                 rl = cast_rl(type, rl);
2691 
2692                 if (!is_whole_rl(rl)) {
2693                         rl = intersect_with_real_abs_expr(arg, rl);
2694                         sql_insert_caller_info(expr, PARAM_VALUE, i, "$", show_rl(rl));
2695                 }
2696                 state = get_state_expr(SMATCH_EXTRA, arg);
2697                 if (!estate_get_single_value(state, &dummy) && estate_has_hard_max(state)) {
2698                         sql_insert_caller_info(expr, HARD_MAX, i, "$",
2699                                                sval_to_str(estate_max(state)));
2700                 }
2701                 if (estate_has_fuzzy_max(state)) {
2702                         sql_insert_caller_info(expr, FUZZY_MAX, i, "$",
2703                                                sval_to_str(estate_get_fuzzy_max(state)));
2704                 }
2705                 i++;
2706         } END_FOR_EACH_PTR(arg);
2707 }
2708 
2709 static void set_param_value(const char *name, struct symbol *sym, char *key, char *value)
2710 {
2711         struct expression *expr;
2712         struct range_list *rl = NULL;
2713         struct smatch_state *state;
2714         struct symbol *type;
2715         char fullname[256];
2716         char *key_orig = key;
2717         bool add_star = false;
2718         sval_t dummy;
2719 
2720         if (key[0] == '*') {
2721                 add_star = true;
2722                 key++;
2723         }


2724 
2725         snprintf(fullname, 256, "%s%s%s", add_star ? "*" : "", name, key + 1);
2726 
2727         expr = symbol_expression(sym);
2728         type = get_member_type_from_key(expr, key_orig);
2729         str_to_rl(type, value, &rl);
2730         state = alloc_estate_rl(rl);
2731         if (estate_get_single_value(state, &dummy))
2732                 estate_set_hard_max(state);
2733         set_state(SMATCH_EXTRA, fullname, sym, state);
2734 }
2735 
2736 static void set_param_fuzzy_max(const char *name, struct symbol *sym, char *key, char *value)
2737 {
2738         struct range_list *rl = NULL;
2739         struct smatch_state *state;
2740         struct symbol *type;
2741         char fullname[256];
2742         sval_t max;
2743 
2744         if (strcmp(key, "*$") == 0)
2745                 snprintf(fullname, sizeof(fullname), "*%s", name);
2746         else if (strncmp(key, "$", 1) == 0)
2747                 snprintf(fullname, 256, "%s%s", name, key + 1);
2748         else
2749                 return;
2750 
2751         state = get_state(SMATCH_EXTRA, fullname, sym);
2752         if (!state)
2753                 return;
2754         type = estate_type(state);
2755         str_to_rl(type, value, &rl);
2756         if (!rl_to_sval(rl, &max))
2757                 return;
2758         estate_set_fuzzy_max(state, max);
2759 }
2760 
2761 static void set_param_hard_max(const char *name, struct symbol *sym, char *key, char *value)
2762 {
2763         struct smatch_state *state;
2764         char fullname[256];
2765 
2766         if (strcmp(key, "*$") == 0)
2767                 snprintf(fullname, sizeof(fullname), "*%s", name);
2768         else if (strncmp(key, "$", 1) == 0)
2769                 snprintf(fullname, 256, "%s%s", name, key + 1);
2770         else
2771                 return;
2772 
2773         state = get_state(SMATCH_EXTRA, fullname, sym);
2774         if (!state)
2775                 return;
2776         estate_set_hard_max(state);
2777 }
2778 
2779 struct sm_state *get_extra_sm_state(struct expression *expr)
2780 {
2781         char *name;
2782         struct symbol *sym;
2783         struct sm_state *ret = NULL;
2784 
2785         name = expr_to_known_chunk_sym(expr, &sym);
2786         if (!name)
2787                 goto free;
2788 
2789         ret = get_sm_state(SMATCH_EXTRA, name, sym);
2790 free:
2791         free_string(name);
2792         return ret;
2793 }
2794 
2795 struct smatch_state *get_extra_state(struct expression *expr)
2796 {
2797         struct sm_state *sm;
2798 
2799         sm = get_extra_sm_state(expr);
2800         if (!sm)
2801                 return NULL;
2802         return sm->state;
2803 }
2804 
2805 void register_smatch_extra(int id)
2806 {
2807         my_id = id;
2808 
2809         set_dynamic_states(my_id);
2810         add_merge_hook(my_id, &merge_estates);
2811         add_unmatched_state_hook(my_id, &unmatched_state);
2812         select_caller_info_hook(set_param_value, PARAM_VALUE);
2813         select_caller_info_hook(set_param_fuzzy_max, FUZZY_MAX);
2814         select_caller_info_hook(set_param_hard_max, HARD_MAX);
2815         select_return_states_before(&db_limited_before);
2816         select_return_states_hook(PARAM_LIMIT, &db_param_limit);
2817         select_return_states_hook(PARAM_FILTER, &db_param_filter);
2818         select_return_states_hook(PARAM_ADD, &db_param_add);
2819         select_return_states_hook(PARAM_SET, &db_param_set);
2820         add_lost_param_hook(&match_lost_param);
2821         select_return_states_hook(PARAM_VALUE, &db_param_value);
2822         select_return_states_after(&db_limited_after);
2823 }
2824 
2825 static void match_link_modify(struct sm_state *sm, struct expression *mod_expr)
2826 {
2827         struct var_sym_list *links;
2828         struct var_sym *tmp;
2829         struct smatch_state *state;
2830 
2831         links = sm->state->data;
2832 
2833         FOR_EACH_PTR(links, tmp) {
2834                 if (sm->sym == tmp->sym &&
2835                     strcmp(sm->name, tmp->var) == 0)
2836                         continue;
2837                 state = get_state(SMATCH_EXTRA, tmp->var, tmp->sym);
2838                 if (!state)
2839                         continue;
2840                 set_state(SMATCH_EXTRA, tmp->var, tmp->sym, alloc_estate_whole(estate_type(state)));
2841         } END_FOR_EACH_PTR(tmp);
2842         set_state(link_id, sm->name, sm->sym, &undefined);
2843 }
2844 
2845 void register_smatch_extra_links(int id)
2846 {
2847         link_id = id;
2848         set_dynamic_states(link_id);
2849 }
2850 
2851 void register_smatch_extra_late(int id)
2852 {
2853         add_merge_hook(link_id, &merge_link_states);
2854         add_modification_hook(link_id, &match_link_modify);
2855         add_hook(&match_dereferences, DEREF_HOOK);
2856         add_hook(&match_pointer_as_array, OP_HOOK);
2857         select_return_implies_hook(DEREFERENCE, &set_param_dereferenced);
2858         add_hook(&match_function_call, FUNCTION_CALL_HOOK);
2859         add_hook(&match_assign, ASSIGNMENT_HOOK);
2860         add_hook(&match_assign, GLOBAL_ASSIGNMENT_HOOK);
2861         add_hook(&unop_expr, OP_HOOK);
2862         add_hook(&asm_expr, ASM_HOOK);
2863 
2864         add_hook(&match_call_info, FUNCTION_CALL_HOOK);
2865         add_member_info_callback(my_id, struct_member_callback);
2866         add_split_return_callback(&returned_struct_members);
2867 
2868 //      add_hook(&assume_indexes_are_valid, OP_HOOK);