From 3fe6bcb9756f34a3b25da07f14229619cf2694ff Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 6 Nov 2012 14:57:51 +0300 Subject: [PATCH] sval: create cast_rl() which casts a range list to a different type If the first range list falls outside the list of possible values then it just returns the whole range for that type. That's not totally the right thing to do, but it works for now. I use this function in smatch_extra.c match_comparison() because I want to get rid of a place which uses the pre sval version of range lists. Signed-off-by: Dan Carpenter --- smatch_extra.c | 4 ++-- smatch_extra.h | 1 + smatch_ranges.c | 25 +++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/smatch_extra.c b/smatch_extra.c index c3674e8c..8c3a3860 100644 --- a/smatch_extra.c +++ b/smatch_extra.c @@ -701,12 +701,12 @@ static void match_comparison(struct expression *expr) min = sval_type_min(&llong_ctype); max = sval_type_max(&llong_ctype); if (get_implied_range_list_sval(left, &left_orig)) - left_orig = range_list_to_sval(rl_sval_to_rl(left_orig)); // temporary hack to make things llong_ctype + left_orig = cast_rl(left_orig, &llong_ctype); // temporary hack to make things llong_ctype else left_orig = alloc_range_list_sval(min, max); if (get_implied_range_list_sval(right, &right_orig)) - right_orig = range_list_to_sval(rl_sval_to_rl(right_orig)); // temporary hack to make things llong_ctype + right_orig = cast_rl(right_orig, &llong_ctype); // temporary hack to make things llong_ctype else right_orig = alloc_range_list_sval(min, max); diff --git a/smatch_extra.h b/smatch_extra.h index 0a1cee4b..a01dae0f 100644 --- a/smatch_extra.h +++ b/smatch_extra.h @@ -115,6 +115,7 @@ struct range_list_sval *pop_range_list_sval(struct range_list_stack_sval **rl_st struct range_list_sval *top_range_list_sval(struct range_list_stack_sval *rl_stack); void filter_top_range_list_sval(struct range_list_stack_sval **rl_stack, sval_t sval); +struct range_list_sval *cast_rl(struct range_list_sval *rl, struct symbol *type); int get_implied_range_list_sval(struct expression *expr, struct range_list_sval **rl); int is_whole_range(struct smatch_state *state); diff --git a/smatch_ranges.c b/smatch_ranges.c index 2864145a..0249c392 100644 --- a/smatch_ranges.c +++ b/smatch_ranges.c @@ -694,6 +694,31 @@ void filter_top_range_list_sval(struct range_list_stack_sval **rl_stack, sval_t push_range_list_sval(rl_stack, rl); } +struct range_list_sval *cast_rl(struct range_list_sval *rl, struct symbol *type) +{ + struct data_range_sval *tmp; + struct data_range_sval *new; + struct range_list_sval *ret = NULL; + sval_t sval; + + if (!type) + return clone_range_list_sval(rl); + + sval = sval_cast(rl_min_sval(rl), type); + if (sval_cmp(sval, rl_min_sval(rl)) != 0) + return alloc_range_list_sval(sval_type_min(type), sval_type_max(type)); + sval = sval_cast(rl_min_sval(rl), type); + if (sval_cmp(sval, rl_min_sval(rl)) != 0) + return alloc_range_list_sval(sval_type_min(type), sval_type_max(type)); + + FOR_EACH_PTR(rl, tmp) { + new = alloc_range_sval(sval_cast(tmp->min, type), sval_cast(tmp->max, type)); + add_ptr_list(&ret, new); + } END_FOR_EACH_PTR(tmp); + + return ret; +} + void free_range_list_sval(struct range_list_sval **rlist) { __free_ptr_list((struct ptr_list **)rlist); -- 2.11.4.GIT