Print this page
11506 smatch resync

Split Close
Expand all
Collapse all
          --- old/usr/src/tools/smatch/src/check_uninitialized.c
          +++ new/usr/src/tools/smatch/src/check_uninitialized.c
↓ open down ↓ 87 lines elided ↑ open up ↑
  88   88  
  89   89  static void match_assign(struct expression *expr)
  90   90  {
  91   91          struct expression *right;
  92   92  
  93   93          right = strip_expr(expr->right);
  94   94          if (right->type == EXPR_PREOP && right->op == '&')
  95   95                  set_state_expr(my_id, right->unop, &initialized);
  96   96  }
  97   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 +
  98  133  static int is_initialized(struct expression *expr)
  99  134  {
 100  135          struct sm_state *sm;
 101  136  
 102  137          expr = strip_expr(expr);
 103  138          if (expr->type != EXPR_SYMBOL)
 104  139                  return 1;
 105  140          sm = get_sm_state_expr(my_id, expr);
 106  141          if (!sm)
 107  142                  return 1;
 108  143          if (!slist_has_state(sm->possible, &uninitialized))
 109  144                  return 1;
 110  145          return 0;
 111  146  }
 112  147  
 113  148  static void match_dereferences(struct expression *expr)
 114  149  {
 115  150          char *name;
 116  151  
 117      -        if (parse_error)
      152 +        if (implications_off || parse_error)
 118  153                  return;
 119  154  
 120  155          if (expr->type != EXPR_PREOP)
 121  156                  return;
 122  157          if (is_impossible_path())
 123  158                  return;
 124  159          if (is_initialized(expr->unop))
 125  160                  return;
 126  161  
 127  162          name = expr_to_str(expr->unop);
 128  163          sm_error("potentially dereferencing uninitialized '%s'.", name);
 129  164          free_string(name);
 130  165  
 131  166          set_state_expr(my_id, expr->unop, &initialized);
 132  167  }
 133  168  
 134  169  static void match_condition(struct expression *expr)
 135  170  {
 136  171          char *name;
 137  172  
 138      -        if (parse_error)
      173 +        if (implications_off || parse_error)
 139  174                  return;
 140  175  
 141  176          if (is_impossible_path())
 142  177                  return;
 143  178  
 144  179          if (is_initialized(expr))
 145  180                  return;
 146  181  
 147  182          name = expr_to_str(expr);
 148  183          sm_error("potentially using uninitialized '%s'.", name);
↓ open down ↓ 109 lines elided ↑ open up ↑
 258  293          if (stmt && stmt->type == STMT_ASM)
 259  294                  return 1;
 260  295  
 261  296          return 0;
 262  297  }
 263  298  
 264  299  static void match_symbol(struct expression *expr)
 265  300  {
 266  301          char *name;
 267  302  
 268      -        if (parse_error)
      303 +        if (implications_off || parse_error)
 269  304                  return;
 270  305  
 271  306          if (is_impossible_path())
 272  307                  return;
 273  308  
 274  309          if (is_initialized(expr))
 275  310                  return;
 276  311  
 277  312          if (is_being_modified(expr))
 278  313                  return;
↓ open down ↓ 66 lines elided ↑ open up ↑
 345  380          clear_token_alloc();
 346  381  }
 347  382  
 348  383  void check_uninitialized(int id)
 349  384  {
 350  385          my_id = id;
 351  386  
 352  387          add_hook(&match_declarations, DECLARATION_HOOK);
 353  388          add_extra_mod_hook(&extra_mod_hook);
 354  389          add_hook(&match_assign, ASSIGNMENT_HOOK);
      390 +        add_hook(&match_negative_comparison, CONDITION_HOOK);
 355  391          add_untracked_param_hook(&match_untracked);
 356  392          add_pre_merge_hook(my_id, &pre_merge_hook);
 357  393  
 358  394          add_hook(&match_dereferences, DEREF_HOOK);
 359  395          add_hook(&match_condition, CONDITION_HOOK);
 360  396          add_hook(&match_call, FUNCTION_CALL_HOOK);
 361  397          add_hook(&match_call_struct_members, FUNCTION_CALL_HOOK);
 362  398          add_hook(&match_symbol, SYM_HOOK);
 363  399  
 364  400          register_ignored_params_from_file();
 365  401  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX