1 /* 2 * Copyright (C) 2006 Dan Carpenter. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt 16 */ 17 18 /* 19 * Miscellaneous helper functions. 20 */ 21 22 #include <stdlib.h> 23 #include <stdio.h> 24 #include "allocate.h" 25 #include "smatch.h" 26 #include "smatch_extra.h" 27 #include "smatch_slist.h" 28 29 #define VAR_LEN 512 30 31 char *alloc_string(const char *str) 32 { 33 char *tmp; 34 35 if (!str) 36 return NULL; 37 tmp = malloc(strlen(str) + 1); 38 strcpy(tmp, str); 39 return tmp; 40 } 41 42 void free_string(char *str) 43 { 44 free(str); 45 } 46 47 void remove_parens(char *str) 48 { 49 char *src, *dst; 50 51 dst = src = str; 52 while (*src != '\0') { 53 if (*src == '(' || *src == ')') { 54 src++; 55 continue; 56 } 57 *dst++ = *src++; 58 } 59 *dst = *src; 60 } 61 62 struct smatch_state *alloc_state_num(int num) 63 { 64 struct smatch_state *state; 65 static char buff[256]; 66 67 state = __alloc_smatch_state(0); 68 snprintf(buff, 255, "%d", num); 69 buff[255] = '\0'; 70 state->name = alloc_string(buff); 71 state->data = INT_PTR(num); 72 return state; 73 } 74 75 struct smatch_state *alloc_state_str(const char *name) 76 { 77 struct smatch_state *state; 78 79 state = __alloc_smatch_state(0); 80 state->name = alloc_string(name); 81 return state; 82 } 83 84 struct smatch_state *alloc_state_expr(struct expression *expr) 85 { 86 struct smatch_state *state; 87 char *name; 88 89 state = __alloc_smatch_state(0); 90 expr = strip_expr(expr); 91 name = expr_to_str(expr); 92 state->name = alloc_sname(name); 93 free_string(name); 94 state->data = expr; 95 return state; 96 } 97 98 void append(char *dest, const char *data, int buff_len) 99 { 100 strncat(dest, data, buff_len - strlen(dest) - 1); 101 } 102 103 /* 104 * If you have "foo(a, b, 1);" then use 105 * get_argument_from_call_expr(expr, 0) to return the expression for 106 * a. Yes, it does start counting from 0. 107 */ 108 struct expression *get_argument_from_call_expr(struct expression_list *args, 109 int num) 110 { 111 struct expression *expr; 112 int i = 0; 113 114 if (!args) 115 return NULL; 116 117 FOR_EACH_PTR(args, expr) { 118 if (i == num) 119 return expr; 120 i++; 121 } END_FOR_EACH_PTR(expr); 122 return NULL; 123 } 124 125 static struct expression *get_array_expr(struct expression *expr) 126 { 127 struct expression *parent; 128 struct symbol *type; 129 130 if (expr->type != EXPR_BINOP || expr->op != '+') 131 return NULL; 132 133 type = get_type(expr->left); 134 if (!type) 135 return NULL; 136 if (type->type == SYM_ARRAY) 137 return expr->left; 138 if (type->type != SYM_PTR) 139 return NULL; 140 141 parent = expr_get_parent_expr(expr); 142 if (!parent) /* Sometimes we haven't set up the ->parent yet. FIXME!! */ 143 return expr->left; 144 if (parent->type == EXPR_PREOP && parent->op == '*') 145 return expr->left; 146 147 return NULL; 148 } 149 150 static void __get_variable_from_expr(struct symbol **sym_ptr, char *buf, 151 struct expression *expr, int len, 152 int *complicated, int no_parens) 153 { 154 155 156 if (!expr) { 157 /* can't happen on valid code */ 158 *complicated = 1; 159 return; 160 } 161 162 switch (expr->type) { 163 case EXPR_DEREF: { 164 struct expression *deref; 165 int op; 166 167 deref = expr->deref; 168 op = deref->op; 169 if (op == '*') { 170 struct expression *unop = strip_expr(deref->unop); 171 172 if (unop->type == EXPR_PREOP && unop->op == '&') { 173 deref = unop->unop; 174 op = '.'; 175 } else { 176 deref = deref->unop; 177 if (!is_pointer(deref)) 178 op = '.'; 179 } 180 } 181 182 __get_variable_from_expr(sym_ptr, buf, deref, len, complicated, no_parens); 183 184 if (op == '*') 185 append(buf, "->", len); 186 else 187 append(buf, ".", len); 188 189 if (expr->member) 190 append(buf, expr->member->name, len); 191 else 192 append(buf, "unknown_member", len); 193 194 return; 195 } 196 case EXPR_SYMBOL: 197 if (expr->symbol_name) 198 append(buf, expr->symbol_name->name, len); 199 if (sym_ptr) { 200 if (*sym_ptr) 201 *complicated = 1; 202 *sym_ptr = expr->symbol; 203 } 204 return; 205 case EXPR_PREOP: { 206 const char *tmp; 207 208 if (get_expression_statement(expr)) { 209 *complicated = 2; 210 return; 211 } 212 213 if (expr->op == '(') { 214 if (!no_parens && expr->unop->type != EXPR_SYMBOL) 215 append(buf, "(", len); 216 } else if (expr->op != '*' || !get_array_expr(expr->unop)) { 217 tmp = show_special(expr->op); 218 append(buf, tmp, len); 219 } 220 __get_variable_from_expr(sym_ptr, buf, expr->unop, 221 len, complicated, no_parens); 222 223 if (expr->op == '(' && !no_parens && expr->unop->type != EXPR_SYMBOL) 224 append(buf, ")", len); 225 226 if (expr->op == SPECIAL_DECREMENT || 227 expr->op == SPECIAL_INCREMENT) 228 *complicated = 1; 229 230 return; 231 } 232 case EXPR_POSTOP: { 233 const char *tmp; 234 235 __get_variable_from_expr(sym_ptr, buf, expr->unop, 236 len, complicated, no_parens); 237 tmp = show_special(expr->op); 238 append(buf, tmp, len); 239 240 if (expr->op == SPECIAL_DECREMENT || expr->op == SPECIAL_INCREMENT) 241 *complicated = 1; 242 return; 243 } 244 case EXPR_ASSIGNMENT: 245 case EXPR_COMPARE: 246 case EXPR_LOGICAL: 247 case EXPR_BINOP: { 248 char tmp[10]; 249 struct expression *array_expr; 250 251 *complicated = 1; 252 array_expr = get_array_expr(expr); 253 if (array_expr) { 254 __get_variable_from_expr(sym_ptr, buf, array_expr, len, complicated, no_parens); 255 append(buf, "[", len); 256 } else { 257 __get_variable_from_expr(sym_ptr, buf, expr->left, len, complicated, no_parens); 258 snprintf(tmp, sizeof(tmp), " %s ", show_special(expr->op)); 259 append(buf, tmp, len); 260 } 261 __get_variable_from_expr(NULL, buf, expr->right, len, complicated, no_parens); 262 if (array_expr) 263 append(buf, "]", len); 264 return; 265 } 266 case EXPR_VALUE: { 267 char tmp[25]; 268 269 *complicated = 1; 270 snprintf(tmp, 25, "%lld", expr->value); 271 append(buf, tmp, len); 272 return; 273 } 274 case EXPR_STRING: 275 append(buf, "\"", len); 276 if (expr->string) 277 append(buf, expr->string->data, len); 278 append(buf, "\"", len); 279 return; 280 case EXPR_CALL: { 281 struct expression *tmp; 282 int i; 283 284 *complicated = 1; 285 __get_variable_from_expr(NULL, buf, expr->fn, len, complicated, no_parens); 286 append(buf, "(", len); 287 i = 0; 288 FOR_EACH_PTR(expr->args, tmp) { 289 if (i++) 290 append(buf, ", ", len); 291 __get_variable_from_expr(NULL, buf, tmp, len, complicated, no_parens); 292 } END_FOR_EACH_PTR(tmp); 293 append(buf, ")", len); 294 return; 295 } 296 case EXPR_CAST: 297 case EXPR_FORCE_CAST: 298 __get_variable_from_expr(sym_ptr, buf, 299 expr->cast_expression, len, 300 complicated, no_parens); 301 return; 302 case EXPR_SIZEOF: { 303 sval_t sval; 304 int size; 305 char tmp[25]; 306 307 if (expr->cast_type && get_base_type(expr->cast_type)) { 308 size = type_bytes(get_base_type(expr->cast_type)); 309 snprintf(tmp, 25, "%d", size); 310 append(buf, tmp, len); 311 } else if (get_value(expr, &sval)) { 312 snprintf(tmp, 25, "%s", sval_to_str(sval)); 313 append(buf, tmp, len); 314 } 315 return; 316 } 317 case EXPR_IDENTIFIER: 318 *complicated = 1; 319 if (expr->expr_ident) 320 append(buf, expr->expr_ident->name, len); 321 return; 322 default: 323 *complicated = 1; 324 //printf("unknown type = %d\n", expr->type); 325 return; 326 } 327 } 328 329 struct expr_str_cache_results { 330 struct expression *expr; 331 int no_parens; 332 char str[VAR_LEN]; 333 struct symbol *sym; 334 int complicated; 335 }; 336 337 static void get_variable_from_expr(struct symbol **sym_ptr, char *buf, 338 struct expression *expr, int len, 339 int *complicated, int no_parens) 340 { 341 static struct expr_str_cache_results cached[8]; 342 struct symbol *tmp_sym = NULL; 343 static int idx; 344 int i; 345 346 for (i = 0; i < ARRAY_SIZE(cached); i++) { 347 if (expr == cached[i].expr && 348 no_parens == cached[i].no_parens) { 349 strncpy(buf, cached[i].str, len); 350 if (sym_ptr) 351 *sym_ptr = cached[i].sym; 352 *complicated = cached[i].complicated; 353 return; 354 } 355 } 356 357 __get_variable_from_expr(&tmp_sym, buf, expr, len, complicated, no_parens); 358 if (sym_ptr) 359 *sym_ptr = tmp_sym; 360 361 cached[idx].expr = expr; 362 cached[idx].no_parens = no_parens; 363 strncpy(cached[idx].str, buf, VAR_LEN); 364 cached[idx].sym = tmp_sym; 365 cached[idx].complicated = *complicated; 366 367 idx = (idx + 1) % ARRAY_SIZE(cached); 368 } 369 370 /* 371 * This is returns a stylized "c looking" representation of the 372 * variable name. 373 * 374 * It uses the same buffer every time so you have to save the result 375 * yourself if you want to keep it. 376 * 377 */ 378 379 char *expr_to_str_sym(struct expression *expr, struct symbol **sym_ptr) 380 { 381 static char var_name[VAR_LEN]; 382 int complicated = 0; 383 384 if (sym_ptr) 385 *sym_ptr = NULL; 386 var_name[0] = '\0'; 387 388 if (!expr) 389 return NULL; 390 get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name), 391 &complicated, 0); 392 if (complicated < 2) 393 return alloc_string(var_name); 394 else 395 return NULL; 396 } 397 398 char *expr_to_str(struct expression *expr) 399 { 400 return expr_to_str_sym(expr, NULL); 401 } 402 403 /* 404 * get_variable_from_expr_simple() only returns simple variables. 405 * If it's a complicated variable like a->foo[x] instead of just 'a->foo' 406 * then it returns NULL. 407 */ 408 char *expr_to_var_sym(struct expression *expr, 409 struct symbol **sym_ptr) 410 { 411 static char var_name[VAR_LEN]; 412 int complicated = 0; 413 414 if (sym_ptr) 415 *sym_ptr = NULL; 416 var_name[0] = '\0'; 417 418 if (!expr) 419 return NULL; 420 expr = strip_expr(expr); 421 get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name), 422 &complicated, 1); 423 424 if (complicated) { 425 if (sym_ptr) 426 *sym_ptr = NULL; 427 return NULL; 428 } 429 return alloc_string(var_name); 430 } 431 432 char *expr_to_var(struct expression *expr) 433 { 434 return expr_to_var_sym(expr, NULL); 435 } 436 437 struct symbol *expr_to_sym(struct expression *expr) 438 { 439 struct symbol *sym; 440 char *name; 441 442 name = expr_to_var_sym(expr, &sym); 443 free_string(name); 444 return sym; 445 } 446 447 int get_complication_score(struct expression *expr) 448 { 449 expr = strip_expr(expr); 450 451 /* 452 * Don't forget to keep get_complication_score() and store_all_links() 453 * in sync. 454 * 455 */ 456 457 if (!expr) 458 return 990; 459 460 switch (expr->type) { 461 case EXPR_CALL: 462 return 991; 463 case EXPR_COMPARE: 464 case EXPR_BINOP: 465 return get_complication_score(expr->left) + 466 get_complication_score(expr->right); 467 case EXPR_SYMBOL: 468 return 1; 469 case EXPR_PREOP: 470 if (expr->op == '*' || expr->op == '(') 471 return get_complication_score(expr->unop); 472 return 993; 473 case EXPR_DEREF: 474 return get_complication_score(expr->deref); 475 case EXPR_VALUE: 476 case EXPR_SIZEOF: 477 return 0; 478 default: 479 return 994; 480 } 481 } 482 483 struct expression *reorder_expr_alphabetically(struct expression *expr) 484 { 485 struct expression *ret; 486 char *left, *right; 487 488 if (expr->type != EXPR_BINOP) 489 return expr; 490 if (expr->op != '+' && expr->op != '*') 491 return expr; 492 493 left = expr_to_var(expr->left); 494 right = expr_to_var(expr->right); 495 ret = expr; 496 if (!left || !right) 497 goto free; 498 if (strcmp(left, right) <= 0) 499 goto free; 500 501 ret = binop_expression(expr->right, expr->op, expr->left); 502 free: 503 free_string(left); 504 free_string(right); 505 506 return ret; 507 } 508 509 char *expr_to_chunk_helper(struct expression *expr, struct symbol **sym, struct var_sym_list **vsl) 510 { 511 struct var_sym_list *tmp_vsl; 512 char *name; 513 struct symbol *tmp; 514 int score; 515 516 if (vsl) 517 *vsl = NULL; 518 if (sym) 519 *sym = NULL; 520 521 expr = strip_parens(expr); 522 if (!expr) 523 return NULL; 524 525 name = expr_to_var_sym(expr, &tmp); 526 if (name && tmp) { 527 if (sym) 528 *sym = tmp; 529 if (vsl) 530 *vsl = expr_to_vsl(expr); 531 return name; 532 } 533 free_string(name); 534 535 score = get_complication_score(expr); 536 if (score <= 0 || score > 2) 537 return NULL; 538 539 tmp_vsl = expr_to_vsl(expr); 540 if (vsl) { 541 *vsl = tmp_vsl; 542 if (!*vsl) 543 return NULL; 544 } 545 if (sym) { 546 if (ptr_list_size((struct ptr_list *)tmp_vsl) == 1) { 547 struct var_sym *vs; 548 549 vs = first_ptr_list((struct ptr_list *)tmp_vsl); 550 *sym = vs->sym; 551 } 552 } 553 554 expr = reorder_expr_alphabetically(expr); 555 556 return expr_to_str(expr); 557 } 558 559 char *expr_to_known_chunk_sym(struct expression *expr, struct symbol **sym) 560 { 561 return expr_to_chunk_helper(expr, sym, NULL); 562 } 563 564 char *expr_to_chunk_sym_vsl(struct expression *expr, struct symbol **sym, struct var_sym_list **vsl) 565 { 566 return expr_to_chunk_helper(expr, sym, vsl); 567 } 568 569 int sym_name_is(const char *name, struct expression *expr) 570 { 571 if (!expr) 572 return 0; 573 if (expr->type != EXPR_SYMBOL) 574 return 0; 575 if (!strcmp(expr->symbol_name->name, name)) 576 return 1; 577 return 0; 578 } 579 580 int is_zero(struct expression *expr) 581 { 582 sval_t sval; 583 584 if (get_value(expr, &sval) && sval.value == 0) 585 return 1; 586 return 0; 587 } 588 589 int is_array(struct expression *expr) 590 { 591 struct symbol *type; 592 593 expr = strip_expr(expr); 594 if (!expr) 595 return 0; 596 597 if (expr->type == EXPR_PREOP && expr->op == '*') { 598 expr = strip_expr(expr->unop); 599 if (!expr) 600 return 0; 601 if (expr->type == EXPR_BINOP && expr->op == '+') 602 return 1; 603 } 604 605 if (expr->type != EXPR_BINOP || expr->op != '+') 606 return 0; 607 608 type = get_type(expr->left); 609 if (!type || type->type != SYM_ARRAY) 610 return 0; 611 612 return 1; 613 } 614 615 struct expression *get_array_base(struct expression *expr) 616 { 617 if (!is_array(expr)) 618 return NULL; 619 expr = strip_expr(expr); 620 if (expr->type == EXPR_PREOP && expr->op == '*') 621 expr = strip_expr(expr->unop); 622 if (expr->type != EXPR_BINOP || expr->op != '+') 623 return NULL; 624 return strip_parens(expr->left); 625 } 626 627 struct expression *get_array_offset(struct expression *expr) 628 { 629 if (!is_array(expr)) 630 return NULL; 631 expr = strip_expr(expr); 632 if (expr->type == EXPR_PREOP && expr->op == '*') 633 expr = strip_expr(expr->unop); 634 if (expr->type != EXPR_BINOP || expr->op != '+') 635 return NULL; 636 return strip_parens(expr->right); 637 } 638 639 const char *show_state(struct smatch_state *state) 640 { 641 if (!state) 642 return NULL; 643 return state->name; 644 } 645 646 struct statement *get_expression_statement(struct expression *expr) 647 { 648 /* What are those things called? if (({....; ret;})) { ...*/ 649 650 if (expr->type != EXPR_PREOP) 651 return NULL; 652 if (expr->op != '(') 653 return NULL; 654 if (!expr->unop) 655 return NULL; 656 if (expr->unop->type != EXPR_STATEMENT) 657 return NULL; 658 if (expr->unop->statement->type != STMT_COMPOUND) 659 return NULL; 660 return expr->unop->statement; 661 } 662 663 struct expression *strip_parens(struct expression *expr) 664 { 665 if (!expr) 666 return NULL; 667 668 if (expr->type == EXPR_PREOP) { 669 if (!expr->unop) 670 return expr; /* parsing invalid code */ 671 672 if (expr->op == '(' && expr->unop->type == EXPR_STATEMENT && 673 expr->unop->statement->type == STMT_COMPOUND) 674 return expr; 675 if (expr->op == '(') 676 return strip_parens(expr->unop); 677 } 678 return expr; 679 } 680 681 static struct expression *strip_expr_helper(struct expression *expr, bool set_parent) 682 { 683 if (!expr) 684 return NULL; 685 686 switch (expr->type) { 687 case EXPR_FORCE_CAST: 688 case EXPR_CAST: 689 if (set_parent) 690 expr_set_parent_expr(expr->cast_expression, expr); 691 692 if (!expr->cast_expression) 693 return expr; 694 return strip_expr_helper(expr->cast_expression, set_parent); 695 case EXPR_PREOP: { 696 struct expression *unop; 697 698 if (!expr->unop) /* parsing invalid code */ 699 return expr; 700 if (set_parent) 701 expr_set_parent_expr(expr->unop, expr); 702 703 704 if (expr->op == '(' && expr->unop->type == EXPR_STATEMENT && 705 expr->unop->statement->type == STMT_COMPOUND) 706 return expr; 707 708 unop = strip_expr_helper(expr->unop, set_parent); 709 710 if (expr->op == '*' && unop && 711 unop->type == EXPR_PREOP && unop->op == '&') { 712 struct symbol *type = get_type(unop->unop); 713 714 if (type && type->type == SYM_ARRAY) 715 return expr; 716 return strip_expr_helper(unop->unop, set_parent); 717 } 718 719 if (expr->op == '(') 720 return unop; 721 722 return expr; 723 } 724 case EXPR_CONDITIONAL: 725 if (known_condition_true(expr->conditional)) { 726 if (expr->cond_true) { 727 if (set_parent) 728 expr_set_parent_expr(expr->cond_true, expr); 729 return strip_expr_helper(expr->cond_true, set_parent); 730 } 731 if (set_parent) 732 expr_set_parent_expr(expr->conditional, expr); 733 return strip_expr_helper(expr->conditional, set_parent); 734 } 735 if (known_condition_false(expr->conditional)) { 736 if (set_parent) 737 expr_set_parent_expr(expr->cond_false, expr); 738 return strip_expr_helper(expr->cond_false, set_parent); 739 } 740 return expr; 741 case EXPR_CALL: 742 if (sym_name_is("__builtin_expect", expr->fn) || 743 sym_name_is("__builtin_bswap16", expr->fn) || 744 sym_name_is("__builtin_bswap32", expr->fn) || 745 sym_name_is("__builtin_bswap64", expr->fn)) { 746 expr = get_argument_from_call_expr(expr->args, 0); 747 return strip_expr_helper(expr, set_parent); 748 } 749 return expr; 750 } 751 return expr; 752 } 753 754 struct expression *strip_expr(struct expression *expr) 755 { 756 return strip_expr_helper(expr, false); 757 } 758 759 struct expression *strip_expr_set_parent(struct expression *expr) 760 { 761 return strip_expr_helper(expr, true); 762 } 763 764 static void delete_state_tracker(struct tracker *t) 765 { 766 delete_state(t->owner, t->name, t->sym); 767 __free_tracker(t); 768 } 769 770 void scoped_state(int my_id, const char *name, struct symbol *sym) 771 { 772 struct tracker *t; 773 774 t = alloc_tracker(my_id, name, sym); 775 add_scope_hook((scope_hook *)&delete_state_tracker, t); 776 } 777 778 int is_error_return(struct expression *expr) 779 { 780 struct symbol *cur_func = cur_func_sym; 781 struct range_list *rl; 782 sval_t sval; 783 784 if (!expr) 785 return 0; 786 if (cur_func->type != SYM_NODE) 787 return 0; 788 cur_func = get_base_type(cur_func); 789 if (cur_func->type != SYM_FN) 790 return 0; 791 cur_func = get_base_type(cur_func); 792 if (cur_func == &void_ctype) 793 return 0; 794 if (option_project == PROJ_KERNEL && 795 get_implied_rl(expr, &rl) && 796 rl_type(rl) == &int_ctype && 797 sval_is_negative(rl_min(rl)) && 798 rl_max(rl).value == -1) 799 return 1; 800 if (!get_implied_value(expr, &sval)) 801 return 0; 802 if (sval.value < 0) 803 return 1; 804 if (cur_func->type == SYM_PTR && sval.value == 0) 805 return 1; 806 return 0; 807 } 808 809 int getting_address(void) 810 { 811 struct expression *tmp; 812 int i = 0; 813 int dot_ops = 0; 814 815 FOR_EACH_PTR_REVERSE(big_expression_stack, tmp) { 816 if (!i++) 817 continue; 818 if (tmp->type == EXPR_PREOP && tmp->op == '(') 819 continue; 820 if (tmp->op == '.' && !dot_ops++) 821 continue; 822 if (tmp->op == '&') 823 return 1; 824 return 0; 825 } END_FOR_EACH_PTR_REVERSE(tmp); 826 return 0; 827 } 828 829 int get_struct_and_member(struct expression *expr, const char **type, const char **member) 830 { 831 struct symbol *sym; 832 833 expr = strip_expr(expr); 834 if (expr->type != EXPR_DEREF) 835 return 0; 836 if (!expr->member) 837 return 0; 838 839 sym = get_type(expr->deref); 840 if (!sym) 841 return 0; 842 if (sym->type == SYM_UNION) 843 return 0; 844 if (!sym->ident) 845 return 0; 846 847 *type = sym->ident->name; 848 *member = expr->member->name; 849 return 1; 850 } 851 852 char *get_member_name(struct expression *expr) 853 { 854 char buf[256]; 855 struct symbol *sym; 856 857 expr = strip_expr(expr); 858 if (!expr || expr->type != EXPR_DEREF) 859 return NULL; 860 if (!expr->member) 861 return NULL; 862 863 sym = get_type(expr->deref); 864 if (!sym) 865 return NULL; 866 if (sym->type == SYM_UNION) { 867 snprintf(buf, sizeof(buf), "(union %s)->%s", 868 sym->ident ? sym->ident->name : "anonymous", 869 expr->member->name); 870 return alloc_string(buf); 871 } 872 if (!sym->ident) 873 return NULL; 874 snprintf(buf, sizeof(buf), "(struct %s)->%s", sym->ident->name, expr->member->name); 875 return alloc_string(buf); 876 } 877 878 int cmp_pos(struct position pos1, struct position pos2) 879 { 880 /* the stream position is ... */ 881 if (pos1.stream > pos2.stream) 882 return -1; 883 if (pos1.stream < pos2.stream) 884 return 1; 885 886 if (pos1.line < pos2.line) 887 return -1; 888 if (pos1.line > pos2.line) 889 return 1; 890 891 if (pos1.pos < pos2.pos) 892 return -1; 893 if (pos1.pos > pos2.pos) 894 return 1; 895 896 return 0; 897 } 898 899 int positions_eq(struct position pos1, struct position pos2) 900 { 901 if (pos1.line != pos2.line) 902 return 0; 903 if (pos1.pos != pos2.pos) 904 return 0; 905 if (pos1.stream != pos2.stream) 906 return 0; 907 return 1; 908 } 909 910 struct statement *get_current_statement(void) 911 { 912 struct statement *prev, *tmp; 913 914 prev = last_ptr_list((struct ptr_list *)big_statement_stack); 915 916 if (!prev || !get_macro_name(prev->pos)) 917 return prev; 918 919 FOR_EACH_PTR_REVERSE(big_statement_stack, tmp) { 920 if (positions_eq(tmp->pos, prev->pos)) 921 continue; 922 if (prev->pos.line > tmp->pos.line) 923 return prev; 924 return tmp; 925 } END_FOR_EACH_PTR_REVERSE(tmp); 926 return prev; 927 } 928 929 struct statement *get_prev_statement(void) 930 { 931 struct statement *tmp; 932 int i; 933 934 i = 0; 935 FOR_EACH_PTR_REVERSE(big_statement_stack, tmp) { 936 if (i++ == 1) 937 return tmp; 938 } END_FOR_EACH_PTR_REVERSE(tmp); 939 return NULL; 940 } 941 942 struct expression *get_last_expr_from_expression_stmt(struct expression *expr) 943 { 944 struct statement *stmt; 945 struct statement *last_stmt; 946 947 while (expr->type == EXPR_PREOP && expr->op == '(') 948 expr = expr->unop; 949 if (expr->type != EXPR_STATEMENT) 950 return NULL; 951 stmt = expr->statement; 952 if (!stmt) 953 return NULL; 954 if (stmt->type == STMT_COMPOUND) { 955 last_stmt = last_ptr_list((struct ptr_list *)stmt->stmts); 956 if (!last_stmt) 957 return NULL; 958 if (last_stmt->type == STMT_LABEL) 959 last_stmt = last_stmt->label_statement; 960 if (last_stmt->type != STMT_EXPRESSION) 961 return NULL; 962 return last_stmt->expression; 963 } 964 if (stmt->type == STMT_EXPRESSION) 965 return stmt->expression; 966 return NULL; 967 } 968 969 int get_param_num_from_sym(struct symbol *sym) 970 { 971 struct symbol *tmp; 972 int i; 973 974 if (!cur_func_sym) 975 return -1; 976 977 i = 0; 978 FOR_EACH_PTR(cur_func_sym->ctype.base_type->arguments, tmp) { 979 if (tmp == sym) 980 return i; 981 i++; 982 } END_FOR_EACH_PTR(tmp); 983 return -1; 984 } 985 986 int get_param_num(struct expression *expr) 987 { 988 struct symbol *sym; 989 char *name; 990 991 if (!cur_func_sym) 992 return -1; 993 name = expr_to_var_sym(expr, &sym); 994 free_string(name); 995 if (!sym) 996 return -1; 997 return get_param_num_from_sym(sym); 998 } 999 1000 int ms_since(struct timeval *start) 1001 { 1002 struct timeval end; 1003 double diff; 1004 1005 gettimeofday(&end, NULL); 1006 diff = (end.tv_sec - start->tv_sec) * 1000.0; 1007 diff += (end.tv_usec - start->tv_usec) / 1000.0; 1008 return (int)diff; 1009 } 1010 1011 int parent_is_gone_var_sym(const char *name, struct symbol *sym) 1012 { 1013 if (!name || !sym) 1014 return 0; 1015 1016 if (parent_is_null_var_sym(name, sym) || 1017 parent_is_free_var_sym(name, sym)) 1018 return 1; 1019 return 0; 1020 } 1021 1022 int parent_is_gone(struct expression *expr) 1023 { 1024 struct symbol *sym; 1025 char *var; 1026 int ret = 0; 1027 1028 expr = strip_expr(expr); 1029 var = expr_to_var_sym(expr, &sym); 1030 if (!var || !sym) 1031 goto free; 1032 ret = parent_is_gone_var_sym(var, sym); 1033 free: 1034 free_string(var); 1035 return ret; 1036 } 1037 1038 int invert_op(int op) 1039 { 1040 switch (op) { 1041 case '*': 1042 return '/'; 1043 case '/': 1044 return '*'; 1045 case '+': 1046 return '-'; 1047 case '-': 1048 return '+'; 1049 case SPECIAL_LEFTSHIFT: 1050 return SPECIAL_RIGHTSHIFT; 1051 case SPECIAL_RIGHTSHIFT: 1052 return SPECIAL_LEFTSHIFT; 1053 } 1054 return 0; 1055 } 1056 1057 int expr_equiv(struct expression *one, struct expression *two) 1058 { 1059 struct symbol *one_sym = NULL; 1060 struct symbol *two_sym = NULL; 1061 char *one_name = NULL; 1062 char *two_name = NULL; 1063 int ret = 0; 1064 1065 if (!one || !two) 1066 return 0; 1067 if (one->type != two->type) 1068 return 0; 1069 if (is_fake_call(one) || is_fake_call(two)) 1070 return 0; 1071 1072 one_name = expr_to_str_sym(one, &one_sym); 1073 if (!one_name) 1074 goto free; 1075 two_name = expr_to_str_sym(two, &two_sym); 1076 if (!two_name) 1077 goto free; 1078 if (one_sym != two_sym) 1079 goto free; 1080 /* 1081 * This is a terrible hack because expr_to_str() sometimes gives up in 1082 * the middle and just returns what it has. If you see a () you know 1083 * the string is bogus. 1084 */ 1085 if (strstr(one_name, "()")) 1086 goto free; 1087 if (strcmp(one_name, two_name) == 0) 1088 ret = 1; 1089 free: 1090 free_string(one_name); 1091 free_string(two_name); 1092 return ret; 1093 } 1094 1095 void push_int(struct int_stack **stack, int num) 1096 { 1097 int *munged; 1098 1099 /* 1100 * Just put the int on directly instead of a pointer to the int. 1101 * Shift it to the left because Sparse uses the last two bits. 1102 * This is sort of a dirty hack, yes. 1103 */ 1104 1105 munged = INT_PTR(num << 2); 1106 1107 add_ptr_list(stack, munged); 1108 } 1109 1110 int pop_int(struct int_stack **stack) 1111 { 1112 int *num; 1113 1114 num = last_ptr_list((struct ptr_list *)*stack); 1115 delete_ptr_list_last((struct ptr_list **)stack); 1116 1117 return PTR_INT(num) >> 2; 1118 }