2 * Copyright (C) 2009 Dan Carpenter.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
20 #include "smatch_extra.h"
21 #include "smatch_slist.h"
23 ALLOCATOR(data_info
, "smatch extra data");
24 ALLOCATOR(data_range
, "data range");
25 __DO_ALLOCATOR(struct data_range
, sizeof(struct data_range
), __alignof__(struct data_range
),
26 "permanent ranges", perm_data_range
);
28 char *show_rl(struct range_list
*list
)
30 struct data_range
*tmp
;
35 full
[sizeof(full
) - 1] = '\0';
36 FOR_EACH_PTR(list
, tmp
) {
38 strncat(full
, ",", 254 - strlen(full
));
39 if (sval_cmp(tmp
->min
, tmp
->max
) == 0) {
40 strncat(full
, sval_to_str(tmp
->min
), 254 - strlen(full
));
43 strncat(full
, sval_to_str(tmp
->min
), 254 - strlen(full
));
44 strncat(full
, "-", 254 - strlen(full
));
45 strncat(full
, sval_to_str(tmp
->max
), 254 - strlen(full
));
46 } END_FOR_EACH_PTR(tmp
);
47 if (strlen(full
) == sizeof(full
) - 1)
48 full
[sizeof(full
) - 2] = '+';
49 return alloc_sname(full
);
52 static int sval_too_big(struct symbol
*type
, sval_t sval
)
54 if (type_bits(type
) >= 32 &&
55 type_bits(sval
.type
) <= type_bits(type
))
57 if (sval
.uvalue
<= ((1ULL << type_bits(type
)) - 1))
59 if (type_signed(sval
.type
)) {
60 if (type_unsigned(type
)) {
61 unsigned long long neg
= ~sval
.uvalue
;
62 if (neg
<= sval_type_max(type
).uvalue
)
65 if (sval
.value
< sval_type_min(type
).value
)
67 if (sval
.value
> sval_type_max(type
).value
)
71 if (sval
.uvalue
> sval_type_max(type
).uvalue
)
76 static void add_range_t(struct symbol
*type
, struct range_list
**rl
, sval_t min
, sval_t max
)
78 /* If we're just adding a number, cast it and add it */
79 if (sval_cmp(min
, max
) == 0) {
80 add_range(rl
, sval_cast(type
, min
), sval_cast(type
, max
));
84 /* If the range is within the type range then add it */
85 if (sval_fits(type
, min
) && sval_fits(type
, max
)) {
86 add_range(rl
, sval_cast(type
, min
), sval_cast(type
, max
));
91 * If the range we are adding has more bits than the range type then
92 * add the whole range type. Eg:
93 * 0x8000000000000000 - 0xf000000000000000 -> cast to int
94 * This isn't totally the right thing to do. We could be more granular.
96 if (sval_too_big(type
, min
) || sval_too_big(type
, max
)) {
97 add_range(rl
, sval_type_min(type
), sval_type_max(type
));
101 /* Cast negative values to high positive values */
102 if (sval_is_negative(min
) && type_unsigned(type
)) {
103 if (sval_is_positive(max
)) {
104 if (sval_too_high(type
, max
)) {
105 add_range(rl
, sval_type_min(type
), sval_type_max(type
));
108 add_range(rl
, sval_type_val(type
, 0), sval_cast(type
, max
));
109 max
= sval_type_max(type
);
111 max
= sval_cast(type
, max
);
113 min
= sval_cast(type
, min
);
114 add_range(rl
, min
, max
);
117 /* Cast high positive numbers to negative */
118 if (sval_unsigned(max
) && sval_is_negative(sval_cast(type
, max
))) {
119 if (!sval_is_negative(sval_cast(type
, min
))) {
120 add_range(rl
, sval_cast(type
, min
), sval_type_max(type
));
121 min
= sval_type_min(type
);
123 min
= sval_cast(type
, min
);
125 max
= sval_cast(type
, max
);
126 add_range(rl
, min
, max
);
129 add_range(rl
, sval_cast(type
, min
), sval_cast(type
, max
));
133 static int str_to_comparison_arg_helper(const char *str
,
134 struct expression
*call
, int *comparison
,
135 struct expression
**arg
, char **endp
)
138 char *c
= (char *)str
;
147 *comparison
= SPECIAL_LTE
;
152 } else if (*c
== '=') {
155 *comparison
= SPECIAL_EQUAL
;
156 } else if (*c
== '>') {
159 *comparison
= SPECIAL_GTE
;
164 } else if (*c
== '!') {
167 *comparison
= SPECIAL_NOTEQUAL
;
176 param
= strtoll(c
, &c
, 10);
177 c
++; /* skip the ']' character */
183 *arg
= get_argument_from_call_expr(call
->args
, param
);
189 int str_to_comparison_arg(const char *str
, struct expression
*call
, int *comparison
, struct expression
**arg
)
198 return str_to_comparison_arg_helper(str
, call
, comparison
, arg
, NULL
);
201 static int get_val_from_key(int use_max
, struct symbol
*type
, char *c
, struct expression
*call
, char **endp
, sval_t
*sval
)
203 struct expression
*arg
;
208 ret
= sval_type_max(type
);
210 ret
= sval_type_min(type
);
212 if (!str_to_comparison_arg_helper(c
, call
, &comparison
, &arg
, endp
)) {
217 if (use_max
&& get_implied_max(arg
, &tmp
)) {
219 if (comparison
== '<') {
221 ret
= sval_binop(ret
, '-', tmp
);
224 if (!use_max
&& get_implied_min(arg
, &tmp
)) {
226 if (comparison
== '>') {
228 ret
= sval_binop(ret
, '+', tmp
);
236 static sval_t
add_one(sval_t sval
)
242 static sval_t
sub_one(sval_t sval
)
248 void filter_by_comparison(struct range_list
**rl
, int comparison
, struct range_list
*right
)
250 struct range_list
*left_orig
= *rl
;
251 struct range_list
*right_orig
= right
;
252 struct range_list
*ret_rl
= *rl
;
253 struct symbol
*cast_type
;
256 cast_type
= rl_type(left_orig
);
257 if (sval_type_max(rl_type(left_orig
)).uvalue
< sval_type_max(rl_type(right_orig
)).uvalue
)
258 cast_type
= rl_type(right_orig
);
259 if (sval_type_max(cast_type
).uvalue
< INT_MAX
)
260 cast_type
= &int_ctype
;
262 min
= sval_type_min(cast_type
);
263 max
= sval_type_max(cast_type
);
264 left_orig
= cast_rl(cast_type
, left_orig
);
265 right_orig
= cast_rl(cast_type
, right_orig
);
267 switch (comparison
) {
269 case SPECIAL_UNSIGNED_LT
:
270 ret_rl
= remove_range(left_orig
, rl_max(right_orig
), max
);
273 case SPECIAL_UNSIGNED_LTE
:
274 if (!sval_is_max(rl_max(right_orig
)))
275 ret_rl
= remove_range(left_orig
, add_one(rl_max(right_orig
)), max
);
278 if (!sval_is_max(rl_max(right_orig
)))
279 ret_rl
= remove_range(ret_rl
, add_one(rl_max(right_orig
)), max
);
280 if (!sval_is_min(rl_min(right_orig
)))
281 ret_rl
= remove_range(ret_rl
, min
, sub_one(rl_min(right_orig
)));
284 case SPECIAL_UNSIGNED_GTE
:
285 if (!sval_is_min(rl_min(right_orig
)))
286 ret_rl
= remove_range(left_orig
, min
, sub_one(rl_min(right_orig
)));
289 case SPECIAL_UNSIGNED_GT
:
290 ret_rl
= remove_range(left_orig
, min
, rl_min(right_orig
));
292 case SPECIAL_NOTEQUAL
:
293 if (sval_cmp(rl_min(right_orig
), rl_max(right_orig
)) == 0)
294 ret_rl
= remove_range(left_orig
, rl_min(right_orig
), rl_min(right_orig
));
297 sm_msg("internal error: unhandled comparison %s", show_special(comparison
));
301 *rl
= cast_rl(rl_type(*rl
), ret_rl
);
304 static struct range_list
*filter_by_comparison_call(char *c
, struct expression
*call
, char **endp
, struct range_list
*start_rl
)
307 struct expression
*arg
;
308 struct range_list
*casted_start
, *right_orig
;
311 if (!str_to_comparison_arg_helper(c
, call
, &comparison
, &arg
, endp
))
314 if (!get_implied_rl(arg
, &right_orig
))
318 if (type_positive_bits(rl_type(start_rl
)) > type_positive_bits(type
))
319 type
= rl_type(start_rl
);
320 if (type_positive_bits(rl_type(right_orig
)) > type_positive_bits(type
))
321 type
= rl_type(right_orig
);
323 casted_start
= cast_rl(type
, start_rl
);
324 right_orig
= cast_rl(type
, right_orig
);
326 filter_by_comparison(&casted_start
, comparison
, right_orig
);
327 return cast_rl(rl_type(start_rl
), casted_start
);
330 static sval_t
parse_val(int use_max
, struct expression
*call
, struct symbol
*type
, char *c
, char **endp
)
335 if (!strncmp(start
, "max", 3)) {
336 ret
= sval_type_max(type
);
338 } else if (!strncmp(start
, "u64max", 6)) {
339 ret
= sval_type_val(type
, ULLONG_MAX
);
341 } else if (!strncmp(start
, "s64max", 6)) {
342 ret
= sval_type_val(type
, LLONG_MAX
);
344 } else if (!strncmp(start
, "u32max", 6)) {
345 ret
= sval_type_val(type
, UINT_MAX
);
347 } else if (!strncmp(start
, "s32max", 6)) {
348 ret
= sval_type_val(type
, INT_MAX
);
350 } else if (!strncmp(start
, "u16max", 6)) {
351 ret
= sval_type_val(type
, USHRT_MAX
);
353 } else if (!strncmp(start
, "s16max", 6)) {
354 ret
= sval_type_val(type
, SHRT_MAX
);
356 } else if (!strncmp(start
, "min", 3)) {
357 ret
= sval_type_min(type
);
359 } else if (!strncmp(start
, "s64min", 6)) {
360 ret
= sval_type_val(type
, LLONG_MIN
);
362 } else if (!strncmp(start
, "s32min", 6)) {
363 ret
= sval_type_val(type
, INT_MIN
);
365 } else if (!strncmp(start
, "s16min", 6)) {
366 ret
= sval_type_val(type
, SHRT_MIN
);
368 } else if (!strncmp(start
, "long_min", 8)) {
369 ret
= sval_type_val(type
, LONG_MIN
);
371 } else if (!strncmp(start
, "long_max", 8)) {
372 ret
= sval_type_val(type
, LONG_MAX
);
374 } else if (!strncmp(start
, "ulong_max", 9)) {
375 ret
= sval_type_val(type
, ULONG_MAX
);
377 } else if (!strncmp(start
, "ptr_max", 7)) {
378 ret
= sval_type_val(type
, valid_ptr_max
);
380 } else if (start
[0] == '[') {
381 /* this parses [==p0] comparisons */
382 get_val_from_key(1, type
, start
, call
, &c
, &ret
);
383 } else if (type_positive_bits(type
) == 64) {
384 ret
= sval_type_val(type
, strtoull(start
, &c
, 10));
386 ret
= sval_type_val(type
, strtoll(start
, &c
, 10));
392 static char *jump_to_call_math(char *value
)
396 while (*c
&& *c
!= '[')
402 if (*c
== '<' || *c
== '=' || *c
== '>' || *c
== '!')
408 static void str_to_rl_helper(struct expression
*call
, struct symbol
*type
, char *str
, char **endp
, struct range_list
**rl
)
410 struct range_list
*rl_tmp
= NULL
;
414 min
= sval_type_min(type
);
415 max
= sval_type_max(type
);
417 while (*c
!= '\0' && *c
!= '[') {
419 if (sval_cmp(min
, sval_type_min(type
)) != 0)
421 max
= sval_type_max(type
);
422 add_range_t(type
, &rl_tmp
, min
, max
);
427 min
= parse_val(0, call
, type
, c
, &c
);
428 if (!sval_fits(type
, min
))
429 min
= sval_type_min(type
);
433 if (*c
== '\0' || *c
== '[') {
434 add_range_t(type
, &rl_tmp
, min
, min
);
438 add_range_t(type
, &rl_tmp
, min
, min
);
443 min
= sval_type_max(type
);
447 sm_msg("debug XXX: trouble parsing %s c = %s", str
, c
);
453 max
= parse_val(1, call
, type
, c
, &c
);
454 if (!sval_fits(type
, max
))
455 max
= sval_type_max(type
);
457 max
= sval_type_max(type
);
460 add_range_t(type
, &rl_tmp
, min
, max
);
471 static void str_to_dinfo(struct expression
*call
, struct symbol
*type
, char *value
, struct data_info
*dinfo
)
473 struct range_list
*math_rl
;
476 struct range_list
*rl
= NULL
;
481 if (strcmp(value
, "empty") == 0)
484 if (strncmp(value
, "[==$", 4) == 0) {
485 struct expression
*arg
;
488 if (!str_to_comparison_arg(value
, call
, &comparison
, &arg
))
490 if (!get_implied_rl(arg
, &rl
))
495 str_to_rl_helper(call
, type
, value
, &c
, &rl
);
499 call_math
= jump_to_call_math(value
);
500 if (call_math
&& parse_call_math_rl(call
, call_math
, &math_rl
)) {
501 rl
= rl_intersection(rl
, math_rl
);
506 * For now if we already tried to handle the call math and couldn't
507 * figure it out then bail.
509 if (jump_to_call_math(c
) == c
+ 1)
512 rl
= filter_by_comparison_call(c
, call
, &c
, rl
);
515 rl
= cast_rl(type
, rl
);
516 dinfo
->value_ranges
= rl
;
519 void str_to_rl(struct symbol
*type
, char *value
, struct range_list
**rl
)
521 struct data_info dinfo
= {};
523 str_to_dinfo(NULL
, type
, value
, &dinfo
);
524 *rl
= dinfo
.value_ranges
;
527 void call_results_to_rl(struct expression
*expr
, struct symbol
*type
, char *value
, struct range_list
**rl
)
529 struct data_info dinfo
= {};
531 str_to_dinfo(strip_expr(expr
), type
, value
, &dinfo
);
532 *rl
= dinfo
.value_ranges
;
535 int is_whole_rl(struct range_list
*rl
)
537 struct data_range
*drange
;
539 if (ptr_list_empty(rl
))
541 drange
= first_ptr_list((struct ptr_list
*)rl
);
542 if (sval_is_min(drange
->min
) && sval_is_max(drange
->max
))
547 int is_whole_rl_non_zero(struct range_list
*rl
)
549 struct data_range
*drange
;
551 if (ptr_list_empty(rl
))
553 drange
= first_ptr_list((struct ptr_list
*)rl
);
554 if (sval_unsigned(drange
->min
) &&
555 drange
->min
.value
== 1 &&
556 sval_is_max(drange
->max
))
558 if (!sval_is_min(drange
->min
) || drange
->max
.value
!= -1)
560 drange
= last_ptr_list((struct ptr_list
*)rl
);
561 if (drange
->min
.value
!= 1 || !sval_is_max(drange
->max
))
566 sval_t
rl_min(struct range_list
*rl
)
568 struct data_range
*drange
;
571 ret
.type
= &llong_ctype
;
572 ret
.value
= LLONG_MIN
;
573 if (ptr_list_empty(rl
))
575 drange
= first_ptr_list((struct ptr_list
*)rl
);
579 sval_t
rl_max(struct range_list
*rl
)
581 struct data_range
*drange
;
584 ret
.type
= &llong_ctype
;
585 ret
.value
= LLONG_MAX
;
586 if (ptr_list_empty(rl
))
588 drange
= last_ptr_list((struct ptr_list
*)rl
);
592 int rl_to_sval(struct range_list
*rl
, sval_t
*sval
)
601 if (sval_cmp(min
, max
) != 0)
607 struct symbol
*rl_type(struct range_list
*rl
)
611 return rl_min(rl
).type
;
614 static struct data_range
*alloc_range_helper_sval(sval_t min
, sval_t max
, int perm
)
616 struct data_range
*ret
;
619 ret
= __alloc_perm_data_range(0);
621 ret
= __alloc_data_range(0);
627 struct data_range
*alloc_range(sval_t min
, sval_t max
)
629 return alloc_range_helper_sval(min
, max
, 0);
632 struct data_range
*alloc_range_perm(sval_t min
, sval_t max
)
634 return alloc_range_helper_sval(min
, max
, 1);
637 struct range_list
*alloc_rl(sval_t min
, sval_t max
)
639 struct range_list
*rl
= NULL
;
641 if (sval_cmp(min
, max
) > 0)
642 return alloc_whole_rl(min
.type
);
644 add_range(&rl
, min
, max
);
648 struct range_list
*alloc_whole_rl(struct symbol
*type
)
650 if (!type
|| type_positive_bits(type
) < 0)
652 if (type
->type
== SYM_ARRAY
)
655 return alloc_rl(sval_type_min(type
), sval_type_max(type
));
658 void add_range(struct range_list
**list
, sval_t min
, sval_t max
)
660 struct data_range
*tmp
;
661 struct data_range
*new = NULL
;
665 * There is at least on valid reason why the types might be confusing
666 * and that's when you have a void pointer and on some paths you treat
667 * it as a u8 pointer and on other paths you treat it as a u16 pointer.
668 * This case is hard to deal with.
670 * There are other cases where we probably should be more specific about
671 * the types than we are. For example, we end up merging a lot of ulong
672 * with pointers and I have not figured out why we do that.
674 * But this hack works for both cases, I think. We cast it to pointers
675 * or we use the bigger size.
678 if (*list
&& rl_type(*list
) != min
.type
) {
679 if (rl_type(*list
)->type
== SYM_PTR
) {
680 min
= sval_cast(rl_type(*list
), min
);
681 max
= sval_cast(rl_type(*list
), max
);
682 } else if (min
.type
->type
== SYM_PTR
) {
683 *list
= cast_rl(min
.type
, *list
);
684 } else if (type_bits(rl_type(*list
)) >= type_bits(min
.type
)) {
685 min
= sval_cast(rl_type(*list
), min
);
686 max
= sval_cast(rl_type(*list
), max
);
688 *list
= cast_rl(min
.type
, *list
);
692 if (sval_cmp(min
, max
) > 0) {
693 min
= sval_type_min(min
.type
);
694 max
= sval_type_max(min
.type
);
698 * FIXME: This has a problem merging a range_list like: min-0,3-max
699 * with a range like 1-2. You end up with min-2,3-max instead of
702 FOR_EACH_PTR(*list
, tmp
) {
704 /* Sometimes we overlap with more than one range
705 so we have to delete or modify the next range. */
706 if (!sval_is_max(max
) && max
.value
+ 1 == tmp
->min
.value
) {
707 /* join 2 ranges here */
709 DELETE_CURRENT_PTR(tmp
);
713 /* Doesn't overlap with the next one. */
714 if (sval_cmp(max
, tmp
->min
) < 0)
717 if (sval_cmp(max
, tmp
->max
) <= 0) {
718 /* Partially overlaps the next one. */
720 DELETE_CURRENT_PTR(tmp
);
723 /* Completely overlaps the next one. */
724 DELETE_CURRENT_PTR(tmp
);
725 /* there could be more ranges to delete */
729 if (!sval_is_max(max
) && max
.value
+ 1 == tmp
->min
.value
) {
730 /* join 2 ranges into a big range */
731 new = alloc_range(min
, tmp
->max
);
732 REPLACE_CURRENT_PTR(tmp
, new);
735 if (sval_cmp(max
, tmp
->min
) < 0) { /* new range entirely below */
736 new = alloc_range(min
, max
);
737 INSERT_CURRENT(new, tmp
);
740 if (sval_cmp(min
, tmp
->min
) < 0) { /* new range partially below */
741 if (sval_cmp(max
, tmp
->max
) < 0)
745 new = alloc_range(min
, max
);
746 REPLACE_CURRENT_PTR(tmp
, new);
751 if (sval_cmp(max
, tmp
->max
) <= 0) /* new range already included */
753 if (sval_cmp(min
, tmp
->max
) <= 0) { /* new range partially above */
755 new = alloc_range(min
, max
);
756 REPLACE_CURRENT_PTR(tmp
, new);
760 if (!sval_is_min(min
) && min
.value
- 1 == tmp
->max
.value
) {
761 /* join 2 ranges into a big range */
762 new = alloc_range(tmp
->min
, max
);
763 REPLACE_CURRENT_PTR(tmp
, new);
767 /* the new range is entirely above the existing ranges */
768 } END_FOR_EACH_PTR(tmp
);
771 new = alloc_range(min
, max
);
772 add_ptr_list(list
, new);
775 struct range_list
*clone_rl(struct range_list
*list
)
777 struct data_range
*tmp
;
778 struct range_list
*ret
= NULL
;
780 FOR_EACH_PTR(list
, tmp
) {
781 add_ptr_list(&ret
, tmp
);
782 } END_FOR_EACH_PTR(tmp
);
786 struct range_list
*clone_rl_permanent(struct range_list
*list
)
788 struct data_range
*tmp
;
789 struct data_range
*new;
790 struct range_list
*ret
= NULL
;
792 FOR_EACH_PTR(list
, tmp
) {
793 new = alloc_range_perm(tmp
->min
, tmp
->max
);
794 add_ptr_list(&ret
, new);
795 } END_FOR_EACH_PTR(tmp
);
799 struct range_list
*rl_union(struct range_list
*one
, struct range_list
*two
)
801 struct data_range
*tmp
;
802 struct range_list
*ret
= NULL
;
804 FOR_EACH_PTR(one
, tmp
) {
805 add_range(&ret
, tmp
->min
, tmp
->max
);
806 } END_FOR_EACH_PTR(tmp
);
807 FOR_EACH_PTR(two
, tmp
) {
808 add_range(&ret
, tmp
->min
, tmp
->max
);
809 } END_FOR_EACH_PTR(tmp
);
813 struct range_list
*remove_range(struct range_list
*list
, sval_t min
, sval_t max
)
815 struct data_range
*tmp
;
816 struct range_list
*ret
= NULL
;
821 min
= sval_cast(rl_type(list
), min
);
822 max
= sval_cast(rl_type(list
), max
);
823 if (sval_cmp(min
, max
) > 0) {
829 FOR_EACH_PTR(list
, tmp
) {
830 if (sval_cmp(tmp
->max
, min
) < 0) {
831 add_range(&ret
, tmp
->min
, tmp
->max
);
834 if (sval_cmp(tmp
->min
, max
) > 0) {
835 add_range(&ret
, tmp
->min
, tmp
->max
);
838 if (sval_cmp(tmp
->min
, min
) >= 0 && sval_cmp(tmp
->max
, max
) <= 0)
840 if (sval_cmp(tmp
->min
, min
) >= 0) {
842 add_range(&ret
, max
, tmp
->max
);
843 } else if (sval_cmp(tmp
->max
, max
) <= 0) {
845 add_range(&ret
, tmp
->min
, min
);
849 add_range(&ret
, tmp
->min
, min
);
850 add_range(&ret
, max
, tmp
->max
);
852 } END_FOR_EACH_PTR(tmp
);
856 int ranges_equiv(struct data_range
*one
, struct data_range
*two
)
862 if (sval_cmp(one
->min
, two
->min
) != 0)
864 if (sval_cmp(one
->max
, two
->max
) != 0)
869 int rl_equiv(struct range_list
*one
, struct range_list
*two
)
871 struct data_range
*one_range
;
872 struct data_range
*two_range
;
877 PREPARE_PTR_LIST(one
, one_range
);
878 PREPARE_PTR_LIST(two
, two_range
);
880 if (!one_range
&& !two_range
)
882 if (!ranges_equiv(one_range
, two_range
))
884 NEXT_PTR_LIST(one_range
);
885 NEXT_PTR_LIST(two_range
);
887 FINISH_PTR_LIST(two_range
);
888 FINISH_PTR_LIST(one_range
);
893 int true_comparison_range(struct data_range
*left
, int comparison
, struct data_range
*right
)
895 switch (comparison
) {
897 case SPECIAL_UNSIGNED_LT
:
898 if (sval_cmp(left
->min
, right
->max
) < 0)
901 case SPECIAL_UNSIGNED_LTE
:
903 if (sval_cmp(left
->min
, right
->max
) <= 0)
907 if (sval_cmp(left
->max
, right
->min
) < 0)
909 if (sval_cmp(left
->min
, right
->max
) > 0)
912 case SPECIAL_UNSIGNED_GTE
:
914 if (sval_cmp(left
->max
, right
->min
) >= 0)
918 case SPECIAL_UNSIGNED_GT
:
919 if (sval_cmp(left
->max
, right
->min
) > 0)
922 case SPECIAL_NOTEQUAL
:
923 if (sval_cmp(left
->min
, left
->max
) != 0)
925 if (sval_cmp(right
->min
, right
->max
) != 0)
927 if (sval_cmp(left
->min
, right
->min
) != 0)
931 sm_msg("unhandled comparison %d\n", comparison
);
937 int true_comparison_range_LR(int comparison
, struct data_range
*var
, struct data_range
*val
, int left
)
940 return true_comparison_range(var
, comparison
, val
);
942 return true_comparison_range(val
, comparison
, var
);
945 static int false_comparison_range_sval(struct data_range
*left
, int comparison
, struct data_range
*right
)
947 switch (comparison
) {
949 case SPECIAL_UNSIGNED_LT
:
950 if (sval_cmp(left
->max
, right
->min
) >= 0)
953 case SPECIAL_UNSIGNED_LTE
:
955 if (sval_cmp(left
->max
, right
->min
) > 0)
959 if (sval_cmp(left
->min
, left
->max
) != 0)
961 if (sval_cmp(right
->min
, right
->max
) != 0)
963 if (sval_cmp(left
->min
, right
->min
) != 0)
966 case SPECIAL_UNSIGNED_GTE
:
968 if (sval_cmp(left
->min
, right
->max
) < 0)
972 case SPECIAL_UNSIGNED_GT
:
973 if (sval_cmp(left
->min
, right
->max
) <= 0)
976 case SPECIAL_NOTEQUAL
:
977 if (sval_cmp(left
->max
, right
->min
) < 0)
979 if (sval_cmp(left
->min
, right
->max
) > 0)
983 sm_msg("unhandled comparison %d\n", comparison
);
989 int false_comparison_range_LR(int comparison
, struct data_range
*var
, struct data_range
*val
, int left
)
992 return false_comparison_range_sval(var
, comparison
, val
);
994 return false_comparison_range_sval(val
, comparison
, var
);
997 int possibly_true(struct expression
*left
, int comparison
, struct expression
*right
)
999 struct range_list
*rl_left
, *rl_right
;
1000 struct data_range
*tmp_left
, *tmp_right
;
1001 struct symbol
*type
;
1003 if (!get_implied_rl(left
, &rl_left
))
1005 if (!get_implied_rl(right
, &rl_right
))
1008 type
= rl_type(rl_left
);
1009 if (type_positive_bits(type
) < type_positive_bits(rl_type(rl_right
)))
1010 type
= rl_type(rl_right
);
1011 if (type_positive_bits(type
) < 31)
1014 rl_left
= cast_rl(type
, rl_left
);
1015 rl_right
= cast_rl(type
, rl_right
);
1017 FOR_EACH_PTR(rl_left
, tmp_left
) {
1018 FOR_EACH_PTR(rl_right
, tmp_right
) {
1019 if (true_comparison_range(tmp_left
, comparison
, tmp_right
))
1021 } END_FOR_EACH_PTR(tmp_right
);
1022 } END_FOR_EACH_PTR(tmp_left
);
1026 int possibly_false(struct expression
*left
, int comparison
, struct expression
*right
)
1028 struct range_list
*rl_left
, *rl_right
;
1029 struct data_range
*tmp_left
, *tmp_right
;
1030 struct symbol
*type
;
1032 if (!get_implied_rl(left
, &rl_left
))
1034 if (!get_implied_rl(right
, &rl_right
))
1037 type
= rl_type(rl_left
);
1038 if (type_positive_bits(type
) < type_positive_bits(rl_type(rl_right
)))
1039 type
= rl_type(rl_right
);
1040 if (type_positive_bits(type
) < 31)
1043 rl_left
= cast_rl(type
, rl_left
);
1044 rl_right
= cast_rl(type
, rl_right
);
1046 FOR_EACH_PTR(rl_left
, tmp_left
) {
1047 FOR_EACH_PTR(rl_right
, tmp_right
) {
1048 if (false_comparison_range_sval(tmp_left
, comparison
, tmp_right
))
1050 } END_FOR_EACH_PTR(tmp_right
);
1051 } END_FOR_EACH_PTR(tmp_left
);
1055 int possibly_true_rl(struct range_list
*left_ranges
, int comparison
, struct range_list
*right_ranges
)
1057 struct data_range
*left_tmp
, *right_tmp
;
1058 struct symbol
*type
;
1060 if (!left_ranges
|| !right_ranges
)
1063 type
= rl_type(left_ranges
);
1064 if (type_positive_bits(type
) < type_positive_bits(rl_type(right_ranges
)))
1065 type
= rl_type(right_ranges
);
1066 if (type_positive_bits(type
) < 31)
1069 left_ranges
= cast_rl(type
, left_ranges
);
1070 right_ranges
= cast_rl(type
, right_ranges
);
1072 FOR_EACH_PTR(left_ranges
, left_tmp
) {
1073 FOR_EACH_PTR(right_ranges
, right_tmp
) {
1074 if (true_comparison_range(left_tmp
, comparison
, right_tmp
))
1076 } END_FOR_EACH_PTR(right_tmp
);
1077 } END_FOR_EACH_PTR(left_tmp
);
1081 int possibly_false_rl(struct range_list
*left_ranges
, int comparison
, struct range_list
*right_ranges
)
1083 struct data_range
*left_tmp
, *right_tmp
;
1084 struct symbol
*type
;
1086 if (!left_ranges
|| !right_ranges
)
1089 type
= rl_type(left_ranges
);
1090 if (type_positive_bits(type
) < type_positive_bits(rl_type(right_ranges
)))
1091 type
= rl_type(right_ranges
);
1092 if (type_positive_bits(type
) < 31)
1095 left_ranges
= cast_rl(type
, left_ranges
);
1096 right_ranges
= cast_rl(type
, right_ranges
);
1098 FOR_EACH_PTR(left_ranges
, left_tmp
) {
1099 FOR_EACH_PTR(right_ranges
, right_tmp
) {
1100 if (false_comparison_range_sval(left_tmp
, comparison
, right_tmp
))
1102 } END_FOR_EACH_PTR(right_tmp
);
1103 } END_FOR_EACH_PTR(left_tmp
);
1107 /* FIXME: the _rl here stands for right left so really it should be _lr */
1108 int possibly_true_rl_LR(int comparison
, struct range_list
*a
, struct range_list
*b
, int left
)
1111 return possibly_true_rl(a
, comparison
, b
);
1113 return possibly_true_rl(b
, comparison
, a
);
1116 int possibly_false_rl_LR(int comparison
, struct range_list
*a
, struct range_list
*b
, int left
)
1119 return possibly_false_rl(a
, comparison
, b
);
1121 return possibly_false_rl(b
, comparison
, a
);
1124 int rl_has_sval(struct range_list
*rl
, sval_t sval
)
1126 struct data_range
*tmp
;
1128 FOR_EACH_PTR(rl
, tmp
) {
1129 if (sval_cmp(tmp
->min
, sval
) <= 0 &&
1130 sval_cmp(tmp
->max
, sval
) >= 0)
1132 } END_FOR_EACH_PTR(tmp
);
1136 void tack_on(struct range_list
**list
, struct data_range
*drange
)
1138 add_ptr_list(list
, drange
);
1141 void push_rl(struct range_list_stack
**rl_stack
, struct range_list
*rl
)
1143 add_ptr_list(rl_stack
, rl
);
1146 struct range_list
*pop_rl(struct range_list_stack
**rl_stack
)
1148 struct range_list
*rl
;
1150 rl
= last_ptr_list((struct ptr_list
*)*rl_stack
);
1151 delete_ptr_list_last((struct ptr_list
**)rl_stack
);
1155 struct range_list
*top_rl(struct range_list_stack
*rl_stack
)
1157 struct range_list
*rl
;
1159 rl
= last_ptr_list((struct ptr_list
*)rl_stack
);
1163 void filter_top_rl(struct range_list_stack
**rl_stack
, struct range_list
*filter
)
1165 struct range_list
*rl
;
1167 rl
= pop_rl(rl_stack
);
1168 rl
= rl_filter(rl
, filter
);
1169 push_rl(rl_stack
, rl
);
1172 struct range_list
*rl_truncate_cast(struct symbol
*type
, struct range_list
*rl
)
1174 struct data_range
*tmp
;
1175 struct range_list
*ret
= NULL
;
1181 if (!type
|| type
== rl_type(rl
))
1184 FOR_EACH_PTR(rl
, tmp
) {
1187 if (type_bits(type
) < type_bits(rl_type(rl
))) {
1188 min
.uvalue
= tmp
->min
.uvalue
& ((1ULL << type_bits(type
)) - 1);
1189 max
.uvalue
= tmp
->max
.uvalue
& ((1ULL << type_bits(type
)) - 1);
1191 if (sval_cmp(min
, max
) > 0) {
1192 min
= sval_cast(type
, min
);
1193 max
= sval_cast(type
, max
);
1195 add_range_t(type
, &ret
, min
, max
);
1196 } END_FOR_EACH_PTR(tmp
);
1201 static int rl_is_sane(struct range_list
*rl
)
1203 struct data_range
*tmp
;
1204 struct symbol
*type
;
1207 FOR_EACH_PTR(rl
, tmp
) {
1208 if (!sval_fits(type
, tmp
->min
))
1210 if (!sval_fits(type
, tmp
->max
))
1212 if (sval_cmp(tmp
->min
, tmp
->max
) > 0)
1214 } END_FOR_EACH_PTR(tmp
);
1219 static int rl_type_consistent(struct range_list
*rl
)
1221 struct data_range
*tmp
;
1222 struct symbol
*type
;
1225 FOR_EACH_PTR(rl
, tmp
) {
1226 if (type
!= tmp
->min
.type
|| type
!= tmp
->max
.type
)
1228 } END_FOR_EACH_PTR(tmp
);
1232 static struct range_list
*cast_to_bool(struct range_list
*rl
)
1234 struct data_range
*tmp
;
1235 struct range_list
*ret
= NULL
;
1238 sval_t min
= { .type
= &bool_ctype
};
1239 sval_t max
= { .type
= &bool_ctype
};
1241 FOR_EACH_PTR(rl
, tmp
) {
1242 if (tmp
->min
.value
|| tmp
->max
.value
)
1244 if (sval_is_negative(tmp
->min
) &&
1245 sval_is_negative(tmp
->max
))
1247 if (tmp
->min
.value
== 0 ||
1248 tmp
->max
.value
== 0)
1250 if (sval_is_negative(tmp
->min
) &&
1253 } END_FOR_EACH_PTR(tmp
);
1260 add_range(&ret
, min
, max
);
1264 struct range_list
*cast_rl(struct symbol
*type
, struct range_list
*rl
)
1266 struct data_range
*tmp
;
1267 struct range_list
*ret
= NULL
;
1274 if (!rl_is_sane(rl
))
1275 return alloc_whole_rl(type
);
1276 if (type
== rl_type(rl
) && rl_type_consistent(rl
))
1279 if (type
== &bool_ctype
)
1280 return cast_to_bool(rl
);
1282 FOR_EACH_PTR(rl
, tmp
) {
1283 add_range_t(type
, &ret
, tmp
->min
, tmp
->max
);
1284 } END_FOR_EACH_PTR(tmp
);
1287 return alloc_whole_rl(type
);
1292 struct range_list
*rl_invert(struct range_list
*orig
)
1294 struct range_list
*ret
= NULL
;
1295 struct data_range
*tmp
;
1296 sval_t gap_min
, abs_max
, sval
;
1300 if (type_bits(rl_type(orig
)) < 0) /* void type mostly */
1303 gap_min
= sval_type_min(rl_min(orig
).type
);
1304 abs_max
= sval_type_max(rl_max(orig
).type
);
1306 FOR_EACH_PTR(orig
, tmp
) {
1307 if (sval_cmp(tmp
->min
, gap_min
) > 0) {
1308 sval
= sval_type_val(tmp
->min
.type
, tmp
->min
.value
- 1);
1309 add_range(&ret
, gap_min
, sval
);
1311 if (sval_cmp(tmp
->max
, abs_max
) == 0)
1313 gap_min
= sval_type_val(tmp
->max
.type
, tmp
->max
.value
+ 1);
1314 } END_FOR_EACH_PTR(tmp
);
1316 if (sval_cmp(gap_min
, abs_max
) <= 0)
1317 add_range(&ret
, gap_min
, abs_max
);
1322 struct range_list
*rl_filter(struct range_list
*rl
, struct range_list
*filter
)
1324 struct data_range
*tmp
;
1326 FOR_EACH_PTR(filter
, tmp
) {
1327 rl
= remove_range(rl
, tmp
->min
, tmp
->max
);
1328 } END_FOR_EACH_PTR(tmp
);
1333 struct range_list
*rl_intersection(struct range_list
*one
, struct range_list
*two
)
1335 struct range_list
*one_orig
;
1336 struct range_list
*two_orig
;
1337 struct range_list
*ret
;
1338 struct symbol
*ret_type
;
1339 struct symbol
*small_type
;
1340 struct symbol
*large_type
;
1350 ret_type
= rl_type(one
);
1351 small_type
= rl_type(one
);
1352 large_type
= rl_type(two
);
1354 if (type_bits(rl_type(two
)) < type_bits(small_type
)) {
1355 small_type
= rl_type(two
);
1356 large_type
= rl_type(one
);
1359 one
= cast_rl(large_type
, one
);
1360 two
= cast_rl(large_type
, two
);
1363 one
= rl_invert(one
);
1364 two
= rl_invert(two
);
1366 ret
= rl_filter(ret
, one
);
1367 ret
= rl_filter(ret
, two
);
1369 one
= cast_rl(small_type
, one_orig
);
1370 two
= cast_rl(small_type
, two_orig
);
1372 one
= rl_invert(one
);
1373 two
= rl_invert(two
);
1375 ret
= cast_rl(small_type
, ret
);
1376 ret
= rl_filter(ret
, one
);
1377 ret
= rl_filter(ret
, two
);
1379 return cast_rl(ret_type
, ret
);
1382 static struct range_list
*handle_mod_rl(struct range_list
*left
, struct range_list
*right
)
1387 max
= rl_max(right
);
1388 if (sval_is_max(max
))
1393 if (sval_is_negative(max
))
1395 if (sval_cmp(rl_max(left
), max
) < 0)
1399 return alloc_rl(zero
, max
);
1402 static struct range_list
*get_neg_rl(struct range_list
*rl
)
1404 struct data_range
*tmp
;
1405 struct data_range
*new;
1406 struct range_list
*ret
= NULL
;
1410 if (sval_is_positive(rl_min(rl
)))
1413 FOR_EACH_PTR(rl
, tmp
) {
1414 if (sval_is_positive(tmp
->min
))
1416 if (sval_is_positive(tmp
->max
)) {
1417 new = alloc_range(tmp
->min
, tmp
->max
);
1418 new->max
.value
= -1;
1419 add_range(&ret
, new->min
, new->max
);
1422 add_range(&ret
, tmp
->min
, tmp
->max
);
1423 } END_FOR_EACH_PTR(tmp
);
1428 static struct range_list
*get_pos_rl(struct range_list
*rl
)
1430 struct data_range
*tmp
;
1431 struct data_range
*new;
1432 struct range_list
*ret
= NULL
;
1436 if (sval_is_negative(rl_max(rl
)))
1439 FOR_EACH_PTR(rl
, tmp
) {
1440 if (sval_is_negative(tmp
->max
))
1442 if (sval_is_positive(tmp
->min
)) {
1443 add_range(&ret
, tmp
->min
, tmp
->max
);
1446 new = alloc_range(tmp
->min
, tmp
->max
);
1448 add_range(&ret
, new->min
, new->max
);
1449 } END_FOR_EACH_PTR(tmp
);
1454 static struct range_list
*divide_rl_helper(struct range_list
*left
, struct range_list
*right
)
1456 sval_t right_min
, right_max
;
1459 if (!left
|| !right
)
1462 /* let's assume we never divide by zero */
1463 right_min
= rl_min(right
);
1464 right_max
= rl_max(right
);
1465 if (right_min
.value
== 0 && right_max
.value
== 0)
1467 if (right_min
.value
== 0)
1468 right_min
.value
= 1;
1469 if (right_max
.value
== 0)
1470 right_max
.value
= -1;
1472 max
= sval_binop(rl_max(left
), '/', right_min
);
1473 min
= sval_binop(rl_min(left
), '/', right_max
);
1475 return alloc_rl(min
, max
);
1478 static struct range_list
*handle_divide_rl(struct range_list
*left
, struct range_list
*right
)
1480 struct range_list
*left_neg
, *left_pos
, *right_neg
, *right_pos
;
1481 struct range_list
*neg_neg
, *neg_pos
, *pos_neg
, *pos_pos
;
1482 struct range_list
*ret
;
1484 if (is_whole_rl(right
))
1487 left_neg
= get_neg_rl(left
);
1488 left_pos
= get_pos_rl(left
);
1489 right_neg
= get_neg_rl(right
);
1490 right_pos
= get_pos_rl(right
);
1492 neg_neg
= divide_rl_helper(left_neg
, right_neg
);
1493 neg_pos
= divide_rl_helper(left_neg
, right_pos
);
1494 pos_neg
= divide_rl_helper(left_pos
, right_neg
);
1495 pos_pos
= divide_rl_helper(left_pos
, right_pos
);
1497 ret
= rl_union(neg_neg
, neg_pos
);
1498 ret
= rl_union(ret
, pos_neg
);
1499 return rl_union(ret
, pos_pos
);
1502 static struct range_list
*handle_add_mult_rl(struct range_list
*left
, int op
, struct range_list
*right
)
1506 if (sval_binop_overflows(rl_min(left
), op
, rl_min(right
)))
1508 min
= sval_binop(rl_min(left
), op
, rl_min(right
));
1510 if (sval_binop_overflows(rl_max(left
), op
, rl_max(right
)))
1512 max
= sval_binop(rl_max(left
), op
, rl_max(right
));
1514 return alloc_rl(min
, max
);
1517 static struct range_list
*handle_sub_rl(struct range_list
*left_orig
, struct range_list
*right_orig
)
1519 struct range_list
*left_rl
, *right_rl
;
1520 struct symbol
*type
;
1522 sval_t min_ll
, max_ll
, res_ll
;
1525 /* TODO: These things should totally be using dranges where possible */
1527 if (!left_orig
|| !right_orig
)
1531 if (type_positive_bits(rl_type(left_orig
)) > type_positive_bits(type
))
1532 type
= rl_type(left_orig
);
1533 if (type_positive_bits(rl_type(right_orig
)) > type_positive_bits(type
))
1534 type
= rl_type(right_orig
);
1536 left_rl
= cast_rl(type
, left_orig
);
1537 right_rl
= cast_rl(type
, right_orig
);
1539 max
= rl_max(left_rl
);
1540 min
= sval_type_min(type
);
1542 min_ll
= rl_min(left_rl
);
1543 min_ll
.type
= &llong_ctype
;
1544 max_ll
= rl_max(right_rl
);
1545 max_ll
.type
= &llong_ctype
;
1547 res_ll
.value
= min_ll
.value
- max_ll
.value
;
1549 if (!sval_binop_overflows(rl_min(left_rl
), '-', rl_max(right_rl
))) {
1550 tmp
= sval_binop(rl_min(left_rl
), '-', rl_max(right_rl
));
1551 if (sval_cmp(tmp
, min
) > 0)
1553 } else if (type_positive_bits(type
) < 63 &&
1554 !sval_binop_overflows(min_ll
, '-', max_ll
) &&
1555 (min
.value
!= 0 && sval_cmp(res_ll
, min
) >= 0)) {
1556 struct range_list
*left_casted
, *right_casted
, *result
;
1558 left_casted
= cast_rl(&llong_ctype
, left_orig
);
1559 right_casted
= cast_rl(&llong_ctype
, right_orig
);
1560 result
= handle_sub_rl(left_casted
, right_casted
);
1561 return cast_rl(type
, result
);
1564 if (!sval_is_max(rl_max(left_rl
))) {
1565 tmp
= sval_binop(rl_max(left_rl
), '-', rl_min(right_rl
));
1566 if (sval_cmp(tmp
, max
) < 0)
1570 if (sval_is_min(min
) && sval_is_max(max
))
1573 return alloc_rl(min
, max
);
1576 static unsigned long long rl_bits_always_set(struct range_list
*rl
)
1578 return sval_fls_mask(rl_min(rl
));
1581 static unsigned long long rl_bits_maybe_set(struct range_list
*rl
)
1583 return sval_fls_mask(rl_max(rl
));
1586 static struct range_list
*handle_OR_rl(struct range_list
*left
, struct range_list
*right
)
1588 unsigned long long left_min
, left_max
, right_min
, right_max
;
1592 if ((rl_to_sval(left
, &sval
) || rl_to_sval(right
, &sval
)) &&
1593 !sval_binop_overflows(rl_max(left
), '+', rl_max(right
)))
1594 return rl_binop(left
, '+', right
);
1596 left_min
= rl_bits_always_set(left
);
1597 left_max
= rl_bits_maybe_set(left
);
1598 right_min
= rl_bits_always_set(right
);
1599 right_max
= rl_bits_maybe_set(right
);
1601 min
.type
= max
.type
= &ullong_ctype
;
1602 min
.uvalue
= left_min
| right_min
;
1603 max
.uvalue
= left_max
| right_max
;
1605 return cast_rl(rl_type(left
), alloc_rl(min
, max
));
1608 static struct range_list
*handle_XOR_rl(struct range_list
*left
, struct range_list
*right
)
1610 unsigned long long left_set
, left_maybe
;
1611 unsigned long long right_set
, right_maybe
;
1614 left_set
= rl_bits_always_set(left
);
1615 left_maybe
= rl_bits_maybe_set(left
);
1617 right_set
= rl_bits_always_set(right
);
1618 right_maybe
= rl_bits_maybe_set(right
);
1620 zero
= max
= rl_min(left
);
1622 max
.uvalue
= fls_mask((left_maybe
| right_maybe
) ^ (left_set
& right_set
));
1624 return cast_rl(rl_type(left
), alloc_rl(zero
, max
));
1627 static struct range_list
*handle_AND_rl(struct range_list
*left
, struct range_list
*right
)
1629 unsigned long long left_set
, left_maybe
;
1630 unsigned long long right_set
, right_maybe
;
1635 left_set
= rl_bits_always_set(left
);
1636 left_maybe
= rl_bits_maybe_set(left
);
1638 right_set
= rl_bits_always_set(right
);
1639 right_maybe
= rl_bits_maybe_set(right
);
1641 zero
= max
= rl_min(left
);
1643 max
.uvalue
= fls_mask((left_maybe
| right_maybe
) ^ (left_set
& right_set
));
1645 return cast_rl(rl_type(left
), alloc_rl(zero
, max
));
1648 struct range_list
*rl_binop(struct range_list
*left
, int op
, struct range_list
*right
)
1650 struct symbol
*cast_type
;
1651 sval_t left_sval
, right_sval
;
1652 struct range_list
*ret
= NULL
;
1654 cast_type
= rl_type(left
);
1655 if (sval_type_max(rl_type(left
)).uvalue
< sval_type_max(rl_type(right
)).uvalue
)
1656 cast_type
= rl_type(right
);
1657 if (sval_type_max(cast_type
).uvalue
< INT_MAX
)
1658 cast_type
= &int_ctype
;
1660 left
= cast_rl(cast_type
, left
);
1661 right
= cast_rl(cast_type
, right
);
1663 if (!left
&& !right
)
1666 if (rl_to_sval(left
, &left_sval
) && rl_to_sval(right
, &right_sval
)) {
1667 sval_t val
= sval_binop(left_sval
, op
, right_sval
);
1668 return alloc_rl(val
, val
);
1673 ret
= handle_mod_rl(left
, right
);
1676 ret
= handle_divide_rl(left
, right
);
1680 ret
= handle_add_mult_rl(left
, op
, right
);
1683 ret
= handle_OR_rl(left
, right
);
1686 ret
= handle_XOR_rl(left
, right
);
1689 ret
= handle_AND_rl(left
, right
);
1692 ret
= handle_sub_rl(left
, right
);
1694 /* FIXME: Do the rest as well */
1695 case SPECIAL_RIGHTSHIFT
:
1696 case SPECIAL_LEFTSHIFT
:
1703 void free_rl(struct range_list
**rlist
)
1705 __free_ptr_list((struct ptr_list
**)rlist
);
1708 static void free_single_dinfo(struct data_info
*dinfo
)
1710 free_rl(&dinfo
->value_ranges
);
1713 static void free_dinfos(struct allocation_blob
*blob
)
1715 unsigned int size
= sizeof(struct data_info
);
1716 unsigned int offset
= 0;
1718 while (offset
< blob
->offset
) {
1719 free_single_dinfo((struct data_info
*)(blob
->data
+ offset
));
1724 void free_data_info_allocs(void)
1726 struct allocator_struct
*desc
= &data_info_allocator
;
1727 struct allocation_blob
*blob
= desc
->blobs
;
1730 desc
->allocations
= 0;
1731 desc
->total_bytes
= 0;
1732 desc
->useful_bytes
= 0;
1733 desc
->freelist
= NULL
;
1735 struct allocation_blob
*next
= blob
->next
;
1737 blob_free(blob
, desc
->chunking
);
1740 clear_data_range_alloc();
1743 void split_comparison_rl(struct range_list
*left_orig
, int op
, struct range_list
*right_orig
,
1744 struct range_list
**left_true_rl
, struct range_list
**left_false_rl
,
1745 struct range_list
**right_true_rl
, struct range_list
**right_false_rl
)
1747 struct range_list
*left_true
, *left_false
;
1748 struct range_list
*right_true
, *right_false
;
1751 min
= sval_type_min(rl_type(left_orig
));
1752 max
= sval_type_max(rl_type(left_orig
));
1754 left_true
= clone_rl(left_orig
);
1755 left_false
= clone_rl(left_orig
);
1756 right_true
= clone_rl(right_orig
);
1757 right_false
= clone_rl(right_orig
);
1761 case SPECIAL_UNSIGNED_LT
:
1762 left_true
= remove_range(left_orig
, rl_max(right_orig
), max
);
1763 if (!sval_is_min(rl_min(right_orig
))) {
1764 left_false
= remove_range(left_orig
, min
, sub_one(rl_min(right_orig
)));
1767 right_true
= remove_range(right_orig
, min
, rl_min(left_orig
));
1768 if (!sval_is_max(rl_max(left_orig
)))
1769 right_false
= remove_range(right_orig
, add_one(rl_max(left_orig
)), max
);
1771 case SPECIAL_UNSIGNED_LTE
:
1773 if (!sval_is_max(rl_max(right_orig
)))
1774 left_true
= remove_range(left_orig
, add_one(rl_max(right_orig
)), max
);
1775 left_false
= remove_range(left_orig
, min
, rl_min(right_orig
));
1777 if (!sval_is_min(rl_min(left_orig
)))
1778 right_true
= remove_range(right_orig
, min
, sub_one(rl_min(left_orig
)));
1779 right_false
= remove_range(right_orig
, rl_max(left_orig
), max
);
1781 if (sval_cmp(rl_min(left_orig
), rl_min(right_orig
)) == 0)
1782 left_false
= remove_range(left_false
, rl_min(left_orig
), rl_min(left_orig
));
1783 if (sval_cmp(rl_max(left_orig
), rl_max(right_orig
)) == 0)
1784 right_false
= remove_range(right_false
, rl_max(left_orig
), rl_max(left_orig
));
1787 if (!sval_is_max(rl_max(right_orig
))) {
1788 left_true
= remove_range(left_true
, add_one(rl_max(right_orig
)), max
);
1790 if (!sval_is_min(rl_min(right_orig
))) {
1791 left_true
= remove_range(left_true
, min
, sub_one(rl_min(right_orig
)));
1793 if (sval_cmp(rl_min(right_orig
), rl_max(right_orig
)) == 0)
1794 left_false
= remove_range(left_orig
, rl_min(right_orig
), rl_min(right_orig
));
1796 if (!sval_is_max(rl_max(left_orig
)))
1797 right_true
= remove_range(right_true
, add_one(rl_max(left_orig
)), max
);
1798 if (!sval_is_min(rl_min(left_orig
)))
1799 right_true
= remove_range(right_true
, min
, sub_one(rl_min(left_orig
)));
1800 if (sval_cmp(rl_min(left_orig
), rl_max(left_orig
)) == 0)
1801 right_false
= remove_range(right_orig
, rl_min(left_orig
), rl_min(left_orig
));
1803 case SPECIAL_UNSIGNED_GTE
:
1805 if (!sval_is_min(rl_min(right_orig
)))
1806 left_true
= remove_range(left_orig
, min
, sub_one(rl_min(right_orig
)));
1807 left_false
= remove_range(left_orig
, rl_max(right_orig
), max
);
1809 if (!sval_is_max(rl_max(left_orig
)))
1810 right_true
= remove_range(right_orig
, add_one(rl_max(left_orig
)), max
);
1811 right_false
= remove_range(right_orig
, min
, rl_min(left_orig
));
1813 if (sval_cmp(rl_min(left_orig
), rl_min(right_orig
)) == 0)
1814 right_false
= remove_range(right_false
, rl_min(left_orig
), rl_min(left_orig
));
1815 if (sval_cmp(rl_max(left_orig
), rl_max(right_orig
)) == 0)
1816 left_false
= remove_range(left_false
, rl_max(left_orig
), rl_max(left_orig
));
1819 case SPECIAL_UNSIGNED_GT
:
1820 left_true
= remove_range(left_orig
, min
, rl_min(right_orig
));
1821 if (!sval_is_max(rl_max(right_orig
)))
1822 left_false
= remove_range(left_orig
, add_one(rl_max(right_orig
)), max
);
1824 right_true
= remove_range(right_orig
, rl_max(left_orig
), max
);
1825 if (!sval_is_min(rl_min(left_orig
)))
1826 right_false
= remove_range(right_orig
, min
, sub_one(rl_min(left_orig
)));
1828 case SPECIAL_NOTEQUAL
:
1829 if (!sval_is_max(rl_max(right_orig
)))
1830 left_false
= remove_range(left_false
, add_one(rl_max(right_orig
)), max
);
1831 if (!sval_is_min(rl_min(right_orig
)))
1832 left_false
= remove_range(left_false
, min
, sub_one(rl_min(right_orig
)));
1833 if (sval_cmp(rl_min(right_orig
), rl_max(right_orig
)) == 0)
1834 left_true
= remove_range(left_orig
, rl_min(right_orig
), rl_min(right_orig
));
1836 if (!sval_is_max(rl_max(left_orig
)))
1837 right_false
= remove_range(right_false
, add_one(rl_max(left_orig
)), max
);
1838 if (!sval_is_min(rl_min(left_orig
)))
1839 right_false
= remove_range(right_false
, min
, sub_one(rl_min(left_orig
)));
1840 if (sval_cmp(rl_min(left_orig
), rl_max(left_orig
)) == 0)
1841 right_true
= remove_range(right_orig
, rl_min(left_orig
), rl_min(left_orig
));
1844 sm_msg("internal error: unhandled comparison %d", op
);
1849 *left_true_rl
= left_true
;
1850 *left_false_rl
= left_false
;
1852 if (right_true_rl
) {
1853 *right_true_rl
= right_true
;
1854 *right_false_rl
= right_false
;