2 * sparse/smatch_extra.c
4 * Copyright (C) 2008 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
11 * smatch_extra.c is supposed to track the value of every variable.
22 #include "smatch_slist.h"
23 #include "smatch_extra.h"
27 struct string_list
*__ignored_macros
= NULL
;
28 static int in_warn_on_macro()
30 struct statement
*stmt
;
34 stmt
= last_ptr_list((struct ptr_list
*)big_statement_stack
);
35 macro
= get_macro_name(&stmt
->pos
);
39 FOR_EACH_PTR(__ignored_macros
, tmp
) {
40 if (!strcmp(tmp
, macro
))
42 } END_FOR_EACH_PTR(tmp
);
46 struct sm_state
*set_extra_mod(const char *name
, struct symbol
*sym
, struct smatch_state
*state
)
48 if (in_warn_on_macro())
50 remove_from_equiv(name
, sym
);
51 return set_state(SMATCH_EXTRA
, name
, sym
, state
);
54 struct sm_state
*set_extra_expr_mod(struct expression
*expr
, struct smatch_state
*state
)
56 if (in_warn_on_macro())
58 remove_from_equiv_expr(expr
);
59 return set_state_expr(SMATCH_EXTRA
, expr
, state
);
63 * This is for return_implies_state() hooks which modify a SMATCH_EXTRA state
65 void set_extra_expr_nomod(struct expression
*expr
, struct smatch_state
*state
)
68 struct smatch_state
*orig_state
;
70 orig_state
= get_state_expr(SMATCH_EXTRA
, expr
);
72 if (!orig_state
|| !get_dinfo(orig_state
)->related
) {
73 set_state_expr(SMATCH_EXTRA
, expr
, state
);
77 FOR_EACH_PTR(get_dinfo(orig_state
)->related
, rel
) {
78 sm_msg("setting %s to %s", rel
->name
, state
->name
);
79 set_state(SMATCH_EXTRA
, rel
->name
, rel
->sym
, state
);
80 add_equiv(state
, rel
->name
, rel
->sym
);
81 } END_FOR_EACH_PTR(rel
);
84 void set_extra_true_false(const char *name
, struct symbol
*sym
,
85 struct smatch_state
*true_state
,
86 struct smatch_state
*false_state
)
89 struct smatch_state
*orig_state
;
91 if (in_warn_on_macro())
94 orig_state
= get_state(SMATCH_EXTRA
, name
, sym
);
96 if (!orig_state
|| !get_dinfo(orig_state
)->related
) {
97 set_true_false_states(SMATCH_EXTRA
, name
, sym
, true_state
, false_state
);
101 // FIXME!!!! equiv => related
102 FOR_EACH_PTR(get_dinfo(orig_state
)->related
, rel
) {
103 set_true_false_states(SMATCH_EXTRA
, rel
->name
, rel
->sym
,
104 true_state
, false_state
);
106 add_equiv(true_state
, rel
->name
, rel
->sym
);
108 add_equiv(false_state
, rel
->name
, rel
->sym
);
109 } END_FOR_EACH_PTR(rel
);
112 struct data_info
*get_dinfo(struct smatch_state
*state
)
116 return (struct data_info
*)state
->data
;
120 struct smatch_state
*filter_range(struct smatch_state
*orig
,
121 long long filter_min
, long long filter_max
)
123 struct smatch_state
*ret
;
124 struct data_info
*orig_info
;
125 struct data_info
*ret_info
;
128 orig
= extra_undefined();
129 orig_info
= get_dinfo(orig
);
130 ret
= alloc_extra_state_empty();
131 ret_info
= get_dinfo(ret
);
132 ret_info
->value_ranges
= remove_range(orig_info
->value_ranges
, filter_min
, filter_max
);
133 ret
->name
= show_ranges(ret_info
->value_ranges
);
137 struct smatch_state
*add_filter(struct smatch_state
*orig
, long long num
)
139 return filter_range(orig
, num
, num
);
142 static struct smatch_state
*merge_func(const char *name
, struct symbol
*sym
,
143 struct smatch_state
*s1
,
144 struct smatch_state
*s2
)
146 struct data_info
*info1
= get_dinfo(s1
);
147 struct data_info
*info2
= get_dinfo(s2
);
148 struct data_info
*ret_info
;
149 struct smatch_state
*tmp
;
150 struct range_list
*value_ranges
;
151 struct relation
*rel
;
152 struct relation
*new;
154 value_ranges
= range_list_union(info1
->value_ranges
, info2
->value_ranges
);
155 tmp
= alloc_extra_state_empty();
156 ret_info
= get_dinfo(tmp
);
157 ret_info
->value_ranges
= value_ranges
;
158 tmp
->name
= show_ranges(ret_info
->value_ranges
);
159 FOR_EACH_PTR(info1
->related
, rel
) {
160 new = get_common_relationship(info2
, rel
->op
, rel
->name
, rel
->sym
);
162 add_related(tmp
, new->op
, new->name
, new->sym
);
163 } END_FOR_EACH_PTR(rel
);
167 static struct sm_state
*handle_canonical_while_count_down(struct statement
*loop
)
169 struct expression
*iter_var
;
170 struct expression
*condition
;
174 condition
= strip_expr(loop
->iterator_pre_condition
);
177 if (condition
->type
!= EXPR_PREOP
&& condition
->type
!= EXPR_POSTOP
)
179 if (condition
->op
!= SPECIAL_DECREMENT
)
182 iter_var
= condition
->unop
;
183 sm
= get_sm_state_expr(SMATCH_EXTRA
, iter_var
);
186 if (get_dinfo_min(get_dinfo(sm
->state
)) < 0)
188 start
= get_dinfo_max(get_dinfo(sm
->state
));
191 if (start
!= whole_range
.max
)
194 if (condition
->type
== EXPR_PREOP
)
195 set_extra_expr_mod(iter_var
, alloc_extra_state_range(1, start
));
196 if (condition
->type
== EXPR_POSTOP
)
197 set_extra_expr_mod(iter_var
, alloc_extra_state_range(0, start
));
198 return get_sm_state_expr(SMATCH_EXTRA
, iter_var
);
201 static struct sm_state
*handle_canonical_for_inc(struct expression
*iter_expr
,
202 struct expression
*condition
)
204 struct expression
*iter_var
;
209 iter_var
= iter_expr
->unop
;
210 sm
= get_sm_state_expr(SMATCH_EXTRA
, iter_var
);
213 if (!get_single_value_from_dinfo(get_dinfo(sm
->state
), &start
))
215 if (!get_implied_value(condition
->right
, &end
))
216 end
= whole_range
.max
;
217 if (get_sm_state_expr(SMATCH_EXTRA
, condition
->left
) != sm
)
220 switch (condition
->op
) {
221 case SPECIAL_NOTEQUAL
:
223 if (end
!= whole_range
.max
)
233 set_extra_expr_mod(iter_var
, alloc_extra_state_range(start
, end
));
234 return get_sm_state_expr(SMATCH_EXTRA
, iter_var
);
237 static struct sm_state
*handle_canonical_for_dec(struct expression
*iter_expr
,
238 struct expression
*condition
)
240 struct expression
*iter_var
;
245 iter_var
= iter_expr
->unop
;
246 sm
= get_sm_state_expr(SMATCH_EXTRA
, iter_var
);
249 if (!get_single_value_from_dinfo(get_dinfo(sm
->state
), &start
))
251 if (!get_implied_value(condition
->right
, &end
))
252 end
= whole_range
.max
;
253 if (get_sm_state_expr(SMATCH_EXTRA
, condition
->left
) != sm
)
256 switch (condition
->op
) {
257 case SPECIAL_NOTEQUAL
:
259 if (end
!= whole_range
.min
)
269 set_extra_expr_mod(iter_var
, alloc_extra_state_range(end
, start
));
270 return get_sm_state_expr(SMATCH_EXTRA
, iter_var
);
273 static struct sm_state
*handle_canonical_for_loops(struct statement
*loop
)
275 struct expression
*iter_expr
;
276 struct expression
*condition
;
278 if (!loop
->iterator_post_statement
)
280 if (loop
->iterator_post_statement
->type
!= STMT_EXPRESSION
)
282 iter_expr
= loop
->iterator_post_statement
->expression
;
283 if (!loop
->iterator_pre_condition
)
285 if (loop
->iterator_pre_condition
->type
!= EXPR_COMPARE
)
287 condition
= loop
->iterator_pre_condition
;
289 if (iter_expr
->op
== SPECIAL_INCREMENT
)
290 return handle_canonical_for_inc(iter_expr
, condition
);
291 if (iter_expr
->op
== SPECIAL_DECREMENT
)
292 return handle_canonical_for_dec(iter_expr
, condition
);
296 struct sm_state
*__extra_handle_canonical_loops(struct statement
*loop
, struct state_list
**slist
)
298 struct sm_state
*ret
;
300 __push_fake_cur_slist();;
301 if (!loop
->iterator_post_statement
)
302 ret
= handle_canonical_while_count_down(loop
);
304 ret
= handle_canonical_for_loops(loop
);
305 *slist
= __pop_fake_cur_slist();
309 int __iterator_unchanged(struct sm_state
*sm
)
313 if (get_sm_state(my_id
, sm
->name
, sm
->sym
) == sm
)
318 static void while_count_down_after(struct sm_state
*sm
, struct expression
*condition
)
320 long long after_value
;
322 /* paranoid checking. prolly not needed */
323 condition
= strip_expr(condition
);
326 if (condition
->type
!= EXPR_PREOP
&& condition
->type
!= EXPR_POSTOP
)
328 if (condition
->op
!= SPECIAL_DECREMENT
)
330 after_value
= get_dinfo_min(get_dinfo(sm
->state
));
332 set_extra_mod(sm
->name
, sm
->sym
, alloc_extra_state(after_value
));
335 void __extra_pre_loop_hook_after(struct sm_state
*sm
,
336 struct statement
*iterator
,
337 struct expression
*condition
)
339 struct expression
*iter_expr
;
344 struct smatch_state
*state
;
345 struct data_info
*dinfo
;
349 while_count_down_after(sm
, condition
);
353 iter_expr
= iterator
->expression
;
355 if (condition
->type
!= EXPR_COMPARE
)
357 if (!get_value(condition
->left
, &value
)) {
358 if (!get_value(condition
->right
, &value
))
363 name
= get_variable_from_expr(condition
->left
, &sym
);
365 name
= get_variable_from_expr(condition
->right
, &sym
);
368 if (sym
!= sm
->sym
|| strcmp(name
, sm
->name
))
370 state
= get_state(my_id
, name
, sym
);
371 dinfo
= get_dinfo(state
);
372 min
= get_dinfo_min(dinfo
);
373 max
= get_dinfo_max(dinfo
);
374 if (iter_expr
->op
== SPECIAL_INCREMENT
&&
375 min
!= whole_range
.min
&&
376 max
== whole_range
.max
) {
377 set_extra_mod(name
, sym
, alloc_extra_state(min
));
378 } else if (min
== whole_range
.min
&& max
!= whole_range
.max
) {
379 set_extra_mod(name
, sym
, alloc_extra_state(max
));
386 static struct smatch_state
*unmatched_state(struct sm_state
*sm
)
388 return extra_undefined();
391 static void match_function_call(struct expression
*expr
)
393 struct expression
*tmp
;
395 FOR_EACH_PTR(expr
->args
, tmp
) {
396 if (tmp
->type
== EXPR_PREOP
&& tmp
->op
== '&') {
397 remove_from_equiv_expr(tmp
->unop
);
398 set_state_expr(SMATCH_EXTRA
, tmp
->unop
, extra_undefined());
400 } END_FOR_EACH_PTR(tmp
);
403 static void set_equiv(struct sm_state
*right_sm
, struct expression
*left
)
405 struct smatch_state
*state
;
406 struct data_info
*dinfo
;
407 struct relation
*rel
;
411 name
= get_variable_from_expr(left
, &sym
);
415 remove_from_equiv(name
, sym
);
417 state
= clone_extra_state(right_sm
->state
);
418 dinfo
= get_dinfo(state
);
420 add_equiv(state
, right_sm
->name
, right_sm
->sym
);
421 add_equiv(state
, name
, sym
);
423 FOR_EACH_PTR(dinfo
->related
, rel
) {
424 struct sm_state
*new_sm
;
426 new_sm
= clone_sm(right_sm
);
427 new_sm
->name
= rel
->name
;
428 new_sm
->sym
= rel
->sym
;
429 new_sm
->state
= state
;
431 } END_FOR_EACH_PTR(rel
);
436 static void match_assign(struct expression
*expr
)
438 struct expression
*left
;
439 struct expression
*right
;
440 struct sm_state
*right_sm
;
445 long long min
= whole_range
.min
;
446 long long max
= whole_range
.max
;
449 if (__is_condition_assign(expr
))
451 left
= strip_expr(expr
->left
);
452 name
= get_variable_from_expr(left
, &sym
);
455 right
= strip_expr(expr
->right
);
456 while (right
->type
== EXPR_ASSIGNMENT
&& right
->op
== '=')
457 right
= strip_expr(right
->left
);
459 right_sm
= get_sm_state_expr(SMATCH_EXTRA
, right
);
460 if (expr
->op
== '=' && right_sm
) {
461 set_equiv(right_sm
, left
);
465 if (expr
->op
== '=') {
466 struct range_list
*rl
= NULL
;
468 if (get_implied_range_list(right
, &rl
)) {
469 set_extra_mod(name
, sym
, alloc_extra_state_range_list(rl
));
471 struct symbol
*type
= get_type(right
);
473 if (type
&& type_unsigned(type
))
475 set_extra_mod(name
, sym
, alloc_extra_state_range(min
, max
));
480 known
= get_implied_value(right
, &value
);
481 if (expr
->op
== SPECIAL_ADD_ASSIGN
) {
482 if (get_implied_min(left
, &tmp
)) {
488 if (!inside_loop() && known
&& get_implied_max(left
, &tmp
))
491 if (expr
->op
== SPECIAL_SUB_ASSIGN
) {
492 if (get_implied_max(left
, &tmp
)) {
498 if (!inside_loop() && known
&& get_implied_min(left
, &tmp
))
501 set_extra_mod(name
, sym
, alloc_extra_state_range(min
, max
));
506 static void unop_expr(struct expression
*expr
)
510 long long min
= whole_range
.min
;
511 long long max
= whole_range
.max
;
521 name
= get_variable_from_expr(expr
->unop
, &sym
);
524 if (expr
->op
== SPECIAL_INCREMENT
) {
525 if (get_implied_min(expr
->unop
, &val
))
527 if (!inside_loop() && get_implied_max(expr
->unop
, &val
))
530 if (expr
->op
== SPECIAL_DECREMENT
) {
531 if (get_implied_max(expr
->unop
, &val
))
533 if (!inside_loop() && get_implied_min(expr
->unop
, &val
))
536 set_extra_mod(name
, sym
, alloc_extra_state_range(min
, max
));
541 static void delete_state_tracker(struct tracker
*t
)
543 remove_from_equiv(t
->name
, t
->sym
);
544 delete_state(t
->owner
, t
->name
, t
->sym
);
547 static void scoped_state_extra(const char *name
, struct symbol
*sym
)
551 t
= alloc_tracker(SMATCH_EXTRA
, name
, sym
);
552 add_scope_hook((scope_hook
*)&delete_state_tracker
, t
);
555 static void match_declarations(struct symbol
*sym
)
560 name
= sym
->ident
->name
;
561 if (!sym
->initializer
) {
562 set_state(SMATCH_EXTRA
, name
, sym
, extra_undefined());
563 scoped_state_extra(name
, sym
);
568 static void match_function_def(struct symbol
*sym
)
572 FOR_EACH_PTR(sym
->ctype
.base_type
->arguments
, arg
) {
576 set_state(my_id
, arg
->ident
->name
, arg
, extra_undefined());
577 } END_FOR_EACH_PTR(arg
);
580 static int last_stmt_val(struct statement
*stmt
, long long *val
)
582 struct expression
*expr
;
587 stmt
= last_ptr_list((struct ptr_list
*)stmt
->stmts
);
588 if (stmt
->type
!= STMT_EXPRESSION
)
590 expr
= stmt
->expression
;
591 return get_value(expr
, val
);
594 static void match_comparison(struct expression
*expr
)
599 struct smatch_state
*true_state
;
600 struct smatch_state
*false_state
;
601 struct smatch_state
*orig
;
603 int comparison
= expr
->op
;
604 struct expression
*varies
;
607 varies
= strip_expr(expr
->right
);
608 if (!get_implied_value(expr
->left
, &fixed
)) {
609 if (!get_implied_value(expr
->right
, &fixed
))
611 varies
= strip_expr(expr
->left
);
615 if (varies
->op
== SPECIAL_INCREMENT
|| varies
->op
== SPECIAL_DECREMENT
)
616 varies
= varies
->unop
;
617 if (varies
->type
== EXPR_CALL
) {
618 function_comparison(comparison
, varies
, fixed
, left
);
622 name
= get_variable_from_expr(varies
, &sym
);
626 orig
= get_state(my_id
, name
, sym
);
628 orig
= extra_undefined();
630 switch (comparison
) {
632 case SPECIAL_UNSIGNED_LT
:
634 true_state
= filter_range(orig
, fixed
, whole_range
.max
);
635 false_state
= filter_range(orig
, whole_range
.min
, fixed
- 1);
637 true_state
= filter_range(orig
, whole_range
.min
, fixed
);
638 false_state
= filter_range(orig
, fixed
+ 1, whole_range
.max
);
641 case SPECIAL_UNSIGNED_LTE
:
644 true_state
= filter_range(orig
, fixed
+ 1, whole_range
.max
);
645 false_state
= filter_range(orig
, whole_range
.min
, fixed
);
647 true_state
= filter_range(orig
, whole_range
.min
, fixed
- 1);
648 false_state
= filter_range(orig
, fixed
, whole_range
.max
);
652 if (possibly_true(SPECIAL_EQUAL
, get_dinfo(orig
), fixed
, fixed
))
653 true_state
= alloc_extra_state(fixed
);
655 true_state
= alloc_extra_state_empty();
656 false_state
= filter_range(orig
, fixed
, fixed
);
658 case SPECIAL_UNSIGNED_GTE
:
661 true_state
= filter_range(orig
, whole_range
.min
, fixed
- 1);
662 false_state
= filter_range(orig
, fixed
, whole_range
.max
);
664 true_state
= filter_range(orig
, fixed
+ 1, whole_range
.max
);
665 false_state
= filter_range(orig
, whole_range
.min
, fixed
);
669 case SPECIAL_UNSIGNED_GT
:
671 true_state
= filter_range(orig
, whole_range
.min
, fixed
);
672 false_state
= filter_range(orig
, fixed
+ 1, whole_range
.max
);
674 true_state
= filter_range(orig
, fixed
, whole_range
.max
);
675 false_state
= filter_range(orig
, whole_range
.min
, fixed
- 1);
678 case SPECIAL_NOTEQUAL
:
679 true_state
= filter_range(orig
, fixed
, fixed
);
680 if (possibly_true(SPECIAL_EQUAL
, get_dinfo(orig
), fixed
, fixed
))
681 false_state
= alloc_extra_state(fixed
);
683 false_state
= alloc_extra_state_empty();
686 sm_msg("unhandled comparison %d\n", comparison
);
689 set_extra_true_false(name
, sym
, true_state
, false_state
);
694 /* this is actually hooked from smatch_implied.c... it's hacky, yes */
695 void __extra_match_condition(struct expression
*expr
)
699 struct smatch_state
*pre_state
;
700 struct smatch_state
*true_state
;
701 struct smatch_state
*false_state
;
703 expr
= strip_expr(expr
);
704 switch (expr
->type
) {
706 function_comparison(SPECIAL_NOTEQUAL
, expr
, 0, 1);
711 name
= get_variable_from_expr(expr
, &sym
);
714 pre_state
= get_state(my_id
, name
, sym
);
715 true_state
= add_filter(pre_state
, 0);
716 if (possibly_true(SPECIAL_EQUAL
, get_dinfo(pre_state
), 0, 0))
717 false_state
= alloc_extra_state(0);
719 false_state
= alloc_extra_state_empty();
720 set_extra_true_false(name
, sym
, true_state
, false_state
);
724 match_comparison(expr
);
726 case EXPR_ASSIGNMENT
:
727 __extra_match_condition(expr
->left
);
732 /* returns 1 if it is not possible for expr to be value, otherwise returns 0 */
733 int implied_not_equal(struct expression
*expr
, long long val
)
737 struct smatch_state
*state
;
741 if (get_value(expr
, &expr_val
)) {
742 return expr_val
!= val
;
744 name
= get_variable_from_expr(expr
, &sym
);
747 state
= get_state(my_id
, name
, sym
);
748 if (!state
|| !state
->data
)
750 ret
= !possibly_false(SPECIAL_NOTEQUAL
, get_dinfo(state
), val
, 1);
756 int known_condition_true(struct expression
*expr
)
759 struct statement
*stmt
;
764 if (get_value(expr
, &tmp
) && tmp
)
767 expr
= strip_expr(expr
);
768 switch (expr
->type
) {
770 if (expr
->op
== '!') {
771 if (known_condition_false(expr
->unop
))
775 stmt
= get_expression_statement(expr
);
776 if (last_stmt_val(stmt
, &tmp
) && tmp
== 1)
785 int known_condition_false(struct expression
*expr
)
788 struct statement
*stmt
;
796 switch (expr
->type
) {
798 if (expr
->op
== '!') {
799 if (known_condition_true(expr
->unop
))
803 stmt
= get_expression_statement(expr
);
804 if (last_stmt_val(stmt
, &tmp
) && tmp
== 0)
808 if (sym_name_is("__builtin_constant_p", expr
->fn
))
817 struct range_list
*get_range_list(struct expression
*expr
)
821 struct range_list
*ret
= NULL
;
822 struct smatch_state
*state
;
824 state
= get_state_expr(SMATCH_EXTRA
, expr
);
826 return clone_range_list(get_dinfo(state
)->value_ranges
);
827 if (!get_absolute_min(expr
, &min
))
829 if (!get_absolute_max(expr
, &max
))
831 add_range(&ret
, min
, max
);
835 static int do_comparison(struct expression
*expr
)
837 struct range_list
*left_ranges
;
838 struct range_list
*right_ranges
;
839 int poss_true
, poss_false
;
841 left_ranges
= get_range_list(expr
->left
);
842 right_ranges
= get_range_list(expr
->right
);
844 poss_true
= possibly_true_range_lists(left_ranges
, expr
->op
, right_ranges
);
845 poss_false
= possibly_false_range_lists(left_ranges
, expr
->op
, right_ranges
);
847 free_range_list(&left_ranges
);
848 free_range_list(&right_ranges
);
850 if (!poss_true
&& !poss_false
)
852 if (poss_true
&& !poss_false
)
854 if (!poss_true
&& poss_false
)
859 int implied_condition_true(struct expression
*expr
)
861 struct statement
*stmt
;
868 if (get_implied_value(expr
, &tmp
) && tmp
)
871 if (expr
->type
== EXPR_POSTOP
)
872 return implied_condition_true(expr
->unop
);
874 if (expr
->type
== EXPR_PREOP
&& expr
->op
== SPECIAL_DECREMENT
)
875 return implied_not_equal(expr
->unop
, 1);
876 if (expr
->type
== EXPR_PREOP
&& expr
->op
== SPECIAL_INCREMENT
)
877 return implied_not_equal(expr
->unop
, -1);
879 expr
= strip_expr(expr
);
880 switch (expr
->type
) {
882 if (do_comparison(expr
) == 1)
886 if (expr
->op
== '!') {
887 if (implied_condition_false(expr
->unop
))
891 stmt
= get_expression_statement(expr
);
892 if (last_stmt_val(stmt
, &val
) && val
== 1)
896 if (implied_not_equal(expr
, 0) == 1)
903 int implied_condition_false(struct expression
*expr
)
905 struct statement
*stmt
;
906 struct expression
*tmp
;
915 switch (expr
->type
) {
917 if (do_comparison(expr
) == 2)
920 if (expr
->op
== '!') {
921 if (implied_condition_true(expr
->unop
))
925 stmt
= get_expression_statement(expr
);
926 if (last_stmt_val(stmt
, &val
) && val
== 0)
928 tmp
= strip_expr(expr
);
930 return implied_condition_false(tmp
);
933 if (get_implied_value(expr
, &val
) && val
== 0)
940 int get_implied_range_list(struct expression
*expr
, struct range_list
**rl
)
943 struct smatch_state
*state
;
945 expr
= strip_expr(expr
);
947 state
= get_state_expr(my_id
, expr
);
949 *rl
= clone_range_list(get_dinfo(state
)->value_ranges
);
953 if (get_implied_value(expr
, &val
)) {
955 add_range(rl
, val
, val
);
959 if (expr
->type
== EXPR_BINOP
&& expr
->op
== '%') {
960 if (!get_implied_value(expr
->right
, &val
))
963 add_range(rl
, 0, val
- 1);
970 int is_whole_range(struct smatch_state
*state
)
972 struct data_info
*dinfo
;
973 struct data_range
*drange
;
977 dinfo
= get_dinfo(state
);
978 drange
= first_ptr_list((struct ptr_list
*)dinfo
->value_ranges
);
979 if (drange
->min
== whole_range
.min
&& drange
->max
== whole_range
.max
)
984 void register_smatch_extra(int id
)
987 add_merge_hook(my_id
, &merge_func
);
988 add_unmatched_state_hook(my_id
, &unmatched_state
);
989 add_hook(&unop_expr
, OP_HOOK
);
990 add_hook(&match_function_def
, FUNC_DEF_HOOK
);
991 add_hook(&match_function_call
, FUNCTION_CALL_HOOK
);
992 add_hook(&match_assign
, ASSIGNMENT_HOOK
);
993 add_hook(&match_declarations
, DECLARATION_HOOK
);