Print this page
11506 smatch resync


  78 }
  79 
  80 static void extra_mod_hook(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
  81 {
  82         if (!sym || !sym->ident)
  83                 return;
  84         if (strcmp(name, sym->ident->name) != 0)
  85                 return;
  86         set_state(my_id, name, sym, &initialized);
  87 }
  88 
  89 static void match_assign(struct expression *expr)
  90 {
  91         struct expression *right;
  92 
  93         right = strip_expr(expr->right);
  94         if (right->type == EXPR_PREOP && right->op == '&')
  95                 set_state_expr(my_id, right->unop, &initialized);
  96 }
  97 



































  98 static int is_initialized(struct expression *expr)
  99 {
 100         struct sm_state *sm;
 101 
 102         expr = strip_expr(expr);
 103         if (expr->type != EXPR_SYMBOL)
 104                 return 1;
 105         sm = get_sm_state_expr(my_id, expr);
 106         if (!sm)
 107                 return 1;
 108         if (!slist_has_state(sm->possible, &uninitialized))
 109                 return 1;
 110         return 0;
 111 }
 112 
 113 static void match_dereferences(struct expression *expr)
 114 {
 115         char *name;
 116 
 117         if (parse_error)
 118                 return;
 119 
 120         if (expr->type != EXPR_PREOP)
 121                 return;
 122         if (is_impossible_path())
 123                 return;
 124         if (is_initialized(expr->unop))
 125                 return;
 126 
 127         name = expr_to_str(expr->unop);
 128         sm_error("potentially dereferencing uninitialized '%s'.", name);
 129         free_string(name);
 130 
 131         set_state_expr(my_id, expr->unop, &initialized);
 132 }
 133 
 134 static void match_condition(struct expression *expr)
 135 {
 136         char *name;
 137 
 138         if (parse_error)
 139                 return;
 140 
 141         if (is_impossible_path())
 142                 return;
 143 
 144         if (is_initialized(expr))
 145                 return;
 146 
 147         name = expr_to_str(expr);
 148         sm_error("potentially using uninitialized '%s'.", name);
 149         free_string(name);
 150 
 151         set_state_expr(my_id, expr, &initialized);
 152 }
 153 
 154 static void match_call(struct expression *expr)
 155 {
 156         struct expression *arg;
 157         char *name;
 158 


 248                 parent = expr_get_parent_expr(parent);
 249                 if (!parent)
 250                         return 0;
 251         }
 252         if (parent->type == EXPR_PREOP && parent->op == '&')
 253                 return 1;
 254         if (parent->type == EXPR_ASSIGNMENT && expr_equiv(parent->left, expr))
 255                 return 1;
 256 
 257         stmt = last_ptr_list((struct ptr_list *)big_statement_stack);
 258         if (stmt && stmt->type == STMT_ASM)
 259                 return 1;
 260 
 261         return 0;
 262 }
 263 
 264 static void match_symbol(struct expression *expr)
 265 {
 266         char *name;
 267 
 268         if (parse_error)
 269                 return;
 270 
 271         if (is_impossible_path())
 272                 return;
 273 
 274         if (is_initialized(expr))
 275                 return;
 276 
 277         if (is_being_modified(expr))
 278                 return;
 279 
 280         name = expr_to_str(expr);
 281         sm_error("uninitialized symbol '%s'.", name);
 282         free_string(name);
 283 
 284         set_state_expr(my_id, expr, &initialized);
 285 }
 286 
 287 static void match_untracked(struct expression *call, int param)
 288 {


 335 
 336                 token = token->next;
 337                 if (token_type(token) != TOKEN_NUMBER)
 338                         return;
 339                 param = atoi(token->number);
 340 
 341                 add_function_hook(func, &match_ignore_param, INT_PTR(param));
 342 
 343                 token = token->next;
 344         }
 345         clear_token_alloc();
 346 }
 347 
 348 void check_uninitialized(int id)
 349 {
 350         my_id = id;
 351 
 352         add_hook(&match_declarations, DECLARATION_HOOK);
 353         add_extra_mod_hook(&extra_mod_hook);
 354         add_hook(&match_assign, ASSIGNMENT_HOOK);

 355         add_untracked_param_hook(&match_untracked);
 356         add_pre_merge_hook(my_id, &pre_merge_hook);
 357 
 358         add_hook(&match_dereferences, DEREF_HOOK);
 359         add_hook(&match_condition, CONDITION_HOOK);
 360         add_hook(&match_call, FUNCTION_CALL_HOOK);
 361         add_hook(&match_call_struct_members, FUNCTION_CALL_HOOK);
 362         add_hook(&match_symbol, SYM_HOOK);
 363 
 364         register_ignored_params_from_file();
 365 }


  78 }
  79 
  80 static void extra_mod_hook(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
  81 {
  82         if (!sym || !sym->ident)
  83                 return;
  84         if (strcmp(name, sym->ident->name) != 0)
  85                 return;
  86         set_state(my_id, name, sym, &initialized);
  87 }
  88 
  89 static void match_assign(struct expression *expr)
  90 {
  91         struct expression *right;
  92 
  93         right = strip_expr(expr->right);
  94         if (right->type == EXPR_PREOP && right->op == '&')
  95                 set_state_expr(my_id, right->unop, &initialized);
  96 }
  97 
  98 static void match_negative_comparison(struct expression *expr)
  99 {
 100         struct expression *success;
 101         struct sm_state *sm;
 102         sval_t max;
 103 
 104         /*
 105          * In the kernel, people don't use "if (ret) {" and "if (ret < 0) {"
 106          * consistently.  Ideally Smatch would know the return but often it
 107          * doesn't.
 108          *
 109          */
 110 
 111         if (option_project != PROJ_KERNEL)
 112                 return;
 113 
 114         if (expr->type != EXPR_COMPARE || expr->op != '<')
 115                 return;
 116         if (!is_zero(expr->right))
 117                 return;
 118         if (get_implied_max(expr->left, &max) && max.value == 0)
 119                 return;
 120 
 121         success = compare_expression(expr->left, SPECIAL_EQUAL, expr->right);
 122         if (!assume(success))
 123                 return;
 124 
 125         FOR_EACH_MY_SM(my_id, __get_cur_stree(), sm) {
 126                 if (sm->state == &initialized)
 127                         set_true_false_states(my_id, sm->name, sm->sym, NULL, &initialized);
 128         } END_FOR_EACH_SM(sm);
 129 
 130         end_assume();
 131 }
 132 
 133 static int is_initialized(struct expression *expr)
 134 {
 135         struct sm_state *sm;
 136 
 137         expr = strip_expr(expr);
 138         if (expr->type != EXPR_SYMBOL)
 139                 return 1;
 140         sm = get_sm_state_expr(my_id, expr);
 141         if (!sm)
 142                 return 1;
 143         if (!slist_has_state(sm->possible, &uninitialized))
 144                 return 1;
 145         return 0;
 146 }
 147 
 148 static void match_dereferences(struct expression *expr)
 149 {
 150         char *name;
 151 
 152         if (implications_off || parse_error)
 153                 return;
 154 
 155         if (expr->type != EXPR_PREOP)
 156                 return;
 157         if (is_impossible_path())
 158                 return;
 159         if (is_initialized(expr->unop))
 160                 return;
 161 
 162         name = expr_to_str(expr->unop);
 163         sm_error("potentially dereferencing uninitialized '%s'.", name);
 164         free_string(name);
 165 
 166         set_state_expr(my_id, expr->unop, &initialized);
 167 }
 168 
 169 static void match_condition(struct expression *expr)
 170 {
 171         char *name;
 172 
 173         if (implications_off || parse_error)
 174                 return;
 175 
 176         if (is_impossible_path())
 177                 return;
 178 
 179         if (is_initialized(expr))
 180                 return;
 181 
 182         name = expr_to_str(expr);
 183         sm_error("potentially using uninitialized '%s'.", name);
 184         free_string(name);
 185 
 186         set_state_expr(my_id, expr, &initialized);
 187 }
 188 
 189 static void match_call(struct expression *expr)
 190 {
 191         struct expression *arg;
 192         char *name;
 193 


 283                 parent = expr_get_parent_expr(parent);
 284                 if (!parent)
 285                         return 0;
 286         }
 287         if (parent->type == EXPR_PREOP && parent->op == '&')
 288                 return 1;
 289         if (parent->type == EXPR_ASSIGNMENT && expr_equiv(parent->left, expr))
 290                 return 1;
 291 
 292         stmt = last_ptr_list((struct ptr_list *)big_statement_stack);
 293         if (stmt && stmt->type == STMT_ASM)
 294                 return 1;
 295 
 296         return 0;
 297 }
 298 
 299 static void match_symbol(struct expression *expr)
 300 {
 301         char *name;
 302 
 303         if (implications_off || parse_error)
 304                 return;
 305 
 306         if (is_impossible_path())
 307                 return;
 308 
 309         if (is_initialized(expr))
 310                 return;
 311 
 312         if (is_being_modified(expr))
 313                 return;
 314 
 315         name = expr_to_str(expr);
 316         sm_error("uninitialized symbol '%s'.", name);
 317         free_string(name);
 318 
 319         set_state_expr(my_id, expr, &initialized);
 320 }
 321 
 322 static void match_untracked(struct expression *call, int param)
 323 {


 370 
 371                 token = token->next;
 372                 if (token_type(token) != TOKEN_NUMBER)
 373                         return;
 374                 param = atoi(token->number);
 375 
 376                 add_function_hook(func, &match_ignore_param, INT_PTR(param));
 377 
 378                 token = token->next;
 379         }
 380         clear_token_alloc();
 381 }
 382 
 383 void check_uninitialized(int id)
 384 {
 385         my_id = id;
 386 
 387         add_hook(&match_declarations, DECLARATION_HOOK);
 388         add_extra_mod_hook(&extra_mod_hook);
 389         add_hook(&match_assign, ASSIGNMENT_HOOK);
 390         add_hook(&match_negative_comparison, CONDITION_HOOK);
 391         add_untracked_param_hook(&match_untracked);
 392         add_pre_merge_hook(my_id, &pre_merge_hook);
 393 
 394         add_hook(&match_dereferences, DEREF_HOOK);
 395         add_hook(&match_condition, CONDITION_HOOK);
 396         add_hook(&match_call, FUNCTION_CALL_HOOK);
 397         add_hook(&match_call_struct_members, FUNCTION_CALL_HOOK);
 398         add_hook(&match_symbol, SYM_HOOK);
 399 
 400         register_ignored_params_from_file();
 401 }