helper: remove bogus parens from get_variable_from_expr() output
[smatch.git] / smatch_capped.c
blob96df0e42f5b00617c748e585c0117741137c05a8
1 /*
2 * smatch/smatch_capped.c
4 * Copyright (C) 2011 Oracle. All rights reserved.
6 * Licensed under the Open Software License version 1.1
8 */
11 * This is trying to make a list of the variables which
12 * have capped values. Sometimes we don't know what the
13 * cap is, for example if we are comparing variables but
14 * we don't know the values of the variables. In that
15 * case we only know that our variable is capped and we
16 * sort that information here.
19 #include "smatch.h"
20 #include "smatch_slist.h"
22 static int my_id;
24 STATE(capped);
25 STATE(uncapped);
27 int is_capped(struct expression *expr)
29 long long val;
31 if (expr->type == EXPR_BINOP) {
32 if (expr->op == '&')
33 return 1;
34 if (expr->op == SPECIAL_RIGHTSHIFT)
35 return 1;
36 if (expr->op == '%')
37 return is_capped(expr->right);
38 if (!is_capped(expr->left))
39 return 0;
40 if (expr->op == '/')
41 return 1;
42 if (!is_capped(expr->right))
43 return 0;
44 return 1;
46 if (get_implied_max(expr, &val))
47 return 1;
48 if (get_state_expr(my_id, expr) == &capped)
49 return 1;
50 return 0;
53 static void match_condition(struct expression *expr)
55 struct smatch_state *left_true = NULL;
56 struct smatch_state *left_false = NULL;
57 struct smatch_state *right_true = NULL;
58 struct smatch_state *right_false = NULL;
61 if (expr->type != EXPR_COMPARE)
62 return;
64 switch (expr->op) {
65 case '<':
66 case SPECIAL_LTE:
67 case SPECIAL_UNSIGNED_LT:
68 case SPECIAL_UNSIGNED_LTE:
69 left_true = &capped;
70 right_false = &capped;
71 break;
72 case '>':
73 case SPECIAL_GTE:
74 case SPECIAL_UNSIGNED_GT:
75 case SPECIAL_UNSIGNED_GTE:
76 left_false = &capped;
77 right_true = &capped;
78 break;
79 case SPECIAL_EQUAL:
80 left_true = &capped;
81 right_true = &capped;
82 break;
83 case SPECIAL_NOTEQUAL:
84 left_false = &capped;
85 right_false = &capped;
86 break;
88 default:
89 return;
92 set_true_false_states_expr(my_id, expr->right, right_true, right_false);
93 set_true_false_states_expr(my_id, expr->left, left_true, left_false);
96 static void match_min_assign(const char *fn, struct expression *expr, void *unused)
98 set_state_expr(my_id, expr->left, &capped);
101 static void match_assign(struct expression *expr)
103 if (is_capped(expr->right)) {
104 set_state_expr(my_id, expr->left, &capped);
105 } else {
106 if (get_state_expr(my_id, expr->left))
107 set_state_expr(my_id, expr->left, &uncapped);
111 void register_capped(int id)
113 my_id = id;
115 add_hook(&match_condition, CONDITION_HOOK);
116 add_hook(&match_assign, ASSIGNMENT_HOOK);
117 add_macro_assign_hook("min", &match_min_assign, NULL);
118 add_macro_assign_hook("min_t", &match_min_assign, NULL);