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.
24 #include "smatch_extra.h"
25 #include "smatch_slist.h"
29 static const struct bit_info unknown_bit_info
= {
33 ALLOCATOR(bit_info
, "bit data");
34 static struct bit_info
*alloc_bit_info(unsigned long long set
, unsigned long long possible
)
36 struct bit_info
*bit_info
= __alloc_bit_info(0);
39 bit_info
->possible
= possible
;
44 static struct smatch_state
*alloc_bstate(unsigned long long set
, unsigned long long possible
)
46 struct smatch_state
*state
;
49 state
= __alloc_smatch_state(0);
50 snprintf(buf
, sizeof(buf
), "0x%llx + 0x%llx", set
, possible
);
51 state
->name
= alloc_sname(buf
);
52 state
->data
= alloc_bit_info(set
, possible
);
57 struct bit_info
*rl_to_binfo(struct range_list
*rl
)
59 struct bit_info
*ret
= __alloc_bit_info(0);
62 if (rl_to_sval(rl
, &sval
)) {
63 ret
->set
= sval
.uvalue
;
64 ret
->possible
= sval
.uvalue
;
70 ret
->possible
= sval_fls_mask(rl_max(rl
));
71 // FIXME: what about negatives?
76 static int is_unknown_binfo(struct symbol
*type
, struct bit_info
*binfo
)
83 if (binfo
->possible
< (-1ULL >> (64 - type_bits(type
))))
89 static struct smatch_state
*unmatched_state(struct sm_state
*sm
)
91 struct smatch_state
*estate
;
93 unsigned long long possible
;
96 estate
= get_state(SMATCH_EXTRA
, sm
->name
, sm
->sym
);
97 if (estate_rl(estate
)) {
98 p
= rl_to_binfo(estate_rl(estate
));
99 return alloc_bstate(p
->set
, p
->possible
);
102 type
= estate_type(estate
);
104 return alloc_bstate(0, -1ULL);
106 if (type_bits(type
) == 64)
109 possible
= (1ULL << type_bits(type
)) - 1;
111 return alloc_bstate(0, possible
);
114 static bool is_loop_iterator(struct expression
*expr
)
116 struct statement
*pre_stmt
, *loop_stmt
;
118 pre_stmt
= expr_get_parent_stmt(expr
);
119 if (!pre_stmt
|| pre_stmt
->type
!= STMT_EXPRESSION
)
122 loop_stmt
= stmt_get_parent_stmt(pre_stmt
);
123 if (!loop_stmt
|| loop_stmt
->type
!= STMT_ITERATOR
)
125 if (loop_stmt
->iterator_pre_statement
!= pre_stmt
)
131 static bool handled_by_assign_hook(struct expression
*expr
)
133 if (!expr
|| expr
->type
!= EXPR_ASSIGNMENT
)
135 if (__in_fake_assign
)
137 if (is_loop_iterator(expr
))
140 if (expr
->op
== '=' ||
141 expr
->op
== SPECIAL_OR_ASSIGN
||
142 expr
->op
== SPECIAL_AND_ASSIGN
)
148 static void match_modify(struct sm_state
*sm
, struct expression
*mod_expr
)
150 // FIXME: we really need to store the type
152 if (handled_by_assign_hook(mod_expr
))
154 set_state(my_id
, sm
->name
, sm
->sym
, alloc_bstate(0, -1ULL));
157 static int binfo_equiv(struct bit_info
*one
, struct bit_info
*two
)
159 if (one
->set
== two
->set
&&
160 one
->possible
== two
->possible
)
165 static struct smatch_state
*merge_bstates(struct smatch_state
*one_state
, struct smatch_state
*two_state
)
167 struct bit_info
*one
, *two
;
169 one
= one_state
->data
;
170 two
= two_state
->data
;
172 if (binfo_equiv(one
, two
))
175 return alloc_bstate(one
->set
& two
->set
, one
->possible
| two
->possible
);
179 * The combine_bit_info() takes two bit_infos and takes creates the most
180 * accurate picture we can assuming both are true. Or it returns unknown if
181 * the information is logically impossible.
183 * Which means that it takes the | of the ->set bits and the & of the possibly
184 * set bits, which is the opposite of what merge_bstates() does.
187 static struct bit_info
*combine_bit_info(struct bit_info
*one
, struct bit_info
*two
)
189 struct bit_info
*ret
= __alloc_bit_info(0);
191 if ((one
->set
& two
->possible
) != one
->set
)
192 return alloc_bit_info(0, -1ULL);
193 if ((two
->set
& one
->possible
) != two
->set
)
194 return alloc_bit_info(0, -1ULL);
196 ret
->set
= one
->set
| two
->set
;
197 ret
->possible
= one
->possible
& two
->possible
;
202 static struct bit_info
*binfo_AND(struct bit_info
*left
, struct bit_info
*right
)
204 unsigned long long set
= 0;
205 unsigned long long possible
= -1ULL;
207 if (!left
&& !right
) {
210 possible
= right
->possible
;
212 possible
= left
->possible
;
214 set
= left
->set
& right
->set
;
215 possible
= left
->possible
& right
->possible
;
218 return alloc_bit_info(set
, possible
);
221 static struct bit_info
*binfo_OR(struct bit_info
*left
, struct bit_info
*right
)
223 unsigned long long set
= 0;
224 unsigned long long possible
= -1ULL;
226 if (!left
&& !right
) {
233 set
= left
->set
| right
->set
;
234 possible
= left
->possible
| right
->possible
;
237 return alloc_bit_info(set
, possible
);
240 struct bit_info
*get_bit_info(struct expression
*expr
)
242 struct range_list
*rl
;
243 struct smatch_state
*bstate
;
245 struct bit_info
*extra_info
;
246 struct bit_info
*bit_info
;
249 expr
= strip_parens(expr
);
251 if (get_implied_value(expr
, &known
))
252 return alloc_bit_info(known
.value
, known
.value
);
254 if (expr
->type
== EXPR_BINOP
) {
256 return binfo_AND(get_bit_info(expr
->left
),
257 get_bit_info(expr
->right
));
259 return binfo_OR(get_bit_info(expr
->left
),
260 get_bit_info(expr
->right
));
263 if (get_implied_rl(expr
, &rl
))
264 extra_info
= rl_to_binfo(rl
);
268 tmp
= unknown_bit_info
;
271 type
= get_type(expr
);
273 type
= &ullong_ctype
;
274 if (type_bits(type
) == 64)
275 extra_info
->possible
= -1ULL;
277 extra_info
->possible
= (1ULL << type_bits(type
)) - 1;
280 bstate
= get_state_expr(my_id
, expr
);
282 bit_info
= bstate
->data
;
284 bit_info
= (struct bit_info
*)&unknown_bit_info
;
286 return combine_bit_info(extra_info
, bit_info
);
289 static int is_single_bit(sval_t sval
)
294 for (i
= 0; i
< 64; i
++) {
295 if (sval
.uvalue
& 1ULL << i
&&
304 static void match_compare(struct expression
*expr
)
308 if (expr
->type
!= EXPR_COMPARE
)
310 if (expr
->op
!= SPECIAL_EQUAL
&&
311 expr
->op
!= SPECIAL_NOTEQUAL
)
314 if (!get_implied_value(expr
->right
, &val
))
317 set_true_false_states_expr(my_id
, expr
->left
,
318 (expr
->op
== SPECIAL_EQUAL
) ? alloc_bstate(val
.uvalue
, val
.uvalue
) : NULL
,
319 (expr
->op
== SPECIAL_EQUAL
) ? NULL
: alloc_bstate(val
.uvalue
, val
.uvalue
));
322 static void match_assign(struct expression
*expr
)
324 struct bit_info
*start
, *binfo
;
325 struct smatch_state
*new;
327 if (!handled_by_assign_hook(expr
))
330 binfo
= get_bit_info(expr
->right
);
333 if (expr
->op
== '=') {
334 if (is_unknown_binfo(get_type(expr
->left
), binfo
))
337 set_state_expr(my_id
, expr
->left
, alloc_bstate(binfo
->set
, binfo
->possible
));
338 } else if (expr
->op
== SPECIAL_OR_ASSIGN
) {
339 start
= get_bit_info(expr
->left
);
340 new = alloc_bstate(start
->set
| binfo
->set
, start
->possible
| binfo
->possible
);
341 set_state_expr(my_id
, expr
->left
, new);
342 } else if (expr
->op
== SPECIAL_AND_ASSIGN
) {
343 start
= get_bit_info(expr
->left
);
344 new = alloc_bstate(start
->set
& binfo
->set
, start
->possible
& binfo
->possible
);
345 set_state_expr(my_id
, expr
->left
, new);
349 static void match_condition(struct expression
*expr
)
351 struct bit_info
*orig
;
352 struct bit_info true_info
;
353 struct bit_info false_info
;
356 if (expr
->type
!= EXPR_BINOP
||
360 if (!get_value(expr
->right
, &right
))
363 orig
= get_bit_info(expr
->left
);
367 if (right
.uvalue
== 0 || is_single_bit(right
))
368 true_info
.set
&= right
.uvalue
;
370 true_info
.possible
&= right
.uvalue
;
371 false_info
.possible
&= ~right
.uvalue
;
373 set_true_false_states_expr(my_id
, expr
->left
,
374 alloc_bstate(true_info
.set
, true_info
.possible
),
375 alloc_bstate(false_info
.set
, false_info
.possible
));
378 static void match_call_info(struct expression
*expr
)
380 struct bit_info
*binfo
, *rl_binfo
;
381 struct expression
*arg
;
382 struct range_list
*rl
;
387 FOR_EACH_PTR(expr
->args
, arg
) {
389 binfo
= get_bit_info(arg
);
392 if (is_unknown_binfo(get_type(arg
), binfo
))
394 if (get_implied_rl(arg
, &rl
)) {
395 rl_binfo
= rl_to_binfo(rl
);
396 if (binfo_equiv(rl_binfo
, binfo
))
399 // If is just non-negative continue
400 // If ->set == ->possible continue
401 snprintf(buf
, sizeof(buf
), "0x%llx,0x%llx", binfo
->set
, binfo
->possible
);
402 sql_insert_caller_info(expr
, BIT_INFO
, i
, "$", buf
);
403 } END_FOR_EACH_PTR(arg
);
406 static void struct_member_callback(struct expression
*call
, int param
, char *printed_name
, struct sm_state
*sm
)
408 struct bit_info
*binfo
= sm
->state
->data
;
409 struct smatch_state
*estate
;
410 struct bit_info
*implied_binfo
;
416 /* This means it can only be one value, so it's handled by smatch_extra. */
417 if (binfo
->set
== binfo
->possible
)
420 estate
= get_state(SMATCH_EXTRA
, sm
->name
, sm
->sym
);
421 if (is_unknown_binfo(estate_type(estate
), binfo
))
424 if (estate_rl(estate
)) {
427 if (estate_get_single_value(estate
, &sval
))
430 implied_binfo
= rl_to_binfo(estate_rl(estate
));
431 if (binfo_equiv(implied_binfo
, binfo
))
435 snprintf(buf
, sizeof(buf
), "0x%llx,0x%llx", binfo
->set
, binfo
->possible
);
436 sql_insert_caller_info(call
, BIT_INFO
, param
, printed_name
, buf
);
439 static void set_param_bits(const char *name
, struct symbol
*sym
, char *key
, char *value
)
442 unsigned long long set
, possible
;
444 if (strcmp(key
, "*$") == 0)
445 snprintf(fullname
, sizeof(fullname
), "*%s", name
);
446 else if (strncmp(key
, "$", 1) == 0)
447 snprintf(fullname
, 256, "%s%s", name
, key
+ 1);
451 set
= strtoull(value
, &value
, 16);
455 possible
= strtoull(value
, &value
, 16);
457 set_state(my_id
, fullname
, sym
, alloc_bstate(set
, possible
));
460 void register_bits(int id
)
464 set_dynamic_states(my_id
);
466 add_unmatched_state_hook(my_id
, &unmatched_state
);
467 add_merge_hook(my_id
, &merge_bstates
);
469 add_hook(&match_condition
, CONDITION_HOOK
);
470 add_hook(&match_compare
, CONDITION_HOOK
);
471 add_hook(&match_assign
, ASSIGNMENT_HOOK
);
472 add_modification_hook(my_id
, &match_modify
);
474 add_hook(&match_call_info
, FUNCTION_CALL_HOOK
);
475 add_member_info_callback(my_id
, struct_member_callback
);
476 select_caller_info_hook(set_param_bits
, BIT_INFO
);