extra: get max correctly
[smatch.git] / smatch_estate.c
bloba58706fdc45f9ee4477f0bd7455b8daef2d4f20e
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 data_info *get_dinfo(struct smatch_state *state)
27 if (!state)
28 return NULL;
29 return (struct data_info *)state->data;
32 struct range_list *estate_ranges(struct smatch_state *state)
34 if (!state)
35 return NULL;
36 return get_dinfo(state)->value_ranges;
39 struct related_list *estate_related(struct smatch_state *state)
41 if (!state)
42 return NULL;
43 return get_dinfo(state)->related;
46 int estate_has_hard_max(struct smatch_state *state)
48 if (!state)
49 return 0;
50 return get_dinfo(state)->hard_max;
53 void estate_set_hard_max(struct smatch_state *state)
55 get_dinfo(state)->hard_max = 1;
58 void estate_clear_hard_max(struct smatch_state *state)
60 get_dinfo(state)->hard_max = 0;
63 int estate_get_hard_max(struct smatch_state *state, sval_t *sval)
65 if (!state || !get_dinfo(state)->hard_max || !estate_ranges(state))
66 return 0;
67 *sval = rl_max(estate_ranges(state));
68 return 1;
71 sval_t estate_min(struct smatch_state *state)
73 return rl_min(estate_ranges(state));
76 sval_t estate_max(struct smatch_state *state)
78 return rl_max(estate_ranges(state));
81 struct symbol *estate_type(struct smatch_state *state)
83 return rl_max(estate_ranges(state)).type;
86 static int rlists_equiv(struct related_list *one, struct related_list *two)
88 struct relation *one_rel;
89 struct relation *two_rel;
91 PREPARE_PTR_LIST(one, one_rel);
92 PREPARE_PTR_LIST(two, two_rel);
93 for (;;) {
94 if (!one_rel && !two_rel)
95 return 1;
96 if (!one_rel || !two_rel)
97 return 0;
98 if (one_rel->sym != two_rel->sym)
99 return 0;
100 if (strcmp(one_rel->name, two_rel->name))
101 return 0;
102 NEXT_PTR_LIST(one_rel);
103 NEXT_PTR_LIST(two_rel);
105 FINISH_PTR_LIST(two_rel);
106 FINISH_PTR_LIST(one_rel);
108 return 1;
111 int estates_equiv(struct smatch_state *one, struct smatch_state *two)
113 if (one == two)
114 return 1;
115 if (!rlists_equiv(estate_related(one), estate_related(two)))
116 return 0;
117 if (strcmp(one->name, two->name) == 0)
118 return 1;
119 return 0;
122 int estate_get_single_value(struct smatch_state *state, sval_t *sval)
124 sval_t min, max;
126 min = rl_min(estate_ranges(state));
127 max = rl_max(estate_ranges(state));
128 if (sval_cmp(min, max) != 0)
129 return 0;
130 *sval = min;
131 return 1;
134 static struct data_info *alloc_dinfo(void)
136 struct data_info *ret;
138 ret = __alloc_data_info(0);
139 ret->related = NULL;
140 ret->type = DATA_RANGE;
141 ret->value_ranges = NULL;
142 ret->hard_max = 0;
143 return ret;
146 static struct data_info *alloc_dinfo_range(sval_t min, sval_t max)
148 struct data_info *ret;
150 ret = alloc_dinfo();
151 add_range(&ret->value_ranges, min, max);
152 return ret;
155 static struct data_info *alloc_dinfo_range_list(struct range_list *rl)
157 struct data_info *ret;
159 ret = alloc_dinfo();
160 ret->value_ranges = rl;
161 return ret;
164 static struct data_info *clone_dinfo(struct data_info *dinfo)
166 struct data_info *ret;
168 ret = alloc_dinfo();
169 ret->related = clone_related_list(dinfo->related);
170 ret->value_ranges = clone_range_list(dinfo->value_ranges);
171 ret->hard_max = dinfo->hard_max;
172 return ret;
175 struct smatch_state *clone_estate(struct smatch_state *state)
177 struct smatch_state *ret;
179 ret = __alloc_smatch_state(0);
180 ret->name = state->name;
181 ret->data = clone_dinfo(get_dinfo(state));
182 return ret;
185 struct smatch_state *alloc_estate_empty(void)
187 struct smatch_state *state;
188 struct data_info *dinfo;
190 dinfo = alloc_dinfo();
191 state = __alloc_smatch_state(0);
192 state->data = dinfo;
193 state->name = "";
194 return state;
197 struct smatch_state *extra_undefined(struct symbol *type)
199 return alloc_estate_range_list(whole_range_list(type));
202 struct smatch_state *extra_empty(void)
204 struct smatch_state *ret;
206 ret = __alloc_smatch_state(0);
207 ret->name = "empty";
208 ret->data = alloc_dinfo();
209 return ret;
212 struct smatch_state *alloc_estate(sval_t sval)
214 struct smatch_state *state;
216 state = __alloc_smatch_state(0);
217 state->data = alloc_dinfo_range(sval, sval);
218 state->name = show_ranges(get_dinfo(state)->value_ranges);
219 estate_set_hard_max(state);
220 return state;
223 struct smatch_state *alloc_estate_range(sval_t min, sval_t max)
225 struct smatch_state *state;
227 state = __alloc_smatch_state(0);
228 state->data = alloc_dinfo_range(min, max);
229 state->name = show_ranges(get_dinfo(state)->value_ranges);
230 return state;
233 struct smatch_state *alloc_estate_range_list(struct range_list *rl)
235 struct smatch_state *state;
237 if (!rl)
238 return extra_empty();
240 state = __alloc_smatch_state(0);
241 state->data = alloc_dinfo_range_list(rl);
242 state->name = show_ranges(rl);
243 return state;