From 2283d50c5ee24373d46a29fdee5807377181410e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 3 Apr 2009 23:17:35 +0300 Subject: [PATCH] range fix. anding slists. Anding slists is still not totally right but this patch moves it back to the way it was before the implied ranges change. Signed-off-by: Dan Carpenter --- Makefile | 2 +- smatch_extra.c | 27 +++++++++++++++++++++++++++ smatch_extra.h | 7 +++++++ smatch_slist.c | 32 ++++++++++++++++++++++++++++++-- smatch_slist.h | 2 -- 5 files changed, 65 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 2448f4f2..a7be884b 100644 --- a/Makefile +++ b/Makefile @@ -179,7 +179,7 @@ smatch_files.o: $(LIB_H) smatch.h smatch_hooks.o: $(LIB_H) smatch.h smatch_function_hooks.o: $(LIB_H) smatch.h smatch_helper.o: $(LIB_H) smatch.h -smatch_slist.o: $(LIB_H) smatch.h smatch_slist.h +smatch_slist.o: $(LIB_H) smatch.h smatch_slist.h smatch_extra.h smatch_states.o: $(LIB_H) smatch.h smatch_slist.h smatch.o: $(LIB_H) smatch.h $(SMATCH_CHECKS): smatch.h smatch_slist.h diff --git a/smatch_extra.c b/smatch_extra.c index 4e332388..4aaaa4eb 100644 --- a/smatch_extra.c +++ b/smatch_extra.c @@ -102,6 +102,33 @@ struct sm_state *__extra_merge(struct sm_state *one, struct state_list *slist1, return merge_sm_states(one, two); } +struct sm_state *__extra_and_merge(struct sm_state *sm, + struct state_list_stack *stack) +{ + struct state_list *slist; + struct sm_state *ret = NULL; + struct sm_state *tmp; + int i = 0; + + FOR_EACH_PTR(stack, slist) { + if (!i++) { + ret = get_sm_state_slist(slist, sm->name, sm->owner, + sm->sym); + } else { + tmp = get_sm_state_slist(slist, sm->name, sm->owner, + sm->sym); + ret = merge_sm_states(ret, tmp); + } + } END_FOR_EACH_PTR(slist); + if (!ret) { + smatch_msg("Internal error in __extra_and_merge"); + return NULL; + } + ret->my_pools = stack; + ret->all_pools = clone_stack(stack); + return ret; +} + static struct smatch_state *unmatched_state(struct sm_state *sm) { return &extra_undefined; diff --git a/smatch_extra.h b/smatch_extra.h index b5e5fd43..f915259b 100644 --- a/smatch_extra.h +++ b/smatch_extra.h @@ -28,3 +28,10 @@ int num_matches(struct data_info *dinfo, long long num); long long get_single_value(struct data_info *dinfo); int possibly_true(int comparison, struct data_info *dinfo, int num, int left); int possibly_false(int comparison, struct data_info *dinfo, int num, int left); + +/* used in smatch_slist. implemented in smatch_extra.c */ +struct sm_state *__extra_merge(struct sm_state *one, struct state_list *slist1, + struct sm_state *two, struct state_list *slist2); +struct sm_state *__extra_and_merge(struct sm_state *sm, + struct state_list_stack *stack); + diff --git a/smatch_slist.c b/smatch_slist.c index df3f795a..4fee8e4b 100644 --- a/smatch_slist.c +++ b/smatch_slist.c @@ -11,6 +11,7 @@ #include #include "smatch.h" #include "smatch_slist.h" +#include "smatch_extra.h" #undef CHECKORDER #undef CHECKMYPOOLS @@ -708,10 +709,12 @@ static struct sm_state *find_intersection(struct sm_state *one, struct state_list_stack *stack = NULL; struct sm_state *tmp_state; struct sm_state *ret; + int count = 0; if (!one) return two; - if (one->state != &merged) { + + if (one->owner != SMATCH_EXTRA && one->state != &merged) { if (one->state == two->state) return one; if (two->state != &merged) { @@ -722,6 +725,24 @@ static struct sm_state *find_intersection(struct sm_state *one, return two; } } + if (one->owner == SMATCH_EXTRA) { + if (one->state == two->state) + return one; + + ret = NULL; + if (!one->my_pools) { + smatch_msg("debug: huh? no pools for %s %s", + one->name, show_state(one->state)); + ret = one; + } + if (!two->my_pools) { + smatch_msg("debug: what? no pools for %s %s", + two->name, show_state(two->state)); + ret = two; + } + if (ret) + return ret; + } PREPARE_PTR_LIST(one->my_pools, tmp1); PREPARE_PTR_LIST(two->my_pools, tmp2); @@ -732,6 +753,7 @@ static struct sm_state *find_intersection(struct sm_state *one, NEXT_PTR_LIST(tmp1); } else if (tmp1 == tmp2) { push_slist(&stack, tmp1); + count++; NEXT_PTR_LIST(tmp1); NEXT_PTR_LIST(tmp2); } else { @@ -741,12 +763,18 @@ static struct sm_state *find_intersection(struct sm_state *one, FINISH_PTR_LIST(tmp2); FINISH_PTR_LIST(tmp1); - if (!stack) { + if (count == 0) { smatch_msg("mutually eXclusive 'and' conditions states " "'%s': %s + %s", one->name, show_state(one->state), show_state(two->state)); return two; } + if (count == 1) + return get_sm_state_stack(stack, one->name, one->owner, + one->sym); + + if (one->owner == SMATCH_EXTRA) + return __extra_and_merge(one, stack); ret = alloc_state_no_name(one->name, one->owner, one->sym, &merged); FOR_EACH_PTR(stack, tmp1) { diff --git a/smatch_slist.h b/smatch_slist.h index ced3d86d..1bddf13f 100644 --- a/smatch_slist.h +++ b/smatch_slist.h @@ -75,5 +75,3 @@ struct state_list **get_slist_from_named_stack(struct named_stack *stack, const char *name); void overwrite_slist(struct state_list *from, struct state_list **to); -struct sm_state *__extra_merge(struct sm_state *one, struct state_list *slist1, - struct sm_state *two, struct state_list *slist2); -- 2.11.4.GIT