Print this page
new smatch

@@ -67,10 +67,22 @@
         } END_FOR_EACH_SM(tmp);
 
         return 0;
 }
 
+static bool is_ignored_macro(struct expression *expr)
+{
+        char *macro;
+
+        macro = get_macro_name(expr->pos);
+        if (!macro)
+                return false;
+        if (strcmp(macro, "EXPORT_SYMBOL") == 0)
+                return true;
+        return false;
+}
+
 static void insert_mtag_data(mtag_t tag, int offset, struct range_list *rl)
 {
         rl = clone_rl_permanent(rl);
 
         mem_sql(NULL, NULL, "delete from mtag_data where tag = %lld and offset = %d and type = %d",

@@ -77,18 +89,37 @@
                 tag, offset, DATA_VALUE);
         mem_sql(NULL, NULL, "insert into mtag_data values (%lld, %d, %d, '%lu');",
                 tag, offset, DATA_VALUE, (unsigned long)rl);
 }
 
-void update_mtag_data(struct expression *expr)
+static bool invalid_type(struct symbol *type)
 {
-        struct range_list *orig, *new, *rl;
+        if (!type)
+                return true;
+        if (type == &void_ctype)
+                return true;
+        if (type->type == SYM_STRUCT ||
+            type->type == SYM_ARRAY ||
+            type->type == SYM_UNION)
+                return true;
+        return false;
+}
+
+void update_mtag_data(struct expression *expr, struct smatch_state *state)
+{
+        struct range_list *orig, *new;
         struct symbol *type;
         char *name;
         mtag_t tag;
         int offset;
 
+        if (!expr)
+                return;
+        if (is_local_variable(expr))
+                return;
+        if (is_ignored_macro(expr))
+                return;
         name = expr_to_var(expr);
         if (is_kernel_param(name)) {
                 free_string(name);
                 return;
         }

@@ -96,19 +127,15 @@
 
         if (!expr_to_mtag_offset(expr, &tag, &offset))
                 return;
 
         type = get_type(expr);
-        if ((offset == 0) &&
-            (!type || type == &void_ctype ||
-             type->type == SYM_STRUCT || type->type == SYM_UNION || type->type == SYM_ARRAY))
+        if (offset == 0 && invalid_type(type))
                 return;
 
-        get_absolute_rl(expr, &rl);
-
         orig = select_orig(tag, offset);
-        new = rl_union(orig, rl);
+        new = rl_union(orig, estate_rl(state));
         insert_mtag_data(tag, offset, new);
 }
 
 static void match_global_assign(struct expression *expr)
 {

@@ -115,10 +142,12 @@
         struct range_list *rl;
         mtag_t tag;
         int offset;
         char *name;
 
+        if (is_ignored_macro(expr))
+                return;
         name = expr_to_var(expr->left);
         if (is_kernel_param(name)) {
                 free_string(name);
                 return;
         }

@@ -186,14 +215,10 @@
         mtag_t merged = tag | offset;
         static int idx;
         int ret;
         int i;
 
-        if (!type || type == &void_ctype ||
-            (type->type == SYM_STRUCT || type->type == SYM_ARRAY || type->type == SYM_UNION))
-                return 0;
-
         for (i = 0; i < ARRAY_SIZE(cached_results); i++) {
                 if (merged == cached_results[i].tag) {
                         if (cached_results[i].rl) {
                                 *rl = cached_results[i].rl;
                                 return 1;

@@ -233,17 +258,19 @@
 {
         struct symbol *type;
         mtag_t tag;
         int offset;
 
+        if (is_local_variable(expr))
+                return 0;
         if (!expr_to_mtag_offset(expr, &tag, &offset))
                 return 0;
         if (offset >= MTAG_OFFSET_MASK)
                 return 0;
 
         type = get_type(expr);
-        if (!type)
+        if (invalid_type(type))
                 return 0;
 
         return get_rl_from_mtag_offset(tag, offset, type, rl);
 }