From b7c7aacffb11c9437507f101eb47d78f80cc3c48 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 10 Feb 2009 19:46:25 +0300 Subject: [PATCH] Fix implied pools so that at least it does something. If you have the simple case of: if (foo) then it will hopefully use the states which are implied by a non-zero foo. Signed-off-by: Dan Carpenter --- smatch_implied.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- smatch_slist.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 94 insertions(+), 12 deletions(-) diff --git a/smatch_implied.c b/smatch_implied.c index 819d6a75..5a8dac1e 100644 --- a/smatch_implied.c +++ b/smatch_implied.c @@ -49,6 +49,39 @@ #include "smatch_slist.h" /* + * This function gets all the states which are implied by a non zero value. + * So for example for the code: + * if (c) { + * We would want to know what was implied by c is non zero. + */ + +static struct state_list *get_non_zero_filtered(struct sm_state *sm_state) +{ + struct state_list *list; + struct smatch_state *s; + struct state_list *ret = NULL; + + FOR_EACH_PTR(sm_state->pools, list) { + s = get_state_slist(list, sm_state->name, sm_state->owner, + sm_state->sym); + if (s == &undefined) { + del_slist(&ret); + return NULL; + } + if (s->data && *(int *)s->data != 0) { + printf("debug %s is %d\n", s->name, *(int *)s->data); + + if (!ret) + ret = clone_slist(list); + else + filter(&ret, list); + } + } END_FOR_EACH_PTR(list); + return ret; +} + + +/* * This condition hook is very connected to smatch_extra.c. * It's registered there. */ @@ -58,13 +91,24 @@ void __implied_states_hook(struct expression *expr) struct symbol *sym; char *name; struct sm_state *state; + struct state_list *implied_states; - //printf("type = %d\n", expr->type); - - if (expr->type != EXPR_COMPARE || expr->op != SPECIAL_EQUAL) + if (expr->type != EXPR_COMPARE) return; - name = get_variable_from_expr(expr->left, &sym); + name = get_variable_from_expr(expr, &sym); state = __get_sm_state(name, SMATCH_EXTRA, sym); + if (!state) + return; + if (!state->pools) { + printf("no pools for %s\n", state->name); + return; + } + implied_states = get_non_zero_filtered(state); + if (debug_states) { + printf("Setting the following implied states\n"); + __print_slist(implied_states); + } + __overwrite_cur_slist(implied_states); free_string(name); } diff --git a/smatch_slist.c b/smatch_slist.c index f1e0cec8..e742d874 100644 --- a/smatch_slist.c +++ b/smatch_slist.c @@ -24,7 +24,7 @@ void __print_slist(struct state_list *slist) printf("dumping slist at %d\n", get_lineno()); FOR_EACH_PTR(slist, state) { - printf("'%s'=%s\n", state->name, show_state(state->state)); + printf("%d '%s'=%s\n", state->owner, state->name, show_state(state->state)); } END_FOR_EACH_PTR(state); printf("---\n"); } @@ -260,7 +260,7 @@ void set_state_slist(struct state_list **slist, const char *name, int owner, { struct sm_state *tmp; struct sm_state *new = alloc_state(name, owner, sym, state); - + FOR_EACH_PTR(*slist, tmp) { if (cmp_sm_states(tmp, new) < 0) continue; @@ -359,6 +359,34 @@ static void add_pool(struct sm_state *state, struct state_list **pool) push_slist(&state->pools, *pool); } +/* fixme. rename. heck cleanup this whole file */ +static void add_single_pool(struct sm_state *to, struct state_list *new) +{ + struct state_list *tmp; + + FOR_EACH_PTR(to->pools, tmp) { + if (tmp < new) + continue; + else if (tmp == new) { + return; + } else { + INSERT_CURRENT(new, tmp); + return; + } + } END_FOR_EACH_PTR(tmp); + add_ptr_list(&to->pools, new); +} + +static void copy_pools(struct sm_state *to, struct sm_state *sm) +{ + struct state_list *tmp; + + + FOR_EACH_PTR(sm->pools, tmp) { + add_single_pool(to, tmp); + } END_FOR_EACH_PTR(tmp); +} + void merge_slist(struct state_list **to, struct state_list *slist) { struct sm_state *to_state, *state, *tmp; @@ -398,18 +426,28 @@ void merge_slist(struct state_list **to, struct state_list *slist) } else if (cmp_sm_states(to_state, state) == 0) { if (to_state->state == state->state) { s = to_state->state; + tmp = alloc_state(to_state->name, + to_state->owner, + to_state->sym, s); + } else { s = merge_states(to_state->name, to_state->owner, to_state->sym, to_state->state, state->state); - add_pool(to_state, &implied_to); - add_pool(state, &implied_from); + + tmp = alloc_state(to_state->name, + to_state->owner, + to_state->sym, s); + + + add_ptr_list(&implied_to, to_state); + add_ptr_list(&implied_from, state); + copy_pools(tmp, to_state); + copy_pools(tmp, state); + add_single_pool(tmp, implied_to); + add_single_pool(tmp, implied_from); } - tmp = alloc_state(to_state->name, to_state->owner, - to_state->sym, s); - add_possible(tmp, to_state); - add_possible(tmp, state); add_ptr_list(&results, tmp); NEXT_PTR_LIST(to_state); NEXT_PTR_LIST(state); -- 2.11.4.GIT