Print this page
12724 update smatch to 0.6.1-rc1-il-5

@@ -30,14 +30,14 @@
 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)) {
+        if (!get_implied_rl(arg, rl))
                 *rl = alloc_rl(err_ptr_min, err_ptr_max);
-                *rl = cast_rl(get_type(arg), *rl);
-        }
+
+        *rl = cast_rl(get_type(call), *rl);
         return 1;
 }
 
 static void hack_ERR_PTR(struct symbol *sym)
 {

@@ -128,16 +128,13 @@
         struct smatch_state *pre_state;
         struct range_list *rl;
 
         arg = get_argument_from_call_expr(call_expr->args, 0);
         pre_state = get_state_expr(SMATCH_EXTRA, arg);
-        if (estate_rl(pre_state)) {
-                rl = estate_rl(pre_state);
-                rl = remove_range(rl, err_ptr_min, err_ptr_max);
-        } else {
+        if (pre_state)
+                return;
                 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,

@@ -152,10 +149,18 @@
         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);
+        if (pre_state && rl) {
+                /*
+                 * Ideally this would all be handled by smatch_implied.c
+                 * but it doesn't work very well for impossible paths.
+                 *
+                 */
+                return;
+        }
         set_extra_expr_nomod(arg, alloc_estate_rl(rl));
 }
 
 static void match_container_of_macro(const char *fn, struct expression *expr, void *unused)
 {

@@ -255,12 +260,10 @@
                 start.value = 1;
         *rl = alloc_rl(start, end);
         return 1;
 }
 
-
-
 static void find_module_init_exit(struct symbol_list *sym_list)
 {
         struct symbol *sym;
         struct symbol *fn;
         struct statement *stmt;

@@ -404,10 +407,26 @@
         __in_fake_assign++;
         __split_expr(assign);
         __in_fake_assign--;
 }
 
+static void match_closure_call(const char *name, struct expression *call,
+                               void *unused)
+{
+        struct expression *cl, *fn, *fake_call;
+        struct expression_list *args = NULL;
+
+        cl = get_argument_from_call_expr(call->args, 0);
+        fn = get_argument_from_call_expr(call->args, 1);
+        if (!fn || !cl)
+                return;
+
+        add_ptr_list(&args, cl);
+        fake_call = call_expression(fn, args);
+        __split_expr(fake_call);
+}
+
 bool is_ignored_kernel_data(const char *name)
 {
         if (option_project != PROJ_KERNEL)
                 return false;
 

@@ -461,8 +480,10 @@
         add_function_hook("__write_once_size", &match__write_once_size, NULL);
 
         add_function_hook("__read_once_size", &match__read_once_size, NULL);
         add_function_hook("__read_once_size_nocheck", &match__read_once_size, NULL);
 
+        add_function_hook("closure_call", &match_closure_call, NULL);
+
         if (option_info)
                 add_hook(match_end_file, END_FILE_HOOK);
 }