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
;
37 struct range_list
*estate_ranges(struct smatch_state
*state
)
41 return get_dinfo(state
)->value_ranges
;
44 struct related_list
*estate_related(struct smatch_state
*state
)
48 return get_dinfo(state
)->related
;
51 long long estate_min(struct smatch_state
*state
)
53 return rl_min(estate_ranges(state
));
56 long long estate_max(struct smatch_state
*state
)
58 return rl_max(estate_ranges(state
));
61 static int rlists_equiv(struct related_list
*one
, struct related_list
*two
)
63 struct relation
*one_rel
;
64 struct relation
*two_rel
;
66 PREPARE_PTR_LIST(one
, one_rel
);
67 PREPARE_PTR_LIST(two
, two_rel
);
69 if (!one_rel
&& !two_rel
)
71 if (!one_rel
|| !two_rel
)
73 if (one_rel
->sym
!= two_rel
->sym
)
75 if (strcmp(one_rel
->name
, two_rel
->name
))
77 NEXT_PTR_LIST(one_rel
);
78 NEXT_PTR_LIST(two_rel
);
80 FINISH_PTR_LIST(two_rel
);
81 FINISH_PTR_LIST(one_rel
);
86 int estates_equiv(struct smatch_state
*one
, struct smatch_state
*two
)
90 if (!rlists_equiv(estate_related(one
), estate_related(two
)))
92 if (strcmp(one
->name
, two
->name
) == 0)
97 static struct data_info
*alloc_dinfo(void)
99 struct data_info
*ret
;
101 ret
= __alloc_data_info(0);
103 ret
->type
= DATA_RANGE
;
104 ret
->value_ranges
= NULL
;
108 static struct data_info
*alloc_dinfo_range(long long min
, long long max
)
110 struct data_info
*ret
;
113 add_range(&ret
->value_ranges
, min
, max
);
117 static struct data_info
*alloc_dinfo_range_list(struct range_list
*rl
)
119 struct data_info
*ret
;
122 ret
->value_ranges
= rl
;
126 static struct data_info
*clone_dinfo(struct data_info
*dinfo
)
128 struct data_info
*ret
;
131 ret
->related
= clone_related_list(dinfo
->related
);
132 ret
->value_ranges
= clone_range_list(dinfo
->value_ranges
);
136 struct smatch_state
*clone_estate(struct smatch_state
*state
)
138 struct smatch_state
*ret
;
140 ret
= __alloc_smatch_state(0);
141 ret
->name
= state
->name
;
142 ret
->data
= clone_dinfo(get_dinfo(state
));
146 struct smatch_state
*alloc_estate_empty(void)
148 struct smatch_state
*state
;
149 struct data_info
*dinfo
;
151 dinfo
= alloc_dinfo();
152 state
= __alloc_smatch_state(0);
158 static struct smatch_state
*alloc_estate_no_name(int val
)
160 struct smatch_state
*state
;
162 state
= __alloc_smatch_state(0);
163 state
->data
= (void *)alloc_dinfo_range(val
, val
);
167 /* We do this because ->value_ranges is a list */
168 struct smatch_state
*extra_undefined(void)
170 return &estate_undefined
;
173 struct smatch_state
*extra_empty(void)
175 struct smatch_state
*ret
;
177 ret
= __alloc_smatch_state(0);
179 ret
->data
= alloc_dinfo();
183 struct smatch_state
*alloc_estate(long long val
)
185 struct smatch_state
*state
;
187 state
= alloc_estate_no_name(val
);
188 state
->name
= show_ranges(get_dinfo(state
)->value_ranges
);
192 struct smatch_state
*alloc_estate_range(long long min
, long long max
)
194 struct smatch_state
*state
;
196 if (min
== whole_range
.min
&& max
== whole_range
.max
)
197 return extra_undefined();
198 state
= __alloc_smatch_state(0);
199 state
->data
= (void *)alloc_dinfo_range(min
, max
);
200 state
->name
= show_ranges(get_dinfo(state
)->value_ranges
);
204 struct smatch_state
*alloc_estate_range_list(struct range_list
*rl
)
206 struct smatch_state
*state
;
209 return extra_empty();
211 if (is_whole_range_rl(rl
))
212 return extra_undefined();
214 state
= __alloc_smatch_state(0);
215 state
->data
= (void *)alloc_dinfo_range_list(rl
);
216 state
->name
= show_ranges(get_dinfo(state
)->value_ranges
);
220 void alloc_estate_undefined(void)
222 static struct data_info dinfo
= {
226 dinfo
.value_ranges
= clone_permanent(whole_range_list());
227 estate_undefined
.data
= &dinfo
;