Print this page
12724 update smatch to 0.6.1-rc1-il-5

Split Close
Expand all
Collapse all
          --- old/usr/src/tools/smatch/src/smatch_function_hooks.c
          +++ new/usr/src/tools/smatch/src/smatch_function_hooks.c
↓ open down ↓ 349 lines elided ↑ open up ↑
 350  350          *implied_false = false_states;
 351  351  }
 352  352  
 353  353  struct db_callback_info {
 354  354          int true_side;
 355  355          int comparison;
 356  356          struct expression *expr;
 357  357          struct range_list *rl;
 358  358          int left;
 359  359          struct stree *stree;
      360 +        struct stree *implied;
 360  361          struct db_implies_list *callbacks;
 361  362          int prev_return_id;
 362  363          int cull;
 363  364          int has_states;
 364  365          char *ret_str;
 365  366          struct smatch_state *ret_state;
 366  367          struct expression *var_expr;
 367  368          int handled;
 368  369  };
 369  370  
      371 +static void set_implied_states(struct db_callback_info *db_info)
      372 +{
      373 +        struct sm_state *sm;
      374 +
      375 +        FOR_EACH_SM(db_info->implied, sm) {
      376 +                __set_sm(sm);
      377 +        } END_FOR_EACH_SM(sm);
      378 +
      379 +        free_stree(&db_info->implied);
      380 +}
      381 +
 370  382  static void store_return_state(struct db_callback_info *db_info, const char *ret_str, struct smatch_state *state)
 371  383  {
 372  384          db_info->ret_str = alloc_sname(ret_str),
 373  385          db_info->ret_state = state;
 374  386  }
 375  387  
 376  388  static bool fake_a_param_assignment(struct expression *expr, const char *return_str, struct smatch_state *orig)
 377  389  {
 378  390          struct expression *arg, *left, *right, *tmp, *fake_assign;
 379  391          char *p;
↓ open down ↓ 73 lines elided ↑ open up ↑
 453  465                  if (estate_rl(faked)) {
 454  466                          rl = rl_intersection(estate_rl(faked), estate_rl(orig));
 455  467                          if (rl)
 456  468                                  set_extra_expr_nomod(expr, alloc_estate_rl(rl));
 457  469                  }
 458  470          }
 459  471  
 460  472          return true;
 461  473  }
 462  474  
      475 +static void set_fresh_mtag_returns(struct db_callback_info *db_info)
      476 +{
      477 +        struct expression *expr = db_info->expr->left;
      478 +        struct smatch_state *state;
      479 +
      480 +        if (!db_info->ret_state)
      481 +                return;
      482 +
      483 +        state = alloc_estate_rl(cast_rl(get_type(expr), clone_rl(estate_rl(db_info->ret_state))));
      484 +        state = get_mtag_return(db_info->expr, state);
      485 +        if (!state)
      486 +                return;
      487 +
      488 +        set_real_absolute(expr, state);
      489 +        set_extra_expr_mod(expr, state);
      490 +
      491 +        db_info->ret_state = NULL;
      492 +        db_info->ret_str = NULL;
      493 +}
      494 +
 463  495  static void set_return_assign_state(struct db_callback_info *db_info)
 464  496  {
 465  497          struct expression *expr = db_info->expr->left;
 466  498          struct smatch_state *state;
 467  499  
 468  500          if (!db_info->ret_state)
 469  501                  return;
 470  502  
 471  503          state = alloc_estate_rl(cast_rl(get_type(expr), clone_rl(estate_rl(db_info->ret_state))));
 472  504          if (!fake_a_param_assignment(db_info->expr, db_info->ret_str, state))
↓ open down ↓ 155 lines elided ↑ open up ↑
 628  660          return_id = atoi(argv[0]);
 629  661          ret_str = argv[1];
 630  662          type = atoi(argv[2]);
 631  663          param = atoi(argv[3]);
 632  664          key = argv[4];
 633  665          value = argv[5];
 634  666  
 635  667          db_info->has_states = 1;
 636  668          if (db_info->prev_return_id != -1 && type == INTERNAL) {
 637  669                  set_other_side_state(db_info);
      670 +                set_implied_states(db_info);
 638  671                  stree = __pop_fake_cur_stree();
 639      -
 640  672                  if (!db_info->cull)
 641  673                          merge_fake_stree(&db_info->stree, stree);
 642  674                  free_stree(&stree);
 643  675                  __push_fake_cur_stree();
 644  676                  db_info->cull = 0;
 645  677          }
 646  678          db_info->prev_return_id = return_id;
 647  679  
 648  680          if (type == INTERNAL && func_type_mismatch(db_info->expr, value))
 649  681                  db_info->cull = 1;
↓ open down ↓ 15 lines elided ↑ open up ↑
 665  697                  ret_range = alloc_whole_rl(get_type(db_info->expr));
 666  698  
 667  699          comparison = db_info->comparison;
 668  700          if (db_info->left)
 669  701                  comparison = flip_comparison(comparison);
 670  702  
 671  703          if (db_info->true_side) {
 672  704                  if (!possibly_true_rl(var_rl, comparison, ret_range))
 673  705                          return 0;
 674  706                  if (type == PARAM_LIMIT)
 675      -                        param_limit_implications(db_info->expr, param, key, value);
      707 +                        param_limit_implications(db_info->expr, param, key, value, &db_info->implied);
 676  708                  filter_by_comparison(&var_rl, comparison, ret_range);
 677  709                  filter_by_comparison(&ret_range, flip_comparison(comparison), var_rl);
 678  710          } else {
 679  711                  if (!possibly_false_rl(var_rl, comparison, ret_range))
 680  712                          return 0;
 681  713                  if (type == PARAM_LIMIT)
 682      -                        param_limit_implications(db_info->expr, param, key, value);
      714 +                        param_limit_implications(db_info->expr, param, key, value, &db_info->implied);
 683  715                  filter_by_comparison(&var_rl, negate_comparison(comparison), ret_range);
 684  716                  filter_by_comparison(&ret_range, flip_comparison(negate_comparison(comparison)), var_rl);
 685  717          }
 686  718  
 687  719          handle_ret_equals_param(ret_str, ret_range, db_info->expr);
 688  720  
 689  721          if (type == INTERNAL) {
 690  722                  set_state(-1, "unnull_path", NULL, &true_state);
 691  723                  __add_return_comparison(strip_expr(db_info->expr), ret_str);
 692  724                  __add_return_to_param_mapping(db_info->expr, ret_str);
↓ open down ↓ 44 lines elided ↑ open up ↑
 737  769  
 738  770          call_return_states_before_hooks();
 739  771  
 740  772          db_info.true_side = 1;
 741  773          db_info.stree = NULL;
 742  774          db_info.prev_return_id = -1;
 743  775          __push_fake_cur_stree();
 744  776          sql_select_return_states("return_id, return, type, parameter, key, value",
 745  777                                   call_expr, db_compare_callback, &db_info);
 746  778          set_other_side_state(&db_info);
      779 +        set_implied_states(&db_info);
 747  780          stree = __pop_fake_cur_stree();
 748  781          if (!db_info.cull)
 749  782                  merge_fake_stree(&db_info.stree, stree);
 750  783          free_stree(&stree);
 751  784          true_states = db_info.stree;
 752  785          if (!true_states && db_info.has_states) {
 753  786                  __push_fake_cur_stree();
 754  787                  set_path_impossible();
 755  788                  true_states = __pop_fake_cur_stree();
 756  789          }
↓ open down ↓ 5 lines elided ↑ open up ↑
 762  795          } END_FOR_EACH_SM(sm);
 763  796  
 764  797          db_info.true_side = 0;
 765  798          db_info.stree = NULL;
 766  799          db_info.prev_return_id = -1;
 767  800          db_info.cull = 0;
 768  801          __push_fake_cur_stree();
 769  802          sql_select_return_states("return_id, return, type, parameter, key, value", call_expr,
 770  803                          db_compare_callback, &db_info);
 771  804          set_other_side_state(&db_info);
      805 +        set_implied_states(&db_info);
 772  806          stree = __pop_fake_cur_stree();
 773  807          if (!db_info.cull)
 774  808                  merge_fake_stree(&db_info.stree, stree);
 775  809          free_stree(&stree);
 776  810          false_states = db_info.stree;
 777  811          if (!false_states && db_info.has_states) {
 778  812                  __push_fake_cur_stree();
 779  813                  set_path_impossible();
 780  814                  false_states = __pop_fake_cur_stree();
 781  815          }
↓ open down ↓ 104 lines elided ↑ open up ↑
 886  920          return_id = atoi(argv[0]);
 887  921          ret_str = argv[1];
 888  922          type = atoi(argv[2]);
 889  923          param = atoi(argv[3]);
 890  924          key = argv[4];
 891  925          value = argv[5];
 892  926  
 893  927          if (db_info->prev_return_id != -1 && type == INTERNAL) {
 894  928                  call_ranged_return_hooks(db_info);
 895  929                  set_return_assign_state(db_info);
      930 +                set_implied_states(db_info);
 896  931                  stree = __pop_fake_cur_stree();
 897  932                  if (!db_info->cull)
 898  933                          merge_fake_stree(&db_info->stree, stree);
 899  934                  free_stree(&stree);
 900  935                  __push_fake_cur_stree();
 901  936                  db_info->cull = 0;
 902  937          }
 903  938          db_info->prev_return_id = return_id;
 904  939  
 905  940          if (type == INTERNAL && func_type_mismatch(db_info->expr, value))
↓ open down ↓ 3 lines elided ↑ open up ↑
 909  944          if (type == CULL_PATH) {
 910  945                  db_info->cull = 1;
 911  946                  return 0;
 912  947          }
 913  948          if (is_impossible_data(type, db_info->expr, param, key, value)) {
 914  949                  db_info->cull = 1;
 915  950                  return 0;
 916  951          }
 917  952  
 918  953          if (type == PARAM_LIMIT)
 919      -                param_limit_implications(db_info->expr, param, key, value);
      954 +                param_limit_implications(db_info->expr, param, key, value, &db_info->implied);
 920  955  
 921  956          db_info->handled = 1;
 922  957          call_results_to_rl(db_info->expr->right, get_type(strip_expr(db_info->expr->right)), ret_str, &ret_range);
 923  958          if (!ret_range)
 924  959                  ret_range = alloc_whole_rl(get_type(strip_expr(db_info->expr->right)));
 925  960          ret_range = cast_rl(get_type(db_info->expr->right), ret_range);
 926  961  
 927  962          if (type == INTERNAL) {
 928  963                  set_state(-1, "unnull_path", NULL, &true_state);
 929  964                  __add_return_comparison(strip_expr(db_info->expr->right), ret_str);
 930  965                  __add_comparison_info(db_info->expr->left, strip_expr(db_info->expr->right), ret_str);
 931  966                  __add_return_to_param_mapping(db_info->expr, ret_str);
 932  967                  store_return_state(db_info, ret_str, alloc_estate_rl(ret_range));
      968 +                set_fresh_mtag_returns(db_info);
 933  969          }
 934  970  
 935  971          FOR_EACH_PTR(db_return_states_list, tmp) {
 936  972                  if (tmp->type == type)
 937  973                          tmp->callback(db_info->expr, param, key, value);
 938  974          } END_FOR_EACH_PTR(tmp);
 939  975  
 940  976          return 0;
 941  977  }
 942  978  
