user_data2: math: function calls should be handled by the custom call back
[smatch.git] / smatch_ranges.c
blob6ef47a4b219269ac4e2584430a9531daf0a13211
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 start_rl;
296 if (!get_implied_rl(arg, &right_orig))
297 return start_rl;
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 if (type_positive_bits(type) == 64) {
362 ret = sval_type_val(type, strtoull(start, &c, 10));
363 } else {
364 ret = sval_type_val(type, strtoll(start, &c, 10));
366 *endp = c;
367 return ret;
370 static char *jump_to_call_math(char *value)
372 char *c = value;
374 while (*c && *c != '[')
375 c++;
377 if (!*c)
378 return NULL;
379 c++;
380 if (*c == '<' || *c == '=' || *c == '>' || *c == '!')
381 return NULL;
383 return c;
386 static void str_to_rl_helper(struct expression *call, struct symbol *type, char *str, char **endp, struct range_list **rl)
388 struct range_list *rl_tmp = NULL;
389 sval_t min, max;
390 char *c;
392 min = sval_type_min(type);
393 max = sval_type_max(type);
394 c = str;
395 while (*c != '\0' && *c != '[') {
396 if (*c == '(')
397 c++;
398 min = parse_val(0, call, type, c, &c);
399 max = min;
400 if (*c == ')')
401 c++;
402 if (*c == '\0' || *c == '[') {
403 add_range_t(type, &rl_tmp, min, min);
404 break;
406 if (*c == ',') {
407 add_range_t(type, &rl_tmp, min, min);
408 c++;
409 continue;
411 if (*c != '-') {
412 sm_msg("debug XXX: trouble parsing %s c = %s", str, c);
413 break;
415 c++;
416 if (*c == '(')
417 c++;
418 max = parse_val(1, call, type, c, &c);
419 add_range_t(type, &rl_tmp, min, max);
420 if (*c == ')')
421 c++;
422 if (*c == ',')
423 c++;
426 *rl = rl_tmp;
427 *endp = c;
430 static void str_to_dinfo(struct expression *call, struct symbol *type, char *value, struct data_info *dinfo)
432 struct range_list *math_rl;
433 char *call_math;
434 char *c;
435 struct range_list *rl = NULL;
437 if (!type)
438 type = &llong_ctype;
440 if (strcmp(value, "empty") == 0)
441 return;
443 if (strncmp(value, "[==$", 4) == 0) {
444 struct expression *arg;
445 int comparison;
447 if (!str_to_comparison_arg(value, call, &comparison, &arg))
448 return;
449 if (!get_implied_rl(arg, &rl))
450 return;
451 goto cast;
454 str_to_rl_helper(call, type, value, &c, &rl);
455 if (*c == '\0')
456 goto cast;
458 call_math = jump_to_call_math(value);
459 if (call_math && parse_call_math_rl(call, call_math, &math_rl)) {
460 rl = rl_intersection(rl, math_rl);
461 goto cast;
465 * For now if we already tried to handle the call math and couldn't
466 * figure it out then bail.
468 if (jump_to_call_math(c) == c + 1)
469 goto cast;
471 rl = filter_by_comparison_call(c, call, &c, rl);
473 cast:
474 rl = cast_rl(type, rl);
475 dinfo->value_ranges = rl;
478 void str_to_rl(struct symbol *type, char *value, struct range_list **rl)
480 struct data_info dinfo = {};
482 str_to_dinfo(NULL, type, value, &dinfo);
483 *rl = dinfo.value_ranges;
486 void call_results_to_rl(struct expression *expr, struct symbol *type, char *value, struct range_list **rl)
488 struct data_info dinfo = {};
490 str_to_dinfo(strip_expr(expr), type, value, &dinfo);
491 *rl = dinfo.value_ranges;
494 int is_whole_rl(struct range_list *rl)
496 struct data_range *drange;
498 if (ptr_list_empty(rl))
499 return 0;
500 drange = first_ptr_list((struct ptr_list *)rl);
501 if (sval_is_min(drange->min) && sval_is_max(drange->max))
502 return 1;
503 return 0;
506 int is_whole_rl_non_zero(struct range_list *rl)
508 struct data_range *drange;
510 if (ptr_list_empty(rl))
511 return 0;
512 drange = first_ptr_list((struct ptr_list *)rl);
513 if (sval_unsigned(drange->min) &&
514 drange->min.value == 1 &&
515 sval_is_max(drange->max))
516 return 1;
517 if (!sval_is_min(drange->min) || drange->max.value != -1)
518 return 0;
519 drange = last_ptr_list((struct ptr_list *)rl);
520 if (drange->min.value != 1 || !sval_is_max(drange->max))
521 return 0;
522 return 1;
525 sval_t rl_min(struct range_list *rl)
527 struct data_range *drange;
528 sval_t ret;
530 ret.type = &llong_ctype;
531 ret.value = LLONG_MIN;
532 if (ptr_list_empty(rl))
533 return ret;
534 drange = first_ptr_list((struct ptr_list *)rl);
535 return drange->min;
538 sval_t rl_max(struct range_list *rl)
540 struct data_range *drange;
541 sval_t ret;
543 ret.type = &llong_ctype;
544 ret.value = LLONG_MAX;
545 if (ptr_list_empty(rl))
546 return ret;
547 drange = last_ptr_list((struct ptr_list *)rl);
548 return drange->max;
551 int rl_to_sval(struct range_list *rl, sval_t *sval)
553 sval_t min, max;
555 if (!rl)
556 return 0;
558 min = rl_min(rl);
559 max = rl_max(rl);
560 if (sval_cmp(min, max) != 0)
561 return 0;
562 *sval = min;
563 return 1;
566 struct symbol *rl_type(struct range_list *rl)
568 if (!rl)
569 return NULL;
570 return rl_min(rl).type;
573 static struct data_range *alloc_range_helper_sval(sval_t min, sval_t max, int perm)
575 struct data_range *ret;
577 if (perm)
578 ret = __alloc_perm_data_range(0);
579 else
580 ret = __alloc_data_range(0);
581 ret->min = min;
582 ret->max = max;
583 return ret;
586 struct data_range *alloc_range(sval_t min, sval_t max)
588 return alloc_range_helper_sval(min, max, 0);
591 struct data_range *alloc_range_perm(sval_t min, sval_t max)
593 return alloc_range_helper_sval(min, max, 1);
596 struct range_list *alloc_rl(sval_t min, sval_t max)
598 struct range_list *rl = NULL;
600 if (sval_cmp(min, max) > 0)
601 return alloc_whole_rl(min.type);
603 add_range(&rl, min, max);
604 return rl;
607 struct range_list *alloc_whole_rl(struct symbol *type)
609 if (!type || type_positive_bits(type) < 0)
610 type = &llong_ctype;
611 if (type->type == SYM_ARRAY)
612 type = &ptr_ctype;
614 return alloc_rl(sval_type_min(type), sval_type_max(type));
617 void add_range(struct range_list **list, sval_t min, sval_t max)
619 struct data_range *tmp;
620 struct data_range *new = NULL;
621 int check_next = 0;
623 if (sval_cmp(min, max) > 0) {
624 min = sval_type_min(min.type);
625 max = sval_type_max(min.type);
629 * FIXME: This has a problem merging a range_list like: min-0,3-max
630 * with a range like 1-2. You end up with min-2,3-max instead of
631 * just min-max.
633 FOR_EACH_PTR(*list, tmp) {
634 if (check_next) {
635 /* Sometimes we overlap with more than one range
636 so we have to delete or modify the next range. */
637 if (!sval_is_max(max) && max.value + 1 == tmp->min.value) {
638 /* join 2 ranges here */
639 new->max = tmp->max;
640 DELETE_CURRENT_PTR(tmp);
641 return;
644 /* Doesn't overlap with the next one. */
645 if (sval_cmp(max, tmp->min) < 0)
646 return;
648 if (sval_cmp(max, tmp->max) <= 0) {
649 /* Partially overlaps the next one. */
650 new->max = tmp->max;
651 DELETE_CURRENT_PTR(tmp);
652 return;
653 } else {
654 /* Completely overlaps the next one. */
655 DELETE_CURRENT_PTR(tmp);
656 /* there could be more ranges to delete */
657 continue;
660 if (!sval_is_max(max) && max.value + 1 == tmp->min.value) {
661 /* join 2 ranges into a big range */
662 new = alloc_range(min, tmp->max);
663 REPLACE_CURRENT_PTR(tmp, new);
664 return;
666 if (sval_cmp(max, tmp->min) < 0) { /* new range entirely below */
667 new = alloc_range(min, max);
668 INSERT_CURRENT(new, tmp);
669 return;
671 if (sval_cmp(min, tmp->min) < 0) { /* new range partially below */
672 if (sval_cmp(max, tmp->max) < 0)
673 max = tmp->max;
674 else
675 check_next = 1;
676 new = alloc_range(min, max);
677 REPLACE_CURRENT_PTR(tmp, new);
678 if (!check_next)
679 return;
680 continue;
682 if (sval_cmp(max, tmp->max) <= 0) /* new range already included */
683 return;
684 if (sval_cmp(min, tmp->max) <= 0) { /* new range partially above */
685 min = tmp->min;
686 new = alloc_range(min, max);
687 REPLACE_CURRENT_PTR(tmp, new);
688 check_next = 1;
689 continue;
691 if (!sval_is_min(min) && min.value - 1 == tmp->max.value) {
692 /* join 2 ranges into a big range */
693 new = alloc_range(tmp->min, max);
694 REPLACE_CURRENT_PTR(tmp, new);
695 check_next = 1;
696 continue;
698 /* the new range is entirely above the existing ranges */
699 } END_FOR_EACH_PTR(tmp);
700 if (check_next)
701 return;
702 new = alloc_range(min, max);
703 add_ptr_list(list, new);
706 struct range_list *clone_rl(struct range_list *list)
708 struct data_range *tmp;
709 struct range_list *ret = NULL;
711 FOR_EACH_PTR(list, tmp) {
712 add_ptr_list(&ret, tmp);
713 } END_FOR_EACH_PTR(tmp);
714 return ret;
717 struct range_list *clone_rl_permanent(struct range_list *list)
719 struct data_range *tmp;
720 struct data_range *new;
721 struct range_list *ret = NULL;
723 FOR_EACH_PTR(list, tmp) {
724 new = alloc_range_perm(tmp->min, tmp->max);
725 add_ptr_list(&ret, new);
726 } END_FOR_EACH_PTR(tmp);
727 return ret;
730 struct range_list *rl_union(struct range_list *one, struct range_list *two)
732 struct data_range *tmp;
733 struct range_list *ret = NULL;
735 FOR_EACH_PTR(one, tmp) {
736 add_range(&ret, tmp->min, tmp->max);
737 } END_FOR_EACH_PTR(tmp);
738 FOR_EACH_PTR(two, tmp) {
739 add_range(&ret, tmp->min, tmp->max);
740 } END_FOR_EACH_PTR(tmp);
741 return ret;
744 struct range_list *remove_range(struct range_list *list, sval_t min, sval_t max)
746 struct data_range *tmp;
747 struct range_list *ret = NULL;
749 if (!list)
750 return NULL;
752 min = sval_cast(rl_type(list), min);
753 max = sval_cast(rl_type(list), max);
754 if (sval_cmp(min, max) > 0) {
755 sval_t tmp = min;
756 min = max;
757 max = tmp;
760 FOR_EACH_PTR(list, tmp) {
761 if (sval_cmp(tmp->max, min) < 0) {
762 add_range(&ret, tmp->min, tmp->max);
763 continue;
765 if (sval_cmp(tmp->min, max) > 0) {
766 add_range(&ret, tmp->min, tmp->max);
767 continue;
769 if (sval_cmp(tmp->min, min) >= 0 && sval_cmp(tmp->max, max) <= 0)
770 continue;
771 if (sval_cmp(tmp->min, min) >= 0) {
772 max.value++;
773 add_range(&ret, max, tmp->max);
774 } else if (sval_cmp(tmp->max, max) <= 0) {
775 min.value--;
776 add_range(&ret, tmp->min, min);
777 } else {
778 min.value--;
779 max.value++;
780 add_range(&ret, tmp->min, min);
781 add_range(&ret, max, tmp->max);
783 } END_FOR_EACH_PTR(tmp);
784 return ret;
787 int ranges_equiv(struct data_range *one, struct data_range *two)
789 if (!one && !two)
790 return 1;
791 if (!one || !two)
792 return 0;
793 if (sval_cmp(one->min, two->min) != 0)
794 return 0;
795 if (sval_cmp(one->max, two->max) != 0)
796 return 0;
797 return 1;
800 int rl_equiv(struct range_list *one, struct range_list *two)
802 struct data_range *one_range;
803 struct data_range *two_range;
805 if (one == two)
806 return 1;
808 PREPARE_PTR_LIST(one, one_range);
809 PREPARE_PTR_LIST(two, two_range);
810 for (;;) {
811 if (!one_range && !two_range)
812 return 1;
813 if (!ranges_equiv(one_range, two_range))
814 return 0;
815 NEXT_PTR_LIST(one_range);
816 NEXT_PTR_LIST(two_range);
818 FINISH_PTR_LIST(two_range);
819 FINISH_PTR_LIST(one_range);
821 return 1;
824 int true_comparison_range(struct data_range *left, int comparison, struct data_range *right)
826 switch (comparison) {
827 case '<':
828 case SPECIAL_UNSIGNED_LT:
829 if (sval_cmp(left->min, right->max) < 0)
830 return 1;
831 return 0;
832 case SPECIAL_UNSIGNED_LTE:
833 case SPECIAL_LTE:
834 if (sval_cmp(left->min, right->max) <= 0)
835 return 1;
836 return 0;
837 case SPECIAL_EQUAL:
838 if (sval_cmp(left->max, right->min) < 0)
839 return 0;
840 if (sval_cmp(left->min, right->max) > 0)
841 return 0;
842 return 1;
843 case SPECIAL_UNSIGNED_GTE:
844 case SPECIAL_GTE:
845 if (sval_cmp(left->max, right->min) >= 0)
846 return 1;
847 return 0;
848 case '>':
849 case SPECIAL_UNSIGNED_GT:
850 if (sval_cmp(left->max, right->min) > 0)
851 return 1;
852 return 0;
853 case SPECIAL_NOTEQUAL:
854 if (sval_cmp(left->min, left->max) != 0)
855 return 1;
856 if (sval_cmp(right->min, right->max) != 0)
857 return 1;
858 if (sval_cmp(left->min, right->min) != 0)
859 return 1;
860 return 0;
861 default:
862 sm_msg("unhandled comparison %d\n", comparison);
863 return 0;
865 return 0;
868 int true_comparison_range_LR(int comparison, struct data_range *var, struct data_range *val, int left)
870 if (left)
871 return true_comparison_range(var, comparison, val);
872 else
873 return true_comparison_range(val, comparison, var);
876 static int false_comparison_range_sval(struct data_range *left, int comparison, struct data_range *right)
878 switch (comparison) {
879 case '<':
880 case SPECIAL_UNSIGNED_LT:
881 if (sval_cmp(left->max, right->min) >= 0)
882 return 1;
883 return 0;
884 case SPECIAL_UNSIGNED_LTE:
885 case SPECIAL_LTE:
886 if (sval_cmp(left->max, right->min) > 0)
887 return 1;
888 return 0;
889 case SPECIAL_EQUAL:
890 if (sval_cmp(left->min, left->max) != 0)
891 return 1;
892 if (sval_cmp(right->min, right->max) != 0)
893 return 1;
894 if (sval_cmp(left->min, right->min) != 0)
895 return 1;
896 return 0;
897 case SPECIAL_UNSIGNED_GTE:
898 case SPECIAL_GTE:
899 if (sval_cmp(left->min, right->max) < 0)
900 return 1;
901 return 0;
902 case '>':
903 case SPECIAL_UNSIGNED_GT:
904 if (sval_cmp(left->min, right->max) <= 0)
905 return 1;
906 return 0;
907 case SPECIAL_NOTEQUAL:
908 if (sval_cmp(left->max, right->min) < 0)
909 return 0;
910 if (sval_cmp(left->min, right->max) > 0)
911 return 0;
912 return 1;
913 default:
914 sm_msg("unhandled comparison %d\n", comparison);
915 return 0;
917 return 0;
920 int false_comparison_range_LR(int comparison, struct data_range *var, struct data_range *val, int left)
922 if (left)
923 return false_comparison_range_sval(var, comparison, val);
924 else
925 return false_comparison_range_sval(val, comparison, var);
928 int possibly_true(struct expression *left, int comparison, struct expression *right)
930 struct range_list *rl_left, *rl_right;
931 struct data_range *tmp_left, *tmp_right;
932 struct symbol *type;
934 if (!get_implied_rl(left, &rl_left))
935 return 1;
936 if (!get_implied_rl(right, &rl_right))
937 return 1;
939 type = rl_type(rl_left);
940 if (type_positive_bits(type) < type_positive_bits(rl_type(rl_right)))
941 type = rl_type(rl_right);
942 if (type_positive_bits(type) < 31)
943 type = &int_ctype;
945 rl_left = cast_rl(type, rl_left);
946 rl_right = cast_rl(type, rl_right);
948 FOR_EACH_PTR(rl_left, tmp_left) {
949 FOR_EACH_PTR(rl_right, tmp_right) {
950 if (true_comparison_range(tmp_left, comparison, tmp_right))
951 return 1;
952 } END_FOR_EACH_PTR(tmp_right);
953 } END_FOR_EACH_PTR(tmp_left);
954 return 0;
957 int possibly_false(struct expression *left, int comparison, struct expression *right)
959 struct range_list *rl_left, *rl_right;
960 struct data_range *tmp_left, *tmp_right;
961 struct symbol *type;
963 if (!get_implied_rl(left, &rl_left))
964 return 1;
965 if (!get_implied_rl(right, &rl_right))
966 return 1;
968 type = rl_type(rl_left);
969 if (type_positive_bits(type) < type_positive_bits(rl_type(rl_right)))
970 type = rl_type(rl_right);
971 if (type_positive_bits(type) < 31)
972 type = &int_ctype;
974 rl_left = cast_rl(type, rl_left);
975 rl_right = cast_rl(type, rl_right);
977 FOR_EACH_PTR(rl_left, tmp_left) {
978 FOR_EACH_PTR(rl_right, tmp_right) {
979 if (false_comparison_range_sval(tmp_left, comparison, tmp_right))
980 return 1;
981 } END_FOR_EACH_PTR(tmp_right);
982 } END_FOR_EACH_PTR(tmp_left);
983 return 0;
986 int possibly_true_rl(struct range_list *left_ranges, int comparison, struct range_list *right_ranges)
988 struct data_range *left_tmp, *right_tmp;
989 struct symbol *type;
991 if (!left_ranges || !right_ranges)
992 return 1;
994 type = rl_type(left_ranges);
995 if (type_positive_bits(type) < type_positive_bits(rl_type(right_ranges)))
996 type = rl_type(right_ranges);
997 if (type_positive_bits(type) < 31)
998 type = &int_ctype;
1000 left_ranges = cast_rl(type, left_ranges);
1001 right_ranges = cast_rl(type, right_ranges);
1003 FOR_EACH_PTR(left_ranges, left_tmp) {
1004 FOR_EACH_PTR(right_ranges, right_tmp) {
1005 if (true_comparison_range(left_tmp, comparison, right_tmp))
1006 return 1;
1007 } END_FOR_EACH_PTR(right_tmp);
1008 } END_FOR_EACH_PTR(left_tmp);
1009 return 0;
1012 int possibly_false_rl(struct range_list *left_ranges, int comparison, struct range_list *right_ranges)
1014 struct data_range *left_tmp, *right_tmp;
1015 struct symbol *type;
1017 if (!left_ranges || !right_ranges)
1018 return 1;
1020 type = rl_type(left_ranges);
1021 if (type_positive_bits(type) < type_positive_bits(rl_type(right_ranges)))
1022 type = rl_type(right_ranges);
1023 if (type_positive_bits(type) < 31)
1024 type = &int_ctype;
1026 left_ranges = cast_rl(type, left_ranges);
1027 right_ranges = cast_rl(type, right_ranges);
1029 FOR_EACH_PTR(left_ranges, left_tmp) {
1030 FOR_EACH_PTR(right_ranges, right_tmp) {
1031 if (false_comparison_range_sval(left_tmp, comparison, right_tmp))
1032 return 1;
1033 } END_FOR_EACH_PTR(right_tmp);
1034 } END_FOR_EACH_PTR(left_tmp);
1035 return 0;
1038 /* FIXME: the _rl here stands for right left so really it should be _lr */
1039 int possibly_true_rl_LR(int comparison, struct range_list *a, struct range_list *b, int left)
1041 if (left)
1042 return possibly_true_rl(a, comparison, b);
1043 else
1044 return possibly_true_rl(b, comparison, a);
1047 int possibly_false_rl_LR(int comparison, struct range_list *a, struct range_list *b, int left)
1049 if (left)
1050 return possibly_false_rl(a, comparison, b);
1051 else
1052 return possibly_false_rl(b, comparison, a);
1055 int rl_has_sval(struct range_list *rl, sval_t sval)
1057 struct data_range *tmp;
1059 FOR_EACH_PTR(rl, tmp) {
1060 if (sval_cmp(tmp->min, sval) <= 0 &&
1061 sval_cmp(tmp->max, sval) >= 0)
1062 return 1;
1063 } END_FOR_EACH_PTR(tmp);
1064 return 0;
1067 void tack_on(struct range_list **list, struct data_range *drange)
1069 add_ptr_list(list, drange);
1072 void push_rl(struct range_list_stack **rl_stack, struct range_list *rl)
1074 add_ptr_list(rl_stack, rl);
1077 struct range_list *pop_rl(struct range_list_stack **rl_stack)
1079 struct range_list *rl;
1081 rl = last_ptr_list((struct ptr_list *)*rl_stack);
1082 delete_ptr_list_last((struct ptr_list **)rl_stack);
1083 return rl;
1086 struct range_list *top_rl(struct range_list_stack *rl_stack)
1088 struct range_list *rl;
1090 rl = last_ptr_list((struct ptr_list *)rl_stack);
1091 return rl;
1094 void filter_top_rl(struct range_list_stack **rl_stack, struct range_list *filter)
1096 struct range_list *rl;
1098 rl = pop_rl(rl_stack);
1099 rl = rl_filter(rl, filter);
1100 push_rl(rl_stack, rl);
1103 struct range_list *rl_truncate_cast(struct symbol *type, struct range_list *rl)
1105 struct data_range *tmp;
1106 struct range_list *ret = NULL;
1107 sval_t min, max;
1109 if (!rl)
1110 return NULL;
1112 if (!type || type == rl_type(rl))
1113 return rl;
1115 FOR_EACH_PTR(rl, tmp) {
1116 min = tmp->min;
1117 max = tmp->max;
1118 if (type_bits(type) < type_bits(rl_type(rl))) {
1119 min.uvalue = tmp->min.uvalue & ((1ULL << type_bits(type)) - 1);
1120 max.uvalue = tmp->max.uvalue & ((1ULL << type_bits(type)) - 1);
1122 if (sval_cmp(min, max) > 0) {
1123 min = sval_cast(type, min);
1124 max = sval_cast(type, max);
1126 add_range_t(type, &ret, min, max);
1127 } END_FOR_EACH_PTR(tmp);
1129 return ret;
1132 static int rl_is_sane(struct range_list *rl)
1134 struct data_range *tmp;
1135 struct symbol *type;
1137 type = rl_type(rl);
1138 FOR_EACH_PTR(rl, tmp) {
1139 if (!sval_fits(type, tmp->min))
1140 return 0;
1141 if (!sval_fits(type, tmp->max))
1142 return 0;
1143 if (sval_cmp(tmp->min, tmp->max) > 0)
1144 return 0;
1145 } END_FOR_EACH_PTR(tmp);
1147 return 1;
1150 static int rl_type_consistent(struct range_list *rl)
1152 struct data_range *tmp;
1153 struct symbol *type;
1155 type = rl_type(rl);
1156 FOR_EACH_PTR(rl, tmp) {
1157 if (type != tmp->min.type || type != tmp->max.type)
1158 return 0;
1159 } END_FOR_EACH_PTR(tmp);
1160 return 1;
1163 static struct range_list *cast_to_bool(struct range_list *rl)
1165 struct data_range *tmp;
1166 struct range_list *ret = NULL;
1167 int has_one = 0;
1168 int has_zero = 0;
1169 sval_t min = { .type = &bool_ctype };
1170 sval_t max = { .type = &bool_ctype };
1172 FOR_EACH_PTR(rl, tmp) {
1173 if (tmp->min.value || tmp->max.value)
1174 has_one = 1;
1175 if (sval_is_negative(tmp->min) &&
1176 sval_is_negative(tmp->max))
1177 continue;
1178 if (tmp->min.value == 0 ||
1179 tmp->max.value == 0)
1180 has_zero = 1;
1181 if (sval_is_negative(tmp->min) &&
1182 tmp->max.value > 0)
1183 has_zero = 1;
1184 } END_FOR_EACH_PTR(tmp);
1186 if (!has_zero)
1187 min.value = 1;
1188 if (has_one)
1189 max.value = 1;
1191 add_range(&ret, min, max);
1192 return ret;
1195 struct range_list *cast_rl(struct symbol *type, struct range_list *rl)
1197 struct data_range *tmp;
1198 struct range_list *ret = NULL;
1200 if (!rl)
1201 return NULL;
1203 if (!type)
1204 return rl;
1205 if (!rl_is_sane(rl))
1206 return alloc_whole_rl(type);
1207 if (type == rl_type(rl) && rl_type_consistent(rl))
1208 return rl;
1210 if (type == &bool_ctype)
1211 return cast_to_bool(rl);
1213 FOR_EACH_PTR(rl, tmp) {
1214 add_range_t(type, &ret, tmp->min, tmp->max);
1215 } END_FOR_EACH_PTR(tmp);
1217 if (!ret)
1218 return alloc_whole_rl(type);
1220 return ret;
1223 struct range_list *rl_invert(struct range_list *orig)
1225 struct range_list *ret = NULL;
1226 struct data_range *tmp;
1227 sval_t gap_min, abs_max, sval;
1229 if (!orig)
1230 return NULL;
1231 if (type_bits(rl_type(orig)) < 0) /* void type mostly */
1232 return NULL;
1234 gap_min = sval_type_min(rl_min(orig).type);
1235 abs_max = sval_type_max(rl_max(orig).type);
1237 FOR_EACH_PTR(orig, tmp) {
1238 if (sval_cmp(tmp->min, gap_min) > 0) {
1239 sval = sval_type_val(tmp->min.type, tmp->min.value - 1);
1240 add_range(&ret, gap_min, sval);
1242 if (sval_cmp(tmp->max, abs_max) == 0)
1243 return ret;
1244 gap_min = sval_type_val(tmp->max.type, tmp->max.value + 1);
1245 } END_FOR_EACH_PTR(tmp);
1247 if (sval_cmp(gap_min, abs_max) <= 0)
1248 add_range(&ret, gap_min, abs_max);
1250 return ret;
1253 struct range_list *rl_filter(struct range_list *rl, struct range_list *filter)
1255 struct data_range *tmp;
1257 FOR_EACH_PTR(filter, tmp) {
1258 rl = remove_range(rl, tmp->min, tmp->max);
1259 } END_FOR_EACH_PTR(tmp);
1261 return rl;
1264 struct range_list *rl_intersection(struct range_list *one, struct range_list *two)
1266 struct range_list *one_orig;
1267 struct range_list *two_orig;
1268 struct range_list *ret;
1269 struct symbol *ret_type;
1270 struct symbol *small_type;
1271 struct symbol *large_type;
1273 if (!two)
1274 return NULL;
1275 if (!one)
1276 return NULL;
1278 one_orig = one;
1279 two_orig = two;
1281 ret_type = rl_type(one);
1282 small_type = rl_type(one);
1283 large_type = rl_type(two);
1285 if (type_bits(rl_type(two)) < type_bits(small_type)) {
1286 small_type = rl_type(two);
1287 large_type = rl_type(one);
1290 one = cast_rl(large_type, one);
1291 two = cast_rl(large_type, two);
1293 ret = one;
1294 one = rl_invert(one);
1295 two = rl_invert(two);
1297 ret = rl_filter(ret, one);
1298 ret = rl_filter(ret, two);
1300 one = cast_rl(small_type, one_orig);
1301 two = cast_rl(small_type, two_orig);
1303 one = rl_invert(one);
1304 two = rl_invert(two);
1306 ret = cast_rl(small_type, ret);
1307 ret = rl_filter(ret, one);
1308 ret = rl_filter(ret, two);
1310 return cast_rl(ret_type, ret);
1313 static struct range_list *handle_mod_rl(struct range_list *left, struct range_list *right)
1315 sval_t zero;
1316 sval_t max;
1318 max = rl_max(right);
1319 if (sval_is_max(max))
1320 return left;
1321 if (max.value == 0)
1322 return NULL;
1323 max.value--;
1324 if (sval_is_negative(max))
1325 return NULL;
1326 if (sval_cmp(rl_max(left), max) < 0)
1327 return left;
1328 zero = max;
1329 zero.value = 0;
1330 return alloc_rl(zero, max);
1333 static struct range_list *get_neg_rl(struct range_list *rl)
1335 struct data_range *tmp;
1336 struct data_range *new;
1337 struct range_list *ret = NULL;
1339 if (!rl)
1340 return NULL;
1341 if (sval_is_positive(rl_min(rl)))
1342 return NULL;
1344 FOR_EACH_PTR(rl, tmp) {
1345 if (sval_is_positive(tmp->min))
1346 return ret;
1347 if (sval_is_positive(tmp->max)) {
1348 new = alloc_range(tmp->min, tmp->max);
1349 new->max.value = -1;
1350 add_range(&ret, new->min, new->max);
1351 return ret;
1353 add_range(&ret, tmp->min, tmp->max);
1354 } END_FOR_EACH_PTR(tmp);
1356 return ret;
1359 static struct range_list *get_pos_rl(struct range_list *rl)
1361 struct data_range *tmp;
1362 struct data_range *new;
1363 struct range_list *ret = NULL;
1365 if (!rl)
1366 return NULL;
1367 if (sval_is_negative(rl_max(rl)))
1368 return NULL;
1370 FOR_EACH_PTR(rl, tmp) {
1371 if (sval_is_negative(tmp->max))
1372 continue;
1373 if (sval_is_positive(tmp->min)) {
1374 add_range(&ret, tmp->min, tmp->max);
1375 continue;
1377 new = alloc_range(tmp->min, tmp->max);
1378 new->min.value = 0;
1379 add_range(&ret, new->min, new->max);
1380 } END_FOR_EACH_PTR(tmp);
1382 return ret;
1385 static struct range_list *divide_rl_helper(struct range_list *left, struct range_list *right)
1387 sval_t right_min, right_max;
1388 sval_t min, max;
1390 if (!left || !right)
1391 return NULL;
1393 /* let's assume we never divide by zero */
1394 right_min = rl_min(right);
1395 right_max = rl_max(right);
1396 if (right_min.value == 0 && right_max.value == 0)
1397 return NULL;
1398 if (right_min.value == 0)
1399 right_min.value = 1;
1400 if (right_max.value == 0)
1401 right_max.value = -1;
1403 max = sval_binop(rl_max(left), '/', right_min);
1404 min = sval_binop(rl_min(left), '/', right_max);
1406 return alloc_rl(min, max);
1409 static struct range_list *handle_divide_rl(struct range_list *left, struct range_list *right)
1411 struct range_list *left_neg, *left_pos, *right_neg, *right_pos;
1412 struct range_list *neg_neg, *neg_pos, *pos_neg, *pos_pos;
1413 struct range_list *ret;
1415 if (is_whole_rl(right))
1416 return NULL;
1418 left_neg = get_neg_rl(left);
1419 left_pos = get_pos_rl(left);
1420 right_neg = get_neg_rl(right);
1421 right_pos = get_pos_rl(right);
1423 neg_neg = divide_rl_helper(left_neg, right_neg);
1424 neg_pos = divide_rl_helper(left_neg, right_pos);
1425 pos_neg = divide_rl_helper(left_pos, right_neg);
1426 pos_pos = divide_rl_helper(left_pos, right_pos);
1428 ret = rl_union(neg_neg, neg_pos);
1429 ret = rl_union(ret, pos_neg);
1430 return rl_union(ret, pos_pos);
1433 static struct range_list *handle_add_mult_rl(struct range_list *left, int op, struct range_list *right)
1435 sval_t min, max;
1437 if (sval_binop_overflows(rl_min(left), op, rl_min(right)))
1438 return NULL;
1439 min = sval_binop(rl_min(left), op, rl_min(right));
1441 if (sval_binop_overflows(rl_max(left), op, rl_max(right)))
1442 return NULL;
1443 max = sval_binop(rl_max(left), op, rl_max(right));
1445 return alloc_rl(min, max);
1448 static unsigned long long rl_bits_always_set(struct range_list *rl)
1450 return sval_fls_mask(rl_min(rl));
1453 static unsigned long long rl_bits_maybe_set(struct range_list *rl)
1455 return sval_fls_mask(rl_max(rl));
1458 static struct range_list *handle_OR_rl(struct range_list *left, struct range_list *right)
1460 unsigned long long left_min, left_max, right_min, right_max;
1461 sval_t min, max;
1462 sval_t sval;
1464 if ((rl_to_sval(left, &sval) || rl_to_sval(right, &sval)) &&
1465 !sval_binop_overflows(rl_max(left), '+', rl_max(right)))
1466 return rl_binop(left, '+', right);
1468 left_min = rl_bits_always_set(left);
1469 left_max = rl_bits_maybe_set(left);
1470 right_min = rl_bits_always_set(right);
1471 right_max = rl_bits_maybe_set(right);
1473 min.type = max.type = &ullong_ctype;
1474 min.uvalue = left_min | right_min;
1475 max.uvalue = left_max | right_max;
1477 return cast_rl(rl_type(left), alloc_rl(min, max));
1480 static struct range_list *handle_XOR_rl(struct range_list *left, struct range_list *right)
1482 unsigned long long left_set, left_maybe;
1483 unsigned long long right_set, right_maybe;
1484 sval_t zero, max;
1486 left_set = rl_bits_always_set(left);
1487 left_maybe = rl_bits_maybe_set(left);
1489 right_set = rl_bits_always_set(right);
1490 right_maybe = rl_bits_maybe_set(right);
1492 zero = max = rl_min(left);
1493 zero.uvalue = 0;
1494 max.uvalue = fls_mask((left_maybe | right_maybe) ^ (left_set & right_set));
1496 return cast_rl(rl_type(left), alloc_rl(zero, max));
1499 struct range_list *rl_binop(struct range_list *left, int op, struct range_list *right)
1501 struct symbol *cast_type;
1502 sval_t left_sval, right_sval;
1503 struct range_list *ret = NULL;
1505 cast_type = rl_type(left);
1506 if (sval_type_max(rl_type(left)).uvalue < sval_type_max(rl_type(right)).uvalue)
1507 cast_type = rl_type(right);
1508 if (sval_type_max(cast_type).uvalue < INT_MAX)
1509 cast_type = &int_ctype;
1511 left = cast_rl(cast_type, left);
1512 right = cast_rl(cast_type, right);
1514 if (!left || !right)
1515 return alloc_whole_rl(cast_type);
1517 if (rl_to_sval(left, &left_sval) && rl_to_sval(right, &right_sval)) {
1518 sval_t val = sval_binop(left_sval, op, right_sval);
1519 return alloc_rl(val, val);
1522 switch (op) {
1523 case '%':
1524 ret = handle_mod_rl(left, right);
1525 break;
1526 case '/':
1527 ret = handle_divide_rl(left, right);
1528 break;
1529 case '*':
1530 case '+':
1531 ret = handle_add_mult_rl(left, op, right);
1532 break;
1533 case '|':
1534 ret = handle_OR_rl(left, right);
1535 break;
1536 case '^':
1537 ret = handle_XOR_rl(left, right);
1538 break;
1540 /* FIXME: Do the rest as well */
1541 case '-':
1542 case '&':
1543 case SPECIAL_RIGHTSHIFT:
1544 case SPECIAL_LEFTSHIFT:
1545 break;
1548 if (!ret)
1549 ret = alloc_whole_rl(cast_type);
1550 return ret;
1553 void free_rl(struct range_list **rlist)
1555 __free_ptr_list((struct ptr_list **)rlist);
1558 static void free_single_dinfo(struct data_info *dinfo)
1560 free_rl(&dinfo->value_ranges);
1563 static void free_dinfos(struct allocation_blob *blob)
1565 unsigned int size = sizeof(struct data_info);
1566 unsigned int offset = 0;
1568 while (offset < blob->offset) {
1569 free_single_dinfo((struct data_info *)(blob->data + offset));
1570 offset += size;
1574 void free_data_info_allocs(void)
1576 struct allocator_struct *desc = &data_info_allocator;
1577 struct allocation_blob *blob = desc->blobs;
1579 desc->blobs = NULL;
1580 desc->allocations = 0;
1581 desc->total_bytes = 0;
1582 desc->useful_bytes = 0;
1583 desc->freelist = NULL;
1584 while (blob) {
1585 struct allocation_blob *next = blob->next;
1586 free_dinfos(blob);
1587 blob_free(blob, desc->chunking);
1588 blob = next;
1590 clear_data_range_alloc();
1593 void split_comparison_rl(struct range_list *left_orig, int op, struct range_list *right_orig,
1594 struct range_list **left_true_rl, struct range_list **left_false_rl,
1595 struct range_list **right_true_rl, struct range_list **right_false_rl)
1597 struct range_list *left_true, *left_false;
1598 struct range_list *right_true, *right_false;
1599 sval_t min, max;
1601 min = sval_type_min(rl_type(left_orig));
1602 max = sval_type_max(rl_type(left_orig));
1604 left_true = clone_rl(left_orig);
1605 left_false = clone_rl(left_orig);
1606 right_true = clone_rl(right_orig);
1607 right_false = clone_rl(right_orig);
1609 switch (op) {
1610 case '<':
1611 case SPECIAL_UNSIGNED_LT:
1612 left_true = remove_range(left_orig, rl_max(right_orig), max);
1613 if (!sval_is_min(rl_min(right_orig))) {
1614 left_false = remove_range(left_orig, min, sub_one(rl_min(right_orig)));
1617 right_true = remove_range(right_orig, min, rl_min(left_orig));
1618 if (!sval_is_max(rl_max(left_orig)))
1619 right_false = remove_range(right_orig, add_one(rl_max(left_orig)), max);
1620 break;
1621 case SPECIAL_UNSIGNED_LTE:
1622 case SPECIAL_LTE:
1623 if (!sval_is_max(rl_max(right_orig)))
1624 left_true = remove_range(left_orig, add_one(rl_max(right_orig)), max);
1625 left_false = remove_range(left_orig, min, rl_min(right_orig));
1627 if (!sval_is_min(rl_min(left_orig)))
1628 right_true = remove_range(right_orig, min, sub_one(rl_min(left_orig)));
1629 right_false = remove_range(right_orig, rl_max(left_orig), max);
1631 if (sval_cmp(rl_min(left_orig), rl_min(right_orig)) == 0)
1632 left_false = remove_range(left_false, rl_min(left_orig), rl_min(left_orig));
1633 if (sval_cmp(rl_max(left_orig), rl_max(right_orig)) == 0)
1634 right_false = remove_range(right_false, rl_max(left_orig), rl_max(left_orig));
1635 break;
1636 case SPECIAL_EQUAL:
1637 if (!sval_is_max(rl_max(right_orig))) {
1638 left_true = remove_range(left_true, add_one(rl_max(right_orig)), max);
1640 if (!sval_is_min(rl_min(right_orig))) {
1641 left_true = remove_range(left_true, min, sub_one(rl_min(right_orig)));
1643 if (sval_cmp(rl_min(right_orig), rl_max(right_orig)) == 0)
1644 left_false = remove_range(left_orig, rl_min(right_orig), rl_min(right_orig));
1646 if (!sval_is_max(rl_max(left_orig)))
1647 right_true = remove_range(right_true, add_one(rl_max(left_orig)), max);
1648 if (!sval_is_min(rl_min(left_orig)))
1649 right_true = remove_range(right_true, min, sub_one(rl_min(left_orig)));
1650 if (sval_cmp(rl_min(left_orig), rl_max(left_orig)) == 0)
1651 right_false = remove_range(right_orig, rl_min(left_orig), rl_min(left_orig));
1652 break;
1653 case SPECIAL_UNSIGNED_GTE:
1654 case SPECIAL_GTE:
1655 if (!sval_is_min(rl_min(right_orig)))
1656 left_true = remove_range(left_orig, min, sub_one(rl_min(right_orig)));
1657 left_false = remove_range(left_orig, rl_max(right_orig), max);
1659 if (!sval_is_max(rl_max(left_orig)))
1660 right_true = remove_range(right_orig, add_one(rl_max(left_orig)), max);
1661 right_false = remove_range(right_orig, min, rl_min(left_orig));
1663 if (sval_cmp(rl_min(left_orig), rl_min(right_orig)) == 0)
1664 right_false = remove_range(right_false, rl_min(left_orig), rl_min(left_orig));
1665 if (sval_cmp(rl_max(left_orig), rl_max(right_orig)) == 0)
1666 left_false = remove_range(left_false, rl_max(left_orig), rl_max(left_orig));
1667 break;
1668 case '>':
1669 case SPECIAL_UNSIGNED_GT:
1670 left_true = remove_range(left_orig, min, rl_min(right_orig));
1671 if (!sval_is_max(rl_max(right_orig)))
1672 left_false = remove_range(left_orig, add_one(rl_max(right_orig)), max);
1674 right_true = remove_range(right_orig, rl_max(left_orig), max);
1675 if (!sval_is_min(rl_min(left_orig)))
1676 right_false = remove_range(right_orig, min, sub_one(rl_min(left_orig)));
1677 break;
1678 case SPECIAL_NOTEQUAL:
1679 if (!sval_is_max(rl_max(right_orig)))
1680 left_false = remove_range(left_false, add_one(rl_max(right_orig)), max);
1681 if (!sval_is_min(rl_min(right_orig)))
1682 left_false = remove_range(left_false, min, sub_one(rl_min(right_orig)));
1683 if (sval_cmp(rl_min(right_orig), rl_max(right_orig)) == 0)
1684 left_true = remove_range(left_orig, rl_min(right_orig), rl_min(right_orig));
1686 if (!sval_is_max(rl_max(left_orig)))
1687 right_false = remove_range(right_false, add_one(rl_max(left_orig)), max);
1688 if (!sval_is_min(rl_min(left_orig)))
1689 right_false = remove_range(right_false, min, sub_one(rl_min(left_orig)));
1690 if (sval_cmp(rl_min(left_orig), rl_max(left_orig)) == 0)
1691 right_true = remove_range(right_orig, rl_min(left_orig), rl_min(left_orig));
1692 break;
1693 default:
1694 sm_msg("internal error: unhandled comparison %d", op);
1695 return;
1698 if (left_true_rl) {
1699 *left_true_rl = left_true;
1700 *left_false_rl = left_false;
1702 if (right_true_rl) {
1703 *right_true_rl = right_true;
1704 *right_false_rl = right_false;