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

@@ -79,12 +79,51 @@
         if (strcmp(macro, "EXPORT_SYMBOL") == 0)
                 return true;
         return false;
 }
 
+static bool is_head_next(struct expression *expr)
+{
+        struct symbol *type;
+
+        /* Smatch thinks head->next == head is always true.  *sad face* */
+
+        if (option_project != PROJ_KERNEL)
+                return false;
+
+        if (expr->type != EXPR_DEREF)
+                return false;
+        if (!expr->member || !expr->member->name ||
+            strcmp(expr->member->name, "next") != 0)
+                return false;
+
+        type = get_type(expr->deref);
+        if (!type)
+                return false;
+        if (type->type == SYM_PTR)
+                type = get_real_base_type(type);
+        if (type->type != SYM_STRUCT)
+                return false;
+        if (!type->ident || !type->ident->name ||
+            strcmp(type->ident->name, "list_head") != 0)
+                return false;
+        return true;
+}
+
+mtag_t ignored_mtag;
+static bool is_ignored_tag(mtag_t tag)
+{
+        if (tag == ignored_mtag)
+                return true;
+        return false;
+}
+
 static void insert_mtag_data(mtag_t tag, int offset, struct range_list *rl)
 {
+        if (is_ignored_tag(tag))
+                return;
+
         rl = clone_rl_permanent(rl);
 
         mem_sql(NULL, NULL, "delete from mtag_data where tag = %lld and offset = %d and type = %d",
                 tag, offset, DATA_VALUE);
         mem_sql(NULL, NULL, "insert into mtag_data values (%lld, %d, %d, '%lu');",

@@ -102,10 +141,20 @@
             type->type == SYM_UNION)
                 return true;
         return false;
 }
 
+static bool parent_is_fresh_alloc(struct expression *expr)
+{
+        struct symbol *sym;
+
+        sym = expr_to_sym(expr);
+        if (!sym || !sym->ident)
+                return false;
+        return is_fresh_alloc_var_sym(sym->ident->name, sym);
+}
+
 void update_mtag_data(struct expression *expr, struct smatch_state *state)
 {
         struct range_list *orig, *new;
         struct symbol *type;
         char *name;

@@ -116,10 +165,12 @@
                 return;
         if (is_local_variable(expr))
                 return;
         if (is_ignored_macro(expr))
                 return;
+        if (is_head_next(expr))
+                return;
         name = expr_to_var(expr);
         if (is_kernel_param(name)) {
                 free_string(name);
                 return;
         }

@@ -130,10 +181,13 @@
 
         type = get_type(expr);
         if (offset == 0 && invalid_type(type))
                 return;
 
+        if (parent_is_fresh_alloc(expr))
+                orig = NULL;
+        else
         orig = select_orig(tag, offset);
         new = rl_union(orig, estate_rl(state));
         insert_mtag_data(tag, offset, new);
 }
 

@@ -144,10 +198,12 @@
         int offset;
         char *name;
 
         if (is_ignored_macro(expr))
                 return;
+        if (is_head_next(expr->left))
+                return;
         name = expr_to_var(expr->left);
         if (is_kernel_param(name)) {
                 free_string(name);
                 return;
         }

@@ -276,10 +332,11 @@
 
 void register_mtag_data(int id)
 {
         my_id = id;
 
+        ignored_mtag = str_to_mtag("extern boot_params");
         add_hook(&clear_cache, FUNC_DEF_HOOK);
 
 //      if (!option_info)
 //              return;
         add_hook(&match_global_assign, GLOBAL_ASSIGNMENT_HOOK);