Print this page
11506 smatch resync

@@ -21,17 +21,23 @@
 
 #include "scope.h"
 #include "smatch.h"
 #include "smatch_extra.h"
 
+static sval_t err_ptr_min;
+static sval_t err_ptr_max;
+static sval_t null_ptr;
+
 static int implied_err_cast_return(struct expression *call, void *unused, struct range_list **rl)
 {
         struct expression *arg;
 
         arg = get_argument_from_call_expr(call->args, 0);
-        if (!get_implied_rl(arg, rl))
-                *rl = alloc_rl(ll_to_sval(-4095), ll_to_sval(-1));
+        if (!get_implied_rl(arg, rl)) {
+                *rl = alloc_rl(err_ptr_min, err_ptr_max);
+                *rl = cast_rl(get_type(arg), *rl);
+        }
         return 1;
 }
 
 static void hack_ERR_PTR(struct symbol *sym)
 {

@@ -76,14 +82,22 @@
 {
         int param = PTR_INT(_param);
         struct expression *arg;
         struct smatch_state *pre_state;
         struct smatch_state *end_state;
+        struct range_list *rl;
 
         arg = get_argument_from_call_expr(call_expr->args, param);
         pre_state = get_state_expr(SMATCH_EXTRA, arg);
-        end_state = estate_filter_range(pre_state, ll_to_sval(-4095), ll_to_sval(0));
+        if (estate_rl(pre_state)) {
+                rl = estate_rl(pre_state);
+                rl = remove_range(rl, null_ptr, null_ptr);
+                rl = remove_range(rl, err_ptr_min, err_ptr_max);
+        } else {
+                rl = alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
+        }
+        end_state = alloc_estate_rl(rl);
         set_extra_expr_nomod(arg, end_state);
 }
 
 static void match_param_err_or_null(const char *fn, struct expression *call_expr,
                         struct expression *assign_expr, void *_param)

@@ -94,42 +108,51 @@
         struct smatch_state *pre_state;
         struct smatch_state *end_state;
 
         arg = get_argument_from_call_expr(call_expr->args, param);
         pre_state = get_state_expr(SMATCH_EXTRA, arg);
-        rl = alloc_rl(ll_to_sval(-4095), ll_to_sval(0));
+        call_results_to_rl(call_expr, &ptr_ctype, "0,(-4095)-(-1)", &rl);
         rl = rl_intersection(estate_rl(pre_state), rl);
-        rl = cast_rl(estate_type(pre_state), rl);
+        rl = cast_rl(get_type(arg), rl);
         end_state = alloc_estate_rl(rl);
         set_extra_expr_nomod(arg, end_state);
 }
 
 static void match_not_err(const char *fn, struct expression *call_expr,
                         struct expression *assign_expr, void *unused)
 {
         struct expression *arg;
         struct smatch_state *pre_state;
-        struct smatch_state *new_state;
+        struct range_list *rl;
 
         arg = get_argument_from_call_expr(call_expr->args, 0);
         pre_state = get_state_expr(SMATCH_EXTRA, arg);
-        new_state = estate_filter_range(pre_state, sval_type_min(&long_ctype), ll_to_sval(-1));
-        set_extra_expr_nomod(arg, new_state);
+        if (estate_rl(pre_state)) {
+                rl = estate_rl(pre_state);
+                rl = remove_range(rl, err_ptr_min, err_ptr_max);
+        } else {
+                rl = alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
+        }
+        rl = cast_rl(get_type(arg), rl);
+        set_extra_expr_nomod(arg, alloc_estate_rl(rl));
 }
 
 static void match_err(const char *fn, struct expression *call_expr,
                         struct expression *assign_expr, void *unused)
 {
         struct expression *arg;
         struct smatch_state *pre_state;
-        struct smatch_state *new_state;
+        struct range_list *rl;
 
         arg = get_argument_from_call_expr(call_expr->args, 0);
         pre_state = get_state_expr(SMATCH_EXTRA, arg);
-        new_state = estate_filter_range(pre_state, sval_type_min(&long_ctype), ll_to_sval(-4096));
-        new_state = estate_filter_range(new_state, ll_to_sval(0), sval_type_max(&long_ctype));
-        set_extra_expr_nomod(arg, new_state);
+        rl = estate_rl(pre_state);
+        if (!rl)
+                rl = alloc_rl(err_ptr_min, err_ptr_max);
+        rl = rl_intersection(rl, alloc_rl(err_ptr_min, err_ptr_max));
+        rl = cast_rl(get_type(arg), rl);
+        set_extra_expr_nomod(arg, alloc_estate_rl(rl));
 }
 
 static void match_container_of_macro(const char *fn, struct expression *expr, void *unused)
 {
         set_extra_expr_mod(expr->left, alloc_estate_range(valid_ptr_min_sval, valid_ptr_max_sval));

@@ -377,15 +400,40 @@
         __in_fake_assign++;
         __split_expr(assign);
         __in_fake_assign--;
 }
 
+bool is_ignored_kernel_data(const char *name)
+{
+        if (option_project != PROJ_KERNEL)
+                return false;
+
+        /*
+         * On the file I was looking at lockdep was 25% of the DB.
+         */
+        if (strstr(name, ".dep_map."))
+                return true;
+        if (strstr(name, ".lockdep_map."))
+                return true;
+        return false;
+}
+
 void check_kernel(int id)
 {
         if (option_project != PROJ_KERNEL)
                 return;
 
+        err_ptr_min.type = &ptr_ctype;
+        err_ptr_min.value = -4095;
+        err_ptr_max.type = &ptr_ctype;
+        err_ptr_max.value = -1l;
+        null_ptr.type = &ptr_ctype;
+        null_ptr.value = 0;
+
+        err_ptr_min = sval_cast(&ptr_ctype, err_ptr_min);
+        err_ptr_max = sval_cast(&ptr_ctype, err_ptr_max);
+
         add_implied_return_hook("ERR_PTR", &implied_err_cast_return, NULL);
         add_implied_return_hook("ERR_CAST", &implied_err_cast_return, NULL);
         add_implied_return_hook("PTR_ERR", &implied_err_cast_return, NULL);
         add_hook(hack_ERR_PTR, AFTER_DEF_HOOK);
         return_implies_state("IS_ERR_OR_NULL", 0, 0, &match_param_valid_ptr, (void *)0);