2 * smatch/smatch_dinfo.c
4 * Copyright (C) 2010 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
11 * smatch_dinfo.c has helper functions for handling data_info structs
22 #include "smatch_slist.h"
23 #include "smatch_extra.h"
25 struct smatch_state estate_undefined
= {
29 struct data_info
*get_dinfo(struct smatch_state
*state
)
33 return (struct data_info
*)state
->data
;
36 struct range_list
*estate_ranges(struct smatch_state
*state
)
40 return get_dinfo(state
)->value_ranges
;
43 struct range_list_sval
*estate_ranges_sval(struct smatch_state
*state
)
47 return range_list_to_sval(get_dinfo(state
)->value_ranges
);
50 struct related_list
*estate_related(struct smatch_state
*state
)
54 return get_dinfo(state
)->related
;
57 long long estate_min(struct smatch_state
*state
)
59 return rl_min(estate_ranges(state
));
62 sval_t
estate_min_sval(struct smatch_state
*state
)
64 return rl_min_sval(estate_ranges_sval(state
));
67 long long estate_max(struct smatch_state
*state
)
69 return rl_max(estate_ranges(state
));
72 sval_t
estate_max_sval(struct smatch_state
*state
)
74 return rl_max_sval(estate_ranges_sval(state
));
77 static int rlists_equiv(struct related_list
*one
, struct related_list
*two
)
79 struct relation
*one_rel
;
80 struct relation
*two_rel
;
82 PREPARE_PTR_LIST(one
, one_rel
);
83 PREPARE_PTR_LIST(two
, two_rel
);
85 if (!one_rel
&& !two_rel
)
87 if (!one_rel
|| !two_rel
)
89 if (one_rel
->sym
!= two_rel
->sym
)
91 if (strcmp(one_rel
->name
, two_rel
->name
))
93 NEXT_PTR_LIST(one_rel
);
94 NEXT_PTR_LIST(two_rel
);
96 FINISH_PTR_LIST(two_rel
);
97 FINISH_PTR_LIST(one_rel
);
102 int estates_equiv(struct smatch_state
*one
, struct smatch_state
*two
)
106 if (!rlists_equiv(estate_related(one
), estate_related(two
)))
108 if (strcmp(one
->name
, two
->name
) == 0)
113 static struct data_info
*alloc_dinfo(void)
115 struct data_info
*ret
;
117 ret
= __alloc_data_info(0);
119 ret
->type
= DATA_RANGE
;
120 ret
->value_ranges
= NULL
;
124 static struct data_info
*alloc_dinfo_range(long long min
, long long max
)
126 struct data_info
*ret
;
129 add_range(&ret
->value_ranges
, min
, max
);
133 static struct data_info
*alloc_dinfo_range_list(struct range_list
*rl
)
135 struct data_info
*ret
;
138 ret
->value_ranges
= rl
;
142 static struct data_info
*clone_dinfo(struct data_info
*dinfo
)
144 struct data_info
*ret
;
147 ret
->related
= clone_related_list(dinfo
->related
);
148 ret
->value_ranges
= clone_range_list(dinfo
->value_ranges
);
152 struct smatch_state
*clone_estate(struct smatch_state
*state
)
154 struct smatch_state
*ret
;
156 ret
= __alloc_smatch_state(0);
157 ret
->name
= state
->name
;
158 ret
->data
= clone_dinfo(get_dinfo(state
));
162 struct smatch_state
*alloc_estate_empty(void)
164 struct smatch_state
*state
;
165 struct data_info
*dinfo
;
167 dinfo
= alloc_dinfo();
168 state
= __alloc_smatch_state(0);
174 static struct smatch_state
*alloc_estate_no_name(int val
)
176 struct smatch_state
*state
;
178 state
= __alloc_smatch_state(0);
179 state
->data
= (void *)alloc_dinfo_range(val
, val
);
183 /* We do this because ->value_ranges is a list */
184 struct smatch_state
*extra_undefined(void)
186 return &estate_undefined
;
189 struct smatch_state
*extra_empty(void)
191 struct smatch_state
*ret
;
193 ret
= __alloc_smatch_state(0);
195 ret
->data
= alloc_dinfo();
199 struct smatch_state
*alloc_estate(long long val
)
201 struct smatch_state
*state
;
203 state
= alloc_estate_no_name(val
);
204 state
->name
= show_ranges(get_dinfo(state
)->value_ranges
);
208 struct smatch_state
*alloc_estate_sval(sval_t sval
)
210 struct smatch_state
*state
;
212 state
= alloc_estate_no_name(sval
.value
);
213 state
->name
= show_ranges(get_dinfo(state
)->value_ranges
);
217 struct smatch_state
*alloc_estate_range(long long min
, long long max
)
219 struct smatch_state
*state
;
221 if (min
== whole_range
.min
&& max
== whole_range
.max
)
222 return extra_undefined();
223 state
= __alloc_smatch_state(0);
224 state
->data
= (void *)alloc_dinfo_range(min
, max
);
225 state
->name
= show_ranges(get_dinfo(state
)->value_ranges
);
229 struct smatch_state
*alloc_estate_range_sval(sval_t min
, sval_t max
)
231 struct smatch_state
*state
;
233 if (sval_is_min(min
) && sval_is_max(max
))
234 return extra_undefined();
235 state
= __alloc_smatch_state(0);
236 state
->data
= (void *)alloc_dinfo_range(min
.value
, max
.value
);
237 state
->name
= show_ranges(get_dinfo(state
)->value_ranges
);
241 struct smatch_state
*alloc_estate_range_list(struct range_list
*rl
)
243 struct smatch_state
*state
;
246 return extra_empty();
248 if (is_whole_range_rl(rl
))
249 return extra_undefined();
251 state
= __alloc_smatch_state(0);
252 state
->data
= (void *)alloc_dinfo_range_list(rl
);
253 state
->name
= show_ranges(get_dinfo(state
)->value_ranges
);
257 struct smatch_state
*alloc_estate_range_list_sval(struct range_list_sval
*rl
)
259 struct smatch_state
*state
;
262 return extra_empty();
264 state
= __alloc_smatch_state(0);
265 state
->data
= (void *)alloc_dinfo_range_list(rl_sval_to_rl(rl
));
266 state
->name
= show_ranges_sval(rl
);
270 void alloc_estate_undefined(void)
272 static struct data_info dinfo
= {
276 dinfo
.value_ranges
= clone_permanent(whole_range_list());
277 estate_undefined
.data
= &dinfo
;