db: make the size limit for the database larger
[smatch.git] / smatch_estate.c
blob711013d8f75ca2c95be6064b8e03ad7e1f8c9057
1 /*
2 * smatch/smatch_dinfo.c
4 * Copyright (C) 2010 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
11 * smatch_dinfo.c has helper functions for handling data_info structs
15 #include <stdlib.h>
16 #ifndef __USE_ISOC99
17 #define __USE_ISOC99
18 #endif
19 #include <limits.h>
20 #include "parse.h"
21 #include "smatch.h"
22 #include "smatch_slist.h"
23 #include "smatch_extra.h"
25 struct smatch_state *merge_estates(struct smatch_state *s1, struct smatch_state *s2)
27 struct smatch_state *tmp;
28 struct range_list *value_ranges;
29 struct related_list *rlist;
31 if (estates_equiv(s1, s2))
32 return s1;
34 value_ranges = range_list_union(estate_ranges(s1), estate_ranges(s2));
35 tmp = alloc_estate_range_list(value_ranges);
36 rlist = get_shared_relations(estate_related(s1), estate_related(s2));
37 set_related(tmp, rlist);
38 if (estate_has_hard_max(s1) && estate_has_hard_max(s2))
39 estate_set_hard_max(tmp);
41 return tmp;
44 struct data_info *get_dinfo(struct smatch_state *state)
46 if (!state)
47 return NULL;
48 return (struct data_info *)state->data;
51 struct range_list *estate_ranges(struct smatch_state *state)
53 if (!state)
54 return NULL;
55 return get_dinfo(state)->value_ranges;
58 struct related_list *estate_related(struct smatch_state *state)
60 if (!state)
61 return NULL;
62 return get_dinfo(state)->related;
65 int estate_has_hard_max(struct smatch_state *state)
67 if (!state)
68 return 0;
69 return get_dinfo(state)->hard_max;
72 void estate_set_hard_max(struct smatch_state *state)
74 get_dinfo(state)->hard_max = 1;
77 void estate_clear_hard_max(struct smatch_state *state)
79 get_dinfo(state)->hard_max = 0;
82 int estate_get_hard_max(struct smatch_state *state, sval_t *sval)
84 if (!state || !get_dinfo(state)->hard_max || !estate_ranges(state))
85 return 0;
86 *sval = rl_max(estate_ranges(state));
87 return 1;
90 sval_t estate_min(struct smatch_state *state)
92 return rl_min(estate_ranges(state));
95 sval_t estate_max(struct smatch_state *state)
97 return rl_max(estate_ranges(state));
100 struct symbol *estate_type(struct smatch_state *state)
102 return rl_max(estate_ranges(state)).type;
105 static int rlists_equiv(struct related_list *one, struct related_list *two)
107 struct relation *one_rel;
108 struct relation *two_rel;
110 PREPARE_PTR_LIST(one, one_rel);
111 PREPARE_PTR_LIST(two, two_rel);
112 for (;;) {
113 if (!one_rel && !two_rel)
114 return 1;
115 if (!one_rel || !two_rel)
116 return 0;
117 if (one_rel->sym != two_rel->sym)
118 return 0;
119 if (strcmp(one_rel->name, two_rel->name))
120 return 0;
121 NEXT_PTR_LIST(one_rel);
122 NEXT_PTR_LIST(two_rel);
124 FINISH_PTR_LIST(two_rel);
125 FINISH_PTR_LIST(one_rel);
127 return 1;
130 int estates_equiv(struct smatch_state *one, struct smatch_state *two)
132 if (one == two)
133 return 1;
134 if (!rlists_equiv(estate_related(one), estate_related(two)))
135 return 0;
136 if (strcmp(one->name, two->name) == 0)
137 return 1;
138 return 0;
141 int estate_get_single_value(struct smatch_state *state, sval_t *sval)
143 sval_t min, max;
145 min = rl_min(estate_ranges(state));
146 max = rl_max(estate_ranges(state));
147 if (sval_cmp(min, max) != 0)
148 return 0;
149 *sval = min;
150 return 1;
153 static struct data_info *alloc_dinfo(void)
155 struct data_info *ret;
157 ret = __alloc_data_info(0);
158 ret->related = NULL;
159 ret->type = DATA_RANGE;
160 ret->value_ranges = NULL;
161 ret->hard_max = 0;
162 return ret;
165 static struct data_info *alloc_dinfo_range(sval_t min, sval_t max)
167 struct data_info *ret;
169 ret = alloc_dinfo();
170 add_range(&ret->value_ranges, min, max);
171 return ret;
174 static struct data_info *alloc_dinfo_range_list(struct range_list *rl)
176 struct data_info *ret;
178 ret = alloc_dinfo();
179 ret->value_ranges = rl;
180 return ret;
183 static struct data_info *clone_dinfo(struct data_info *dinfo)
185 struct data_info *ret;
187 ret = alloc_dinfo();
188 ret->related = clone_related_list(dinfo->related);
189 ret->value_ranges = clone_range_list(dinfo->value_ranges);
190 ret->hard_max = dinfo->hard_max;
191 return ret;
194 struct smatch_state *clone_estate(struct smatch_state *state)
196 struct smatch_state *ret;
198 ret = __alloc_smatch_state(0);
199 ret->name = state->name;
200 ret->data = clone_dinfo(get_dinfo(state));
201 return ret;
204 struct smatch_state *alloc_estate_empty(void)
206 struct smatch_state *state;
207 struct data_info *dinfo;
209 dinfo = alloc_dinfo();
210 state = __alloc_smatch_state(0);
211 state->data = dinfo;
212 state->name = "";
213 return state;
216 struct smatch_state *extra_undefined(struct symbol *type)
218 return alloc_estate_range_list(whole_range_list(type));
221 struct smatch_state *extra_empty(void)
223 struct smatch_state *ret;
225 ret = __alloc_smatch_state(0);
226 ret->name = "empty";
227 ret->data = alloc_dinfo();
228 return ret;
231 struct smatch_state *alloc_estate(sval_t sval)
233 struct smatch_state *state;
235 state = __alloc_smatch_state(0);
236 state->data = alloc_dinfo_range(sval, sval);
237 state->name = show_ranges(get_dinfo(state)->value_ranges);
238 estate_set_hard_max(state);
239 return state;
242 struct smatch_state *alloc_estate_range(sval_t min, sval_t max)
244 struct smatch_state *state;
246 state = __alloc_smatch_state(0);
247 state->data = alloc_dinfo_range(min, max);
248 state->name = show_ranges(get_dinfo(state)->value_ranges);
249 return state;
252 struct smatch_state *alloc_estate_range_list(struct range_list *rl)
254 struct smatch_state *state;
256 if (!rl)
257 return extra_empty();
259 state = __alloc_smatch_state(0);
260 state->data = alloc_dinfo_range_list(rl);
261 state->name = show_ranges(rl);
262 return state;
265 struct smatch_state *get_implied_estate(struct expression *expr)
267 struct smatch_state *state;
268 struct range_list *rl;
270 state = get_state_expr(SMATCH_EXTRA, expr);
271 if (state)
272 return state;
273 if (!get_implied_range_list(expr, &rl))
274 rl = whole_range_list(get_type(expr));
275 return alloc_estate_range_list(rl);