Print this page
11506 smatch resync


  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;


 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);


 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;


 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)


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)




  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 *merge_str_state(struct smatch_state *s1, struct smatch_state *s2)
  85 {
  86         if (!s1->name || !s2->name)
  87                 return &merged;
  88         if (strcmp(s1->name, s2->name) == 0)
  89                 return s1;
  90         return &merged;
  91 }
  92 
  93 struct smatch_state *alloc_state_expr(struct expression *expr)
  94 {
  95         struct smatch_state *state;
  96         char *name;
  97 

  98         expr = strip_expr(expr);
  99         name = expr_to_str(expr);
 100         if (!name)
 101                 return NULL;
 102 
 103         state = __alloc_smatch_state(0);
 104         state->name = alloc_sname(name);
 105         free_string(name);
 106         state->data = expr;
 107         return state;
 108 }
 109 
 110 void append(char *dest, const char *data, int buff_len)
 111 {
 112         strncat(dest, data, buff_len - strlen(dest) - 1);
 113 }
 114 
 115 /*
 116  * If you have "foo(a, b, 1);" then use
 117  * get_argument_from_call_expr(expr, 0) to return the expression for
 118  * a.  Yes, it does start counting from 0.
 119  */
 120 struct expression *get_argument_from_call_expr(struct expression_list *args,
 121                                                int num)
 122 {
 123         struct expression *expr;


 161 
 162 static void __get_variable_from_expr(struct symbol **sym_ptr, char *buf,
 163                                      struct expression *expr, int len,
 164                                      int *complicated, int no_parens)
 165 {
 166 
 167 
 168         if (!expr) {
 169                 /* can't happen on valid code */
 170                 *complicated = 1;
 171                 return;
 172         }
 173 
 174         switch (expr->type) {
 175         case EXPR_DEREF: {
 176                 struct expression *deref;
 177                 int op;
 178 
 179                 deref = expr->deref;
 180                 op = deref->op;
 181                 if (deref->type == EXPR_PREOP && op == '*') {
 182                         struct expression *unop = strip_expr(deref->unop);
 183 
 184                         if (unop->type == EXPR_PREOP && unop->op == '&') {
 185                                 deref = unop->unop;
 186                                 op = '.';
 187                         } else {
 188                                 if (!is_pointer(deref) && !is_pointer(deref->unop))

 189                                         op = '.';
 190                                 deref = deref->unop;
 191                         }
 192                 }
 193 
 194                 __get_variable_from_expr(sym_ptr, buf, deref, len, complicated, no_parens);
 195 
 196                 if (op == '*')
 197                         append(buf, "->", len);
 198                 else
 199                         append(buf, ".", len);
 200 
 201                 if (expr->member)
 202                         append(buf, expr->member->name, len);
 203                 else
 204                         append(buf, "unknown_member", len);
 205 
 206                 return;
 207         }
 208         case EXPR_SYMBOL:
 209                 if (expr->symbol_name)
 210                         append(buf, expr->symbol_name->name, len);


 522 {
 523         struct var_sym_list *tmp_vsl;
 524         char *name;
 525         struct symbol *tmp;
 526         int score;
 527 
 528         if (vsl)
 529                 *vsl = NULL;
 530         if (sym)
 531                 *sym = NULL;
 532 
 533         expr = strip_parens(expr);
 534         if (!expr)
 535                 return NULL;
 536 
 537         name = expr_to_var_sym(expr, &tmp);
 538         if (name && tmp) {
 539                 if (sym)
 540                         *sym = tmp;
 541                 if (vsl)
 542                         add_var_sym(vsl, name, tmp);
 543                 return name;
 544         }
 545         free_string(name);
 546 
 547         score = get_complication_score(expr);
 548         if (score <= 0 || score > 2)
 549                 return NULL;
 550 
 551         tmp_vsl = expr_to_vsl(expr);
 552         if (vsl) {
 553                 *vsl = tmp_vsl;
 554                 if (!*vsl)
 555                         return NULL;
 556         }
 557         if (sym) {
 558                 if (ptr_list_size((struct ptr_list *)tmp_vsl) == 1) {
 559                         struct var_sym *vs;
 560 
 561                         vs = first_ptr_list((struct ptr_list *)tmp_vsl);
 562                         *sym = vs->sym;


 864 char *get_member_name(struct expression *expr)
 865 {
 866         char buf[256];
 867         struct symbol *sym;
 868 
 869         expr = strip_expr(expr);
 870         if (!expr || expr->type != EXPR_DEREF)
 871                 return NULL;
 872         if (!expr->member)
 873                 return NULL;
 874 
 875         sym = get_type(expr->deref);
 876         if (!sym)
 877                 return NULL;
 878         if (sym->type == SYM_UNION) {
 879                 snprintf(buf, sizeof(buf), "(union %s)->%s",
 880                          sym->ident ? sym->ident->name : "anonymous",
 881                          expr->member->name);
 882                 return alloc_string(buf);
 883         }
 884         if (!sym->ident) {
 885                 struct expression *deref;
 886                 char *full, *outer;
 887                 int len;
 888 
 889                 /*
 890                  * If we're in an anonymous struct then maybe we can find an
 891                  * outer struct name to use as a name.  This code should be
 892                  * recursive and cleaner.  I am not very proud of it.
 893                  *
 894                  */
 895 
 896                 deref = expr->deref;
 897                 if (deref->type != EXPR_DEREF || !deref->member)
 898                         return NULL;
 899                 sym = get_type(deref->deref);
 900                 if (!sym || sym->type != SYM_STRUCT || !sym->ident)
 901                         return NULL;
 902 
 903                 full = expr_to_str(expr);
 904                 if (!full)
 905                         return NULL;
 906                 deref = deref->deref;
 907                 if (deref->type == EXPR_PREOP && deref->op == '*')
 908                         deref = deref->unop;
 909                 outer = expr_to_str(deref);
 910                 if (!outer) {
 911                         free_string(full);
 912                         return NULL;
 913                 }
 914                 len = strlen(outer);
 915                 if (strncmp(outer, full, len) != 0) {
 916                         free_string(full);
 917                         free_string(outer);
 918                         return NULL;
 919                 }
 920                 if (full[len] == '-' && full[len + 1] == '>')
 921                         len += 2;
 922                 if (full[len] == '.')
 923                         len++;
 924                 snprintf(buf, sizeof(buf), "(struct %s)->%s", sym->ident->name, full + len);
 925                 free_string(outer);
 926                 free_string(full);
 927 
 928                 return alloc_string(buf);
 929         }
 930         snprintf(buf, sizeof(buf), "(struct %s)->%s", sym->ident->name, expr->member->name);
 931         return alloc_string(buf);
 932 }
 933 
 934 int cmp_pos(struct position pos1, struct position pos2)
 935 {
 936         /* the stream position is ... */
 937         if (pos1.stream > pos2.stream)
 938                 return -1;
 939         if (pos1.stream < pos2.stream)
 940                 return 1;
 941 
 942         if (pos1.line < pos2.line)
 943                 return -1;
 944         if (pos1.line > pos2.line)
 945                 return 1;
 946 
 947         if (pos1.pos < pos2.pos)
 948                 return -1;
 949         if (pos1.pos > pos2.pos)


1093 
1094 int invert_op(int op)
1095 {
1096         switch (op) {
1097         case '*':
1098                 return '/';
1099         case '/':
1100                 return '*';
1101         case '+':
1102                 return '-';
1103         case '-':
1104                 return '+';
1105         case SPECIAL_LEFTSHIFT:
1106                 return SPECIAL_RIGHTSHIFT;
1107         case SPECIAL_RIGHTSHIFT:
1108                 return SPECIAL_LEFTSHIFT;
1109         }
1110         return 0;
1111 }
1112 
1113 int op_remove_assign(int op)
1114 {
1115         switch (op) {
1116         case SPECIAL_ADD_ASSIGN:
1117                 return '+';
1118         case SPECIAL_SUB_ASSIGN:
1119                 return '-';
1120         case SPECIAL_MUL_ASSIGN:
1121                 return '*';
1122         case SPECIAL_DIV_ASSIGN:
1123                 return '/';
1124         case SPECIAL_MOD_ASSIGN:
1125                 return '%';
1126         case SPECIAL_AND_ASSIGN:
1127                 return '&';
1128         case SPECIAL_OR_ASSIGN:
1129                 return '|';
1130         case SPECIAL_XOR_ASSIGN:
1131                 return '^';
1132         case SPECIAL_SHL_ASSIGN:
1133                 return SPECIAL_LEFTSHIFT;
1134         case SPECIAL_SHR_ASSIGN:
1135                 return SPECIAL_RIGHTSHIFT;
1136         default:
1137                 return op;
1138         }
1139 }
1140 
1141 int expr_equiv(struct expression *one, struct expression *two)
1142 {
1143         struct symbol *one_sym = NULL;
1144         struct symbol *two_sym = NULL;
1145         char *one_name = NULL;
1146         char *two_name = NULL;
1147         int ret = 0;
1148 
1149         if (!one || !two)
1150                 return 0;
1151         if (one->type != two->type)
1152                 return 0;
1153         if (is_fake_call(one) || is_fake_call(two))
1154                 return 0;
1155 
1156         one_name = expr_to_str_sym(one, &one_sym);
1157         if (!one_name)
1158                 goto free;
1159         two_name = expr_to_str_sym(two, &two_sym);
1160         if (!two_name)