From b215689f648c2ced400e9db5884d8cdc808e7a1d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 14 Dec 2012 15:37:13 +0300 Subject: [PATCH] implied: introduce overwrite_states_using_pool() The situation here is that I have a "return foo;". I know that "foo" can be 0, -EINVAL, or -ENOMEM. All the possible values of foo are stored in the ->possible slist. I don't care so much about the merged states, only the original places where the error codes were set. So I pass the each of the possible states here to find out what implications are. Signed-off-by: Dan Carpenter --- smatch.h | 1 + smatch_implied.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/smatch.h b/smatch.h index 4b9805fe..274a23fe 100644 --- a/smatch.h +++ b/smatch.h @@ -336,6 +336,7 @@ struct state_list *__implied_case_slist(struct expression *switch_expr, struct range_list_stack **remaining_cases, struct state_list **raw_slist); struct range_list *__get_implied_values(struct expression *switch_expr); +void overwrite_states_using_pool(struct sm_state *sm); /* smatch_extras.c */ #define SMATCH_EXTRA 1 /* this is my_id from smatch extra set in smatch.c */ diff --git a/smatch_implied.c b/smatch_implied.c index be6d44c5..b0df4377 100644 --- a/smatch_implied.c +++ b/smatch_implied.c @@ -631,6 +631,40 @@ void get_implications(char *name, struct symbol *sym, int comparison, long long separate_and_filter(sm, comparison, tmp_range_list(num), LEFT, __get_cur_slist(), true_states, false_states); } +static int sm_state_in_slist(struct sm_state *sm, struct state_list *slist) +{ + struct sm_state *tmp; + + FOR_EACH_PTR(sm->pool, tmp) { + if (tmp == sm) + return 1; + } END_FOR_EACH_PTR(tmp); + return 0; +} + +/* + * The situation is we have a SMATCH_EXTRA state and we want to break it into + * each of the ->possible states and find the implications of each. The caller + * has to use __push_fake_cur_slist() to preserve the correct states so they + * can be restored later. + */ +void overwrite_states_using_pool(struct sm_state *sm) +{ + struct sm_state *old; + struct sm_state *new; + + if (!sm->pool) + return; + + FOR_EACH_PTR(sm->pool, old) { + new = get_sm_state(old->owner, old->name, old->sym); + if (!new) /* the variable went out of scope */ + continue; + if (sm_state_in_slist(old, new->possible)) + set_state(old->owner, old->name, old->sym, old->state); + } END_FOR_EACH_PTR(old); +} + void __extra_match_condition(struct expression *expr); void register_implications(int id) { -- 2.11.4.GIT