From 7339cbd9fc478f4082d1661148344a7ef70575ef Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 13 Apr 2012 18:49:36 +0300 Subject: [PATCH] db: print all return values at end of function The current code prints the return range whenever we come to a return statement. But sometimes we just want to know what the return values are that the function returns. That's what this change does. It combines a list of all the return ranges and prints out the possible return values at the end of the function. It looks like: fs/ntfs/super.c:541 ntfs_remount() info: function_return_values '(-30),(-22),0' Signed-off-by: Dan Carpenter --- check_db_info.c | 30 ++++++++++++++++++++++++++++-- smatch_extra.h | 1 + smatch_ranges.c | 5 +++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/check_db_info.c b/check_db_info.c index e1f07663..59310ae9 100644 --- a/check_db_info.c +++ b/check_db_info.c @@ -12,6 +12,17 @@ static int my_id; +static struct range_list *return_ranges; + +static void add_return_range(struct range_list *rl) +{ + if (!return_ranges) { + return_ranges = rl; + return; + } + return_ranges = range_list_union(return_ranges, rl); +} + static void match_return(struct expression *ret_value) { struct smatch_state *state; @@ -24,24 +35,38 @@ static void match_return(struct expression *ret_value) if (ret_value->type == EXPR_CALL) { rl = db_return_vals(ret_value); - if (rl) + if (rl) { sm_msg("info: return_value %s", show_ranges(rl)); - else + add_return_range(rl); + } else { sm_msg("info: return_value unknown"); + add_return_range(whole_range_list()); + } return; } if (get_value(ret_value, &val)) { sm_msg("info: return_value %lld", val); + add_return_range(alloc_range_list(val, val)); return; } state = get_state_expr(SMATCH_EXTRA, ret_value); if (!state) { sm_msg("info: return_value unknown"); + add_return_range(whole_range_list()); return; } sm_msg("info: return_value %s", state->name); + add_return_range(whole_range_list()); +} + +static void match_end_func(struct symbol *sym) +{ + if (!return_ranges) + return; + sm_msg("info: function_return_values '%s'", show_ranges(return_ranges)); + return_ranges = NULL; } void check_db_info(int id) @@ -50,4 +75,5 @@ void check_db_info(int id) return; my_id = id; add_hook(&match_return, RETURN_HOOK); + add_hook(&match_end_func, END_FUNC_HOOK); } diff --git a/smatch_extra.h b/smatch_extra.h index 7d9038ef..08b5920c 100644 --- a/smatch_extra.h +++ b/smatch_extra.h @@ -37,6 +37,7 @@ long long rl_min(struct range_list *rl); long long rl_max(struct range_list *rl); struct data_range *alloc_range_perm(long long min, long long max); struct range_list *alloc_range_list(long long min, long long max); +struct range_list *whole_range_list(void); void add_range(struct range_list **list, long long min, long long max); int true_comparison_range(struct data_range *left, int comparison, struct data_range *right); int possibly_true(struct expression *left, int comparison, struct expression *right); diff --git a/smatch_ranges.c b/smatch_ranges.c index bb8f7794..6a98db2d 100644 --- a/smatch_ranges.c +++ b/smatch_ranges.c @@ -202,6 +202,11 @@ struct range_list *alloc_range_list(long long min, long long max) return rl; } +struct range_list *whole_range_list(void) +{ + return alloc_range_list(whole_range.min, whole_range.max); +} + void add_range(struct range_list **list, long long min, long long max) { struct data_range *tmp = NULL; -- 2.11.4.GIT