Print this page
11506 smatch resync
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/tools/smatch/src/smatch_estate.c
+++ new/usr/src/tools/smatch/src/smatch_estate.c
1 1 /*
2 2 * Copyright (C) 2010 Dan Carpenter.
3 3 *
4 4 * This program is free software; you can redistribute it and/or
5 5 * modify it under the terms of the GNU General Public License
6 6 * as published by the Free Software Foundation; either version 2
7 7 * of the License, or (at your option) any later version.
8 8 *
9 9 * This program is distributed in the hope that it will be useful,
10 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 * GNU General Public License for more details.
13 13 *
14 14 * You should have received a copy of the GNU General Public License
15 15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
16 16 */
17 17
18 18 /*
19 19 * smatch_dinfo.c has helper functions for handling data_info structs
20 20 *
21 21 */
22 22
23 23 #include <stdlib.h>
24 24 #ifndef __USE_ISOC99
25 25 #define __USE_ISOC99
26 26 #endif
27 27 #include <limits.h>
28 28 #include "parse.h"
29 29 #include "smatch.h"
30 30 #include "smatch_slist.h"
31 31 #include "smatch_extra.h"
32 32
33 33 struct smatch_state *merge_estates(struct smatch_state *s1, struct smatch_state *s2)
34 34 {
35 35 struct smatch_state *tmp;
↓ open down ↓ |
35 lines elided |
↑ open up ↑ |
36 36 struct range_list *value_ranges;
37 37 struct related_list *rlist;
38 38
39 39 if (estates_equiv(s1, s2))
40 40 return s1;
41 41
42 42 value_ranges = rl_union(estate_rl(s1), estate_rl(s2));
43 43 tmp = alloc_estate_rl(value_ranges);
44 44 rlist = get_shared_relations(estate_related(s1), estate_related(s2));
45 45 set_related(tmp, rlist);
46 - if (estate_has_hard_max(s1) && estate_has_hard_max(s2))
46 +
47 + if ((estate_has_hard_max(s1) && (!estate_rl(s2) || estate_has_hard_max(s2))) ||
48 + (estate_has_hard_max(s2) && (!estate_rl(s1) || estate_has_hard_max(s1))))
47 49 estate_set_hard_max(tmp);
48 50
49 51 estate_set_fuzzy_max(tmp, sval_max(estate_get_fuzzy_max(s1), estate_get_fuzzy_max(s2)));
50 52
53 + if (estate_capped(s1) && estate_capped(s2))
54 + estate_set_capped(tmp);
55 +
51 56 return tmp;
52 57 }
53 58
54 59 struct data_info *get_dinfo(struct smatch_state *state)
55 60 {
56 61 if (!state)
57 62 return NULL;
58 63 return (struct data_info *)state->data;
59 64 }
60 65
61 66 struct range_list *estate_rl(struct smatch_state *state)
62 67 {
63 68 if (!state)
64 69 return NULL;
65 70 return get_dinfo(state)->value_ranges;
66 71 }
67 72
68 73 struct related_list *estate_related(struct smatch_state *state)
69 74 {
70 75 if (!state)
71 76 return NULL;
72 77 return get_dinfo(state)->related;
73 78 }
74 79
75 80 sval_t estate_get_fuzzy_max(struct smatch_state *state)
76 81 {
77 82 sval_t empty = {};
78 83
79 84 if (!state || !get_dinfo(state))
80 85 return empty;
81 86 return get_dinfo(state)->fuzzy_max;
82 87 }
83 88
84 89 int estate_has_fuzzy_max(struct smatch_state *state)
85 90 {
86 91 if (estate_get_fuzzy_max(state).type)
87 92 return 1;
88 93 return 0;
89 94 }
90 95
91 96 void estate_set_fuzzy_max(struct smatch_state *state, sval_t fuzzy_max)
92 97 {
93 98 if (!rl_has_sval(estate_rl(state), fuzzy_max))
94 99 return;
95 100 get_dinfo(state)->fuzzy_max = fuzzy_max;
96 101 }
97 102
98 103 void estate_copy_fuzzy_max(struct smatch_state *new, struct smatch_state *old)
99 104 {
100 105 if (!estate_has_fuzzy_max(old))
101 106 return;
102 107 estate_set_fuzzy_max(new, estate_get_fuzzy_max(old));
103 108 }
104 109
105 110 void estate_clear_fuzzy_max(struct smatch_state *state)
106 111 {
107 112 sval_t empty = {};
108 113
109 114 get_dinfo(state)->fuzzy_max = empty;
110 115 }
111 116
112 117 int estate_has_hard_max(struct smatch_state *state)
113 118 {
114 119 if (!state)
115 120 return 0;
116 121 return get_dinfo(state)->hard_max;
117 122 }
118 123
119 124 void estate_set_hard_max(struct smatch_state *state)
120 125 {
121 126 get_dinfo(state)->hard_max = 1;
122 127 }
123 128
124 129 void estate_clear_hard_max(struct smatch_state *state)
125 130 {
126 131 get_dinfo(state)->hard_max = 0;
↓ open down ↓ |
66 lines elided |
↑ open up ↑ |
127 132 }
128 133
129 134 int estate_get_hard_max(struct smatch_state *state, sval_t *sval)
130 135 {
131 136 if (!state || !get_dinfo(state)->hard_max || !estate_rl(state))
132 137 return 0;
133 138 *sval = rl_max(estate_rl(state));
134 139 return 1;
135 140 }
136 141
142 +bool estate_capped(struct smatch_state *state)
143 +{
144 + if (!state)
145 + return false;
146 + /* impossible states are capped */
147 + if (!estate_rl(state))
148 + return true;
149 + return get_dinfo(state)->capped;
150 +}
151 +
152 +void estate_set_capped(struct smatch_state *state)
153 +{
154 + get_dinfo(state)->capped = true;
155 +}
156 +
137 157 sval_t estate_min(struct smatch_state *state)
138 158 {
139 159 return rl_min(estate_rl(state));
140 160 }
141 161
142 162 sval_t estate_max(struct smatch_state *state)
143 163 {
144 164 return rl_max(estate_rl(state));
145 165 }
146 166
147 167 struct symbol *estate_type(struct smatch_state *state)
148 168 {
149 169 return rl_max(estate_rl(state)).type;
150 170 }
151 171
152 172 static int rlists_equiv(struct related_list *one, struct related_list *two)
153 173 {
154 174 struct relation *one_rel;
155 175 struct relation *two_rel;
156 176
157 177 PREPARE_PTR_LIST(one, one_rel);
158 178 PREPARE_PTR_LIST(two, two_rel);
159 179 for (;;) {
160 180 if (!one_rel && !two_rel)
161 181 return 1;
162 182 if (!one_rel || !two_rel)
163 183 return 0;
164 184 if (one_rel->sym != two_rel->sym)
165 185 return 0;
166 186 if (strcmp(one_rel->name, two_rel->name))
167 187 return 0;
168 188 NEXT_PTR_LIST(one_rel);
169 189 NEXT_PTR_LIST(two_rel);
170 190 }
171 191 FINISH_PTR_LIST(two_rel);
172 192 FINISH_PTR_LIST(one_rel);
173 193
174 194 return 1;
↓ open down ↓ |
28 lines elided |
↑ open up ↑ |
175 195 }
176 196
177 197 int estates_equiv(struct smatch_state *one, struct smatch_state *two)
178 198 {
179 199 if (!one || !two)
180 200 return 0;
181 201 if (one == two)
182 202 return 1;
183 203 if (!rlists_equiv(estate_related(one), estate_related(two)))
184 204 return 0;
205 + if (estate_capped(one) != estate_capped(two))
206 + return 0;
185 207 if (strcmp(one->name, two->name) == 0)
186 208 return 1;
187 209 return 0;
188 210 }
189 211
190 212 int estate_is_whole(struct smatch_state *state)
191 213 {
192 214 return is_whole_rl(estate_rl(state));
193 215 }
194 216
195 217 int estate_is_empty(struct smatch_state *state)
196 218 {
197 219 return state && !estate_rl(state);
198 220 }
199 221
200 222 int estate_is_unknown(struct smatch_state *state)
201 223 {
202 224 if (!estate_is_whole(state))
203 225 return 0;
204 226 if (estate_related(state))
205 227 return 0;
206 228 if (estate_has_fuzzy_max(state))
207 229 return 0;
208 230 return 1;
209 231 }
210 232
211 233 int estate_get_single_value(struct smatch_state *state, sval_t *sval)
212 234 {
213 235 sval_t min, max;
214 236
215 237 min = rl_min(estate_rl(state));
216 238 max = rl_max(estate_rl(state));
217 239 if (sval_cmp(min, max) != 0)
218 240 return 0;
219 241 *sval = min;
220 242 return 1;
221 243 }
222 244
223 245 static struct data_info *alloc_dinfo(void)
224 246 {
225 247 struct data_info *ret;
226 248
227 249 ret = __alloc_data_info(0);
228 250 memset(ret, 0, sizeof(*ret));
229 251 return ret;
230 252 }
231 253
232 254 static struct data_info *alloc_dinfo_range(sval_t min, sval_t max)
233 255 {
234 256 struct data_info *ret;
235 257
236 258 ret = alloc_dinfo();
237 259 add_range(&ret->value_ranges, min, max);
238 260 return ret;
239 261 }
240 262
241 263 static struct data_info *alloc_dinfo_range_list(struct range_list *rl)
242 264 {
243 265 struct data_info *ret;
244 266
245 267 ret = alloc_dinfo();
246 268 ret->value_ranges = rl;
247 269 return ret;
248 270 }
249 271
250 272 static struct data_info *clone_dinfo(struct data_info *dinfo)
251 273 {
252 274 struct data_info *ret;
253 275
254 276 ret = alloc_dinfo();
255 277 ret->related = clone_related_list(dinfo->related);
256 278 ret->value_ranges = clone_rl(dinfo->value_ranges);
257 279 ret->hard_max = dinfo->hard_max;
258 280 ret->fuzzy_max = dinfo->fuzzy_max;
259 281 return ret;
260 282 }
261 283
262 284 struct smatch_state *clone_estate(struct smatch_state *state)
263 285 {
264 286 struct smatch_state *ret;
↓ open down ↓ |
70 lines elided |
↑ open up ↑ |
265 287
266 288 if (!state)
267 289 return NULL;
268 290
269 291 ret = __alloc_smatch_state(0);
270 292 ret->name = state->name;
271 293 ret->data = clone_dinfo(get_dinfo(state));
272 294 return ret;
273 295 }
274 296
297 +struct smatch_state *clone_partial_estate(struct smatch_state *state, struct range_list *rl)
298 +{
299 + struct smatch_state *ret;
300 +
301 + if (!state)
302 + return NULL;
303 +
304 + rl = cast_rl(estate_type(state), rl);
305 +
306 + ret = alloc_estate_rl(rl);
307 + set_related(ret, clone_related_list(estate_related(state)));
308 + if (estate_has_hard_max(state))
309 + estate_set_hard_max(ret);
310 + if (estate_has_fuzzy_max(state))
311 + estate_set_fuzzy_max(ret, estate_get_fuzzy_max(state));
312 +
313 + return ret;
314 +}
315 +
275 316 struct smatch_state *alloc_estate_empty(void)
276 317 {
277 318 struct smatch_state *state;
278 319 struct data_info *dinfo;
279 320
280 321 dinfo = alloc_dinfo();
281 322 state = __alloc_smatch_state(0);
282 323 state->data = dinfo;
283 324 state->name = "";
284 325 return state;
285 326 }
286 327
287 328 struct smatch_state *alloc_estate_whole(struct symbol *type)
288 329 {
289 330 return alloc_estate_rl(alloc_whole_rl(type));
290 331 }
291 332
292 333 struct smatch_state *extra_empty(void)
293 334 {
294 335 struct smatch_state *ret;
295 336
296 337 ret = __alloc_smatch_state(0);
297 338 ret->name = "empty";
298 339 ret->data = alloc_dinfo();
299 340 return ret;
300 341 }
301 342
302 343 struct smatch_state *alloc_estate_sval(sval_t sval)
303 344 {
304 345 struct smatch_state *state;
305 346
306 347 state = __alloc_smatch_state(0);
307 348 state->data = alloc_dinfo_range(sval, sval);
308 349 state->name = show_rl(get_dinfo(state)->value_ranges);
309 350 estate_set_hard_max(state);
310 351 estate_set_fuzzy_max(state, sval);
311 352 return state;
312 353 }
313 354
314 355 struct smatch_state *alloc_estate_range(sval_t min, sval_t max)
315 356 {
316 357 struct smatch_state *state;
317 358
318 359 state = __alloc_smatch_state(0);
319 360 state->data = alloc_dinfo_range(min, max);
320 361 state->name = show_rl(get_dinfo(state)->value_ranges);
321 362 return state;
322 363 }
323 364
324 365 struct smatch_state *alloc_estate_rl(struct range_list *rl)
325 366 {
326 367 struct smatch_state *state;
327 368
328 369 if (!rl)
329 370 return extra_empty();
330 371
331 372 state = __alloc_smatch_state(0);
332 373 state->data = alloc_dinfo_range_list(rl);
333 374 state->name = show_rl(rl);
334 375 return state;
335 376 }
336 377
337 378 struct smatch_state *clone_estate_cast(struct symbol *type, struct smatch_state *state)
338 379 {
339 380 struct smatch_state *ret;
340 381 struct data_info *dinfo;
341 382
342 383 if (!state)
343 384 return NULL;
344 385
345 386 dinfo = alloc_dinfo();
346 387 dinfo->value_ranges = clone_rl(cast_rl(type, estate_rl(state)));
347 388
348 389 ret = __alloc_smatch_state(0);
349 390 ret->name = show_rl(dinfo->value_ranges);
350 391 ret->data = dinfo;
351 392
352 393 return ret;
353 394 }
354 395
355 396 struct smatch_state *get_implied_estate(struct expression *expr)
356 397 {
357 398 struct smatch_state *state;
↓ open down ↓ |
73 lines elided |
↑ open up ↑ |
358 399 struct range_list *rl;
359 400
360 401 state = get_state_expr(SMATCH_EXTRA, expr);
361 402 if (state)
362 403 return state;
363 404 if (!get_implied_rl(expr, &rl))
364 405 rl = alloc_whole_rl(get_type(expr));
365 406 return alloc_estate_rl(rl);
366 407 }
367 408
368 -struct smatch_state *estate_filter_range(struct smatch_state *orig,
369 - sval_t filter_min, sval_t filter_max)
370 -{
371 - struct range_list *rl;
372 - struct smatch_state *state;
373 -
374 - if (!orig)
375 - orig = alloc_estate_whole(filter_min.type);
376 -
377 - rl = remove_range(estate_rl(orig), filter_min, filter_max);
378 - state = alloc_estate_rl(rl);
379 - if (estate_has_hard_max(orig))
380 - estate_set_hard_max(state);
381 - if (estate_has_fuzzy_max(orig))
382 - estate_set_fuzzy_max(state, estate_get_fuzzy_max(orig));
383 - return state;
384 -}
385 -
386 -struct smatch_state *estate_filter_sval(struct smatch_state *orig, sval_t sval)
387 -{
388 - return estate_filter_range(orig, sval, sval);
389 -}
390 -
391 409 /*
392 410 * One of the complications is that smatch tries to free a bunch of data at the
393 411 * end of every function.
394 412 */
395 413 struct data_info *clone_dinfo_perm(struct data_info *dinfo)
396 414 {
397 415 struct data_info *ret;
398 416
399 417 ret = malloc(sizeof(*ret));
400 418 memset(ret, 0, sizeof(*ret));
401 419 ret->related = NULL;
402 420 ret->value_ranges = clone_rl_permanent(dinfo->value_ranges);
403 421 ret->hard_max = 0;
404 422 ret->fuzzy_max = dinfo->fuzzy_max;
405 423 return ret;
406 424 }
407 425
408 426 struct smatch_state *clone_estate_perm(struct smatch_state *state)
409 427 {
410 428 struct smatch_state *ret;
411 429
412 430 ret = malloc(sizeof(*ret));
413 431 ret->name = alloc_string(state->name);
414 432 ret->data = clone_dinfo_perm(get_dinfo(state));
415 433 return ret;
416 434 }
417 435
418 436
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX