2 * sparse/smatch_ranges.c
4 * Copyright (C) 2009 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
12 #include "smatch_extra.h"
13 #include "smatch_slist.h"
15 ALLOCATOR(data_info
, "smatch extra data");
16 ALLOCATOR(data_range
, "data range");
17 __DO_ALLOCATOR(struct data_range
, sizeof(struct data_range
), __alignof__(struct data_range
),
18 "permanent ranges", perm_data_range
);
19 ALLOCATOR(data_range_sval
, "data range sval");
20 __DO_ALLOCATOR(struct data_range_sval
, sizeof(struct data_range_sval
), __alignof__(struct data_range_sval
),
21 "permanent ranges sval", perm_data_range_sval
);
23 struct data_range whole_range
= {
28 static char *show_num(long long num
)
30 static char buff
[256];
32 if (num
== whole_range
.min
)
33 snprintf(buff
, 255, "min");
34 else if (num
== whole_range
.max
)
35 snprintf(buff
, 255, "max");
37 snprintf(buff
, 255, "(%lld)", num
);
39 snprintf(buff
, 255, "%lld", num
);
45 char *show_ranges(struct range_list
*list
)
47 struct data_range
*tmp
;
53 FOR_EACH_PTR(list
, tmp
) {
55 strncat(full
, ",", 254 - strlen(full
));
56 if (tmp
->min
== tmp
->max
) {
57 strncat(full
, show_num(tmp
->min
), 254 - strlen(full
));
60 strncat(full
, show_num(tmp
->min
), 254 - strlen(full
));
61 strncat(full
, "-", 254 - strlen(full
));
62 strncat(full
, show_num(tmp
->max
), 254 - strlen(full
));
63 } END_FOR_EACH_PTR(tmp
);
64 return alloc_sname(full
);
67 char *show_ranges_sval(struct range_list_sval
*list
)
69 struct data_range_sval
*tmp
;
75 FOR_EACH_PTR(list
, tmp
) {
77 strncat(full
, ",", 254 - strlen(full
));
78 if (sval_cmp(tmp
->min
, tmp
->max
) == 0) {
79 strncat(full
, sval_to_str(tmp
->min
), 254 - strlen(full
));
82 strncat(full
, sval_to_str(tmp
->min
), 254 - strlen(full
));
83 strncat(full
, "-", 254 - strlen(full
));
84 strncat(full
, sval_to_str(tmp
->max
), 254 - strlen(full
));
85 } END_FOR_EACH_PTR(tmp
);
86 return alloc_sname(full
);
89 void get_value_ranges(char *value
, struct range_list
**rl
)
103 if (!strncmp(start
, "max", 3)) {
106 } else if (!strncmp(start
, "u64max", 6)) {
107 val1
= LLONG_MAX
; // FIXME
109 } else if (!strncmp(start
, "s64max", 6)) {
112 } else if (!strncmp(start
, "u32max", 6)) {
115 } else if (!strncmp(start
, "s32max", 6)) {
118 } else if (!strncmp(start
, "u16max", 6)) {
121 } else if (!strncmp(start
, "s16max", 6)) {
124 } else if (!strncmp(start
, "min", 3)) {
127 } else if (!strncmp(start
, "s64min", 6)) {
130 } else if (!strncmp(start
, "s32min", 6)) {
133 } else if (!strncmp(start
, "s16min", 6)) {
137 while (*c
&& *c
!= ',' && *c
!= '-')
139 val1
= strtoll(start
, &c
, 10);
144 add_range(rl
, val1
, val1
);
148 add_range(rl
, val1
, val1
);
153 c
++; /* skip the dash in eg. 4-5 */
157 if (!strncmp(start
, "max", 3)) {
162 while (*c
&& *c
!= ',' && *c
!= '-')
164 val2
= strtoll(start
, &c
, 10);
166 add_range(rl
, val1
, val2
);
171 c
++; /* skip the comma in eg: 4-5,7 */
175 void get_value_ranges_sval(char *value
, struct range_list_sval
**rl
)
177 struct range_list
*tmp_rl
= NULL
;
179 get_value_ranges(value
, &tmp_rl
);
180 *rl
= range_list_to_sval(tmp_rl
);
183 static struct data_range range_zero
= {
188 static struct data_range range_one
= {
193 int is_whole_range_rl(struct range_list
*rl
)
195 struct data_range
*drange
;
197 if (ptr_list_empty(rl
))
199 drange
= first_ptr_list((struct ptr_list
*)rl
);
200 if (drange
->min
== whole_range
.min
&& drange
->max
== whole_range
.max
)
205 int is_whole_range_rl_sval(struct range_list_sval
*rl
)
207 struct data_range_sval
*drange
;
209 if (ptr_list_empty(rl
))
211 drange
= first_ptr_list((struct ptr_list
*)rl
);
212 if (sval_is_min(drange
->min
) && sval_is_max(drange
->max
))
217 int rl_contiguous(struct range_list
*rl
)
219 if (first_ptr_list((struct ptr_list
*)rl
) == last_ptr_list((struct ptr_list
*)rl
))
224 long long rl_min(struct range_list
*rl
)
226 struct data_range
*drange
;
228 if (ptr_list_empty(rl
))
229 return whole_range
.min
;
230 drange
= first_ptr_list((struct ptr_list
*)rl
);
234 sval_t
rl_min_sval(struct range_list_sval
*rl
)
236 struct data_range_sval
*drange
;
239 ret
.type
= &llong_ctype
;
240 ret
.value
= LLONG_MIN
;
241 if (ptr_list_empty(rl
))
243 drange
= first_ptr_list((struct ptr_list
*)rl
);
247 long long rl_max(struct range_list
*rl
)
249 struct data_range
*drange
;
251 if (ptr_list_empty(rl
))
252 return whole_range
.max
;
253 drange
= last_ptr_list((struct ptr_list
*)rl
);
257 sval_t
rl_max_sval(struct range_list_sval
*rl
)
259 struct data_range_sval
*drange
;
262 ret
.type
= &llong_ctype
;
263 ret
.value
= LLONG_MAX
;
264 if (ptr_list_empty(rl
))
266 drange
= last_ptr_list((struct ptr_list
*)rl
);
270 static struct data_range
*alloc_range_helper(long long min
, long long max
, int perm
)
272 struct data_range
*ret
;
275 // sm_msg("debug invalid range %lld to %lld", min, max);
276 min
= whole_range
.min
;
277 max
= whole_range
.max
;
279 if (min
== whole_range
.min
&& max
== whole_range
.max
)
281 if (min
== 0 && max
== 0)
283 if (min
== 1 && max
== 1)
287 ret
= __alloc_perm_data_range(0);
289 ret
= __alloc_data_range(0);
295 static struct data_range_sval
*alloc_range_helper_sval(sval_t min
, sval_t max
, int perm
)
297 struct data_range_sval
*ret
;
299 if (sval_cmp(min
, max
) > 0) {
300 // sm_msg("debug invalid range %lld to %lld", min, max);
301 min
.value
= LLONG_MIN
; /* fixme: need a way to represent unknown svals */
302 max
.value
= LLONG_MAX
;
306 ret
= __alloc_perm_data_range_sval(0);
308 ret
= __alloc_data_range_sval(0);
314 struct data_range
*alloc_range(long long min
, long long max
)
316 return alloc_range_helper(min
, max
, 0);
319 struct data_range_sval
*alloc_range_sval(sval_t min
, sval_t max
)
321 return alloc_range_helper_sval(min
, max
, 0);
324 struct data_range_sval
*drange_to_drange_sval(struct data_range
*drange
)
326 return alloc_range_helper_sval(ll_to_sval(drange
->min
), ll_to_sval(drange
->max
), 0);
329 struct data_range
*drange_sval_to_drange(struct data_range_sval
*drange
)
331 return alloc_range_helper(sval_to_ll(drange
->min
), sval_to_ll(drange
->max
), 0);
334 struct data_range
*alloc_range_perm(long long min
, long long max
)
336 return alloc_range_helper(min
, max
, 1);
339 struct data_range_sval
*alloc_range_perm_sval(sval_t min
, sval_t max
)
341 return alloc_range_helper_sval(min
, max
, 1);
344 struct range_list
*alloc_range_list(long long min
, long long max
)
346 struct range_list
*rl
= NULL
;
348 add_range(&rl
, min
, max
);
352 struct range_list_sval
*alloc_range_list_sval(sval_t min
, sval_t max
)
354 struct range_list_sval
*rl
= NULL
;
356 add_range_sval(&rl
, min
, max
);
360 struct range_list
*whole_range_list(void)
362 return alloc_range_list(whole_range
.min
, whole_range
.max
);
365 void add_range(struct range_list
**list
, long long min
, long long max
)
367 struct data_range
*tmp
= NULL
;
368 struct data_range
*new = NULL
;
372 * FIXME: This has a problem merging a range_list like: min-0,3-max
373 * with a range like 1-2. You end up with min-2,3-max instead of
376 FOR_EACH_PTR(*list
, tmp
) {
378 /* Sometimes we overlap with more than one range
379 so we have to delete or modify the next range. */
380 if (max
+ 1 == tmp
->min
) {
381 /* join 2 ranges here */
383 DELETE_CURRENT_PTR(tmp
);
387 /* Doesn't overlap with the next one. */
390 /* Partially overlaps with the next one. */
391 if (max
< tmp
->max
) {
395 /* Completely overlaps with the next one. */
396 if (max
>= tmp
->max
) {
397 DELETE_CURRENT_PTR(tmp
);
398 /* there could be more ranges to delete */
402 if (max
!= whole_range
.max
&& max
+ 1 == tmp
->min
) {
403 /* join 2 ranges into a big range */
404 new = alloc_range(min
, tmp
->max
);
405 REPLACE_CURRENT_PTR(tmp
, new);
408 if (max
< tmp
->min
) { /* new range entirely below */
409 new = alloc_range(min
, max
);
410 INSERT_CURRENT(new, tmp
);
413 if (min
< tmp
->min
) { /* new range partially below */
418 new = alloc_range(min
, max
);
419 REPLACE_CURRENT_PTR(tmp
, new);
424 if (max
<= tmp
->max
) /* new range already included */
426 if (min
<= tmp
->max
) { /* new range partially above */
428 new = alloc_range(min
, max
);
429 REPLACE_CURRENT_PTR(tmp
, new);
433 if (min
!= whole_range
.min
&& min
- 1 == tmp
->max
) {
434 /* join 2 ranges into a big range */
435 new = alloc_range(tmp
->min
, max
);
436 REPLACE_CURRENT_PTR(tmp
, new);
440 /* the new range is entirely above the existing ranges */
441 } END_FOR_EACH_PTR(tmp
);
444 new = alloc_range(min
, max
);
445 add_ptr_list(list
, new);
448 void add_range_sval(struct range_list_sval
**list
, sval_t min
, sval_t max
)
450 struct data_range_sval
*tmp
= NULL
;
451 struct data_range_sval
*new = NULL
;
455 * FIXME: This has a problem merging a range_list like: min-0,3-max
456 * with a range like 1-2. You end up with min-2,3-max instead of
459 FOR_EACH_PTR(*list
, tmp
) {
461 /* Sometimes we overlap with more than one range
462 so we have to delete or modify the next range. */
463 if (max
.value
+ 1 == tmp
->min
.value
) {
464 /* join 2 ranges here */
466 DELETE_CURRENT_PTR(tmp
);
470 /* Doesn't overlap with the next one. */
471 if (sval_cmp(max
, tmp
->min
) < 0)
473 /* Partially overlaps with the next one. */
474 if (sval_cmp(max
, tmp
->max
) < 0) {
475 tmp
->min
.value
= max
.value
+ 1;
478 /* Completely overlaps with the next one. */
479 if (sval_cmp(max
, tmp
->max
) >= 0) {
480 DELETE_CURRENT_PTR(tmp
);
481 /* there could be more ranges to delete */
485 if (!sval_is_max(max
) && max
.value
+ 1 == tmp
->min
.value
) {
486 /* join 2 ranges into a big range */
487 new = alloc_range_sval(min
, tmp
->max
);
488 REPLACE_CURRENT_PTR(tmp
, new);
491 if (sval_cmp(max
, tmp
->min
) < 0) { /* new range entirely below */
492 new = alloc_range_sval(min
, max
);
493 INSERT_CURRENT(new, tmp
);
496 if (sval_cmp(min
, tmp
->min
) < 0) { /* new range partially below */
497 if (sval_cmp(max
, tmp
->max
) < 0)
501 new = alloc_range_sval(min
, max
);
502 REPLACE_CURRENT_PTR(tmp
, new);
507 if (sval_cmp(max
, tmp
->max
) <= 0) /* new range already included */
509 if (sval_cmp(min
, tmp
->max
) <= 0) { /* new range partially above */
511 new = alloc_range_sval(min
, max
);
512 REPLACE_CURRENT_PTR(tmp
, new);
516 if (!sval_is_min(min
) && min
.value
- 1 == tmp
->max
.value
) {
517 /* join 2 ranges into a big range */
518 new = alloc_range_sval(tmp
->min
, max
);
519 REPLACE_CURRENT_PTR(tmp
, new);
523 /* the new range is entirely above the existing ranges */
524 } END_FOR_EACH_PTR(tmp
);
527 new = alloc_range_sval(min
, max
);
528 add_ptr_list(list
, new);
531 struct range_list
*clone_range_list(struct range_list
*list
)
533 struct data_range
*tmp
;
534 struct range_list
*ret
= NULL
;
536 FOR_EACH_PTR(list
, tmp
) {
537 add_ptr_list(&ret
, tmp
);
538 } END_FOR_EACH_PTR(tmp
);
542 struct range_list_sval
*clone_range_list_sval(struct range_list_sval
*list
)
544 struct data_range_sval
*tmp
;
545 struct range_list_sval
*ret
= NULL
;
547 FOR_EACH_PTR(list
, tmp
) {
548 add_ptr_list(&ret
, tmp
);
549 } END_FOR_EACH_PTR(tmp
);
553 struct range_list
*clone_permanent(struct range_list
*list
)
555 struct data_range
*tmp
;
556 struct data_range
*new;
557 struct range_list
*ret
= NULL
;
559 FOR_EACH_PTR(list
, tmp
) {
560 new = alloc_range_perm(tmp
->min
, tmp
->max
);
561 add_ptr_list(&ret
, new);
562 } END_FOR_EACH_PTR(tmp
);
566 struct range_list
*range_list_union(struct range_list
*one
, struct range_list
*two
)
568 struct data_range
*tmp
;
569 struct range_list
*ret
= NULL
;
571 FOR_EACH_PTR(one
, tmp
) {
572 add_range(&ret
, tmp
->min
, tmp
->max
);
573 } END_FOR_EACH_PTR(tmp
);
574 FOR_EACH_PTR(two
, tmp
) {
575 add_range(&ret
, tmp
->min
, tmp
->max
);
576 } END_FOR_EACH_PTR(tmp
);
580 struct range_list_sval
*range_list_union_sval(struct range_list_sval
*one
, struct range_list_sval
*two
)
582 struct data_range_sval
*tmp
;
583 struct range_list_sval
*ret
= NULL
;
585 FOR_EACH_PTR(one
, tmp
) {
586 add_range_sval(&ret
, tmp
->min
, tmp
->max
);
587 } END_FOR_EACH_PTR(tmp
);
588 FOR_EACH_PTR(two
, tmp
) {
589 add_range_sval(&ret
, tmp
->min
, tmp
->max
);
590 } END_FOR_EACH_PTR(tmp
);
594 struct range_list
*remove_range(struct range_list
*list
, long long min
, long long max
)
596 struct data_range
*tmp
;
597 struct range_list
*ret
= NULL
;
599 FOR_EACH_PTR(list
, tmp
) {
600 if (tmp
->max
< min
) {
601 add_range(&ret
, tmp
->min
, tmp
->max
);
604 if (tmp
->min
> max
) {
605 add_range(&ret
, tmp
->min
, tmp
->max
);
608 if (tmp
->min
>= min
&& tmp
->max
<= max
)
610 if (tmp
->min
>= min
) {
611 add_range(&ret
, max
+ 1, tmp
->max
);
612 } else if (tmp
->max
<= max
) {
613 add_range(&ret
, tmp
->min
, min
- 1);
615 add_range(&ret
, tmp
->min
, min
- 1);
616 add_range(&ret
, max
+ 1, tmp
->max
);
618 } END_FOR_EACH_PTR(tmp
);
622 struct range_list_sval
*remove_range_sval(struct range_list_sval
*list
, sval_t min
, sval_t max
)
624 struct data_range_sval
*tmp
;
625 struct range_list_sval
*ret
= NULL
;
627 FOR_EACH_PTR(list
, tmp
) {
628 if (sval_cmp(tmp
->max
, min
) < 0) {
629 add_range_sval(&ret
, tmp
->min
, tmp
->max
);
632 if (sval_cmp(tmp
->min
, max
) > 0) {
633 add_range_sval(&ret
, tmp
->min
, tmp
->max
);
636 if (sval_cmp(tmp
->min
, min
) == 0 && sval_cmp(tmp
->max
, max
) == 0)
638 if (sval_cmp(tmp
->min
, min
) >= 0) {
640 add_range_sval(&ret
, max
, tmp
->max
);
641 } else if (sval_cmp(tmp
->max
, max
) <= 0) {
643 add_range_sval(&ret
, tmp
->min
, min
);
647 add_range_sval(&ret
, tmp
->min
, min
);
648 add_range_sval(&ret
, max
, tmp
->max
);
650 } END_FOR_EACH_PTR(tmp
);
654 struct range_list
*invert_range_list(struct range_list
*orig
)
656 struct range_list
*ret
= NULL
;
657 struct data_range
*tmp
;
663 gap_min
= whole_range
.min
;
664 FOR_EACH_PTR(orig
, tmp
) {
665 if (tmp
->min
> gap_min
)
666 add_range(&ret
, gap_min
, tmp
->min
- 1);
667 gap_min
= tmp
->max
+ 1;
668 if (tmp
->max
== whole_range
.max
)
669 gap_min
= whole_range
.max
;
670 } END_FOR_EACH_PTR(tmp
);
672 if (gap_min
!= whole_range
.max
)
673 add_range(&ret
, gap_min
, whole_range
.max
);
679 * if it can be only one and only value return 1, else return 0
681 int estate_get_single_value(struct smatch_state
*state
, long long *val
)
683 struct data_info
*dinfo
;
684 struct data_range
*tmp
;
687 dinfo
= get_dinfo(state
);
688 if (!dinfo
|| dinfo
->type
!= DATA_RANGE
)
691 FOR_EACH_PTR(dinfo
->value_ranges
, tmp
) {
693 if (tmp
->min
!= tmp
->max
)
699 } END_FOR_EACH_PTR(tmp
);
703 int estate_get_single_value_sval(struct smatch_state
*state
, sval_t
*sval
)
705 struct data_info
*dinfo
;
708 dinfo
= get_dinfo(state
);
709 if (!dinfo
|| dinfo
->type
!= DATA_RANGE
)
712 min
= rl_min_sval(range_list_to_sval(dinfo
->value_ranges
));
713 max
= rl_max_sval(range_list_to_sval(dinfo
->value_ranges
));
714 if (sval_cmp(min
, max
) != 0)
720 int ranges_equiv_sval(struct data_range_sval
*one
, struct data_range_sval
*two
)
726 if (sval_cmp(one
->min
, two
->min
) != 0)
728 if (sval_cmp(one
->max
, two
->max
) != 0)
733 int range_lists_equiv(struct range_list
*one
, struct range_list
*two
)
735 struct data_range
*one_range
;
736 struct data_range
*two_range
;
738 PREPARE_PTR_LIST(one
, one_range
);
739 PREPARE_PTR_LIST(two
, two_range
);
741 if (!one_range
&& !two_range
)
743 if (!one_range
|| !two_range
)
745 if (one_range
->min
!= two_range
->min
)
747 if (one_range
->max
!= two_range
->max
)
749 NEXT_PTR_LIST(one_range
);
750 NEXT_PTR_LIST(two_range
);
752 FINISH_PTR_LIST(two_range
);
753 FINISH_PTR_LIST(one_range
);
758 int true_comparison_range(struct data_range
*left
, int comparison
, struct data_range
*right
)
760 struct data_range_sval
*tmp_left
, *tmp_right
;
762 tmp_left
= drange_to_drange_sval(left
);
763 tmp_right
= drange_to_drange_sval(right
);
764 return true_comparison_range_sval(tmp_left
, comparison
, tmp_right
);
767 int true_comparison_range_sval(struct data_range_sval
*left
, int comparison
, struct data_range_sval
*right
)
769 switch (comparison
) {
771 case SPECIAL_UNSIGNED_LT
:
772 if (sval_cmp(left
->min
, right
->max
) < 0)
775 case SPECIAL_UNSIGNED_LTE
:
777 if (sval_cmp(left
->min
, right
->max
) <= 0)
781 if (sval_cmp(left
->max
, right
->min
) < 0)
783 if (sval_cmp(left
->min
, right
->max
) > 0)
786 case SPECIAL_UNSIGNED_GTE
:
788 if (sval_cmp(left
->max
, right
->min
) >= 0)
792 case SPECIAL_UNSIGNED_GT
:
793 if (sval_cmp(left
->max
, right
->min
) > 0)
796 case SPECIAL_NOTEQUAL
:
797 if (sval_cmp(left
->min
, left
->max
) != 0)
799 if (sval_cmp(right
->min
, right
->max
) != 0)
801 if (sval_cmp(left
->min
, right
->min
) != 0)
805 sm_msg("unhandled comparison %d\n", comparison
);
811 int true_comparison_range_lr(int comparison
, struct data_range
*var
, struct data_range
*val
, int left
)
814 return true_comparison_range(var
, comparison
, val
);
816 return true_comparison_range(val
, comparison
, var
);
819 int true_comparison_range_lr_sval(int comparison
, struct data_range_sval
*var
, struct data_range_sval
*val
, int left
)
822 return true_comparison_range_sval(var
, comparison
, val
);
824 return true_comparison_range_sval(val
, comparison
, var
);
827 static int false_comparison_range_sval(struct data_range_sval
*left
, int comparison
, struct data_range_sval
*right
)
829 switch (comparison
) {
831 case SPECIAL_UNSIGNED_LT
:
832 if (sval_cmp(left
->max
, right
->min
) >= 0)
835 case SPECIAL_UNSIGNED_LTE
:
837 if (sval_cmp(left
->max
, right
->min
) > 0)
841 if (sval_cmp(left
->min
, left
->max
) != 0)
843 if (sval_cmp(right
->min
, right
->max
) != 0)
845 if (sval_cmp(left
->min
, right
->min
) != 0)
848 case SPECIAL_UNSIGNED_GTE
:
850 if (sval_cmp(left
->min
, right
->max
) < 0)
854 case SPECIAL_UNSIGNED_GT
:
855 if (sval_cmp(left
->min
, right
->max
) <= 0)
858 case SPECIAL_NOTEQUAL
:
859 if (sval_cmp(left
->max
, right
->min
) < 0)
861 if (sval_cmp(left
->min
, right
->max
) > 0)
865 sm_msg("unhandled comparison %d\n", comparison
);
871 static int false_comparison_range(struct data_range
*left
, int comparison
, struct data_range
*right
)
873 struct data_range_sval
*tmp_left
, *tmp_right
;
875 tmp_left
= drange_to_drange_sval(left
);
876 tmp_right
= drange_to_drange_sval(right
);
877 return false_comparison_range_sval(tmp_left
, comparison
, tmp_right
);
880 int false_comparison_range_lr(int comparison
, struct data_range
*var
, struct data_range
*val
, int left
)
883 return false_comparison_range(var
, comparison
, val
);
885 return false_comparison_range(val
, comparison
, var
);
888 int false_comparison_range_lr_sval(int comparison
, struct data_range_sval
*var
, struct data_range_sval
*val
, int left
)
891 return false_comparison_range_sval(var
, comparison
, val
);
893 return false_comparison_range_sval(val
, comparison
, var
);
896 int possibly_true(struct expression
*left
, int comparison
, struct expression
*right
)
898 struct range_list
*rl_left
, *rl_right
;
899 struct data_range
*tmp_left
, *tmp_right
;
901 if (!get_implied_range_list(left
, &rl_left
))
903 if (!get_implied_range_list(right
, &rl_right
))
906 FOR_EACH_PTR(rl_left
, tmp_left
) {
907 FOR_EACH_PTR(rl_right
, tmp_right
) {
908 if (true_comparison_range(tmp_left
, comparison
, tmp_right
))
910 } END_FOR_EACH_PTR(tmp_right
);
911 } END_FOR_EACH_PTR(tmp_left
);
915 int possibly_false(struct expression
*left
, int comparison
, struct expression
*right
)
917 struct range_list
*rl_left
, *rl_right
;
918 struct data_range
*tmp_left
, *tmp_right
;
920 if (!get_implied_range_list(left
, &rl_left
))
922 if (!get_implied_range_list(right
, &rl_right
))
925 FOR_EACH_PTR(rl_left
, tmp_left
) {
926 FOR_EACH_PTR(rl_right
, tmp_right
) {
927 if (false_comparison_range(tmp_left
, comparison
, tmp_right
))
929 } END_FOR_EACH_PTR(tmp_right
);
930 } END_FOR_EACH_PTR(tmp_left
);
934 int possibly_true_range_lists(struct range_list
*left_ranges
, int comparison
, struct range_list
*right_ranges
)
936 struct data_range
*left_tmp
, *right_tmp
;
938 if (!left_ranges
|| !right_ranges
)
941 FOR_EACH_PTR(left_ranges
, left_tmp
) {
942 FOR_EACH_PTR(right_ranges
, right_tmp
) {
943 if (true_comparison_range(left_tmp
, comparison
, right_tmp
))
945 } END_FOR_EACH_PTR(right_tmp
);
946 } END_FOR_EACH_PTR(left_tmp
);
950 int possibly_true_range_lists_sval(struct range_list_sval
*left_ranges
, int comparison
, struct range_list_sval
*right_ranges
)
952 struct data_range_sval
*left_tmp
, *right_tmp
;
954 if (!left_ranges
|| !right_ranges
)
957 FOR_EACH_PTR(left_ranges
, left_tmp
) {
958 FOR_EACH_PTR(right_ranges
, right_tmp
) {
959 if (true_comparison_range_sval(left_tmp
, comparison
, right_tmp
))
961 } END_FOR_EACH_PTR(right_tmp
);
962 } END_FOR_EACH_PTR(left_tmp
);
966 int possibly_false_range_lists(struct range_list
*left_ranges
, int comparison
, struct range_list
*right_ranges
)
968 struct data_range
*left_tmp
, *right_tmp
;
970 if (!left_ranges
|| !right_ranges
)
973 FOR_EACH_PTR(left_ranges
, left_tmp
) {
974 FOR_EACH_PTR(right_ranges
, right_tmp
) {
975 if (false_comparison_range(left_tmp
, comparison
, right_tmp
))
977 } END_FOR_EACH_PTR(right_tmp
);
978 } END_FOR_EACH_PTR(left_tmp
);
982 int possibly_false_range_lists_sval(struct range_list_sval
*left_ranges
, int comparison
, struct range_list_sval
*right_ranges
)
984 struct data_range_sval
*left_tmp
, *right_tmp
;
986 if (!left_ranges
|| !right_ranges
)
989 FOR_EACH_PTR(left_ranges
, left_tmp
) {
990 FOR_EACH_PTR(right_ranges
, right_tmp
) {
991 if (false_comparison_range_sval(left_tmp
, comparison
, right_tmp
))
993 } END_FOR_EACH_PTR(right_tmp
);
994 } END_FOR_EACH_PTR(left_tmp
);
998 int possibly_true_range_lists_rl(int comparison
, struct range_list
*a
, struct range_list
*b
, int left
)
1001 return possibly_true_range_lists(a
, comparison
, b
);
1003 return possibly_true_range_lists(b
, comparison
, a
);
1006 /* FIXME: the _rl here stands for right left so really it should be _lr */
1007 int possibly_true_range_lists_rl_sval(int comparison
, struct range_list_sval
*a
, struct range_list_sval
*b
, int left
)
1010 return possibly_true_range_lists_sval(a
, comparison
, b
);
1012 return possibly_true_range_lists_sval(b
, comparison
, a
);
1015 int possibly_false_range_lists_rl(int comparison
, struct range_list
*a
, struct range_list
*b
, int left
)
1018 return possibly_false_range_lists(a
, comparison
, b
);
1020 return possibly_false_range_lists(b
, comparison
, a
);
1023 int possibly_false_range_lists_rl_sval(int comparison
, struct range_list_sval
*a
, struct range_list_sval
*b
, int left
)
1026 return possibly_false_range_lists_sval(a
, comparison
, b
);
1028 return possibly_false_range_lists_sval(b
, comparison
, a
);
1031 void tack_on(struct range_list
**list
, struct data_range
*drange
)
1033 add_ptr_list(list
, drange
);
1036 void tack_on_sval(struct range_list_sval
**list
, struct data_range_sval
*drange
)
1038 add_ptr_list(list
, drange
);
1041 void push_range_list(struct range_list_stack
**rl_stack
, struct range_list
*rl
)
1043 add_ptr_list(rl_stack
, rl
);
1046 void push_range_list_sval(struct range_list_stack_sval
**rl_stack
, struct range_list_sval
*rl
)
1048 add_ptr_list(rl_stack
, rl
);
1051 struct range_list
*pop_range_list(struct range_list_stack
**rl_stack
)
1053 struct range_list
*rl
;
1055 rl
= last_ptr_list((struct ptr_list
*)*rl_stack
);
1056 delete_ptr_list_last((struct ptr_list
**)rl_stack
);
1060 struct range_list_sval
*pop_range_list_sval(struct range_list_stack_sval
**rl_stack
)
1062 struct range_list_sval
*rl
;
1064 rl
= last_ptr_list((struct ptr_list
*)*rl_stack
);
1065 delete_ptr_list_last((struct ptr_list
**)rl_stack
);
1069 struct range_list
*top_range_list(struct range_list_stack
*rl_stack
)
1071 struct range_list
*rl
;
1073 rl
= last_ptr_list((struct ptr_list
*)rl_stack
);
1077 struct range_list_sval
*top_range_list_sval(struct range_list_stack_sval
*rl_stack
)
1079 struct range_list_sval
*rl
;
1081 rl
= last_ptr_list((struct ptr_list
*)rl_stack
);
1085 void filter_top_range_list(struct range_list_stack
**rl_stack
, long long num
)
1087 struct range_list
*rl
;
1089 rl
= pop_range_list(rl_stack
);
1090 rl
= remove_range(rl
, num
, num
);
1091 push_range_list(rl_stack
, rl
);
1094 void filter_top_range_list_sval(struct range_list_stack_sval
**rl_stack
, sval_t sval
)
1096 struct range_list_sval
*rl
;
1098 rl
= pop_range_list_sval(rl_stack
);
1099 rl
= remove_range_sval(rl
, sval
, sval
);
1100 push_range_list_sval(rl_stack
, rl
);
1103 void free_range_list(struct range_list
**rlist
)
1105 __free_ptr_list((struct ptr_list
**)rlist
);
1108 void free_range_list_sval(struct range_list_sval
**rlist
)
1110 __free_ptr_list((struct ptr_list
**)rlist
);
1113 static void free_single_dinfo(struct data_info
*dinfo
)
1115 if (dinfo
->type
== DATA_RANGE
)
1116 free_range_list(&dinfo
->value_ranges
);
1119 static void free_dinfos(struct allocation_blob
*blob
)
1121 unsigned int size
= sizeof(struct data_info
);
1122 unsigned int offset
= 0;
1124 while (offset
< blob
->offset
) {
1125 free_single_dinfo((struct data_info
*)(blob
->data
+ offset
));
1130 void free_data_info_allocs(void)
1132 struct allocator_struct
*desc
= &data_info_allocator
;
1133 struct allocation_blob
*blob
= desc
->blobs
;
1136 desc
->allocations
= 0;
1137 desc
->total_bytes
= 0;
1138 desc
->useful_bytes
= 0;
1139 desc
->freelist
= NULL
;
1141 struct allocation_blob
*next
= blob
->next
;
1143 blob_free(blob
, desc
->chunking
);
1146 clear_data_range_alloc();
1149 struct range_list_sval
*range_list_to_sval(struct range_list
*list
)
1151 struct data_range
*tmp
;
1152 struct data_range_sval
*tmp_sval
;
1153 struct range_list_sval
*ret
= NULL
;
1155 FOR_EACH_PTR(list
, tmp
) {
1156 tmp_sval
= drange_to_drange_sval(tmp
);
1157 add_ptr_list(&ret
, tmp_sval
);
1158 } END_FOR_EACH_PTR(tmp
);
1162 struct range_list
*rl_sval_to_rl(struct range_list_sval
*list
)
1164 struct data_range
*tmp
;
1165 struct data_range_sval
*tmp_sval
;
1166 struct range_list
*ret
= NULL
;
1168 FOR_EACH_PTR(list
, tmp_sval
) {
1169 tmp
= drange_sval_to_drange(tmp_sval
);
1170 add_ptr_list(&ret
, tmp
);
1171 } END_FOR_EACH_PTR(tmp_sval
);