Print this page
11972 resync smatch

@@ -81,35 +81,27 @@
 static struct smatch_state *empty_state(struct sm_state *sm)
 {
         return alloc_estate_empty();
 }
 
-static void pre_merge_hook(struct sm_state *sm)
+static void pre_merge_hook(struct sm_state *cur, struct sm_state *other)
 {
-        struct smatch_state *user;
+        struct smatch_state *user = cur->state;
         struct smatch_state *extra;
         struct smatch_state *state;
         struct range_list *rl;
-        sval_t dummy;
-        sval_t sval_100;
 
-        sval_100.value = 100;
-        sval_100.type = &int_ctype;
-
-        user = __get_state(my_id, sm->name, sm->sym);
-        if (!user || !estate_rl(user))
-                return;
-        extra = __get_state(SMATCH_EXTRA, sm->name, sm->sym);
+        extra = __get_state(SMATCH_EXTRA, cur->name, cur->sym);
         if (!extra)
                 return;
         rl = rl_intersection(estate_rl(user), estate_rl(extra));
-        if (rl_to_sval(rl, &dummy))
-                rl = NULL;
         state = alloc_estate_rl(clone_rl(rl));
-        if (estate_capped(user) || is_capped_var_sym(sm->name, sm->sym))
+        if (estate_capped(user) || is_capped_var_sym(cur->name, cur->sym))
                 estate_set_capped(state);
-        set_state(my_id, sm->name, sm->sym, state);
+        if (estate_treat_untagged(user))
+                estate_set_treat_untagged(state);
+        set_state(my_id, cur->name, cur->sym, state);
 }
 
 static void extra_nomod_hook(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
 {
         struct smatch_state *user, *new;

@@ -122,10 +114,12 @@
         if (rl_equiv(rl, estate_rl(user)))
                 return;
         new = alloc_estate_rl(rl);
         if (estate_capped(user))
                 estate_set_capped(new);
+        if (estate_treat_untagged(user))
+                estate_set_treat_untagged(new);
         set_state(my_id, name, sym, new);
 }
 
 static bool binop_capped(struct expression *expr)
 {

@@ -179,10 +173,32 @@
                 return false;  /* uncapped user data */
 
         return true;  /* not actually user data */
 }
 
+bool user_rl_treat_untagged(struct expression *expr)
+{
+        struct smatch_state *state;
+        struct range_list *rl;
+        sval_t sval;
+
+        expr = strip_expr(expr);
+        if (!expr)
+                return false;
+        if (get_value(expr, &sval))
+                return true;
+
+        state = get_state_expr(my_id, expr);
+        if (state)
+                return estate_treat_untagged(state);
+
+        if (get_user_rl(expr, &rl))
+                return false;  /* uncapped user data */
+
+        return true;  /* not actually user data */
+}
+
 static void tag_inner_struct_members(struct expression *expr, struct symbol *member)
 {
         struct expression *edge_member;
         struct symbol *base = get_real_base_type(member);
         struct symbol *tmp;

@@ -544,11 +560,11 @@
         name = get_macro_name(expr->pos);
         if (!name || strcmp(name, "get_user") != 0)
                 return 0;
 
         name = expr_to_var(expr->right);
-        if (!name || strcmp(name, "__val_gu") != 0)
+        if (!name || (strcmp(name, "__val_gu") != 0 && strcmp(name, "__gu_val") != 0))
                 goto free;
         set_state_expr(my_id, expr->left, alloc_estate_whole(get_type(expr->left)));
         ret = 1;
 free:
         free_string(name);

@@ -580,10 +596,12 @@
 
                 rl = cast_rl(get_type(expr->left), rl);
                 state = alloc_estate_rl(rl);
                 if (user_rl_capped(binop_expr))
                         estate_set_capped(state);
+                if (user_rl_treat_untagged(expr->left))
+                        estate_set_treat_untagged(state);
                 set_state_expr(my_id, expr->left, state);
                 return true;
         }
         return false;
 }

@@ -621,12 +639,15 @@
         if (!get_user_rl(expr->right, &rl))
                 goto clear_old_state;
 
         rl = cast_rl(get_type(expr->left), rl);
         state = alloc_estate_rl(rl);
+
         if (user_rl_capped(expr->right))
                 estate_set_capped(state);
+        if (user_rl_treat_untagged(expr->right))
+                estate_set_treat_untagged(state);
         set_state_expr(my_id, expr->left, state);
 
         return;
 
 clear_old_state:

