implied: delete unused function sm_state_in_slist()
[smatch.git] / smatch_ranges.c
bloba2b4bdfb6d339b601fb04c5f24970858db431b18
1 /*
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
18 #include "parse.h"
19 #include "smatch.h"
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;
31 char full[256];
32 int i = 0;
34 full[0] = '\0';
35 full[255] = '\0';
36 FOR_EACH_PTR(list, tmp) {
37 if (i++)
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));
41 continue;
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 return alloc_sname(full);
50 static int sval_too_big(struct symbol *type, sval_t sval)
52 if (type_bits(type) == 64)
53 return 0;
54 if (sval.uvalue > ((1ULL << type_bits(type)) - 1))
55 return 1;
56 return 0;
59 static void add_range_t(struct symbol *type, struct range_list **rl, sval_t min, sval_t max)
61 /* If we're just adding a number, cast it and add it */
62 if (sval_cmp(min, max) == 0) {
63 add_range(rl, sval_cast(type, min), sval_cast(type, max));
64 return;
67 /* If the range is within the type range then add it */
68 if (sval_fits(type, min) && sval_fits(type, max)) {
69 add_range(rl, sval_cast(type, min), sval_cast(type, max));
70 return;
74 * If the range we are adding has more bits than the range type then
75 * add the whole range type. Eg:
76 * 0x8000000000000000 - 0xf000000000000000 -> cast to int
77 * This isn't totally the right thing to do. We could be more granular.
79 if (sval_too_big(type, min) || sval_too_big(type, max)) {
80 add_range(rl, sval_type_min(type), sval_type_max(type));
81 return;
84 /* Cast negative values to high positive values */
85 if (sval_is_negative(min) && type_unsigned(type)) {
86 if (sval_is_positive(max)) {
87 if (sval_too_high(type, max)) {
88 add_range(rl, sval_type_min(type), sval_type_max(type));
89 return;
91 add_range(rl, sval_type_val(type, 0), sval_cast(type, max));
92 max = sval_type_max(type);
93 } else {
94 max = sval_cast(type, max);
96 min = sval_cast(type, min);
97 add_range(rl, min, max);
100 /* Cast high positive numbers to negative */
101 if (sval_unsigned(max) && sval_is_negative(sval_cast(type, max))) {
102 if (!sval_is_negative(sval_cast(type, min))) {
103 add_range(rl, sval_cast(type, min), sval_type_max(type));
104 min = sval_type_min(type);
105 } else {
106 min = sval_cast(type, min);
108 max = sval_cast(type, max);
109 add_range(rl, min, max);
112 add_range(rl, sval_cast(type, min), sval_cast(type, max));
113 return;
116 static int str_to_comparison_arg_helper(const char *str,
117 struct expression *call, int *comparison,
118 struct expression **arg, char **endp)
120 int param;
121 char *c = (char *)str;
123 if (*c != '[')
124 return 0;
125 c++;
127 if (*c == '<') {
128 c++;
129 if (*c == '=') {
130 *comparison = SPECIAL_LTE;
131 c++;
132 } else {
133 *comparison = '<';
135 } else if (*c == '=') {
136 c++;
137 c++;
138 *comparison = SPECIAL_EQUAL;
139 } else if (*c == '>') {
140 c++;
141 if (*c == '=') {
142 *comparison = SPECIAL_GTE;
143 c++;
144 } else {
145 *comparison = '>';
147 } else if (*c == '!') {
148 c++;
149 c++;
150 *comparison = SPECIAL_NOTEQUAL;
151 } else {
152 return 0;
155 if (*c != '$')
156 return 0;
157 c++;
159 param = strtoll(c, &c, 10);
160 c++; /* skip the ']' character */
161 if (endp)
162 *endp = (char *)c;
164 if (!call)
165 return 0;
166 *arg = get_argument_from_call_expr(call->args, param);
167 if (!*arg)
168 return 0;
169 return 1;
172 int str_to_comparison_arg(const char *str, struct expression *call, int *comparison, struct expression **arg)
174 while (1) {
175 if (!*str)
176 return 0;
177 if (*str == '[')
178 break;
179 str++;
181 return str_to_comparison_arg_helper(str, call, comparison, arg, NULL);
184 static int get_val_from_key(int use_max, struct symbol *type, char *c, struct expression *call, char **endp, sval_t *sval)
186 struct expression *arg;
187 int comparison;
188 sval_t ret, tmp;
190 if (use_max)
191 ret = sval_type_max(type);
192 else
193 ret = sval_type_min(type);
195 if (!str_to_comparison_arg_helper(c, call, &comparison, &arg, endp)) {
196 *sval = ret;
197 return 0;
200 if (use_max && get_implied_max(arg, &tmp)) {
201 ret = tmp;
202 if (comparison == '<') {
203 tmp.value = 1;
204 ret = sval_binop(ret, '-', tmp);
207 if (!use_max && get_implied_min(arg, &tmp)) {
208 ret = tmp;
209 if (comparison == '>') {
210 tmp.value = 1;
211 ret = sval_binop(ret, '+', tmp);
215 *sval = ret;
216 return 1;
219 static sval_t add_one(sval_t sval)
221 sval.value++;
222 return sval;
225 static sval_t sub_one(sval_t sval)
227 sval.value--;
228 return sval;
231 void filter_by_comparison(struct range_list **rl, int comparison, struct range_list *right)
233 struct range_list *left_orig = *rl;
234 struct range_list *right_orig = right;
235 struct range_list *ret_rl = *rl;
236 struct symbol *cast_type;
237 sval_t min, max;
239 cast_type = rl_type(left_orig);
240 if (sval_type_max(rl_type(left_orig)).uvalue < sval_type_max(rl_type(right_orig)).uvalue)
241 cast_type = rl_type(right_orig);
242 if (sval_type_max(cast_type).uvalue < INT_MAX)
243 cast_type = &int_ctype;
245 min = sval_type_min(cast_type);
246 max = sval_type_max(cast_type);
247 left_orig = cast_rl(cast_type, left_orig);
248 right_orig = cast_rl(cast_type, right_orig);
250 switch (comparison) {
251 case '<':
252 case SPECIAL_UNSIGNED_LT:
253 ret_rl = remove_range(left_orig, rl_max(right_orig), max);
254 break;
255 case SPECIAL_LTE:
256 case SPECIAL_UNSIGNED_LTE:
257 if (!sval_is_max(rl_max(right_orig)))
258 ret_rl = remove_range(left_orig, add_one(rl_max(right_orig)), max);
259 break;
260 case SPECIAL_EQUAL:
261 if (!sval_is_max(rl_max(right_orig)))
262 ret_rl = remove_range(ret_rl, add_one(rl_max(right_orig)), max);
263 if (!sval_is_min(rl_min(right_orig)))
264 ret_rl = remove_range(ret_rl, min, sub_one(rl_min(right_orig)));
265 break;
266 case SPECIAL_GTE:
267 case SPECIAL_UNSIGNED_GTE:
268 if (!sval_is_min(rl_min(right_orig)))
269 ret_rl = remove_range(left_orig, min, sub_one(rl_min(right_orig)));
270 break;
271 case '>':
272 case SPECIAL_UNSIGNED_GT:
273 ret_rl = remove_range(left_orig, min, rl_min(right_orig));
274 break;
275 case SPECIAL_NOTEQUAL:
276 if (sval_cmp(rl_min(right_orig), rl_max(right_orig)) == 0)
277 ret_rl = remove_range(left_orig, rl_min(right_orig), rl_min(right_orig));
278 break;
279 default:
280 sm_msg("internal error: unhandled comparison %s", show_special(comparison));
281 return;
284 *rl = cast_rl(rl_type(*rl), ret_rl);
287 static struct range_list *filter_by_comparison_call(char *c, struct expression *call, char **endp, struct range_list *start_rl)
289 struct expression *arg;
290 struct range_list *right_orig;
291 int comparison;
293 if (!str_to_comparison_arg_helper(c, call, &comparison, &arg, endp))
294 return NULL;
296 if (!get_implied_rl(arg, &right_orig))
297 return NULL;
299 if (rl_type(start_rl) == &int_ctype &&
300 sval_is_negative(rl_min(start_rl)) &&
301 type_unsigned(rl_type(right_orig)))
302 right_orig = cast_rl(&int_ctype, right_orig);
304 filter_by_comparison(&start_rl, comparison, right_orig);
305 return start_rl;
308 static sval_t parse_val(int use_max, struct expression *call, struct symbol *type, char *c, char **endp)
310 char *start = c;
311 sval_t ret;
313 if (!strncmp(start, "max", 3)) {
314 ret = sval_type_max(type);
315 c += 3;
316 } else if (!strncmp(start, "u64max", 6)) {
317 ret = sval_type_val(type, ULLONG_MAX);
318 c += 6;
319 } else if (!strncmp(start, "s64max", 6)) {
320 ret = sval_type_val(type, LLONG_MAX);
321 c += 6;
322 } else if (!strncmp(start, "u32max", 6)) {
323 ret = sval_type_val(type, UINT_MAX);
324 c += 6;
325 } else if (!strncmp(start, "s32max", 6)) {
326 ret = sval_type_val(type, INT_MAX);
327 c += 6;
328 } else if (!strncmp(start, "u16max", 6)) {
329 ret = sval_type_val(type, USHRT_MAX);
330 c += 6;
331 } else if (!strncmp(start, "s16max", 6)) {
332 ret = sval_type_val(type, SHRT_MAX);
333 c += 6;
334 } else if (!strncmp(start, "min", 3)) {
335 ret = sval_type_min(type);
336 c += 3;
337 } else if (!strncmp(start, "s64min", 6)) {
338 ret = sval_type_val(type, LLONG_MIN);
339 c += 6;
340 } else if (!strncmp(start, "s32min", 6)) {
341 ret = sval_type_val(type, INT_MIN);
342 c += 6;
343 } else if (!strncmp(start, "s16min", 6)) {
344 ret = sval_type_val(type, SHRT_MIN);
345 c += 6;
346 } else if (!strncmp(start, "long_min", 8)) {
347 ret = sval_type_val(type, LONG_MIN);
348 c += 8;
349 } else if (!strncmp(start, "long_max", 8)) {
350 ret = sval_type_val(type, LONG_MAX);
351 c += 8;
352 } else if (!strncmp(start, "ulong_max", 9)) {
353 ret = sval_type_val(type, ULONG_MAX);
354 c += 8;
355 } else if (!strncmp(start, "ptr_max", 7)) {
356 ret = sval_type_val(type, valid_ptr_max);
357 c += 8;
358 } else if (start[0] == '[') {
359 /* this parses [==p0] comparisons */
360 get_val_from_key(1, type, start, call, &c, &ret);
361 } else {
362 ret = sval_type_val(type, strtoll(start, &c, 10));
364 *endp = c;
365 return ret;
368 static char *jump_to_call_math(char *value)
370 char *c = value;
372 while (*c && *c != '[')
373 c++;
375 if (!*c)
376 return NULL;
377 c++;
378 if (*c == '<' || *c == '=' || *c == '>' || *c == '!')
379 return NULL;
381 return c;
384 static void str_to_rl_helper(struct expression *call, struct symbol *type, char *str, char **endp, struct range_list **rl)
386 struct range_list *rl_tmp = NULL;
387 sval_t min, max;
388 char *c;
390 min = sval_type_min(type);
391 max = sval_type_max(type);
392 c = str;
393 while (*c != '\0' && *c != '[') {
394 if (*c == '(')
395 c++;
396 min = parse_val(0, call, type, c, &c);
397 max = min;
398 if (*c == ')')
399 c++;
400 if (*c == '\0' || *c == '[') {
401 add_range_t(type, &rl_tmp, min, min);
402 break;
404 if (*c == ',') {
405 add_range_t(type, &rl_tmp, min, min);
406 c++;
407 continue;
409 if (*c != '-') {
410 sm_msg("debug XXX: trouble parsing %s c = %s", str, c);
411 break;
413 c++;
414 if (*c == '(')
415 c++;
416 max = parse_val(1, call, type, c, &c);
417 add_range_t(type, &rl_tmp, min, max);
418 if (*c == ')')
419 c++;
420 if (*c == ',')
421 c++;
424 *rl = rl_tmp;
425 *endp = c;
428 static void str_to_dinfo(struct expression *call, struct symbol *type, char *value, struct data_info *dinfo)
430 struct range_list *math_rl;
431 char *call_math;
432 char *c;
433 struct range_list *rl = NULL;
435 if (!type)
436 type = &llong_ctype;
438 if (strcmp(value, "empty") == 0)
439 return;
441 if (strncmp(value, "[==$", 4) == 0) {
442 struct expression *arg;
443 int comparison;
445 if (!str_to_comparison_arg(value, call, &comparison, &arg))
446 return;
447 if (!get_implied_rl(arg, &rl))
448 return;
449 goto cast;
452 str_to_rl_helper(call, type, value, &c, &rl);
453 if (*c == '\0')
454 goto cast;
456 call_math = jump_to_call_math(value);
457 if (call_math && parse_call_math_rl(call, call_math, &math_rl)) {
458 rl = rl_intersection(rl, math_rl);
459 goto cast;
463 * For now if we already tried to handle the call math and couldn't
464 * figure it out then bail.
466 if (jump_to_call_math(c) == c + 1)
467 goto cast;
469 rl = filter_by_comparison_call(c, call, &c, rl);
471 cast:
472 rl = cast_rl(type, rl);
473 dinfo->value_ranges = rl;
476 void str_to_rl(struct symbol *type, char *value, struct range_list **rl)
478 struct data_info dinfo = {};
480 str_to_dinfo(NULL, type, value, &dinfo);
481 *rl = dinfo.value_ranges;
484 void call_results_to_rl(struct expression *expr, struct symbol *type, char *value, struct range_list **rl)
486 struct data_info dinfo = {};
488 str_to_dinfo(strip_expr(expr), type, value, &dinfo);
489 *rl = dinfo.value_ranges;
492 int is_whole_rl(struct range_list *rl)
494 struct data_range *drange;
496 if (ptr_list_empty(rl))
497 return 0;
498 drange = first_ptr_list((struct ptr_list *)rl);
499 if (sval_is_min(drange->min) && sval_is_max(drange->max))
500 return 1;
501 return 0;
504 int is_whole_rl_non_zero(struct range_list *rl)
506 struct data_range *drange;
508 if (ptr_list_empty(rl))
509 return 0;
510 drange = first_ptr_list((struct ptr_list *)rl);
511 if (sval_unsigned(drange->min) &&
512 drange->min.value == 1 &&
513 sval_is_max(drange->max))
514 return 1;
515 if (!sval_is_min(drange->min) || drange->max.value != -1)
516 return 0;
517 drange = last_ptr_list((struct ptr_list *)rl);
518 if (drange->min.value != 1 || !sval_is_max(drange->max))
519 return 0;
520 return 1;
523 sval_t rl_min(struct range_list *rl)
525 struct data_range *drange;
526 sval_t ret;
528 ret.type = &llong_ctype;
529 ret.value = LLONG_MIN;
530 if (ptr_list_empty(rl))
531 return ret;
532 drange = first_ptr_list((struct ptr_list *)rl);
533 return drange->min;
536 sval_t rl_max(struct range_list *rl)
538 struct data_range *drange;
539 sval_t ret;
541 ret.type = &llong_ctype;
542 ret.value = LLONG_MAX;
543 if (ptr_list_empty(rl))
544 return ret;
545 drange = last_ptr_list((struct ptr_list *)rl);
546 return drange->max;
549 int rl_to_sval(struct range_list *rl, sval_t *sval)
551 sval_t min, max;
553 if (!rl)
554 return 0;
556 min = rl_min(rl);
557 max = rl_max(rl);
558 if (sval_cmp(min, max) != 0)
559 return 0;
560 *sval = min;
561 return 1;
564 struct symbol *rl_type(struct range_list *rl)
566 if (!rl)
567 return NULL;
568 return rl_min(rl).type;
571 static struct data_range *alloc_range_helper_sval(sval_t min, sval_t max, int perm)
573 struct data_range *ret;
575 if (perm)
576 ret = __alloc_perm_data_range(0);
577 else
578 ret = __alloc_data_range(0);
579 ret->min = min;
580 ret->max = max;
581 return ret;
584 struct data_range *alloc_range(sval_t min, sval_t max)
586 return alloc_range_helper_sval(min, max, 0);
589 struct data_range *alloc_range_perm(sval_t min, sval_t max)
591 return alloc_range_helper_sval(min, max, 1);
594 struct range_list *alloc_rl(sval_t min, sval_t max)
596 struct range_list *rl = NULL;
598 if (sval_cmp(min, max) > 0)
599 return alloc_whole_rl(min.type);
601 add_range(&rl, min, max);
602 return rl;
605 struct range_list *alloc_whole_rl(struct symbol *type)
607 if (!type || type_positive_bits(type) < 0)
608 type = &llong_ctype;
609 if (type->type == SYM_ARRAY)
610 type = &ptr_ctype;
612 return alloc_rl(sval_type_min(type), sval_type_max(type));
615 void add_range(struct range_list **list, sval_t min, sval_t max)
617 struct data_range *tmp;
618 struct data_range *new = NULL;
619 int check_next = 0;
621 if (sval_cmp(min, max) > 0) {
622 min = sval_type_min(min.type);
623 max = sval_type_max(min.type);
627 * FIXME: This has a problem merging a range_list like: min-0,3-max
628 * with a range like 1-2. You end up with min-2,3-max instead of
629 * just min-max.
631 FOR_EACH_PTR(*list, tmp) {
632 if (check_next) {
633 /* Sometimes we overlap with more than one range
634 so we have to delete or modify the next range. */
635 if (!sval_is_max(max) && max.value + 1 == tmp->min.value) {
636 /* join 2 ranges here */
637 new->max = tmp->max;
638 DELETE_CURRENT_PTR(tmp);
639 return;
642 /* Doesn't overlap with the next one. */
643 if (sval_cmp(max, tmp->min) < 0)
644 return;
646 if (sval_cmp(max, tmp->max) <= 0) {
647 /* Partially overlaps the next one. */
648 new->max = tmp->max;
649 DELETE_CURRENT_PTR(tmp);
650 return;
651 } else {
652 /* Completely overlaps the next one. */
653 DELETE_CURRENT_PTR(tmp);
654 /* there could be more ranges to delete */
655 continue;
658 if (!sval_is_max(max) && max.value + 1 == tmp->min.value) {
659 /* join 2 ranges into a big range */
660 new = alloc_range(min, tmp->max);
661 REPLACE_CURRENT_PTR(tmp, new);
662 return;
664 if (sval_cmp(max, tmp->min) < 0) { /* new range entirely below */
665 new = alloc_range(min, max);
666 INSERT_CURRENT(new, tmp);
667 return;
669 if (sval_cmp(min, tmp->min) < 0) { /* new range partially below */
670 if (sval_cmp(max, tmp->max) < 0)
671 max = tmp->max;
672 else
673 check_next = 1;
674 new = alloc_range(min, max);
675 REPLACE_CURRENT_PTR(tmp, new);
676 if (!check_next)
677 return;
678 continue;
680 if (sval_cmp(max, tmp->max) <= 0) /* new range already included */
681 return;
682 if (sval_cmp(min, tmp->max) <= 0) { /* new range partially above */
683 min = tmp->min;
684 new = alloc_range(min, max);
685 REPLACE_CURRENT_PTR(tmp, new);
686 check_next = 1;
687 continue;
689 if (!sval_is_min(min) && min.value - 1 == tmp->max.value) {
690 /* join 2 ranges into a big range */
691 new = alloc_range(tmp->min, max);
692 REPLACE_CURRENT_PTR(tmp, new);
693 check_next = 1;
694 continue;
696 /* the new range is entirely above the existing ranges */
697 } END_FOR_EACH_PTR(tmp);
698 if (check_next)
699 return;
700 new = alloc_range(min, max);
701 add_ptr_list(list, new);
704 struct range_list *clone_rl(struct range_list *list)
706 struct data_range *tmp;
707 struct range_list *ret = NULL;
709 FOR_EACH_PTR(list, tmp) {
710 add_ptr_list(&ret, tmp);
711 } END_FOR_EACH_PTR(tmp);
712 return ret;
715 struct range_list *clone_rl_permanent(struct range_list *list)
717 struct data_range *tmp;
718 struct data_range *new;
719 struct range_list *ret = NULL;
721 FOR_EACH_PTR(list, tmp) {
722 new = alloc_range_perm(tmp->min, tmp->max);
723 add_ptr_list(&ret, new);
724 } END_FOR_EACH_PTR(tmp);
725 return ret;
728 struct range_list *rl_union(struct range_list *one, struct range_list *two)
730 struct data_range *tmp;
731 struct range_list *ret = NULL;
733 FOR_EACH_PTR(one, tmp) {
734 add_range(&ret, tmp->min, tmp->max);
735 } END_FOR_EACH_PTR(tmp);
736 FOR_EACH_PTR(two, tmp) {
737 add_range(&ret, tmp->min, tmp->max);
738 } END_FOR_EACH_PTR(tmp);
739 return ret;
742 struct range_list *remove_range(struct range_list *list, sval_t min, sval_t max)
744 struct data_range *tmp;
745 struct range_list *ret = NULL;
747 if (!list)
748 return NULL;
750 min = sval_cast(rl_type(list), min);
751 max = sval_cast(rl_type(list), max);
752 if (sval_cmp(min, max) > 0) {
753 sval_t tmp = min;
754 min = max;
755 max = tmp;
758 FOR_EACH_PTR(list, tmp) {
759 if (sval_cmp(tmp->max, min) < 0) {
760 add_range(&ret, tmp->min, tmp->max);
761 continue;
763 if (sval_cmp(tmp->min, max) > 0) {
764 add_range(&ret, tmp->min, tmp->max);
765 continue;
767 if (sval_cmp(tmp->min, min) >= 0 && sval_cmp(tmp->max, max) <= 0)
768 continue;
769 if (sval_cmp(tmp->min, min) >= 0) {
770 max.value++;
771 add_range(&ret, max, tmp->max);
772 } else if (sval_cmp(tmp->max, max) <= 0) {
773 min.value--;
774 add_range(&ret, tmp->min, min);
775 } else {
776 min.value--;
777 max.value++;
778 add_range(&ret, tmp->min, min);
779 add_range(&ret, max, tmp->max);
781 } END_FOR_EACH_PTR(tmp);
782 return ret;
785 int ranges_equiv(struct data_range *one, struct data_range *two)
787 if (!one && !two)
788 return 1;
789 if (!one || !two)
790 return 0;
791 if (sval_cmp(one->min, two->min) != 0)
792 return 0;
793 if (sval_cmp(one->max, two->max) != 0)
794 return 0;
795 return 1;
798 int rl_equiv(struct range_list *one, struct range_list *two)
800 struct data_range *one_range;
801 struct data_range *two_range;
803 if (one == two)
804 return 1;
806 PREPARE_PTR_LIST(one, one_range);
807 PREPARE_PTR_LIST(two, two_range);
808 for (;;) {
809 if (!one_range && !two_range)
810 return 1;
811 if (!ranges_equiv(one_range, two_range))
812 return 0;
813 NEXT_PTR_LIST(one_range);
814 NEXT_PTR_LIST(two_range);
816 FINISH_PTR_LIST(two_range);
817 FINISH_PTR_LIST(one_range);
819 return 1;
822 int true_comparison_range(struct data_range *left, int comparison, struct data_range *right)
824 switch (comparison) {
825 case '<':
826 case SPECIAL_UNSIGNED_LT:
827 if (sval_cmp(left->min, right->max) < 0)
828 return 1;
829 return 0;
830 case SPECIAL_UNSIGNED_LTE:
831 case SPECIAL_LTE:
832 if (sval_cmp(left->min, right->max) <= 0)
833 return 1;
834 return 0;
835 case SPECIAL_EQUAL:
836 if (sval_cmp(left->max, right->min) < 0)
837 return 0;
838 if (sval_cmp(left->min, right->max) > 0)
839 return 0;
840 return 1;
841 case SPECIAL_UNSIGNED_GTE:
842 case SPECIAL_GTE:
843 if (sval_cmp(left->max, right->min) >= 0)
844 return 1;
845 return 0;
846 case '>':
847 case SPECIAL_UNSIGNED_GT:
848 if (sval_cmp(left->max, right->min) > 0)
849 return 1;
850 return 0;
851 case SPECIAL_NOTEQUAL:
852 if (sval_cmp(left->min, left->max) != 0)
853 return 1;
854 if (sval_cmp(right->min, right->max) != 0)
855 return 1;
856 if (sval_cmp(left->min, right->min) != 0)
857 return 1;
858 return 0;
859 default:
860 sm_msg("unhandled comparison %d\n", comparison);
861 return 0;
863 return 0;
866 int true_comparison_range_LR(int comparison, struct data_range *var, struct data_range *val, int left)
868 if (left)
869 return true_comparison_range(var, comparison, val);
870 else
871 return true_comparison_range(val, comparison, var);
874 static int false_comparison_range_sval(struct data_range *left, int comparison, struct data_range *right)
876 switch (comparison) {
877 case '<':
878 case SPECIAL_UNSIGNED_LT:
879 if (sval_cmp(left->max, right->min) >= 0)
880 return 1;
881 return 0;
882 case SPECIAL_UNSIGNED_LTE:
883 case SPECIAL_LTE:
884 if (sval_cmp(left->max, right->min) > 0)
885 return 1;
886 return 0;
887 case SPECIAL_EQUAL:
888 if (sval_cmp(left->min, left->max) != 0)
889 return 1;
890 if (sval_cmp(right->min, right->max) != 0)
891 return 1;
892 if (sval_cmp(left->min, right->min) != 0)
893 return 1;
894 return 0;
895 case SPECIAL_UNSIGNED_GTE:
896 case SPECIAL_GTE:
897 if (sval_cmp(left->min, right->max) < 0)
898 return 1;
899 return 0;
900 case '>':
901 case SPECIAL_UNSIGNED_GT:
902 if (sval_cmp(left->min, right->max) <= 0)
903 return 1;
904 return 0;
905 case SPECIAL_NOTEQUAL:
906 if (sval_cmp(left->max, right->min) < 0)
907 return 0;
908 if (sval_cmp(left->min, right->max) > 0)
909 return 0;
910 return 1;
911 default:
912 sm_msg("unhandled comparison %d\n", comparison);
913 return 0;
915 return 0;
918 int false_comparison_range_LR(int comparison, struct data_range *var, struct data_range *val, int left)
920 if (left)
921 return false_comparison_range_sval(var, comparison, val);
922 else
923 return false_comparison_range_sval(val, comparison, var);
926 int possibly_true(struct expression *left, int comparison, struct expression *right)
928 struct range_list *rl_left, *rl_right;
929 struct data_range *tmp_left, *tmp_right;
930 struct symbol *type;
932 if (!get_implied_rl(left, &rl_left))
933 return 1;
934 if (!get_implied_rl(right, &rl_right))
935 return 1;
937 type = rl_type(rl_left);
938 if (type_positive_bits(type) < type_positive_bits(rl_type(rl_right)))
939 type = rl_type(rl_right);
940 if (type_positive_bits(type) < 31)
941 type = &int_ctype;
943 rl_left = cast_rl(type, rl_left);
944 rl_right = cast_rl(type, rl_right);
946 FOR_EACH_PTR(rl_left, tmp_left) {
947 FOR_EACH_PTR(rl_right, tmp_right) {
948 if (true_comparison_range(tmp_left, comparison, tmp_right))
949 return 1;
950 } END_FOR_EACH_PTR(tmp_right);
951 } END_FOR_EACH_PTR(tmp_left);
952 return 0;
955 int possibly_false(struct expression *left, int comparison, struct expression *right)
957 struct range_list *rl_left, *rl_right;
958 struct data_range *tmp_left, *tmp_right;
959 struct symbol *type;
961 if (!get_implied_rl(left, &rl_left))
962 return 1;
963 if (!get_implied_rl(right, &rl_right))
964 return 1;
966 type = rl_type(rl_left);
967 if (type_positive_bits(type) < type_positive_bits(rl_type(rl_right)))
968 type = rl_type(rl_right);
969 if (type_positive_bits(type) < 31)
970 type = &int_ctype;
972 rl_left = cast_rl(type, rl_left);
973 rl_right = cast_rl(type, rl_right);
975 FOR_EACH_PTR(rl_left, tmp_left) {
976 FOR_EACH_PTR(rl_right, tmp_right) {
977 if (false_comparison_range_sval(tmp_left, comparison, tmp_right))
978 return 1;
979 } END_FOR_EACH_PTR(tmp_right);
980 } END_FOR_EACH_PTR(tmp_left);
981 return 0;
984 int possibly_true_rl(struct range_list *left_ranges, int comparison, struct range_list *right_ranges)
986 struct data_range *left_tmp, *right_tmp;
987 struct symbol *type;
989 if (!left_ranges || !right_ranges)
990 return 1;
992 type = rl_type(left_ranges);
993 if (type_positive_bits(type) < type_positive_bits(rl_type(right_ranges)))
994 type = rl_type(right_ranges);
995 if (type_positive_bits(type) < 31)
996 type = &int_ctype;
998 left_ranges = cast_rl(type, left_ranges);
999 right_ranges = cast_rl(type, right_ranges);
1001 FOR_EACH_PTR(left_ranges, left_tmp) {
1002 FOR_EACH_PTR(right_ranges, right_tmp) {
1003 if (true_comparison_range(left_tmp, comparison, right_tmp))
1004 return 1;
1005 } END_FOR_EACH_PTR(right_tmp);
1006 } END_FOR_EACH_PTR(left_tmp);
1007 return 0;
1010 int possibly_false_rl(struct range_list *left_ranges, int comparison, struct range_list *right_ranges)
1012 struct data_range *left_tmp, *right_tmp;
1013 struct symbol *type;
1015 if (!left_ranges || !right_ranges)
1016 return 1;
1018 type = rl_type(left_ranges);
1019 if (type_positive_bits(type) < type_positive_bits(rl_type(right_ranges)))
1020 type = rl_type(right_ranges);
1021 if (type_positive_bits(type) < 31)
1022 type = &int_ctype;
1024 left_ranges = cast_rl(type, left_ranges);
1025 right_ranges = cast_rl(type, right_ranges);
1027 FOR_EACH_PTR(left_ranges, left_tmp) {
1028 FOR_EACH_PTR(right_ranges, right_tmp) {
1029 if (false_comparison_range_sval(left_tmp, comparison, right_tmp))
1030 return 1;
1031 } END_FOR_EACH_PTR(right_tmp);
1032 } END_FOR_EACH_PTR(left_tmp);
1033 return 0;
1036 /* FIXME: the _rl here stands for right left so really it should be _lr */
1037 int possibly_true_rl_LR(int comparison, struct range_list *a, struct range_list *b, int left)
1039 if (left)
1040 return possibly_true_rl(a, comparison, b);
1041 else
1042 return possibly_true_rl(b, comparison, a);
1045 int possibly_false_rl_LR(int comparison, struct range_list *a, struct range_list *b, int left)
1047 if (left)
1048 return possibly_false_rl(a, comparison, b);
1049 else
1050 return possibly_false_rl(b, comparison, a);
1053 int rl_has_sval(struct range_list *rl, sval_t sval)
1055 struct data_range *tmp;
1057 FOR_EACH_PTR(rl, tmp) {
1058 if (sval_cmp(tmp->min, sval) <= 0 &&
1059 sval_cmp(tmp->max, sval) >= 0)
1060 return 1;
1061 } END_FOR_EACH_PTR(tmp);
1062 return 0;
1065 void tack_on(struct range_list **list, struct data_range *drange)
1067 add_ptr_list(list, drange);
1070 void push_rl(struct range_list_stack **rl_stack, struct range_list *rl)
1072 add_ptr_list(rl_stack, rl);
1075 struct range_list *pop_rl(struct range_list_stack **rl_stack)
1077 struct range_list *rl;
1079 rl = last_ptr_list((struct ptr_list *)*rl_stack);
1080 delete_ptr_list_last((struct ptr_list **)rl_stack);
1081 return rl;
1084 struct range_list *top_rl(struct range_list_stack *rl_stack)
1086 struct range_list *rl;
1088 rl = last_ptr_list((struct ptr_list *)rl_stack);
1089 return rl;
1092 void filter_top_rl(struct range_list_stack **rl_stack, struct range_list *filter)
1094 struct range_list *rl;
1096 rl = pop_rl(rl_stack);
1097 rl = rl_filter(rl, filter);
1098 push_rl(rl_stack, rl);
1101 struct range_list *rl_truncate_cast(struct symbol *type, struct range_list *rl)
1103 struct data_range *tmp;
1104 struct range_list *ret = NULL;
1105 sval_t min, max;
1107 if (!rl)
1108 return NULL;
1110 if (!type || type == rl_type(rl))
1111 return rl;
1113 FOR_EACH_PTR(rl, tmp) {
1114 min = tmp->min;
1115 max = tmp->max;
1116 if (type_bits(type) < type_bits(rl_type(rl))) {
1117 min.uvalue = tmp->min.uvalue & ((1ULL << type_bits(type)) - 1);
1118 max.uvalue = tmp->max.uvalue & ((1ULL << type_bits(type)) - 1);
1120 if (sval_cmp(min, max) > 0) {
1121 min = sval_cast(type, min);
1122 max = sval_cast(type, max);
1124 add_range_t(type, &ret, min, max);
1125 } END_FOR_EACH_PTR(tmp);
1127 return ret;
1130 static int rl_is_sane(struct range_list *rl)
1132 struct data_range *tmp;
1133 struct symbol *type;
1135 type = rl_type(rl);
1136 FOR_EACH_PTR(rl, tmp) {
1137 if (!sval_fits(type, tmp->min))
1138 return 0;
1139 if (!sval_fits(type, tmp->max))
1140 return 0;
1141 if (sval_cmp(tmp->min, tmp->max) > 0)
1142 return 0;
1143 } END_FOR_EACH_PTR(tmp);
1145 return 1;
1148 static int rl_type_consistent(struct range_list *rl)
1150 struct data_range *tmp;
1151 struct symbol *type;
1153 type = rl_type(rl);
1154 FOR_EACH_PTR(rl, tmp) {
1155 if (type != tmp->min.type || type != tmp->max.type)
1156 return 0;
1157 } END_FOR_EACH_PTR(tmp);
1158 return 1;
1161 struct range_list *cast_rl(struct symbol *type, struct range_list *rl)
1163 struct data_range *tmp;
1164 struct range_list *ret = NULL;
1166 if (!rl)
1167 return NULL;
1169 if (!type)
1170 return rl;
1171 if (!rl_is_sane(rl))
1172 return alloc_whole_rl(type);
1173 if (type == rl_type(rl) && rl_type_consistent(rl))
1174 return rl;
1176 FOR_EACH_PTR(rl, tmp) {
1177 add_range_t(type, &ret, tmp->min, tmp->max);
1178 } END_FOR_EACH_PTR(tmp);
1180 if (!ret)
1181 return alloc_whole_rl(type);
1183 return ret;
1186 struct range_list *rl_invert(struct range_list *orig)
1188 struct range_list *ret = NULL;
1189 struct data_range *tmp;
1190 sval_t gap_min, abs_max, sval;
1192 if (!orig)
1193 return NULL;
1194 if (type_bits(rl_type(orig)) < 0) /* void type mostly */
1195 return NULL;
1197 gap_min = sval_type_min(rl_min(orig).type);
1198 abs_max = sval_type_max(rl_max(orig).type);
1200 FOR_EACH_PTR(orig, tmp) {
1201 if (sval_cmp(tmp->min, gap_min) > 0) {
1202 sval = sval_type_val(tmp->min.type, tmp->min.value - 1);
1203 add_range(&ret, gap_min, sval);
1205 if (sval_cmp(tmp->max, abs_max) == 0)
1206 return ret;
1207 gap_min = sval_type_val(tmp->max.type, tmp->max.value + 1);
1208 } END_FOR_EACH_PTR(tmp);
1210 if (sval_cmp(gap_min, abs_max) <= 0)
1211 add_range(&ret, gap_min, abs_max);
1213 return ret;
1216 struct range_list *rl_filter(struct range_list *rl, struct range_list *filter)
1218 struct data_range *tmp;
1220 FOR_EACH_PTR(filter, tmp) {
1221 rl = remove_range(rl, tmp->min, tmp->max);
1222 } END_FOR_EACH_PTR(tmp);
1224 return rl;
1227 struct range_list *rl_intersection(struct range_list *one, struct range_list *two)
1229 struct range_list *one_orig;
1230 struct range_list *two_orig;
1231 struct range_list *ret;
1232 struct symbol *ret_type;
1233 struct symbol *small_type;
1234 struct symbol *large_type;
1236 if (!two)
1237 return NULL;
1238 if (!one)
1239 return NULL;
1241 one_orig = one;
1242 two_orig = two;
1244 ret_type = rl_type(one);
1245 small_type = rl_type(one);
1246 large_type = rl_type(two);
1248 if (type_bits(rl_type(two)) < type_bits(small_type)) {
1249 small_type = rl_type(two);
1250 large_type = rl_type(one);
1253 one = cast_rl(large_type, one);
1254 two = cast_rl(large_type, two);
1256 ret = one;
1257 one = rl_invert(one);
1258 two = rl_invert(two);
1260 ret = rl_filter(ret, one);
1261 ret = rl_filter(ret, two);
1263 one = cast_rl(small_type, one_orig);
1264 two = cast_rl(small_type, two_orig);
1266 one = rl_invert(one);
1267 two = rl_invert(two);
1269 ret = cast_rl(small_type, ret);
1270 ret = rl_filter(ret, one);
1271 ret = rl_filter(ret, two);
1273 return cast_rl(ret_type, ret);
1276 static struct range_list *handle_mod_rl(struct range_list *left, struct range_list *right)
1278 sval_t zero;
1279 sval_t max;
1281 max = rl_max(right);
1282 if (sval_is_max(max))
1283 return left;
1284 if (max.value == 0)
1285 return NULL;
1286 max.value--;
1287 if (sval_is_negative(max))
1288 return NULL;
1289 if (sval_cmp(rl_max(left), max) < 0)
1290 return left;
1291 zero = max;
1292 zero.value = 0;
1293 return alloc_rl(zero, max);
1296 static struct range_list *get_neg_rl(struct range_list *rl)
1298 struct data_range *tmp;
1299 struct data_range *new;
1300 struct range_list *ret = NULL;
1302 if (!rl)
1303 return NULL;
1304 if (sval_is_positive(rl_min(rl)))
1305 return NULL;
1307 FOR_EACH_PTR(rl, tmp) {
1308 if (sval_is_positive(tmp->min))
1309 return ret;
1310 if (sval_is_positive(tmp->max)) {
1311 new = alloc_range(tmp->min, tmp->max);
1312 new->max.value = -1;
1313 add_range(&ret, new->min, new->max);
1314 return ret;
1316 add_range(&ret, tmp->min, tmp->max);
1317 } END_FOR_EACH_PTR(tmp);
1319 return ret;
1322 static struct range_list *get_pos_rl(struct range_list *rl)
1324 struct data_range *tmp;
1325 struct data_range *new;
1326 struct range_list *ret = NULL;
1328 if (!rl)
1329 return NULL;
1330 if (sval_is_negative(rl_max(rl)))
1331 return NULL;
1333 FOR_EACH_PTR(rl, tmp) {
1334 if (sval_is_negative(tmp->max))
1335 continue;
1336 if (sval_is_positive(tmp->min)) {
1337 add_range(&ret, tmp->min, tmp->max);
1338 continue;
1340 new = alloc_range(tmp->min, tmp->max);
1341 new->min.value = 0;
1342 add_range(&ret, new->min, new->max);
1343 } END_FOR_EACH_PTR(tmp);
1345 return ret;
1348 static struct range_list *divide_rl_helper(struct range_list *left, struct range_list *right)
1350 sval_t right_min, right_max;
1351 sval_t min, max;
1353 if (!left || !right)
1354 return NULL;
1356 /* let's assume we never divide by zero */
1357 right_min = rl_min(right);
1358 right_max = rl_max(right);
1359 if (right_min.value == 0 && right_max.value == 0)
1360 return NULL;
1361 if (right_min.value == 0)
1362 right_min.value = 1;
1363 if (right_max.value == 0)
1364 right_max.value = -1;
1366 max = sval_binop(rl_max(left), '/', right_min);
1367 min = sval_binop(rl_min(left), '/', right_max);
1369 return alloc_rl(min, max);
1372 static struct range_list *handle_divide_rl(struct range_list *left, struct range_list *right)
1374 struct range_list *left_neg, *left_pos, *right_neg, *right_pos;
1375 struct range_list *neg_neg, *neg_pos, *pos_neg, *pos_pos;
1376 struct range_list *ret;
1378 if (is_whole_rl(right))
1379 return NULL;
1381 left_neg = get_neg_rl(left);
1382 left_pos = get_pos_rl(left);
1383 right_neg = get_neg_rl(right);
1384 right_pos = get_pos_rl(right);
1386 neg_neg = divide_rl_helper(left_neg, right_neg);
1387 neg_pos = divide_rl_helper(left_neg, right_pos);
1388 pos_neg = divide_rl_helper(left_pos, right_neg);
1389 pos_pos = divide_rl_helper(left_pos, right_pos);
1391 ret = rl_union(neg_neg, neg_pos);
1392 ret = rl_union(ret, pos_neg);
1393 return rl_union(ret, pos_pos);
1396 static struct range_list *handle_add_mult_rl(struct range_list *left, int op, struct range_list *right)
1398 sval_t min, max;
1400 if (sval_binop_overflows(rl_min(left), op, rl_min(right)))
1401 return NULL;
1402 min = sval_binop(rl_min(left), op, rl_min(right));
1404 if (sval_binop_overflows(rl_max(left), op, rl_max(right)))
1405 return NULL;
1406 max = sval_binop(rl_max(left), op, rl_max(right));
1408 return alloc_rl(min, max);
1411 static unsigned long long rl_bits_always_set(struct range_list *rl)
1413 return sval_fls_mask(rl_min(rl));
1416 static unsigned long long rl_bits_maybe_set(struct range_list *rl)
1418 return sval_fls_mask(rl_max(rl));
1421 static struct range_list *handle_OR_rl(struct range_list *left, struct range_list *right)
1423 unsigned long long left_min, left_max, right_min, right_max;
1424 sval_t min, max;
1425 sval_t sval;
1427 if ((rl_to_sval(left, &sval) || rl_to_sval(right, &sval)) &&
1428 !sval_binop_overflows(rl_max(left), '+', rl_max(right)))
1429 return rl_binop(left, '+', right);
1431 left_min = rl_bits_always_set(left);
1432 left_max = rl_bits_maybe_set(left);
1433 right_min = rl_bits_always_set(right);
1434 right_max = rl_bits_maybe_set(right);
1436 min.type = max.type = &ullong_ctype;
1437 min.uvalue = left_min | right_min;
1438 max.uvalue = left_max | right_max;
1440 return cast_rl(rl_type(left), alloc_rl(min, max));
1443 static struct range_list *handle_XOR_rl(struct range_list *left, struct range_list *right)
1445 unsigned long long left_set, left_maybe;
1446 unsigned long long right_set, right_maybe;
1447 sval_t zero, max;
1449 left_set = rl_bits_always_set(left);
1450 left_maybe = rl_bits_maybe_set(left);
1452 right_set = rl_bits_always_set(right);
1453 right_maybe = rl_bits_maybe_set(right);
1455 zero = max = rl_min(left);
1456 zero.uvalue = 0;
1457 max.uvalue = fls_mask((left_maybe | right_maybe) ^ (left_set & right_set));
1459 return cast_rl(rl_type(left), alloc_rl(zero, max));
1462 struct range_list *rl_binop(struct range_list *left, int op, struct range_list *right)
1464 struct symbol *cast_type;
1465 sval_t left_sval, right_sval;
1466 struct range_list *ret = NULL;
1468 cast_type = rl_type(left);
1469 if (sval_type_max(rl_type(left)).uvalue < sval_type_max(rl_type(right)).uvalue)
1470 cast_type = rl_type(right);
1471 if (sval_type_max(cast_type).uvalue < INT_MAX)
1472 cast_type = &int_ctype;
1474 left = cast_rl(cast_type, left);
1475 right = cast_rl(cast_type, right);
1477 if (!left || !right)
1478 return alloc_whole_rl(cast_type);
1480 if (rl_to_sval(left, &left_sval) && rl_to_sval(right, &right_sval)) {
1481 sval_t val = sval_binop(left_sval, op, right_sval);
1482 return alloc_rl(val, val);
1485 switch (op) {
1486 case '%':
1487 ret = handle_mod_rl(left, right);
1488 break;
1489 case '/':
1490 ret = handle_divide_rl(left, right);
1491 break;
1492 case '*':
1493 case '+':
1494 ret = handle_add_mult_rl(left, op, right);
1495 break;
1496 case '|':
1497 ret = handle_OR_rl(left, right);
1498 break;
1499 case '^':
1500 ret = handle_XOR_rl(left, right);
1501 break;
1503 /* FIXME: Do the rest as well */
1504 case '-':
1505 case '&':
1506 case SPECIAL_RIGHTSHIFT:
1507 case SPECIAL_LEFTSHIFT:
1508 break;
1511 if (!ret)
1512 ret = alloc_whole_rl(cast_type);
1513 return ret;
1516 void free_rl(struct range_list **rlist)
1518 __free_ptr_list((struct ptr_list **)rlist);
1521 static void free_single_dinfo(struct data_info *dinfo)
1523 free_rl(&dinfo->value_ranges);
1526 static void free_dinfos(struct allocation_blob *blob)
1528 unsigned int size = sizeof(struct data_info);
1529 unsigned int offset = 0;
1531 while (offset < blob->offset) {
1532 free_single_dinfo((struct data_info *)(blob->data + offset));
1533 offset += size;
1537 void free_data_info_allocs(void)
1539 struct allocator_struct *desc = &data_info_allocator;
1540 struct allocation_blob *blob = desc->blobs;
1542 desc->blobs = NULL;
1543 desc->allocations = 0;
1544 desc->total_bytes = 0;
1545 desc->useful_bytes = 0;
1546 desc->freelist = NULL;
1547 while (blob) {
1548 struct allocation_blob *next = blob->next;
1549 free_dinfos(blob);
1550 blob_free(blob, desc->chunking);
1551 blob = next;
1553 clear_data_range_alloc();
1556 void split_comparison_rl(struct range_list *left_orig, int op, struct range_list *right_orig,
1557 struct range_list **left_true_rl, struct range_list **left_false_rl,
1558 struct range_list **right_true_rl, struct range_list **right_false_rl)
1560 struct range_list *left_true, *left_false;
1561 struct range_list *right_true, *right_false;
1562 sval_t min, max;
1564 min = sval_type_min(rl_type(left_orig));
1565 max = sval_type_max(rl_type(left_orig));
1567 left_true = clone_rl(left_orig);
1568 left_false = clone_rl(left_orig);
1569 right_true = clone_rl(right_orig);
1570 right_false = clone_rl(right_orig);
1572 switch (op) {
1573 case '<':
1574 case SPECIAL_UNSIGNED_LT:
1575 left_true = remove_range(left_orig, rl_max(right_orig), max);
1576 if (!sval_is_min(rl_min(right_orig))) {
1577 left_false = remove_range(left_orig, min, sub_one(rl_min(right_orig)));
1580 right_true = remove_range(right_orig, min, rl_min(left_orig));
1581 if (!sval_is_max(rl_max(left_orig)))
1582 right_false = remove_range(right_orig, add_one(rl_max(left_orig)), max);
1583 break;
1584 case SPECIAL_UNSIGNED_LTE:
1585 case SPECIAL_LTE:
1586 if (!sval_is_max(rl_max(right_orig)))
1587 left_true = remove_range(left_orig, add_one(rl_max(right_orig)), max);
1588 left_false = remove_range(left_orig, min, rl_min(right_orig));
1590 if (!sval_is_min(rl_min(left_orig)))
1591 right_true = remove_range(right_orig, min, sub_one(rl_min(left_orig)));
1592 right_false = remove_range(right_orig, rl_max(left_orig), max);
1594 if (sval_cmp(rl_min(left_orig), rl_min(right_orig)) == 0)
1595 left_false = remove_range(left_false, rl_min(left_orig), rl_min(left_orig));
1596 if (sval_cmp(rl_max(left_orig), rl_max(right_orig)) == 0)
1597 right_false = remove_range(right_false, rl_max(left_orig), rl_max(left_orig));
1598 break;
1599 case SPECIAL_EQUAL:
1600 if (!sval_is_max(rl_max(right_orig))) {
1601 left_true = remove_range(left_true, add_one(rl_max(right_orig)), max);
1603 if (!sval_is_min(rl_min(right_orig))) {
1604 left_true = remove_range(left_true, min, sub_one(rl_min(right_orig)));
1606 if (sval_cmp(rl_min(right_orig), rl_max(right_orig)) == 0)
1607 left_false = remove_range(left_orig, rl_min(right_orig), rl_min(right_orig));
1609 if (!sval_is_max(rl_max(left_orig)))
1610 right_true = remove_range(right_true, add_one(rl_max(left_orig)), max);
1611 if (!sval_is_min(rl_min(left_orig)))
1612 right_true = remove_range(right_true, min, sub_one(rl_min(left_orig)));
1613 if (sval_cmp(rl_min(left_orig), rl_max(left_orig)) == 0)
1614 right_false = remove_range(right_orig, rl_min(left_orig), rl_min(left_orig));
1615 break;
1616 case SPECIAL_UNSIGNED_GTE:
1617 case SPECIAL_GTE:
1618 if (!sval_is_min(rl_min(right_orig)))
1619 left_true = remove_range(left_orig, min, sub_one(rl_min(right_orig)));
1620 left_false = remove_range(left_orig, rl_max(right_orig), max);
1622 if (!sval_is_max(rl_max(left_orig)))
1623 right_true = remove_range(right_orig, add_one(rl_max(left_orig)), max);
1624 right_false = remove_range(right_orig, min, rl_min(left_orig));
1626 if (sval_cmp(rl_min(left_orig), rl_min(right_orig)) == 0)
1627 right_false = remove_range(right_false, rl_min(left_orig), rl_min(left_orig));
1628 if (sval_cmp(rl_max(left_orig), rl_max(right_orig)) == 0)
1629 left_false = remove_range(left_false, rl_max(left_orig), rl_max(left_orig));
1630 break;
1631 case '>':
1632 case SPECIAL_UNSIGNED_GT:
1633 left_true = remove_range(left_orig, min, rl_min(right_orig));
1634 if (!sval_is_max(rl_max(right_orig)))
1635 left_false = remove_range(left_orig, add_one(rl_max(right_orig)), max);
1637 right_true = remove_range(right_orig, rl_max(left_orig), max);
1638 if (!sval_is_min(rl_min(left_orig)))
1639 right_false = remove_range(right_orig, min, sub_one(rl_min(left_orig)));
1640 break;
1641 case SPECIAL_NOTEQUAL:
1642 if (!sval_is_max(rl_max(right_orig)))
1643 left_false = remove_range(left_false, add_one(rl_max(right_orig)), max);
1644 if (!sval_is_min(rl_min(right_orig)))
1645 left_false = remove_range(left_false, min, sub_one(rl_min(right_orig)));
1646 if (sval_cmp(rl_min(right_orig), rl_max(right_orig)) == 0)
1647 left_true = remove_range(left_orig, rl_min(right_orig), rl_min(right_orig));
1649 if (!sval_is_max(rl_max(left_orig)))
1650 right_false = remove_range(right_false, add_one(rl_max(left_orig)), max);
1651 if (!sval_is_min(rl_min(left_orig)))
1652 right_false = remove_range(right_false, min, sub_one(rl_min(left_orig)));
1653 if (sval_cmp(rl_min(left_orig), rl_max(left_orig)) == 0)
1654 right_true = remove_range(right_orig, rl_min(left_orig), rl_min(left_orig));
1655 break;
1656 default:
1657 sm_msg("internal error: unhandled comparison %d", op);
1658 return;
1661 if (left_true_rl) {
1662 *left_true_rl = left_true;
1663 *left_false_rl = left_false;
1665 if (right_true_rl) {
1666 *right_true_rl = right_true;
1667 *right_false_rl = right_false;