smatch_data: update the data director to the latest code
[smatch.git] / smatch_capped.c
blobabb2be8ff042ac0f137efa0f50db57f6ad6be24b
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 expr = strip_expr(expr);
32 if (!expr)
33 return 0;
35 if (expr->type == EXPR_BINOP) {
36 if (expr->op == '&')
37 return 1;
38 if (expr->op == SPECIAL_RIGHTSHIFT)
39 return 1;
40 if (expr->op == '%')
41 return is_capped(expr->right);
42 if (!is_capped(expr->left))
43 return 0;
44 if (expr->op == '/')
45 return 1;
46 if (!is_capped(expr->right))
47 return 0;
48 return 1;
50 if (get_implied_max(expr, &val))
51 return 1;
52 if (get_state_expr(my_id, expr) == &capped)
53 return 1;
54 return 0;
57 void set_param_capped_data(const char *name, struct symbol *sym, char *key, char *value)
59 char fullname[256];
61 if (strncmp(key, "$$", 2))
62 return;
63 snprintf(fullname, 256, "%s%s", name, key + 2);
64 set_state(my_id, fullname, sym, &capped);
67 static void match_condition(struct expression *expr)
69 struct smatch_state *left_true = NULL;
70 struct smatch_state *left_false = NULL;
71 struct smatch_state *right_true = NULL;
72 struct smatch_state *right_false = NULL;
75 if (expr->type != EXPR_COMPARE)
76 return;
78 switch (expr->op) {
79 case '<':
80 case SPECIAL_LTE:
81 case SPECIAL_UNSIGNED_LT:
82 case SPECIAL_UNSIGNED_LTE:
83 left_true = &capped;
84 right_false = &capped;
85 break;
86 case '>':
87 case SPECIAL_GTE:
88 case SPECIAL_UNSIGNED_GT:
89 case SPECIAL_UNSIGNED_GTE:
90 left_false = &capped;
91 right_true = &capped;
92 break;
93 case SPECIAL_EQUAL:
94 left_true = &capped;
95 right_true = &capped;
96 break;
97 case SPECIAL_NOTEQUAL:
98 left_false = &capped;
99 right_false = &capped;
100 break;
102 default:
103 return;
106 set_true_false_states_expr(my_id, expr->right, right_true, right_false);
107 set_true_false_states_expr(my_id, expr->left, left_true, left_false);
110 static void match_min_assign(const char *fn, struct expression *expr, void *unused)
112 set_state_expr(my_id, expr->left, &capped);
115 static void match_assign(struct expression *expr)
117 if (is_capped(expr->right)) {
118 set_state_expr(my_id, expr->left, &capped);
119 } else {
120 if (get_state_expr(my_id, expr->left))
121 set_state_expr(my_id, expr->left, &uncapped);
125 static void match_caller_info(struct expression *expr)
127 struct expression *tmp;
128 char *func;
129 int i;
131 func = get_fnptr_name(expr->fn);
132 if (!func)
133 return;
135 i = 0;
136 FOR_EACH_PTR(expr->args, tmp) {
137 if (is_capped(tmp))
138 sm_msg("info: passes capped_data %s %d '$$' %s", func,
139 i, is_static(expr->fn) ? "static" : "global");
140 i++;
141 } END_FOR_EACH_PTR(tmp);
144 static void struct_member_callback(char *fn, char *global_static, int param, char *printed_name, struct smatch_state *state)
146 if (state != &capped)
147 return;
148 sm_msg("info: passes capped_data '%s' %d '%s' %s", fn, param, printed_name, global_static);
151 void register_capped(int id)
153 my_id = id;
155 add_definition_db_callback(set_param_capped_data, CAPPED_DATA);
156 add_hook(&match_condition, CONDITION_HOOK);
157 add_hook(&match_assign, ASSIGNMENT_HOOK);
158 add_macro_assign_hook("min", &match_min_assign, NULL);
159 add_macro_assign_hook("min_t", &match_min_assign, NULL);
160 if (option_info) {
161 add_hook(&match_caller_info, FUNCTION_CALL_HOOK);
162 add_member_info_callback(my_id, struct_member_callback);