Print this page
new smatch

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 ↓ 365 lines elided ↑ open up ↑
 366  366          struct expression *var_expr;
 367  367          int handled;
 368  368  };
 369  369  
 370  370  static void store_return_state(struct db_callback_info *db_info, const char *ret_str, struct smatch_state *state)
 371  371  {
 372  372          db_info->ret_str = alloc_sname(ret_str),
 373  373          db_info->ret_state = state;
 374  374  }
 375  375  
 376      -static bool fake_a_param_assignment(struct expression *expr, const char *return_str)
      376 +static bool fake_a_param_assignment(struct expression *expr, const char *return_str, struct smatch_state *orig)
 377  377  {
 378  378          struct expression *arg, *left, *right, *tmp, *fake_assign;
 379  379          char *p;
 380  380          int param;
 381  381          char buf[256];
 382  382          char *str;
 383  383  
 384  384          if (expr->type != EXPR_ASSIGNMENT || expr->op != '=')
 385  385                  return false;
 386  386          left = expr->left;
↓ open down ↓ 43 lines elided ↑ open up ↑
 430  430                  return false;
 431  431          free_string(str);
 432  432  
 433  433          right = gen_expression_from_key(arg, buf);
 434  434          if (!right)  /* Mostly fails for binops like [$0 + 4032] */
 435  435                  return false;
 436  436          fake_assign = assign_expression(left, '=', right);
 437  437          __in_fake_parameter_assign++;
 438  438          __split_expr(fake_assign);
 439  439          __in_fake_parameter_assign--;
      440 +
      441 +        /*
      442 +         * If the return is "0-65531[$0->nla_len - 4]" the faked expression
      443 +         * is maybe (-4)-65531 but we know it is in the 0-65531 range so both
      444 +         * parts have to be considered.  We use _nomod() because it's not really
      445 +         * another modification, it's just a clarification.
      446 +         *
      447 +         */
      448 +        if (estate_rl(orig)) {
      449 +                struct smatch_state *faked;
      450 +                struct range_list *rl;
      451 +
      452 +                faked = get_extra_state(left);
      453 +                if (estate_rl(faked)) {
      454 +                        rl = rl_intersection(estate_rl(faked), estate_rl(orig));
      455 +                        if (rl)
      456 +                                set_extra_expr_nomod(expr, alloc_estate_rl(rl));
      457 +                }
      458 +        }
      459 +
 440  460          return true;
 441  461  }
 442  462  
 443  463  static void set_return_assign_state(struct db_callback_info *db_info)
 444  464  {
 445  465          struct expression *expr = db_info->expr->left;
 446  466          struct smatch_state *state;
 447  467  
 448  468          if (!db_info->ret_state)
 449  469                  return;
 450  470  
 451  471          state = alloc_estate_rl(cast_rl(get_type(expr), clone_rl(estate_rl(db_info->ret_state))));
 452      -        set_extra_expr_mod(expr, state);
      472 +        if (!fake_a_param_assignment(db_info->expr, db_info->ret_str, state))
      473 +                set_extra_expr_mod(expr, state);
      474 +
 453  475          db_info->ret_state = NULL;
 454      -        fake_a_param_assignment(db_info->expr, db_info->ret_str);
 455  476          db_info->ret_str = NULL;
 456  477  }
 457  478  
 458  479  static void set_other_side_state(struct db_callback_info *db_info)
 459  480  {
 460  481          struct expression *expr = db_info->var_expr;
 461  482          struct smatch_state *state;
 462  483  
 463  484          if (!db_info->ret_state)
 464  485                  return;
↓ open down ↓ 620 lines elided ↑ open up ↑
1085 1106  
1086 1107          call_results_to_rl(db_info->expr, get_type(strip_expr(db_info->expr)), ret_str, &ret_range);
1087 1108          ret_range = cast_rl(get_type(db_info->expr), ret_range);
1088 1109  
1089 1110          if (type == INTERNAL) {
1090 1111                  set_state(-1, "unnull_path", NULL, &true_state);
1091 1112                  __add_return_comparison(strip_expr(db_info->expr), ret_str);
1092 1113                  __add_return_to_param_mapping(db_info->expr, ret_str);
1093 1114          }
1094 1115  
1095      -
1096 1116          FOR_EACH_PTR(db_return_states_list, tmp) {
1097 1117                  if (tmp->type == type)
1098 1118                          tmp->callback(db_info->expr, param, key, value);
1099 1119          } END_FOR_EACH_PTR(tmp);
1100 1120  
1101 1121          /*
1102 1122           * We want to store the return values so that we can split the strees
1103 1123           * in smatch_db.c.  This uses set_state() directly because it's not a
1104 1124           * real smatch_extra state.
1105 1125           */
↓ open down ↓ 57 lines elided ↑ open up ↑
1163 1183          if (is_assigned_call(expr))
1164 1184                  return;
1165 1185          if (is_condition_call(expr))
1166 1186                  return;
1167 1187          db_return_states(expr);
1168 1188  }
1169 1189  
1170 1190  static void match_function_call(struct expression *expr)
1171 1191  {
1172 1192          struct call_back_list *call_backs;
     1193 +        struct expression *fn;
1173 1194  
1174      -        if (expr->fn->type == EXPR_SYMBOL && expr->fn->symbol) {
1175      -                call_backs = search_callback(func_hash, (char *)expr->fn->symbol->ident->name);
     1195 +        fn = strip_expr(expr->fn);
     1196 +        if (fn->type == EXPR_SYMBOL && fn->symbol) {
     1197 +                call_backs = search_callback(func_hash, (char *)fn->symbol->ident->name);
1176 1198                  if (call_backs)
1177 1199                          call_call_backs(call_backs, REGULAR_CALL,
1178      -                                        expr->fn->symbol->ident->name, expr);
     1200 +                                        fn->symbol->ident->name, expr);
1179 1201          }
1180 1202          db_return_states_call(expr);
1181 1203  }
1182 1204  
1183 1205  static void match_macro_assign(struct expression *expr)
1184 1206  {
1185 1207          struct call_back_list *call_backs;
1186 1208          const char *macro;
1187 1209          struct expression *right;
1188 1210  
↓ open down ↓ 48 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX