Print this page
11506 smatch resync


  97 
  98         while (top_op_precedence() && op_precedence(c) <= top_op_precedence()) {
  99                 op = pop_op();
 100                 right = pop_rl(&rl_stack);
 101                 left = pop_rl(&rl_stack);
 102                 res = rl_binop(left, op, right);
 103                 if (!res)
 104                         res = alloc_whole_rl(&llong_ctype);
 105                 push_rl(&rl_stack, res);
 106         }
 107 }
 108 
 109 static void rl_discard_stacks(void)
 110 {
 111         while (op_list)
 112                 pop_op();
 113         while (rl_stack)
 114                 pop_rl(&rl_stack);
 115 }
 116 
 117 static int read_rl_from_var(struct expression *call, char *p, char **end, struct range_list **rl)
 118 {
 119         struct expression *arg;
 120         struct smatch_state *state;
 121         long param;
 122         char *name;
 123         struct symbol *sym;
 124         char buf[256];
 125         int star;
 126 
 127         p++;
 128         param = strtol(p, &p, 10);
 129 
 130         arg = get_argument_from_call_expr(call->args, param);
 131         if (!arg)
 132                 return 0;
 133 
 134         if (*p != '-' && *p != '.') {
 135                 get_absolute_rl(arg, rl);
 136                 *end = p;
 137                 return 1;
 138         }
 139 
 140         *end = strchr(p, ' ');
 141 
 142         if (arg->type == EXPR_PREOP && arg->op == '&') {
 143                 arg = strip_expr(arg->unop);
 144                 star = 0;
 145                 p++;
 146         } else {
 147                 star = 1;
 148                 p += 2;
 149         }
 150 
 151         name = expr_to_var_sym(arg, &sym);
 152         if (!name)
 153                 return 0;
 154         snprintf(buf, sizeof(buf), "%s%s", name, star ? "->" : ".");
 155         free_string(name);
 156 
 157         if (*end - p + strlen(buf) >= sizeof(buf))
 158                 return 0;
 159         strncat(buf, p, *end - p);
 160 
 161         state = get_state(SMATCH_EXTRA, buf, sym);
 162         if (!state)
 163                 return 0;
 164         *rl = estate_rl(state);
 165         return 1;
 166 }
 167 
 168 static int read_var_num(struct expression *call, char *p, char **end, struct range_list **rl)
 169 {
 170         sval_t sval;
 171 
 172         while (*p == ' ')
 173                 p++;
 174 
 175         if (*p == '$')
 176                 return read_rl_from_var(call, p, end, rl);
 177 
 178         sval.type = &llong_ctype;
 179         sval.value = strtoll(p, end, 10);
 180         if (*end == p)
 181                 return 0;
 182         *rl = alloc_rl(sval, sval);
 183         return 1;
 184 }
 185 
 186 static char *read_op(char *p)
 187 {
 188         while (*p == ' ')
 189                 p++;
 190 
 191         switch (*p) {
 192         case '+':
 193         case '-':
 194         case '*':
 195         case '/':
 196                 return p;
 197         default:
 198                 return NULL;
 199         }
 200 }
 201 
 202 int parse_call_math_rl(struct expression *call, char *math, struct range_list **rl)
 203 {
 204         struct range_list *tmp;
 205         char *c;
 206 
 207         /* try to implement shunting yard algorithm. */
 208 
 209         c = (char *)math;
 210         while (1) {
 211                 if (option_debug)
 212                         sm_msg("parsing %s", c);
 213 
 214                 /* read a number and push it onto the number stack */
 215                 if (!read_var_num(call, c, &c, &tmp))
 216                         goto fail;
 217                 push_rl(&rl_stack, tmp);
 218 
 219                 if (option_debug)
 220                         sm_msg("val = %s remaining = %s", show_rl(tmp), c);
 221 
 222                 if (!*c)
 223                         break;
 224                 if (*c == ']' && *(c + 1) == '\0')
 225                         break;
 226 
 227                 c = read_op(c);
 228                 if (!c)
 229                         goto fail;


 327         char *name;
 328         struct symbol *sym;
 329 
 330         name = expr_to_var_sym(expr, &sym);
 331         if (param_was_set_var_sym(name, sym))
 332                 return 0;
 333         return format_name_sym_helper(buf, remaining, name, sym);
 334 }
 335 
 336 static int format_call_to_param_mapping(char *buf, int remaining, struct expression *expr)
 337 {
 338         char *name;
 339         struct symbol *sym;
 340 
 341         name = map_call_to_param_name_sym(expr, &sym);
 342         if (param_was_set_var_sym(name, sym))
 343                 return 0;
 344         return format_name_sym_helper(buf, remaining, name, sym);
 345 }
 346 










 347 static int format_expr_helper(char *buf, int remaining, struct expression *expr)
 348 {
 349         sval_t sval;
 350         int ret;
 351         char *cur;
 352 
 353         if (!expr)
 354                 return 0;
 355 
 356         cur = buf;
 357 
 358         if (expr->type == EXPR_BINOP) {
 359                 ret = format_expr_helper(cur, remaining, expr->left);
 360                 if (ret == 0)
 361                         return 0;
 362                 remaining -= ret;
 363                 if (remaining <= 0)
 364                         return 0;
 365                 cur += ret;
 366 
 367                 ret = snprintf(cur, remaining, " %s ", show_special(expr->op));
 368                 remaining -= ret;
 369                 if (remaining <= 0)
 370                         return 0;
 371                 cur += ret;
 372 
 373                 ret = format_expr_helper(cur, remaining, expr->right);
 374                 if (ret == 0)
 375                         return 0;
 376                 remaining -= ret;
 377                 if (remaining <= 0)
 378                         return 0;
 379                 cur += ret;
 380                 return cur - buf;
 381         }
 382 
 383         if (get_implied_value(expr, &sval)) {
 384                 ret = snprintf(cur, remaining, "%s", sval_to_str(sval));
 385                 remaining -= ret;
 386                 if (remaining <= 0)
 387                         return 0;
 388                 return ret;
 389         }
 390 
 391         if (expr->type == EXPR_CALL)
 392                 return format_call_to_param_mapping(cur, remaining, expr);
 393 
 394         return format_variable_helper(cur, remaining, expr);
 395 }
 396 
 397 static char *format_expr(struct expression *expr)
 398 {
 399         char buf[256] = "";
 400         int ret;
 401 
 402         ret = format_expr_helper(buf, sizeof(buf), expr);
 403         if (ret == 0)


 418                 expr = tmp;
 419         if (param_was_set(expr))
 420                 return NULL;
 421 
 422         if (get_implied_value(expr, &dummy))
 423                 return NULL;
 424 
 425         ret = format_expr_helper(buf, sizeof(buf), expr);
 426         if (ret == 0)
 427                 return NULL;
 428 
 429         return alloc_sname(buf);
 430 }
 431 
 432 char *get_value_in_terms_of_parameter_math_var_sym(const char *name, struct symbol *sym)
 433 {
 434         struct expression *tmp, *expr;
 435         char buf[256] = "";
 436         int ret;
 437         int cnt = 0;

 438 
 439         expr = get_assigned_expr_name_sym(name, sym);
 440         if (!expr)
 441                 return NULL;
 442         while ((tmp = get_assigned_expr(expr))) {
 443                 expr = strip_expr(tmp);
 444                 if (++cnt > 3)
 445                         break;
 446         }
 447 



 448         ret = format_expr_helper(buf, sizeof(buf), expr);
 449         if (ret == 0)
 450                 return NULL;
 451 
 452         return alloc_sname(buf);
 453 
 454 }
 455 
 456 static void match_alloc(const char *fn, struct expression *expr, void *_size_arg)
 457 {
 458         int size_arg = PTR_INT(_size_arg);
 459         struct expression *right;
 460         struct expression *size_expr;
 461         char *sname;
 462 
 463         right = strip_expr(expr->right);
 464         size_expr = get_argument_from_call_expr(right->args, size_arg);
 465 
 466         sname = format_expr(size_expr);
 467         if (!sname)


 476         long param;
 477         struct expression *arg;
 478         char *p;
 479         char *out;
 480         int ret;
 481 
 482         if (format[0] == '$' && format[2] == '\0') {
 483                 param = strtol(format + 1, NULL, 10);
 484                 arg = get_argument_from_call_expr(call->args, param);
 485                 if (!arg)
 486                         return NULL;
 487                 return format_expr(arg);
 488         }
 489 
 490         buf[0] = '\0';
 491         p = format;
 492         out = buf;
 493         while (*p) {
 494                 if (*p == '$') {
 495                         p++;
 496                         param = strtol(p, &p, 10);
 497                         arg = get_argument_from_call_expr(call->args, param);
 498                         if (!arg)
 499                                 return NULL;
 500                         param = get_arg_number(arg);
 501                         if (param >= 0) {
 502                                 ret = snprintf(out, buf + sizeof(buf) - out, "$%ld", param);
 503                                 out += ret;
 504                                 if (out >= buf + sizeof(buf))
 505                                         return NULL;
 506                         } else if (get_implied_value(arg, &sval)) {
 507                                 ret = snprintf(out, buf + sizeof(buf) - out, "%s", sval_to_str(sval));
 508                                 out += ret;
 509                                 if (out >= buf + sizeof(buf))
 510                                         return NULL;
 511                         } else {
 512                                 return NULL;
 513                         }
 514                 }
 515                 *out = *p;
 516                 p++;


 626         name = expr_to_var_sym(expr, &sym);
 627         if (!name || !sym)
 628                 goto free;
 629 
 630         state = get_state(my_id, name, sym);
 631         if (!state || !state->data)
 632                 goto free;
 633 
 634         sql_insert_return_states(return_id, return_ranges, BUF_SIZE, -1, "",
 635                         state->name);
 636 free:
 637         free_string(name);
 638 }
 639 
 640 void register_parse_call_math(int id)
 641 {
 642         int i;
 643 
 644         my_id = id;
 645 


 646         for (i = 0; i < ARRAY_SIZE(alloc_functions); i++)
 647                 add_function_assign_hook(alloc_functions[i].func, &match_alloc,
 648                                          INT_PTR(alloc_functions[i].param));
 649         add_hook(&match_call_assignment, CALL_ASSIGNMENT_HOOK);
 650         add_split_return_callback(print_returned_allocations);
 651 }
 652 


  97 
  98         while (top_op_precedence() && op_precedence(c) <= top_op_precedence()) {
  99                 op = pop_op();
 100                 right = pop_rl(&rl_stack);
 101                 left = pop_rl(&rl_stack);
 102                 res = rl_binop(left, op, right);
 103                 if (!res)
 104                         res = alloc_whole_rl(&llong_ctype);
 105                 push_rl(&rl_stack, res);
 106         }
 107 }
 108 
 109 static void rl_discard_stacks(void)
 110 {
 111         while (op_list)
 112                 pop_op();
 113         while (rl_stack)
 114                 pop_rl(&rl_stack);
 115 }
 116 
 117 static int read_rl_from_var(struct expression *call, const char *p, const char **end, struct range_list **rl)
 118 {
 119         struct expression *arg;
 120         struct smatch_state *state;
 121         long param;
 122         char *name;
 123         struct symbol *sym;
 124         char buf[256];
 125         int star;
 126 
 127         p++;
 128         param = strtol(p, (char **)&p, 10);
 129 
 130         arg = get_argument_from_call_expr(call->args, param);
 131         if (!arg)
 132                 return 0;
 133 
 134         if (*p != '-' && *p != '.') {
 135                 get_absolute_rl(arg, rl);
 136                 *end = p;
 137                 return 1;
 138         }
 139 
 140         *end = strchr(p, ' ');
 141 
 142         if (arg->type == EXPR_PREOP && arg->op == '&') {
 143                 arg = strip_expr(arg->unop);
 144                 star = 0;
 145                 p++;
 146         } else {
 147                 star = 1;
 148                 p += 2;
 149         }
 150 
 151         name = expr_to_var_sym(arg, &sym);
 152         if (!name)
 153                 return 0;
 154         snprintf(buf, sizeof(buf), "%s%s", name, star ? "->" : ".");
 155         free_string(name);
 156 
 157         if (*end - p + strlen(buf) >= sizeof(buf))
 158                 return 0;
 159         strncat(buf, p, *end - p);
 160 
 161         state = get_state(SMATCH_EXTRA, buf, sym);
 162         if (!state)
 163                 return 0;
 164         *rl = estate_rl(state);
 165         return 1;
 166 }
 167 
 168 static int read_var_num(struct expression *call, const char *p, const char **end, struct range_list **rl)
 169 {
 170         sval_t sval;
 171 
 172         while (*p == ' ')
 173                 p++;
 174 
 175         if (*p == '$')
 176                 return read_rl_from_var(call, p, end, rl);
 177 
 178         sval.type = &llong_ctype;
 179         sval.value = strtoll(p, (char **)end, 10);
 180         if (*end == p)
 181                 return 0;
 182         *rl = alloc_rl(sval, sval);
 183         return 1;
 184 }
 185 
 186 static const char *read_op(const char *p)
 187 {
 188         while (*p == ' ')
 189                 p++;
 190 
 191         switch (*p) {
 192         case '+':
 193         case '-':
 194         case '*':
 195         case '/':
 196                 return p;
 197         default:
 198                 return NULL;
 199         }
 200 }
 201 
 202 int parse_call_math_rl(struct expression *call, const char *math, struct range_list **rl)
 203 {
 204         struct range_list *tmp;
 205         const char *c;
 206 
 207         /* try to implement shunting yard algorithm. */
 208 
 209         c = math;
 210         while (1) {
 211                 if (option_debug)
 212                         sm_msg("parsing %s", c);
 213 
 214                 /* read a number and push it onto the number stack */
 215                 if (!read_var_num(call, c, &c, &tmp))
 216                         goto fail;
 217                 push_rl(&rl_stack, tmp);
 218 
 219                 if (option_debug)
 220                         sm_msg("val = %s remaining = %s", show_rl(tmp), c);
 221 
 222                 if (!*c)
 223                         break;
 224                 if (*c == ']' && *(c + 1) == '\0')
 225                         break;
 226 
 227                 c = read_op(c);
 228                 if (!c)
 229                         goto fail;


 327         char *name;
 328         struct symbol *sym;
 329 
 330         name = expr_to_var_sym(expr, &sym);
 331         if (param_was_set_var_sym(name, sym))
 332                 return 0;
 333         return format_name_sym_helper(buf, remaining, name, sym);
 334 }
 335 
 336 static int format_call_to_param_mapping(char *buf, int remaining, struct expression *expr)
 337 {
 338         char *name;
 339         struct symbol *sym;
 340 
 341         name = map_call_to_param_name_sym(expr, &sym);
 342         if (param_was_set_var_sym(name, sym))
 343                 return 0;
 344         return format_name_sym_helper(buf, remaining, name, sym);
 345 }
 346 
 347 static int is_mtag_sval(sval_t sval)
 348 {
 349         if (!is_ptr_type(sval.type))
 350                 return 0;
 351         if (sval_cmp(sval, valid_ptr_min_sval) >= 0 &&
 352             sval_cmp(sval, valid_ptr_max_sval) <= 0)
 353                 return 1;
 354         return 0;
 355 }
 356 
 357 static int format_expr_helper(char *buf, int remaining, struct expression *expr)
 358 {
 359         sval_t sval;
 360         int ret;
 361         char *cur;
 362 
 363         if (!expr)
 364                 return 0;
 365 
 366         cur = buf;
 367 
 368         if (expr->type == EXPR_BINOP) {
 369                 ret = format_expr_helper(cur, remaining, expr->left);
 370                 if (ret == 0)
 371                         return 0;
 372                 remaining -= ret;
 373                 if (remaining <= 0)
 374                         return 0;
 375                 cur += ret;
 376 
 377                 ret = snprintf(cur, remaining, " %s ", show_special(expr->op));
 378                 remaining -= ret;
 379                 if (remaining <= 0)
 380                         return 0;
 381                 cur += ret;
 382 
 383                 ret = format_expr_helper(cur, remaining, expr->right);
 384                 if (ret == 0)
 385                         return 0;
 386                 remaining -= ret;
 387                 if (remaining <= 0)
 388                         return 0;
 389                 cur += ret;
 390                 return cur - buf;
 391         }
 392 
 393         if (!param_was_set(expr) && get_implied_value(expr, &sval) && !is_mtag_sval(sval)) {
 394                 ret = snprintf(cur, remaining, "%s", sval_to_str(sval));
 395                 remaining -= ret;
 396                 if (remaining <= 0)
 397                         return 0;
 398                 return ret;
 399         }
 400 
 401         if (expr->type == EXPR_CALL)
 402                 return format_call_to_param_mapping(cur, remaining, expr);
 403 
 404         return format_variable_helper(cur, remaining, expr);
 405 }
 406 
 407 static char *format_expr(struct expression *expr)
 408 {
 409         char buf[256] = "";
 410         int ret;
 411 
 412         ret = format_expr_helper(buf, sizeof(buf), expr);
 413         if (ret == 0)


 428                 expr = tmp;
 429         if (param_was_set(expr))
 430                 return NULL;
 431 
 432         if (get_implied_value(expr, &dummy))
 433                 return NULL;
 434 
 435         ret = format_expr_helper(buf, sizeof(buf), expr);
 436         if (ret == 0)
 437                 return NULL;
 438 
 439         return alloc_sname(buf);
 440 }
 441 
 442 char *get_value_in_terms_of_parameter_math_var_sym(const char *name, struct symbol *sym)
 443 {
 444         struct expression *tmp, *expr;
 445         char buf[256] = "";
 446         int ret;
 447         int cnt = 0;
 448         sval_t sval;
 449 
 450         expr = get_assigned_expr_name_sym(name, sym);
 451         if (!expr)
 452                 return NULL;
 453         while ((tmp = get_assigned_expr(expr))) {
 454                 expr = strip_expr(tmp);
 455                 if (++cnt > 3)
 456                         break;
 457         }
 458 
 459         if (get_implied_value(expr, &sval))
 460                 return NULL;
 461 
 462         ret = format_expr_helper(buf, sizeof(buf), expr);
 463         if (ret == 0)
 464                 return NULL;
 465 
 466         return alloc_sname(buf);
 467 
 468 }
 469 
 470 static void match_alloc(const char *fn, struct expression *expr, void *_size_arg)
 471 {
 472         int size_arg = PTR_INT(_size_arg);
 473         struct expression *right;
 474         struct expression *size_expr;
 475         char *sname;
 476 
 477         right = strip_expr(expr->right);
 478         size_expr = get_argument_from_call_expr(right->args, size_arg);
 479 
 480         sname = format_expr(size_expr);
 481         if (!sname)


 490         long param;
 491         struct expression *arg;
 492         char *p;
 493         char *out;
 494         int ret;
 495 
 496         if (format[0] == '$' && format[2] == '\0') {
 497                 param = strtol(format + 1, NULL, 10);
 498                 arg = get_argument_from_call_expr(call->args, param);
 499                 if (!arg)
 500                         return NULL;
 501                 return format_expr(arg);
 502         }
 503 
 504         buf[0] = '\0';
 505         p = format;
 506         out = buf;
 507         while (*p) {
 508                 if (*p == '$') {
 509                         p++;
 510                         param = strtol(p, (char **)&p, 10);
 511                         arg = get_argument_from_call_expr(call->args, param);
 512                         if (!arg)
 513                                 return NULL;
 514                         param = get_arg_number(arg);
 515                         if (param >= 0) {
 516                                 ret = snprintf(out, buf + sizeof(buf) - out, "$%ld", param);
 517                                 out += ret;
 518                                 if (out >= buf + sizeof(buf))
 519                                         return NULL;
 520                         } else if (get_implied_value(arg, &sval)) {
 521                                 ret = snprintf(out, buf + sizeof(buf) - out, "%s", sval_to_str(sval));
 522                                 out += ret;
 523                                 if (out >= buf + sizeof(buf))
 524                                         return NULL;
 525                         } else {
 526                                 return NULL;
 527                         }
 528                 }
 529                 *out = *p;
 530                 p++;


 640         name = expr_to_var_sym(expr, &sym);
 641         if (!name || !sym)
 642                 goto free;
 643 
 644         state = get_state(my_id, name, sym);
 645         if (!state || !state->data)
 646                 goto free;
 647 
 648         sql_insert_return_states(return_id, return_ranges, BUF_SIZE, -1, "",
 649                         state->name);
 650 free:
 651         free_string(name);
 652 }
 653 
 654 void register_parse_call_math(int id)
 655 {
 656         int i;
 657 
 658         my_id = id;
 659 
 660         set_dynamic_states(my_id);
 661 
 662         for (i = 0; i < ARRAY_SIZE(alloc_functions); i++)
 663                 add_function_assign_hook(alloc_functions[i].func, &match_alloc,
 664                                          INT_PTR(alloc_functions[i].param));
 665         add_hook(&match_call_assignment, CALL_ASSIGNMENT_HOOK);
 666         add_split_return_callback(print_returned_allocations);
 667 }
 668