ssa: introduce ssa_set_all_states()
[smatch.git] / smatch_bits.c
blob6608d7125e4f32cb846271b1271e6641fbb76c53
1 /*
2 * Copyright (C) 2015 Oracle.
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
19 * This is to track when variables are masked away.
23 #include "smatch.h"
24 #include "smatch_extra.h"
25 #include "smatch_slist.h"
27 static int my_id;
29 static const struct bit_info unknown_bit_info = {
30 .possible = -1ULL,
33 ALLOCATOR(bit_info, "bit data");
34 struct bit_info *alloc_bit_info(unsigned long long set, unsigned long long possible)
36 struct bit_info *bit_info = __alloc_bit_info(0);
38 bit_info->set = set;
39 bit_info->possible = possible;
41 return bit_info;
44 void set_bits_modified_expr(struct expression *expr, struct smatch_state *state)
46 __set_param_modified_helper(expr, state);
47 set_state_expr(my_id, expr, state);
50 void set_bits_modified_expr_sym(const char *name, struct symbol *sym, struct smatch_state *state)
52 __set_param_modified_helper_sym(name, sym, state);
53 set_state(my_id, name, sym, state);
55 struct smatch_state *alloc_bstate(unsigned long long set, unsigned long long possible)
57 struct smatch_state *state;
58 char buf[64];
60 state = __alloc_smatch_state(0);
61 snprintf(buf, sizeof(buf), "0x%llx + 0x%llx", set, possible);
62 state->name = alloc_sname(buf);
63 state->data = alloc_bit_info(set, possible);
65 return state;
68 struct bit_info *rl_to_binfo(struct range_list *rl)
70 struct bit_info *ret = __alloc_bit_info(0);
71 sval_t sval;
73 if (rl_to_sval(rl, &sval)) {
74 ret->set = sval.uvalue;
75 ret->possible = sval.uvalue;
77 return ret;
80 ret->set = 0;
81 ret->possible = sval_fls_mask(rl_max(rl));
82 // FIXME: what about negatives?
84 return ret;
87 static int is_unknown_binfo(struct symbol *type, struct bit_info *binfo)
89 if (!type)
90 type = &ullong_ctype;
92 if (binfo->set != 0)
93 return 0;
94 if (binfo->possible < (-1ULL >> (64 - type_bits(type))))
95 return 0;
97 return 1;
100 static struct smatch_state *unmatched_state(struct sm_state *sm)
102 struct smatch_state *estate;
103 struct symbol *type;
104 unsigned long long possible;
105 struct bit_info *p;
107 estate = get_state(SMATCH_EXTRA, sm->name, sm->sym);
108 if (estate_rl(estate)) {
109 p = rl_to_binfo(estate_rl(estate));
110 return alloc_bstate(p->set, p->possible);
113 type = estate_type(estate);
114 if (!type)
115 return alloc_bstate(0, -1ULL);
117 if (type_bits(type) == 64)
118 possible = -1ULL;
119 else
120 possible = (1ULL << type_bits(type)) - 1;
122 return alloc_bstate(0, possible);
125 static bool is_loop_iterator(struct expression *expr)
127 struct statement *pre_stmt, *loop_stmt;
129 pre_stmt = expr_get_parent_stmt(expr);
130 if (!pre_stmt || pre_stmt->type != STMT_EXPRESSION)
131 return false;
133 loop_stmt = stmt_get_parent_stmt(pre_stmt);
134 if (!loop_stmt || loop_stmt->type != STMT_ITERATOR)
135 return false;
136 if (loop_stmt->iterator_pre_statement != pre_stmt)
137 return false;
139 return true;
142 static bool handled_by_assign_hook(struct expression *expr)
144 if (!expr || expr->type != EXPR_ASSIGNMENT)
145 return false;
146 if (__in_fake_assign)
147 return false;
148 if (is_loop_iterator(expr))
149 return false;
151 if (expr->op == '=' ||
152 expr->op == SPECIAL_OR_ASSIGN ||
153 expr->op == SPECIAL_AND_ASSIGN)
154 return true;
156 return false;
159 static void match_modify(struct sm_state *sm, struct expression *mod_expr)
161 // FIXME: we really need to store the type
163 if (handled_by_assign_hook(mod_expr))
164 return;
166 set_bits_modified_expr_sym(sm->name, sm->sym, alloc_bstate(0, -1ULL));
169 int binfo_equiv(struct bit_info *one, struct bit_info *two)
171 if (one->set == two->set &&
172 one->possible == two->possible)
173 return 1;
174 return 0;
177 struct smatch_state *merge_bstates(struct smatch_state *one_state, struct smatch_state *two_state)
179 struct bit_info *one, *two;
181 one = one_state->data;
182 two = two_state->data;
184 if (binfo_equiv(one, two))
185 return one_state;
187 return alloc_bstate(one->set & two->set, one->possible | two->possible);
191 * The combine_bit_info() takes two bit_infos and takes creates the most
192 * accurate picture we can assuming both are true. Or it returns unknown if
193 * the information is logically impossible.
195 * Which means that it takes the | of the ->set bits and the & of the possibly
196 * set bits, which is the opposite of what merge_bstates() does.
199 static struct bit_info *combine_bit_info(struct bit_info *one, struct bit_info *two)
201 struct bit_info *ret = __alloc_bit_info(0);
203 if ((one->set & two->possible) != one->set)
204 return alloc_bit_info(0, -1ULL);
205 if ((two->set & one->possible) != two->set)
206 return alloc_bit_info(0, -1ULL);
208 ret->set = one->set | two->set;
209 ret->possible = one->possible & two->possible;
211 return ret;
214 static struct bit_info *binfo_AND(struct bit_info *left, struct bit_info *right)
216 unsigned long long set = 0;
217 unsigned long long possible = -1ULL;
219 if (!left && !right) {
220 /* nothing */
221 } else if (!left) {
222 possible = right->possible;
223 } else if (!right) {
224 possible = left->possible;
225 } else {
226 set = left->set & right->set;
227 possible = left->possible & right->possible;
230 return alloc_bit_info(set, possible);
233 static struct bit_info *binfo_OR(struct bit_info *left, struct bit_info *right)
235 unsigned long long set = 0;
236 unsigned long long possible = -1ULL;
238 if (!left && !right) {
239 /* nothing */
240 } else if (!left) {
241 set = right->set;
242 } else if (!right) {
243 set = left->set;
244 } else {
245 set = left->set | right->set;
246 possible = left->possible | right->possible;
249 return alloc_bit_info(set, possible);
252 struct bit_info *get_bit_info(struct expression *expr)
254 struct range_list *rl;
255 struct smatch_state *bstate;
256 struct bit_info tmp;
257 struct bit_info *extra_info;
258 struct bit_info *bit_info;
259 sval_t known;
261 expr = strip_parens(expr);
263 if (get_implied_value(expr, &known))
264 return alloc_bit_info(known.value, known.value);
266 if (expr->type == EXPR_BINOP) {
267 if (expr->op == '&')
268 return binfo_AND(get_bit_info(expr->left),
269 get_bit_info(expr->right));
270 if (expr->op == '|')
271 return binfo_OR(get_bit_info(expr->left),
272 get_bit_info(expr->right));
275 if (get_implied_rl(expr, &rl))
276 extra_info = rl_to_binfo(rl);
277 else {
278 struct symbol *type;
280 tmp = unknown_bit_info;
281 extra_info = &tmp;
283 type = get_type(expr);
284 if (!type)
285 type = &ullong_ctype;
286 if (type_bits(type) == 64)
287 extra_info->possible = -1ULL;
288 else
289 extra_info->possible = (1ULL << type_bits(type)) - 1;
292 bstate = get_state_expr(my_id, expr);
293 if (bstate)
294 bit_info = bstate->data;
295 else
296 bit_info = (struct bit_info *)&unknown_bit_info;
298 return combine_bit_info(extra_info, bit_info);
301 static int is_single_bit(sval_t sval)
303 int i;
304 int count = 0;
306 for (i = 0; i < 64; i++) {
307 if (sval.uvalue & 1ULL << i &&
308 count++)
309 return 0;
311 if (count == 1)
312 return 1;
313 return 0;
316 static void match_compare(struct expression *expr)
318 sval_t val;
320 if (expr->type != EXPR_COMPARE)
321 return;
322 if (expr->op != SPECIAL_EQUAL &&
323 expr->op != SPECIAL_NOTEQUAL)
324 return;
326 if (!get_implied_value(expr->right, &val))
327 return;
329 set_true_false_states_expr(my_id, expr->left,
330 (expr->op == SPECIAL_EQUAL) ? alloc_bstate(val.uvalue, val.uvalue) : NULL,
331 (expr->op == SPECIAL_EQUAL) ? NULL : alloc_bstate(val.uvalue, val.uvalue));
334 static void match_assign(struct expression *expr)
336 struct bit_info *start, *binfo;
337 struct smatch_state *new;
339 if (!handled_by_assign_hook(expr))
340 return;
342 binfo = get_bit_info(expr->right);
343 if (!binfo)
344 return;
345 if (expr->op == '=') {
346 if (is_unknown_binfo(get_type(expr->left), binfo))
347 return;
348 set_bits_modified_expr(expr->left, alloc_bstate(binfo->set, binfo->possible));
349 } else if (expr->op == SPECIAL_OR_ASSIGN) {
350 start = get_bit_info(expr->left);
351 new = alloc_bstate(start->set | binfo->set, start->possible | binfo->possible);
352 set_bits_modified_expr(expr->left, new);
353 } else if (expr->op == SPECIAL_AND_ASSIGN) {
354 start = get_bit_info(expr->left);
355 new = alloc_bstate(start->set & binfo->set, start->possible & binfo->possible);
356 set_bits_modified_expr(expr->left, new);
360 static void match_condition(struct expression *expr)
362 struct bit_info *orig;
363 struct bit_info true_info;
364 struct bit_info false_info;
365 sval_t right;
367 if (expr->type != EXPR_BINOP ||
368 expr->op != '&')
369 return;
371 if (!get_value(expr->right, &right))
372 return;
374 orig = get_bit_info(expr->left);
375 true_info = *orig;
376 false_info = *orig;
378 if (right.uvalue == 0 || is_single_bit(right))
379 true_info.set &= right.uvalue;
381 true_info.possible &= right.uvalue;
382 false_info.possible &= ~right.uvalue;
384 set_true_false_states_expr(my_id, expr->left,
385 alloc_bstate(true_info.set, true_info.possible),
386 alloc_bstate(false_info.set, false_info.possible));
389 static void match_call_info(struct expression *expr)
391 struct bit_info *binfo, *rl_binfo;
392 struct expression *arg;
393 struct range_list *rl;
394 char buf[64];
395 int i;
397 i = -1;
398 FOR_EACH_PTR(expr->args, arg) {
399 i++;
400 binfo = get_bit_info(arg);
401 if (!binfo)
402 continue;
403 if (is_unknown_binfo(get_type(arg), binfo))
404 continue;
405 if (get_implied_rl(arg, &rl)) {
406 rl_binfo = rl_to_binfo(rl);
407 if (binfo_equiv(rl_binfo, binfo))
408 continue;
410 // If is just non-negative continue
411 // If ->set == ->possible continue
412 snprintf(buf, sizeof(buf), "0x%llx,0x%llx", binfo->set, binfo->possible);
413 sql_insert_caller_info(expr, BIT_INFO, i, "$", buf);
414 } END_FOR_EACH_PTR(arg);
417 static void struct_member_callback(struct expression *call, int param, char *printed_name, struct sm_state *sm)
419 struct bit_info *binfo = sm->state->data;
420 struct smatch_state *estate;
421 struct bit_info *implied_binfo;
422 char buf[64];
424 if (!binfo)
425 return;
427 /* This means it can only be one value, so it's handled by smatch_extra. */
428 if (binfo->set == binfo->possible)
429 return;
431 estate = get_state(SMATCH_EXTRA, sm->name, sm->sym);
432 if (is_unknown_binfo(estate_type(estate), binfo))
433 return;
435 if (estate_rl(estate)) {
436 sval_t sval;
438 if (estate_get_single_value(estate, &sval))
439 return;
441 implied_binfo = rl_to_binfo(estate_rl(estate));
442 if (binfo_equiv(implied_binfo, binfo))
443 return;
446 snprintf(buf, sizeof(buf), "0x%llx,0x%llx", binfo->set, binfo->possible);
447 sql_insert_caller_info(call, BIT_INFO, param, printed_name, buf);
450 static void set_param_bits(const char *name, struct symbol *sym, char *key, char *value)
452 char fullname[256];
453 unsigned long long set, possible;
455 if (strcmp(key, "*$") == 0)
456 snprintf(fullname, sizeof(fullname), "*%s", name);
457 else if (strncmp(key, "$", 1) == 0)
458 snprintf(fullname, 256, "%s%s", name, key + 1);
459 else
460 return;
462 set = strtoull(value, &value, 16);
463 if (*value != ',')
464 return;
465 value++;
466 possible = strtoull(value, &value, 16);
468 set_bits_modified_expr_sym(fullname, sym, alloc_bstate(set, possible));
471 static void returns_bit_set(struct expression *expr, int param, char *key, char *value)
473 char *name;
474 struct symbol *sym;
475 unsigned long long set;
476 char *pEnd;
478 name = get_name_sym_from_key(expr, param, key, &sym);
480 if (!name)
481 return;
483 set = strtoull(value, &pEnd, 16);
484 set_state(my_id, name, sym, alloc_bstate(set, -1ULL));
487 static void returns_bit_clear(struct expression *expr, int param, char *key, char *value)
489 char *name;
490 struct symbol *sym;
491 unsigned long long possible;
492 char *pEnd;
493 struct bit_info *binfo;
495 name = get_name_sym_from_key(expr, param, key, &sym);
497 if (!name)
498 return;
500 binfo = get_bit_info(expr);
501 possible = strtoull(value, &pEnd, 16);
502 set_state(my_id, name, sym, alloc_bstate(possible & binfo->set,
503 possible & binfo->possible));
506 void register_bits(int id)
508 my_id = id;
510 set_dynamic_states(my_id);
512 add_unmatched_state_hook(my_id, &unmatched_state);
513 add_merge_hook(my_id, &merge_bstates);
515 add_hook(&match_condition, CONDITION_HOOK);
516 add_hook(&match_compare, CONDITION_HOOK);
517 add_hook(&match_assign, ASSIGNMENT_HOOK);
518 add_modification_hook(my_id, &match_modify);
520 add_hook(&match_call_info, FUNCTION_CALL_HOOK);
521 add_member_info_callback(my_id, struct_member_callback);
522 select_caller_info_hook(set_param_bits, BIT_INFO);
524 select_return_states_hook(BIT_SET, &returns_bit_set);
525 select_return_states_hook(BIT_CLEAR, &returns_bit_clear);