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);
}
+