From b89d558ac03782530a6430481e113008bc0e8de5 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 13 Jun 2013 14:06:52 +0300 Subject: [PATCH] db, comparison, ranges: store ranges and comparison instead only one or other In the old format something could be stored as a range: s32min-10 Or if we couldn't determine any range then it might be stored as a comparison: s32min-[ --- smatch.h | 3 ++- smatch_comparison.c | 20 -------------------- smatch_db.c | 23 ++++++++++++++++------- smatch_extra.h | 2 +- smatch_ranges.c | 27 +++++++++++++++++++++++---- 5 files changed, 42 insertions(+), 33 deletions(-) diff --git a/smatch.h b/smatch.h index c58b53a3..d4d3690b 100644 --- a/smatch.h +++ b/smatch.h @@ -605,7 +605,8 @@ struct expression *get_assigned_expr(struct expression *expr); /* smatch_comparison.c */ int get_comparison(struct expression *left, struct expression *right); void __add_comparison_info(struct expression *expr, struct expression *call, const char *range); -char *range_comparison_to_param(struct expression *expr); +char *expr_equal_to_param(struct expression *expr); +char *expr_lte_to_param(struct expression *expr); /* smatch_sval.c */ sval_t *sval_alloc(sval_t sval); diff --git a/smatch_comparison.c b/smatch_comparison.c index 67bde5ff..f57d5ccb 100644 --- a/smatch_comparison.c +++ b/smatch_comparison.c @@ -710,26 +710,6 @@ char *expr_lte_to_param(struct expression *expr) return range_comparison_to_param_helper(expr, '<'); } -char *range_comparison_to_param(struct expression *expr) -{ - char *comparison_str; - char buf[256]; - sval_t min; - - comparison_str = expr_equal_to_param(expr); - if (comparison_str) { - snprintf(buf, sizeof(buf), "%s", comparison_str); - return alloc_sname(buf); - } - - comparison_str = expr_lte_to_param(expr); - if (!comparison_str) - return NULL; - get_absolute_min(expr, &min); - snprintf(buf, sizeof(buf), "%s-%s", sval_to_str(min), comparison_str); - return alloc_sname(buf); -} - static void free_data(struct symbol *sym) { if (__inline_fn) diff --git a/smatch_db.c b/smatch_db.c index faa47cd2..1ccd91ad 100644 --- a/smatch_db.c +++ b/smatch_db.c @@ -803,18 +803,27 @@ static char *get_return_ranges_str(struct expression *expr) { struct range_list *rl; char *return_ranges; + char *compare_str; + char buf[128]; if (!expr) return alloc_sname(""); - if (get_implied_rl(expr, &rl) && !is_whole_rl(rl)) { + compare_str = expr_equal_to_param(expr); + if (compare_str) + return compare_str; + + if (get_implied_rl(expr, &rl)) { rl = cast_rl(cur_func_return_type(), rl); - return show_rl(rl); + return_ranges = show_rl(rl); + } else { + rl = cast_rl(cur_func_return_type(), alloc_whole_rl(get_type(expr))); + return_ranges = show_rl(rl); + } + compare_str = expr_lte_to_param(expr); + if (compare_str) { + snprintf(buf, sizeof(buf), "%s%s", return_ranges, compare_str); + return alloc_sname(buf); } - return_ranges = range_comparison_to_param(expr); - if (return_ranges) - return return_ranges; - rl = cast_rl(cur_func_return_type(), alloc_whole_rl(get_type(expr))); - return_ranges = show_rl(rl); return return_ranges; } diff --git a/smatch_extra.h b/smatch_extra.h index f4503c05..003191cd 100644 --- a/smatch_extra.h +++ b/smatch_extra.h @@ -28,7 +28,7 @@ extern struct string_list *__ignored_macros; /* these are implemented in smatch_ranges.c */ char *show_rl(struct range_list *list); -int str_to_comparison_arg(const char *c, struct expression *call, int *comparison, struct expression **arg, char **endp); +int str_to_comparison_arg(const char *c, struct expression *call, int *comparison, struct expression **arg); void str_to_rl(struct symbol *type, char *value, struct range_list **rl); void call_results_to_rl(struct expression *call, struct symbol *type, char *value, struct range_list **rl); diff --git a/smatch_ranges.c b/smatch_ranges.c index 9e31c34f..8098acf9 100644 --- a/smatch_ranges.c +++ b/smatch_ranges.c @@ -39,7 +39,9 @@ char *show_rl(struct range_list *list) return alloc_sname(full); } -int str_to_comparison_arg(const char *str, struct expression *call, int *comparison, struct expression **arg, char **endp) +static int str_to_comparison_arg_helper(const char *str, + struct expression *call, int *comparison, + struct expression **arg, char **endp) { int param; char *c = (char *)str; @@ -89,6 +91,17 @@ int str_to_comparison_arg(const char *str, struct expression *call, int *compari return 1; } +int str_to_comparison_arg(const char *str, struct expression *call, int *comparison, struct expression **arg) +{ + while (1) { + if (!*str) + return 0; + if (*str == '[') + break; + str++; + } + return str_to_comparison_arg_helper(str, call, comparison, arg, NULL); +} static sval_t get_val_from_key(int use_max, struct symbol *type, char *c, struct expression *call, char **endp) { @@ -101,7 +114,7 @@ static sval_t get_val_from_key(int use_max, struct symbol *type, char *c, struct else ret = sval_type_min(type); - if (!str_to_comparison_arg(c, call, &comparison, &arg, endp)) + if (!str_to_comparison_arg_helper(c, call, &comparison, &arg, endp)) return ret; if (use_max && get_implied_max(arg, &tmp)) { @@ -161,6 +174,7 @@ static sval_t parse_val(int use_max, struct expression *call, struct symbol *typ ret = sval_type_val(type, SHRT_MIN); c += 6; } else if (start[0] == '[') { + /* this parses [==p0] comparisons */ ret = get_val_from_key(1, type, start, call, &c); } else { ret = sval_type_val(type, strtoll(start, &c, 10)); @@ -171,7 +185,7 @@ static sval_t parse_val(int use_max, struct expression *call, struct symbol *typ static void str_to_rl_helper(struct expression *call, struct symbol *type, char *value, struct range_list **rl) { - sval_t min, max; + sval_t min, max, arg_max; char *c; if (!type) @@ -185,7 +199,7 @@ static void str_to_rl_helper(struct expression *call, struct symbol *type, char struct expression *arg; int comparison; - if (!str_to_comparison_arg(value, call, &comparison, &arg, NULL)) + if (!str_to_comparison_arg(value, call, &comparison, &arg)) goto out; get_implied_rl(arg, rl); goto out; @@ -215,6 +229,11 @@ static void str_to_rl_helper(struct expression *call, struct symbol *type, char if (*c == '(') c++; max = parse_val(1, call, type, c, &c); + if (*c == '[') { + arg_max = get_val_from_key(1, type, c, call, &c); + if (sval_cmp(arg_max, max) < 0) + max = arg_max; + } add_range(rl, min, max); if (*c == ')') c++; -- 2.11.4.GIT