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

@@ -267,17 +267,20 @@
 
 static void db_returns_buf_size(struct expression *expr, int param, char *unused, char *math)
 {
         struct expression *call;
         struct range_list *rl;
+        sval_t sval;
 
         if (expr->type != EXPR_ASSIGNMENT)
                 return;
         call = strip_expr(expr->right);
 
         call_results_to_rl(call, &int_ctype, math, &rl);
         rl = cast_rl(&int_ctype, rl);
+        if (rl_to_sval(rl, &sval) && sval.value == 0)
+                return;
         set_state_expr(my_size_id, expr->left, alloc_estate_rl(rl));
 }
 
 static int get_real_array_size_from_type(struct symbol *type)
 {

@@ -449,11 +452,11 @@
                 return 0;
         if (!last_member_is_resizable(base_sym))
                 return 0;
 
         state = get_state(my_size_id, sym->ident->name, sym);
-        if (!estate_to_size(state))
+        if (!estate_to_size(state) || estate_to_size(state) == -1)
                 return 0;
 
         return estate_to_size(state) - type_bytes(base_sym) + type_bytes(get_type(expr));
 }
 

@@ -502,24 +505,24 @@
                 if (size <= 0)
                         return NULL;
                 return alloc_int_rl(size - offset.value);
         }
 
+        /* buf = malloc(1024); */
+        ret = get_stored_size_bytes(expr);
+        if (ret)
+                return ret;
+
         size = get_stored_size_end_struct_bytes(expr);
         if (size)
                 return alloc_int_rl(size);
 
         /* buf[4] */
         size = get_real_array_size(expr);
         if (size)
                 return alloc_int_rl(elements_to_bytes(expr, size));
 
-        /* buf = malloc(1024); */
-        ret = get_stored_size_bytes(expr);
-        if (ret)
-                return ret;
-
         /* char *foo = "BAR" */
         size = get_size_from_initializer(expr);
         if (size)
                 return alloc_int_rl(elements_to_bytes(expr, size));
 

@@ -634,10 +637,14 @@
         struct symbol *type;
 
         rl = clone_rl(rl); // FIXME!!!
         if (!rl)
                 rl = size_to_rl(UNKNOWN_SIZE);
+
+        if (rl_min(rl).value != UNKNOWN_SIZE ||
+            rl_max(rl).value != UNKNOWN_SIZE ||
+            get_state_expr(my_size_id, expr))
         set_state_expr(my_size_id, expr, alloc_estate_rl(rl));
 
         type = get_type(expr);
         if (!type)
                 return;

@@ -652,10 +659,20 @@
                 return;
 
         info_record_alloction(expr, rl);
 }
 
+static bool is_array_base(struct expression *expr)
+{
+        struct symbol *type;
+
+        type = get_type(expr);
+        if (type && type->type == SYM_ARRAY)
+                return true;
+        return false;
+}
+
 static void match_array_assignment(struct expression *expr)
 {
         struct expression *left;
         struct expression *right;
         char *left_member, *right_member;

@@ -662,16 +679,20 @@
         struct range_list *rl;
         sval_t sval;
 
         if (expr->op != '=')
                 return;
+
         left = strip_expr(expr->left);
         right = strip_expr(expr->right);
         right = strip_ampersands(right);
 
         if (!is_pointer(left))
                 return;
+        /* char buf[24] = "str"; */
+        if (is_array_base(left))
+                return;
         if (is_allocation_function(right))
                 return;
 
         left_member = get_member_name(left);
         right_member = get_member_name(right);

@@ -708,19 +729,20 @@
         get_absolute_rl(arg, &rl);
         rl = cast_rl(&int_ctype, rl);
         store_alloc(expr->left, rl);
 }
 
-static void match_calloc(const char *fn, struct expression *expr, void *unused)
+static void match_calloc(const char *fn, struct expression *expr, void *_param)
 {
         struct expression *right;
         struct expression *size, *nr, *mult;
         struct range_list *rl;
+        int param = PTR_INT(_param);
 
         right = strip_expr(expr->right);
-        nr = get_argument_from_call_expr(right->args, 0);
-        size = get_argument_from_call_expr(right->args, 1);
+        nr = get_argument_from_call_expr(right->args, param);
+        size = get_argument_from_call_expr(right->args, param + 1);
         mult = binop_expression(nr, '*', size);
         if (get_implied_rl(mult, &rl))
                 store_alloc(expr->left, rl);
         else
                 store_alloc(expr->left, size_to_rl(UNKNOWN_SIZE));

@@ -810,10 +832,13 @@
                 if (!type || (type->type != SYM_PTR && type->type != SYM_ARRAY))
                         continue;
                 rl = get_array_size_bytes_rl(arg);
                 if (!rl)
                         continue;
+                if (rl_min(rl).value == UNKNOWN_SIZE &&
+                    rl_max(rl).value == UNKNOWN_SIZE)
+                        continue;
                 if (is_whole_rl(rl))
                         continue;
                 if (is_type_bytes(rl, arg))
                         continue;
                 sql_insert_caller_info(expr, BUF_SIZE, i, "$", show_rl(rl));

@@ -907,16 +932,16 @@
                 add_allocation_function("kmalloc", &match_alloc, 0);
                 add_allocation_function("kmalloc_node", &match_alloc, 0);
                 add_allocation_function("kzalloc", &match_alloc, 0);
                 add_allocation_function("kzalloc_node", &match_alloc, 0);
                 add_allocation_function("vmalloc", &match_alloc, 0);
+                add_allocation_function("vzalloc", &match_alloc, 0);
                 add_allocation_function("__vmalloc", &match_alloc, 0);
                 add_allocation_function("kvmalloc", &match_alloc, 0);
                 add_allocation_function("kcalloc", &match_calloc, 0);
                 add_allocation_function("kmalloc_array", &match_calloc, 0);
-                add_allocation_function("drm_malloc_ab", &match_calloc, 0);
-                add_allocation_function("drm_calloc_large", &match_calloc, 0);
+                add_allocation_function("devm_kmalloc_array", &match_calloc, 1);
                 add_allocation_function("sock_kmalloc", &match_alloc, 1);
                 add_allocation_function("kmemdup", &match_alloc, 1);
                 add_allocation_function("kmemdup_user", &match_alloc, 1);
                 add_allocation_function("dma_alloc_attrs", &match_alloc, 1);
                 add_allocation_function("pci_alloc_consistent", &match_alloc, 1);