@@ -658,19 +679,14 @@
 }
 
 static struct range_list *strip_negatives(struct range_list *rl)
 {
         sval_t min = rl_min(rl);
-        sval_t minus_one;
-        sval_t over;
+        sval_t minus_one = { .type = rl_type(rl), .value = -1 };
+        sval_t over = { .type = rl_type(rl), .value = INT_MAX + 1ULL };
         sval_t max = sval_type_max(rl_type(rl));
 
-        minus_one.type = rl_type(rl);
-        minus_one.value = INT_MAX + 1ULL;
-        over.type = rl_type(rl);
-        over.value = -1;
-
         if (!rl)
                 return NULL;
 
         if (type_unsigned(rl_type(rl)) && type_bits(rl_type(rl)) > 31)
                 return remove_range(rl, over, max);

@@ -1018,12 +1034,14 @@
         static char buf[64];
 
         if (!get_user_rl(expr, &rl))
                 return NULL;
         rl = cast_rl(type, rl);
-        snprintf(buf, sizeof(buf), "%s%s",
-                 show_rl(rl), user_rl_capped(expr) ? "[c]" : "");
+        snprintf(buf, sizeof(buf), "%s%s%s",
+                 show_rl(rl),
+                 user_rl_capped(expr) ? "[c]" : "",
+                 user_rl_treat_untagged(expr) ? "[u]" : "");
         return buf;
 }
 
 static void match_call_info(struct expression *expr)
 {

@@ -1091,12 +1109,13 @@
                 rl = rl_intersection(estate_rl(sm->state), estate_rl(state));
 
         if (!rl)
                 return;
 
-        snprintf(buf, sizeof(buf), "%s%s", show_rl(rl),
-                 estate_capped(sm->state) ? "[c]" : "");
+        snprintf(buf, sizeof(buf), "%s%s%s", show_rl(rl),
+                 estate_capped(sm->state) ? "[c]" : "",
+                 estate_treat_untagged(sm->state) ? "[u]" : "");
         sql_insert_caller_info(call, USER_DATA, param, printed_name, buf);
 }
 
 static void db_param_set(struct expression *expr, int param, char *key, char *value)
 {

@@ -1131,10 +1150,17 @@
         if (strstr(value, ",c") || strstr(value, "[c"))
                 return true;
         return false;
 }
 
+static bool param_data_treat_untagged(const char *value)
+{
+        if (strstr(value, ",u") || strstr(value, "[u"))
+                return true;
+        return false;
+}
+
 static void set_param_user_data(const char *name, struct symbol *sym, char *key, char *value)
 {
         struct range_list *rl = NULL;
         struct smatch_state *state;
         struct expression *expr;

@@ -1178,10 +1204,12 @@
 
         str_to_rl(type, value, &rl);
         state = alloc_estate_rl(rl);
         if (param_data_capped(value) || is_capped(expr))
                 estate_set_capped(state);
+        if (param_data_treat_untagged(value) || sym->ctype.as == 5)
+                estate_set_treat_untagged(state);
         set_state(my_id, fullname, sym, state);
 }
 
 static void set_called(const char *name, struct symbol *sym, char *key, char *value)
 {

@@ -1250,10 +1278,12 @@
         call_results_to_rl(expr, type, value, &rl);
 
         state = alloc_estate_rl(rl);
         if (param_data_capped(value))
                 estate_set_capped(state);
+        if (param_data_treat_untagged(value))
+                estate_set_treat_untagged(state);
         set_state(my_id, name, sym, state);
 free:
         free_string(name);
 }
 

@@ -1357,13 +1387,14 @@
                 if (!param_name)
                         continue;
                 if (strcmp(param_name, "$") == 0)  /* The -1 param is handled after the loop */
                         continue;
 
-                snprintf(buf, sizeof(buf), "%s%s",
+                snprintf(buf, sizeof(buf), "%s%s%s",
                          show_rl(estate_rl(sm->state)),
-                         estate_capped(sm->state) ? "[c]" : "");
+                         estate_capped(sm->state) ? "[c]" : "",
+                         estate_treat_untagged(sm->state) ? "[u]" : "");
                 sql_insert_return_states(return_id, return_ranges,
                                          func_gets_user_data ? USER_DATA_SET : USER_DATA,
                                          param, param_name, buf);
         } END_FOR_EACH_SM(sm);
 

@@ -1379,22 +1410,25 @@
                         continue;
                 if (strcmp(param_name, "$") == 0)
                         return_found = true;
                 if (strcmp(param_name, "*$") == 0)
                         pointed_at_found = true;
-                snprintf(buf, sizeof(buf), "%s%s",
+                snprintf(buf, sizeof(buf), "%s%s%s",
                          show_rl(estate_rl(sm->state)),
-                         estate_capped(sm->state) ? "[c]" : "");
+                         estate_capped(sm->state) ? "[c]" : "",
+                         estate_treat_untagged(sm->state) ? "[u]" : "");
                 sql_insert_return_states(return_id, return_ranges,
                                          func_gets_user_data ? USER_DATA_SET : USER_DATA,
                                          -1, param_name, buf);
         } END_FOR_EACH_SM(sm);
 
         /* This if for "return ntohl(foo);" */
         if (!return_found && get_user_rl(expr, &rl)) {
-                snprintf(buf, sizeof(buf), "%s%s",
-                         show_rl(rl), user_rl_capped(expr) ? "[c]" : "");
+                snprintf(buf, sizeof(buf), "%s%s%s",
+                         show_rl(rl),
+                         user_rl_capped(expr) ? "[c]" : "",
+                         user_rl_treat_untagged(expr) ? "[u]" : "");
                 sql_insert_return_states(return_id, return_ranges,
                                          func_gets_user_data ? USER_DATA_SET : USER_DATA,
                                          -1, "$", buf);
         }
 

@@ -1510,5 +1544,6 @@
 
         if (option_project != PROJ_KERNEL)
                 return;
         select_caller_info_hook(set_called, INTERNAL);
 }
+