Print this page
12724 update smatch to 0.6.1-rc1-il-5
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;
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 46
47 47 if ((estate_has_hard_max(s1) && (!estate_rl(s2) || estate_has_hard_max(s2))) ||
48 48 (estate_has_hard_max(s2) && (!estate_rl(s1) || estate_has_hard_max(s1))))
↓ open down ↓ |
48 lines elided |
↑ open up ↑ |
49 49 estate_set_hard_max(tmp);
50 50
51 51 estate_set_fuzzy_max(tmp, sval_max(estate_get_fuzzy_max(s1), estate_get_fuzzy_max(s2)));
52 52
53 53 if (estate_capped(s1) && estate_capped(s2))
54 54 estate_set_capped(tmp);
55 55
56 56 if (estate_treat_untagged(s1) && estate_treat_untagged(s2))
57 57 estate_set_treat_untagged(tmp);
58 58
59 + if (estate_new(s1) || estate_new(s2))
60 + estate_set_new(tmp);
61 +
59 62 return tmp;
60 63 }
61 64
62 65 struct data_info *get_dinfo(struct smatch_state *state)
63 66 {
64 67 if (!state)
65 68 return NULL;
66 69 return (struct data_info *)state->data;
67 70 }
68 71
69 72 struct range_list *estate_rl(struct smatch_state *state)
70 73 {
71 74 if (!state)
72 75 return NULL;
73 76 return get_dinfo(state)->value_ranges;
74 77 }
75 78
76 79 struct related_list *estate_related(struct smatch_state *state)
77 80 {
78 81 if (!state)
79 82 return NULL;
80 83 return get_dinfo(state)->related;
81 84 }
82 85
83 86 sval_t estate_get_fuzzy_max(struct smatch_state *state)
84 87 {
85 88 sval_t empty = {};
86 89
87 90 if (!state || !get_dinfo(state))
88 91 return empty;
89 92 return get_dinfo(state)->fuzzy_max;
90 93 }
91 94
92 95 int estate_has_fuzzy_max(struct smatch_state *state)
93 96 {
94 97 if (estate_get_fuzzy_max(state).type)
95 98 return 1;
96 99 return 0;
97 100 }
98 101
99 102 void estate_set_fuzzy_max(struct smatch_state *state, sval_t fuzzy_max)
100 103 {
101 104 if (!rl_has_sval(estate_rl(state), fuzzy_max))
102 105 return;
103 106 get_dinfo(state)->fuzzy_max = fuzzy_max;
104 107 }
105 108
106 109 void estate_copy_fuzzy_max(struct smatch_state *new, struct smatch_state *old)
107 110 {
108 111 if (!estate_has_fuzzy_max(old))
109 112 return;
110 113 estate_set_fuzzy_max(new, estate_get_fuzzy_max(old));
111 114 }
112 115
113 116 void estate_clear_fuzzy_max(struct smatch_state *state)
114 117 {
115 118 sval_t empty = {};
116 119
117 120 get_dinfo(state)->fuzzy_max = empty;
118 121 }
↓ open down ↓ |
50 lines elided |
↑ open up ↑ |
119 122
120 123 int estate_has_hard_max(struct smatch_state *state)
121 124 {
122 125 if (!state || !estate_rl(state))
123 126 return 0;
124 127 return get_dinfo(state)->hard_max;
125 128 }
126 129
127 130 void estate_set_hard_max(struct smatch_state *state)
128 131 {
132 + /* pointers don't have a hard max */
133 + if (is_ptr_type(estate_type(state)))
134 + return;
129 135 get_dinfo(state)->hard_max = 1;
130 136 }
131 137
132 138 void estate_clear_hard_max(struct smatch_state *state)
133 139 {
134 140 get_dinfo(state)->hard_max = 0;
135 141 }
136 142
137 143 int estate_get_hard_max(struct smatch_state *state, sval_t *sval)
138 144 {
139 145 if (!state || !get_dinfo(state)->hard_max || !estate_rl(state))
140 146 return 0;
141 147 *sval = rl_max(estate_rl(state));
142 148 return 1;
143 149 }
144 150
145 151 bool estate_capped(struct smatch_state *state)
146 152 {
147 153 if (!state)
148 154 return false;
149 155 /* impossible states are capped */
150 156 if (!estate_rl(state))
151 157 return true;
152 158 return get_dinfo(state)->capped;
153 159 }
154 160
155 161 void estate_set_capped(struct smatch_state *state)
156 162 {
157 163 get_dinfo(state)->capped = true;
158 164 }
159 165
160 166 bool estate_treat_untagged(struct smatch_state *state)
161 167 {
162 168 if (!state)
163 169 return false;
164 170
165 171 /* impossible states are capped */
166 172 if (!estate_rl(state))
↓ open down ↓ |
28 lines elided |
↑ open up ↑ |
167 173 return true;
168 174
169 175 return get_dinfo(state)->treat_untagged;
170 176 }
171 177
172 178 void estate_set_treat_untagged(struct smatch_state *state)
173 179 {
174 180 get_dinfo(state)->treat_untagged = true;
175 181 }
176 182
183 +bool estate_new(struct smatch_state *state)
184 +{
185 + if (!estate_rl(state))
186 + return false;
187 + return get_dinfo(state)->set;
188 +}
189 +
190 +void estate_set_new(struct smatch_state *state)
191 +{
192 + get_dinfo(state)->set = true;
193 +}
194 +
177 195 sval_t estate_min(struct smatch_state *state)
178 196 {
179 197 return rl_min(estate_rl(state));
180 198 }
181 199
182 200 sval_t estate_max(struct smatch_state *state)
183 201 {
184 202 return rl_max(estate_rl(state));
185 203 }
186 204
187 205 struct symbol *estate_type(struct smatch_state *state)
188 206 {
189 207 return rl_max(estate_rl(state)).type;
190 208 }
191 209
192 210 static int rlists_equiv(struct related_list *one, struct related_list *two)
193 211 {
194 212 struct relation *one_rel;
195 213 struct relation *two_rel;
196 214
197 215 PREPARE_PTR_LIST(one, one_rel);
198 216 PREPARE_PTR_LIST(two, two_rel);
199 217 for (;;) {
200 218 if (!one_rel && !two_rel)
201 219 return 1;
202 220 if (!one_rel || !two_rel)
203 221 return 0;
204 222 if (one_rel->sym != two_rel->sym)
205 223 return 0;
206 224 if (strcmp(one_rel->name, two_rel->name))
207 225 return 0;
208 226 NEXT_PTR_LIST(one_rel);
209 227 NEXT_PTR_LIST(two_rel);
210 228 }
211 229 FINISH_PTR_LIST(two_rel);
212 230 FINISH_PTR_LIST(one_rel);
213 231
214 232 return 1;
215 233 }
216 234
217 235 int estates_equiv(struct smatch_state *one, struct smatch_state *two)
218 236 {
↓ open down ↓ |
32 lines elided |
↑ open up ↑ |
219 237 if (!one || !two)
220 238 return 0;
221 239 if (one == two)
222 240 return 1;
223 241 if (!rlists_equiv(estate_related(one), estate_related(two)))
224 242 return 0;
225 243 if (estate_capped(one) != estate_capped(two))
226 244 return 0;
227 245 if (estate_treat_untagged(one) != estate_treat_untagged(two))
228 246 return 0;
247 + if (estate_has_hard_max(one) != estate_has_hard_max(two))
248 + return 0;
249 + if (estate_new(one) != estate_new(two))
250 + return 0;
229 251 if (strcmp(one->name, two->name) == 0)
230 252 return 1;
231 253 return 0;
232 254 }
233 255
234 256 int estate_is_whole(struct smatch_state *state)
235 257 {
236 258 return is_whole_rl(estate_rl(state));
237 259 }
238 260
239 261 int estate_is_empty(struct smatch_state *state)
240 262 {
241 263 return state && !estate_rl(state);
242 264 }
243 265
244 266 int estate_is_unknown(struct smatch_state *state)
245 267 {
246 268 if (!estate_is_whole(state))
247 269 return 0;
248 270 if (estate_related(state))
249 271 return 0;
250 272 if (estate_has_fuzzy_max(state))
251 273 return 0;
252 274 return 1;
253 275 }
254 276
255 277 int estate_get_single_value(struct smatch_state *state, sval_t *sval)
256 278 {
257 279 sval_t min, max;
258 280
259 281 if (!estate_rl(state))
260 282 return 0;
261 283 min = rl_min(estate_rl(state));
262 284 max = rl_max(estate_rl(state));
263 285 if (sval_cmp(min, max) != 0)
264 286 return 0;
265 287 *sval = min;
266 288 return 1;
267 289 }
268 290
269 291 static struct data_info *alloc_dinfo(void)
270 292 {
271 293 struct data_info *ret;
272 294
273 295 ret = __alloc_data_info(0);
274 296 memset(ret, 0, sizeof(*ret));
275 297 return ret;
276 298 }
277 299
278 300 static struct data_info *alloc_dinfo_range(sval_t min, sval_t max)
279 301 {
280 302 struct data_info *ret;
281 303
282 304 ret = alloc_dinfo();
283 305 add_range(&ret->value_ranges, min, max);
284 306 return ret;
285 307 }
286 308
287 309 static struct data_info *alloc_dinfo_range_list(struct range_list *rl)
288 310 {
289 311 struct data_info *ret;
290 312
291 313 ret = alloc_dinfo();
292 314 ret->value_ranges = rl;
293 315 return ret;
294 316 }
295 317
296 318 static struct data_info *clone_dinfo(struct data_info *dinfo)
297 319 {
298 320 struct data_info *ret;
299 321
300 322 ret = alloc_dinfo();
301 323 ret->related = clone_related_list(dinfo->related);
302 324 ret->value_ranges = clone_rl(dinfo->value_ranges);
303 325 ret->hard_max = dinfo->hard_max;
304 326 ret->fuzzy_max = dinfo->fuzzy_max;
305 327 return ret;
306 328 }
307 329
308 330 struct smatch_state *clone_estate(struct smatch_state *state)
309 331 {
310 332 struct smatch_state *ret;
311 333
312 334 if (!state)
313 335 return NULL;
314 336
315 337 ret = __alloc_smatch_state(0);
316 338 ret->name = state->name;
317 339 ret->data = clone_dinfo(get_dinfo(state));
318 340 return ret;
319 341 }
320 342
321 343 struct smatch_state *clone_partial_estate(struct smatch_state *state, struct range_list *rl)
322 344 {
323 345 struct smatch_state *ret;
324 346
325 347 if (!state)
326 348 return NULL;
327 349
328 350 rl = cast_rl(estate_type(state), rl);
329 351
330 352 ret = alloc_estate_rl(rl);
331 353 set_related(ret, clone_related_list(estate_related(state)));
332 354 if (estate_has_hard_max(state))
333 355 estate_set_hard_max(ret);
334 356 if (estate_has_fuzzy_max(state))
335 357 estate_set_fuzzy_max(ret, estate_get_fuzzy_max(state));
336 358
337 359 return ret;
338 360 }
339 361
340 362 struct smatch_state *alloc_estate_empty(void)
341 363 {
342 364 struct smatch_state *state;
343 365 struct data_info *dinfo;
344 366
345 367 dinfo = alloc_dinfo();
346 368 state = __alloc_smatch_state(0);
347 369 state->data = dinfo;
348 370 state->name = "";
349 371 return state;
350 372 }
351 373
352 374 struct smatch_state *alloc_estate_whole(struct symbol *type)
353 375 {
354 376 return alloc_estate_rl(alloc_whole_rl(type));
355 377 }
356 378
357 379 struct smatch_state *extra_empty(void)
358 380 {
359 381 struct smatch_state *ret;
360 382
361 383 ret = __alloc_smatch_state(0);
362 384 ret->name = "empty";
363 385 ret->data = alloc_dinfo();
364 386 return ret;
365 387 }
366 388
367 389 struct smatch_state *alloc_estate_sval(sval_t sval)
368 390 {
369 391 struct smatch_state *state;
370 392
371 393 state = __alloc_smatch_state(0);
372 394 state->data = alloc_dinfo_range(sval, sval);
373 395 state->name = show_rl(get_dinfo(state)->value_ranges);
374 396 estate_set_hard_max(state);
375 397 estate_set_fuzzy_max(state, sval);
376 398 return state;
377 399 }
378 400
379 401 struct smatch_state *alloc_estate_range(sval_t min, sval_t max)
380 402 {
381 403 struct smatch_state *state;
382 404
383 405 state = __alloc_smatch_state(0);
384 406 state->data = alloc_dinfo_range(min, max);
385 407 state->name = show_rl(get_dinfo(state)->value_ranges);
386 408 return state;
387 409 }
388 410
389 411 struct smatch_state *alloc_estate_rl(struct range_list *rl)
390 412 {
391 413 struct smatch_state *state;
392 414
393 415 if (!rl)
394 416 return extra_empty();
395 417
396 418 state = __alloc_smatch_state(0);
397 419 state->data = alloc_dinfo_range_list(rl);
398 420 state->name = show_rl(rl);
399 421 return state;
400 422 }
401 423
402 424 struct smatch_state *clone_estate_cast(struct symbol *type, struct smatch_state *state)
403 425 {
404 426 struct smatch_state *ret;
405 427 struct data_info *dinfo;
406 428
407 429 if (!state)
408 430 return NULL;
409 431
410 432 dinfo = alloc_dinfo();
411 433 dinfo->value_ranges = clone_rl(cast_rl(type, estate_rl(state)));
412 434
413 435 ret = __alloc_smatch_state(0);
414 436 ret->name = show_rl(dinfo->value_ranges);
415 437 ret->data = dinfo;
416 438
417 439 return ret;
418 440 }
419 441
420 442 struct smatch_state *get_implied_estate(struct expression *expr)
421 443 {
422 444 struct smatch_state *state;
423 445 struct range_list *rl;
424 446
425 447 state = get_state_expr(SMATCH_EXTRA, expr);
426 448 if (state)
427 449 return state;
428 450 if (!get_implied_rl(expr, &rl))
429 451 rl = alloc_whole_rl(get_type(expr));
430 452 return alloc_estate_rl(rl);
431 453 }
432 454
433 455 /*
434 456 * One of the complications is that smatch tries to free a bunch of data at the
435 457 * end of every function.
436 458 */
437 459 struct data_info *clone_dinfo_perm(struct data_info *dinfo)
438 460 {
439 461 struct data_info *ret;
440 462
441 463 ret = malloc(sizeof(*ret));
442 464 memset(ret, 0, sizeof(*ret));
443 465 ret->related = NULL;
444 466 ret->value_ranges = clone_rl_permanent(dinfo->value_ranges);
445 467 ret->hard_max = 0;
446 468 ret->fuzzy_max = dinfo->fuzzy_max;
447 469 return ret;
448 470 }
449 471
450 472 struct smatch_state *clone_estate_perm(struct smatch_state *state)
451 473 {
452 474 struct smatch_state *ret;
453 475
454 476 ret = malloc(sizeof(*ret));
455 477 ret->name = alloc_string(state->name);
456 478 ret->data = clone_dinfo_perm(get_dinfo(state));
457 479 return ret;
458 480 }
459 481
460 482
↓ open down ↓ |
222 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX