implied: introduce overwrite_states_using_pool()
authorDan Carpenter <dan.carpenter@oracle.com>
Fri, 14 Dec 2012 12:37:13 +0000 (14 15:37 +0300)
committerDan Carpenter <dan.carpenter@oracle.com>
Fri, 14 Dec 2012 12:37:13 +0000 (14 15:37 +0300)
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 <dan.carpenter@oracle.com>
smatch.h
smatch_implied.c

index 4b9805f..274a23f 100644 (file)
--- 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 */
index be6d44c..b0df437 100644 (file)
@@ -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)
 {