↓ open down ↓ 18 lines elided ↑ open up ↑
 961  997                          right, db_assign_return_states_callback, &db_info);
 962  998          if (option_debug) {
 963  999                  sm_msg("%s return_id %d return_ranges %s",
 964 1000                          db_info.cull ? "culled" : "merging",
 965 1001                          db_info.prev_return_id,
 966 1002                          db_info.ret_state ? db_info.ret_state->name : "'<empty>'");
 967 1003          }
 968 1004          if (db_info.handled)
 969 1005                  call_ranged_return_hooks(&db_info);
 970 1006          set_return_assign_state(&db_info);
     1007 +        set_implied_states(&db_info);
 971 1008          stree = __pop_fake_cur_stree();
 972 1009          if (!db_info.cull)
 973 1010                  merge_fake_stree(&db_info.stree, stree);
 974 1011          free_stree(&stree);
 975 1012  
 976 1013          if (!db_info.stree && db_info.cull) { /* this means we culled everything */
 977 1014                  set_extra_expr_mod(expr->left, alloc_estate_whole(get_type(expr->left)));
 978 1015                  set_path_impossible();
 979 1016          }
 980 1017          FOR_EACH_SM(db_info.stree, sm) {
↓ open down ↓ 91 lines elided ↑ open up ↑
1072 1109  
1073 1110          return_id = atoi(argv[0]);
1074 1111          ret_str = argv[1];
1075 1112          type = atoi(argv[2]);
1076 1113          param = atoi(argv[3]);
1077 1114          key = argv[4];
1078 1115          value = argv[5];
1079 1116  
1080 1117          if (db_info->prev_return_id != -1 && type == INTERNAL) {
1081 1118                  call_ranged_return_hooks(db_info);
     1119 +                set_implied_states(db_info);
1082 1120                  stree = __pop_fake_cur_stree();
1083 1121                  if (!db_info->cull)
1084 1122                          merge_fake_stree(&db_info->stree, stree);
1085 1123                  free_stree(&stree);
1086 1124                  __push_fake_cur_stree();
1087 1125                  __unnullify_path();
1088 1126                  db_info->cull = 0;
1089 1127          }
1090 1128          db_info->prev_return_id = return_id;
1091 1129  
↓ open down ↓ 4 lines elided ↑ open up ↑
1096 1134          if (type == CULL_PATH) {
1097 1135                  db_info->cull = 1;
1098 1136                  return 0;
1099 1137          }
1100 1138          if (is_impossible_data(type, db_info->expr, param, key, value)) {
1101 1139                  db_info->cull = 1;
1102 1140                  return 0;
1103 1141          }
1104 1142  
1105 1143          if (type == PARAM_LIMIT)
1106      -                param_limit_implications(db_info->expr, param, key, value);
     1144 +                param_limit_implications(db_info->expr, param, key, value, &db_info->implied);
1107 1145  
1108 1146          call_results_to_rl(db_info->expr, get_type(strip_expr(db_info->expr)), ret_str, &ret_range);
1109 1147          ret_range = cast_rl(get_type(db_info->expr), ret_range);
1110 1148  
1111 1149          if (type == INTERNAL) {
1112 1150                  struct smatch_state *state;
1113 1151  
1114 1152                  set_state(-1, "unnull_path", NULL, &true_state);
1115 1153                  __add_return_comparison(strip_expr(db_info->expr), ret_str);
1116 1154                  __add_return_to_param_mapping(db_info->expr, ret_str);
↓ open down ↓ 30 lines elided ↑ open up ↑
1147 1185          db_info.expr = expr;
1148 1186          db_info.stree = NULL;
1149 1187  
1150 1188          call_return_states_before_hooks();
1151 1189  
1152 1190          __push_fake_cur_stree();
1153 1191          __unnullify_path();
1154 1192          sql_select_return_states("return_id, return, type, parameter, key, value",
1155 1193                          expr, db_return_states_callback, &db_info);
1156 1194          call_ranged_return_hooks(&db_info);
     1195 +        set_implied_states(&db_info);
1157 1196          stree = __pop_fake_cur_stree();
1158 1197          if (!db_info.cull)
1159 1198                  merge_fake_stree(&db_info.stree, stree);
1160 1199          free_stree(&stree);
1161 1200  
1162 1201          FOR_EACH_SM(db_info.stree, sm) {
1163 1202                  __set_sm(sm);
1164 1203          } END_FOR_EACH_SM(sm);
1165 1204  
1166 1205          free_stree(&db_info.stree);
↓ open down ↓ 98 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX