1efe51d0cSJohn Levon /*
2efe51d0cSJohn Levon  * Copyright (C) 2015 Oracle.
3efe51d0cSJohn Levon  *
4efe51d0cSJohn Levon  * This program is free software; you can redistribute it and/or
5efe51d0cSJohn Levon  * modify it under the terms of the GNU General Public License
6efe51d0cSJohn Levon  * as published by the Free Software Foundation; either version 2
7efe51d0cSJohn Levon  * of the License, or (at your option) any later version.
8efe51d0cSJohn Levon  *
9efe51d0cSJohn Levon  * This program is distributed in the hope that it will be useful,
10efe51d0cSJohn Levon  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11efe51d0cSJohn Levon  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12efe51d0cSJohn Levon  * GNU General Public License for more details.
13efe51d0cSJohn Levon  *
14efe51d0cSJohn Levon  * You should have received a copy of the GNU General Public License
15efe51d0cSJohn Levon  * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
16efe51d0cSJohn Levon  */
17efe51d0cSJohn Levon 
18efe51d0cSJohn Levon /*
19efe51d0cSJohn Levon  * This is to track when variables are masked away.
20efe51d0cSJohn Levon  *
21efe51d0cSJohn Levon  */
22efe51d0cSJohn Levon 
23efe51d0cSJohn Levon #include "smatch.h"
24efe51d0cSJohn Levon #include "smatch_extra.h"
25efe51d0cSJohn Levon #include "smatch_slist.h"
26efe51d0cSJohn Levon 
27efe51d0cSJohn Levon static int my_id;
28efe51d0cSJohn Levon 
29efe51d0cSJohn Levon static const struct bit_info unknown_bit_info = {
30efe51d0cSJohn Levon 	.possible = -1ULL,
31efe51d0cSJohn Levon };
32efe51d0cSJohn Levon 
33efe51d0cSJohn Levon ALLOCATOR(bit_info, "bit data");
alloc_bit_info(unsigned long long set,unsigned long long possible)34efe51d0cSJohn Levon static struct bit_info *alloc_bit_info(unsigned long long set, unsigned long long possible)
35efe51d0cSJohn Levon {
36efe51d0cSJohn Levon 	struct bit_info *bit_info = __alloc_bit_info(0);
37efe51d0cSJohn Levon 
38efe51d0cSJohn Levon 	bit_info->set = set;
39efe51d0cSJohn Levon 	bit_info->possible = possible;
40efe51d0cSJohn Levon 
41efe51d0cSJohn Levon 	return bit_info;
42efe51d0cSJohn Levon }
43efe51d0cSJohn Levon 
alloc_bstate(unsigned long long set,unsigned long long possible)44efe51d0cSJohn Levon static struct smatch_state *alloc_bstate(unsigned long long set, unsigned long long possible)
45efe51d0cSJohn Levon {
46efe51d0cSJohn Levon 	struct smatch_state *state;
47efe51d0cSJohn Levon 	char buf[64];
48efe51d0cSJohn Levon 
49efe51d0cSJohn Levon 	state = __alloc_smatch_state(0);
50efe51d0cSJohn Levon 	snprintf(buf, sizeof(buf), "0x%llx + 0x%llx", set, possible);
51efe51d0cSJohn Levon 	state->name = alloc_sname(buf);
52efe51d0cSJohn Levon 	state->data = alloc_bit_info(set, possible);
53efe51d0cSJohn Levon 
54efe51d0cSJohn Levon 	return state;
55efe51d0cSJohn Levon }
56efe51d0cSJohn Levon 
rl_to_binfo(struct range_list * rl)57c85f09ccSJohn Levon struct bit_info *rl_to_binfo(struct range_list *rl)
58efe51d0cSJohn Levon {
59efe51d0cSJohn Levon 	struct bit_info *ret = __alloc_bit_info(0);
60efe51d0cSJohn Levon 	sval_t sval;
61efe51d0cSJohn Levon 
62efe51d0cSJohn Levon 	if (rl_to_sval(rl, &sval)) {
63efe51d0cSJohn Levon 		ret->set = sval.uvalue;
64efe51d0cSJohn Levon 		ret->possible = sval.uvalue;
65efe51d0cSJohn Levon 
66efe51d0cSJohn Levon 		return ret;
67efe51d0cSJohn Levon 	}
68efe51d0cSJohn Levon 
69efe51d0cSJohn Levon 	ret->set = 0;
70efe51d0cSJohn Levon 	ret->possible = sval_fls_mask(rl_max(rl));
71efe51d0cSJohn Levon 	// FIXME: what about negatives?
72efe51d0cSJohn Levon 
73efe51d0cSJohn Levon 	return ret;
74efe51d0cSJohn Levon }
75efe51d0cSJohn Levon 
is_unknown_binfo(struct symbol * type,struct bit_info * binfo)76efe51d0cSJohn Levon static int is_unknown_binfo(struct symbol *type, struct bit_info *binfo)
77efe51d0cSJohn Levon {
78efe51d0cSJohn Levon 	if (!type)
79efe51d0cSJohn Levon 		type = &ullong_ctype;
80efe51d0cSJohn Levon 
81efe51d0cSJohn Levon 	if (binfo->set != 0)
82efe51d0cSJohn Levon 		return 0;
83efe51d0cSJohn Levon 	if (binfo->possible < (-1ULL >> (64 - type_bits(type))))
84efe51d0cSJohn Levon 		return 0;
85efe51d0cSJohn Levon 
86efe51d0cSJohn Levon 	return 1;
87efe51d0cSJohn Levon }
88efe51d0cSJohn Levon 
unmatched_state(struct sm_state * sm)89efe51d0cSJohn Levon static struct smatch_state *unmatched_state(struct sm_state *sm)
90efe51d0cSJohn Levon {
91efe51d0cSJohn Levon 	struct smatch_state *estate;
92efe51d0cSJohn Levon 	struct symbol *type;
93efe51d0cSJohn Levon 	unsigned long long possible;
94efe51d0cSJohn Levon 	struct bit_info *p;
95efe51d0cSJohn Levon 
96efe51d0cSJohn Levon 	estate = get_state(SMATCH_EXTRA, sm->name, sm->sym);
97efe51d0cSJohn Levon 	if (estate_rl(estate)) {
98efe51d0cSJohn Levon 		p = rl_to_binfo(estate_rl(estate));
99efe51d0cSJohn Levon 		return alloc_bstate(p->set, p->possible);
100efe51d0cSJohn Levon 	}
101efe51d0cSJohn Levon 
102efe51d0cSJohn Levon 	type = estate_type(estate);
103efe51d0cSJohn Levon 	if (!type)
104efe51d0cSJohn Levon 		return alloc_bstate(0, -1ULL);
105efe51d0cSJohn Levon 
106efe51d0cSJohn Levon 	if (type_bits(type) == 64)
107efe51d0cSJohn Levon 		possible = -1ULL;
108efe51d0cSJohn Levon 	else
109efe51d0cSJohn Levon 		possible = (1ULL << type_bits(type)) - 1;
110efe51d0cSJohn Levon 
111efe51d0cSJohn Levon 	return alloc_bstate(0, possible);
112efe51d0cSJohn Levon }
113efe51d0cSJohn Levon 
is_loop_iterator(struct expression * expr)114*6523a3aaSJohn Levon static bool is_loop_iterator(struct expression *expr)
115*6523a3aaSJohn Levon {
116*6523a3aaSJohn Levon 	struct statement *pre_stmt, *loop_stmt;
117*6523a3aaSJohn Levon 
118*6523a3aaSJohn Levon 	pre_stmt = expr_get_parent_stmt(expr);
119*6523a3aaSJohn Levon 	if (!pre_stmt || pre_stmt->type != STMT_EXPRESSION)
120*6523a3aaSJohn Levon 		return false;
121*6523a3aaSJohn Levon 
122*6523a3aaSJohn Levon 	loop_stmt = stmt_get_parent_stmt(pre_stmt);
123*6523a3aaSJohn Levon 	if (!loop_stmt || loop_stmt->type != STMT_ITERATOR)
124*6523a3aaSJohn Levon 		return false;
125*6523a3aaSJohn Levon 	if (loop_stmt->iterator_pre_statement != pre_stmt)
126*6523a3aaSJohn Levon 		return false;
127*6523a3aaSJohn Levon 
128*6523a3aaSJohn Levon 	return true;
129*6523a3aaSJohn Levon }
130*6523a3aaSJohn Levon 
handled_by_assign_hook(struct expression * expr)131*6523a3aaSJohn Levon static bool handled_by_assign_hook(struct expression *expr)
132*6523a3aaSJohn Levon {
133*6523a3aaSJohn Levon 	if (!expr || expr->type != EXPR_ASSIGNMENT)
134*6523a3aaSJohn Levon 		return false;
135*6523a3aaSJohn Levon 	if (__in_fake_assign)
136*6523a3aaSJohn Levon 		return false;
137*6523a3aaSJohn Levon 	if (is_loop_iterator(expr))
138*6523a3aaSJohn Levon 		return false;
139*6523a3aaSJohn Levon 
140*6523a3aaSJohn Levon 	if (expr->op == '=' ||
141*6523a3aaSJohn Levon 	    expr->op == SPECIAL_OR_ASSIGN ||
142*6523a3aaSJohn Levon 	    expr->op == SPECIAL_AND_ASSIGN)
143*6523a3aaSJohn Levon 		return true;
144*6523a3aaSJohn Levon 
145*6523a3aaSJohn Levon 	return false;
146*6523a3aaSJohn Levon }
147*6523a3aaSJohn Levon 
match_modify(struct sm_state * sm,struct expression * mod_expr)148efe51d0cSJohn Levon static void match_modify(struct sm_state *sm, struct expression *mod_expr)
149efe51d0cSJohn Levon {
150efe51d0cSJohn Levon 	// FIXME: we really need to store the type
151efe51d0cSJohn Levon 
152*6523a3aaSJohn Levon 	if (handled_by_assign_hook(mod_expr))
153*6523a3aaSJohn Levon 		return;
154efe51d0cSJohn Levon 	set_state(my_id, sm->name, sm->sym, alloc_bstate(0, -1ULL));
155efe51d0cSJohn Levon }
156efe51d0cSJohn Levon 
binfo_equiv(struct bit_info * one,struct bit_info * two)157efe51d0cSJohn Levon static int binfo_equiv(struct bit_info *one, struct bit_info *two)
158efe51d0cSJohn Levon {
159efe51d0cSJohn Levon 	if (one->set == two->set &&
160efe51d0cSJohn Levon 	    one->possible == two->possible)
161efe51d0cSJohn Levon 		return 1;
162efe51d0cSJohn Levon 	return 0;
163efe51d0cSJohn Levon }
164efe51d0cSJohn Levon 
merge_bstates(struct smatch_state * one_state,struct smatch_state * two_state)165efe51d0cSJohn Levon static struct smatch_state *merge_bstates(struct smatch_state *one_state, struct smatch_state *two_state)
166efe51d0cSJohn Levon {
167efe51d0cSJohn Levon 	struct bit_info *one, *two;
168efe51d0cSJohn Levon 
169efe51d0cSJohn Levon 	one = one_state->data;
170efe51d0cSJohn Levon 	two = two_state->data;
171efe51d0cSJohn Levon 
172efe51d0cSJohn Levon 	if (binfo_equiv(one, two))
173efe51d0cSJohn Levon 		return one_state;
174efe51d0cSJohn Levon 
175efe51d0cSJohn Levon 	return alloc_bstate(one->set & two->set, one->possible | two->possible);
176efe51d0cSJohn Levon }
177efe51d0cSJohn Levon 
178efe51d0cSJohn Levon /*
179efe51d0cSJohn Levon  * The combine_bit_info() takes two bit_infos and takes creates the most
180efe51d0cSJohn Levon  * accurate picture we can assuming both are true.  Or it returns unknown if
181efe51d0cSJohn Levon  * the information is logically impossible.
182efe51d0cSJohn Levon  *
183efe51d0cSJohn Levon  * Which means that it takes the | of the ->set bits and the & of the possibly
184efe51d0cSJohn Levon  * set bits, which is the opposite of what merge_bstates() does.
185efe51d0cSJohn Levon  *
186efe51d0cSJohn Levon  */
combine_bit_info(struct bit_info * one,struct bit_info * two)187efe51d0cSJohn Levon static struct bit_info *combine_bit_info(struct bit_info *one, struct bit_info *two)
188efe51d0cSJohn Levon {
189efe51d0cSJohn Levon 	struct bit_info *ret = __alloc_bit_info(0);
190efe51d0cSJohn Levon 
191efe51d0cSJohn Levon 	if ((one->set & two->possible) != one->set)
192efe51d0cSJohn Levon 		return alloc_bit_info(0, -1ULL);
193efe51d0cSJohn Levon 	if ((two->set & one->possible) != two->set)
194efe51d0cSJohn Levon 		return alloc_bit_info(0, -1ULL);
195efe51d0cSJohn Levon 
196efe51d0cSJohn Levon 	ret->set = one->set | two->set;
197efe51d0cSJohn Levon 	ret->possible = one->possible & two->possible;
198efe51d0cSJohn Levon 
199efe51d0cSJohn Levon 	return ret;
200efe51d0cSJohn Levon }
201efe51d0cSJohn Levon 
binfo_AND(struct bit_info * left,struct bit_info * right)202efe51d0cSJohn Levon static struct bit_info *binfo_AND(struct bit_info *left, struct bit_info *right)
203efe51d0cSJohn Levon {
204efe51d0cSJohn Levon 	unsigned long long set = 0;
205efe51d0cSJohn Levon 	unsigned long long possible = -1ULL;
206efe51d0cSJohn Levon 
207efe51d0cSJohn Levon 	if (!left && !right) {
208efe51d0cSJohn Levon 		/* nothing */
209efe51d0cSJohn Levon 	} else if (!left) {
210efe51d0cSJohn Levon 		possible = right->possible;
211efe51d0cSJohn Levon 	} else if (!right) {
212efe51d0cSJohn Levon 		possible = left->possible;
213efe51d0cSJohn Levon 	} else {
214efe51d0cSJohn Levon 		set = left->set & right->set;
215efe51d0cSJohn Levon 		possible = left->possible & right->possible;
216efe51d0cSJohn Levon 	}
217efe51d0cSJohn Levon 
218efe51d0cSJohn Levon 	return alloc_bit_info(set, possible);
219efe51d0cSJohn Levon }
220efe51d0cSJohn Levon 
binfo_OR(struct bit_info * left,struct bit_info * right)221efe51d0cSJohn Levon static struct bit_info *binfo_OR(struct bit_info *left, struct bit_info *right)
222efe51d0cSJohn Levon {
223efe51d0cSJohn Levon 	unsigned long long set = 0;
224efe51d0cSJohn Levon 	unsigned long long possible = -1ULL;
225efe51d0cSJohn Levon 
226efe51d0cSJohn Levon 	if (!left && !right) {
227efe51d0cSJohn Levon 		/* nothing */
228efe51d0cSJohn Levon 	} else if (!left) {
229efe51d0cSJohn Levon 		set = right->set;
230efe51d0cSJohn Levon 	} else if (!right) {
231efe51d0cSJohn Levon 		set = left->set;
232efe51d0cSJohn Levon 	} else {
233efe51d0cSJohn Levon 		set = left->set | right->set;
234efe51d0cSJohn Levon 		possible = left->possible | right->possible;
235efe51d0cSJohn Levon 	}
236efe51d0cSJohn Levon 
237efe51d0cSJohn Levon 	return alloc_bit_info(set, possible);
238efe51d0cSJohn Levon }
239efe51d0cSJohn Levon 
get_bit_info(struct expression * expr)240efe51d0cSJohn Levon struct bit_info *get_bit_info(struct expression *expr)
241efe51d0cSJohn Levon {
242efe51d0cSJohn Levon 	struct range_list *rl;
243efe51d0cSJohn Levon 	struct smatch_state *bstate;
244efe51d0cSJohn Levon 	struct bit_info tmp;
245efe51d0cSJohn Levon 	struct bit_info *extra_info;
246efe51d0cSJohn Levon 	struct bit_info *bit_info;
247efe51d0cSJohn Levon 	sval_t known;
248efe51d0cSJohn Levon 
249efe51d0cSJohn Levon 	expr = strip_parens(expr);
250efe51d0cSJohn Levon 
251efe51d0cSJohn Levon 	if (get_implied_value(expr, &known))
252efe51d0cSJohn Levon 		return alloc_bit_info(known.value, known.value);
253efe51d0cSJohn Levon 
254efe51d0cSJohn Levon 	if (expr->type == EXPR_BINOP) {
255efe51d0cSJohn Levon 		if (expr->op == '&')
256efe51d0cSJohn Levon 			return binfo_AND(get_bit_info(expr->left),
257efe51d0cSJohn Levon 					 get_bit_info(expr->right));
258efe51d0cSJohn Levon 		if (expr->op == '|')
259efe51d0cSJohn Levon 			return binfo_OR(get_bit_info(expr->left),
260efe51d0cSJohn Levon 					get_bit_info(expr->right));
261efe51d0cSJohn Levon 	}
262efe51d0cSJohn Levon 
263efe51d0cSJohn Levon 	if (get_implied_rl(expr, &rl))
264efe51d0cSJohn Levon 		extra_info = rl_to_binfo(rl);
265efe51d0cSJohn Levon 	else {
266efe51d0cSJohn Levon 		struct symbol *type;
267efe51d0cSJohn Levon 
268efe51d0cSJohn Levon 		tmp = unknown_bit_info;
269efe51d0cSJohn Levon 		extra_info = &tmp;
270efe51d0cSJohn Levon 
271efe51d0cSJohn Levon 		type = get_type(expr);
272efe51d0cSJohn Levon 		if (!type)
273efe51d0cSJohn Levon 			type = &ullong_ctype;
274efe51d0cSJohn Levon 		if (type_bits(type) == 64)
275efe51d0cSJohn Levon 			extra_info->possible = -1ULL;
276efe51d0cSJohn Levon 		else
277efe51d0cSJohn Levon 			extra_info->possible = (1ULL << type_bits(type)) - 1;
278efe51d0cSJohn Levon 	}
279efe51d0cSJohn Levon 
280efe51d0cSJohn Levon 	bstate = get_state_expr(my_id, expr);
281efe51d0cSJohn Levon 	if (bstate)
282efe51d0cSJohn Levon 		bit_info = bstate->data;
283efe51d0cSJohn Levon 	else
284efe51d0cSJohn Levon 		bit_info = (struct bit_info *)&unknown_bit_info;
285efe51d0cSJohn Levon 
286efe51d0cSJohn Levon 	return combine_bit_info(extra_info, bit_info);
287efe51d0cSJohn Levon }
288efe51d0cSJohn Levon 
is_single_bit(sval_t sval)289efe51d0cSJohn Levon static int is_single_bit(sval_t sval)
290efe51d0cSJohn Levon {
291efe51d0cSJohn Levon 	int i;
292efe51d0cSJohn Levon 	int count = 0;
293efe51d0cSJohn Levon 
294efe51d0cSJohn Levon 	for (i = 0; i < 64; i++) {
295efe51d0cSJohn Levon 		if (sval.uvalue & 1ULL << i &&
296efe51d0cSJohn Levon 		    count++)
297efe51d0cSJohn Levon 			return 0;
298efe51d0cSJohn Levon 	}
299efe51d0cSJohn Levon 	if (count == 1)
300efe51d0cSJohn Levon 		return 1;
301efe51d0cSJohn Levon 	return 0;
302efe51d0cSJohn Levon }
303efe51d0cSJohn Levon 
match_compare(struct expression * expr)304efe51d0cSJohn Levon static void match_compare(struct expression *expr)
305efe51d0cSJohn Levon {
306efe51d0cSJohn Levon 	sval_t val;
307efe51d0cSJohn Levon 
308efe51d0cSJohn Levon 	if (expr->type != EXPR_COMPARE)
309efe51d0cSJohn Levon 		return;
310efe51d0cSJohn Levon 	if (expr->op != SPECIAL_EQUAL &&
311efe51d0cSJohn Levon 	    expr->op != SPECIAL_NOTEQUAL)
312efe51d0cSJohn Levon 		return;
313efe51d0cSJohn Levon 
314efe51d0cSJohn Levon 	if (!get_implied_value(expr->right, &val))
315efe51d0cSJohn Levon 		return;
316efe51d0cSJohn Levon 
317efe51d0cSJohn Levon 	set_true_false_states_expr(my_id, expr->left,
318efe51d0cSJohn Levon 			(expr->op == SPECIAL_EQUAL) ? alloc_bstate(val.uvalue, val.uvalue) : NULL,
319efe51d0cSJohn Levon 			(expr->op == SPECIAL_EQUAL) ? NULL : alloc_bstate(val.uvalue, val.uvalue));
320efe51d0cSJohn Levon }
321efe51d0cSJohn Levon 
match_assign(struct expression * expr)322efe51d0cSJohn Levon static void match_assign(struct expression *expr)
323efe51d0cSJohn Levon {
324*6523a3aaSJohn Levon 	struct bit_info *start, *binfo;
325*6523a3aaSJohn Levon 	struct smatch_state *new;
326efe51d0cSJohn Levon 
327*6523a3aaSJohn Levon 	if (!handled_by_assign_hook(expr))
328efe51d0cSJohn Levon 		return;
329efe51d0cSJohn Levon 
330efe51d0cSJohn Levon 	binfo = get_bit_info(expr->right);
331efe51d0cSJohn Levon 	if (!binfo)
332efe51d0cSJohn Levon 		return;
333*6523a3aaSJohn Levon 	if (expr->op == '=') {
334*6523a3aaSJohn Levon 		if (is_unknown_binfo(get_type(expr->left), binfo))
335*6523a3aaSJohn Levon 			return;
336*6523a3aaSJohn Levon 
337*6523a3aaSJohn Levon 		set_state_expr(my_id, expr->left, alloc_bstate(binfo->set, binfo->possible));
338*6523a3aaSJohn Levon 	} else if (expr->op == SPECIAL_OR_ASSIGN) {
339*6523a3aaSJohn Levon 		start = get_bit_info(expr->left);
340*6523a3aaSJohn Levon 		new = alloc_bstate(start->set | binfo->set, start->possible | binfo->possible);
341*6523a3aaSJohn Levon 		set_state_expr(my_id, expr->left, new);
342*6523a3aaSJohn Levon 	} else if (expr->op == SPECIAL_AND_ASSIGN) {
343*6523a3aaSJohn Levon 		start = get_bit_info(expr->left);
344*6523a3aaSJohn Levon 		new = alloc_bstate(start->set & binfo->set, start->possible & binfo->possible);
345*6523a3aaSJohn Levon 		set_state_expr(my_id, expr->left, new);
346*6523a3aaSJohn Levon 	}
347efe51d0cSJohn Levon }
348efe51d0cSJohn Levon 
match_condition(struct expression * expr)349efe51d0cSJohn Levon static void match_condition(struct expression *expr)
350efe51d0cSJohn Levon {
351efe51d0cSJohn Levon 	struct bit_info *orig;
352efe51d0cSJohn Levon 	struct bit_info true_info;
353efe51d0cSJohn Levon 	struct bit_info false_info;
354efe51d0cSJohn Levon 	sval_t right;
355efe51d0cSJohn Levon 
356efe51d0cSJohn Levon 	if (expr->type != EXPR_BINOP ||
357efe51d0cSJohn Levon 	    expr->op != '&')
358efe51d0cSJohn Levon 		return;
359efe51d0cSJohn Levon 
360efe51d0cSJohn Levon 	if (!get_value(expr->right, &right))
361efe51d0cSJohn Levon 		return;
362efe51d0cSJohn Levon 
363efe51d0cSJohn Levon 	orig = get_bit_info(expr->left);
364efe51d0cSJohn Levon 	true_info = *orig;
365efe51d0cSJohn Levon 	false_info = *orig;
366efe51d0cSJohn Levon 
367efe51d0cSJohn Levon 	if (right.uvalue == 0 || is_single_bit(right))
368efe51d0cSJohn Levon 		true_info.set &= right.uvalue;
369efe51d0cSJohn Levon 
370efe51d0cSJohn Levon 	true_info.possible &= right.uvalue;
371efe51d0cSJohn Levon 	false_info.possible &= ~right.uvalue;
372efe51d0cSJohn Levon 
373efe51d0cSJohn Levon 	set_true_false_states_expr(my_id, expr->left,
374efe51d0cSJohn Levon 				   alloc_bstate(true_info.set, true_info.possible),
375efe51d0cSJohn Levon 				   alloc_bstate(false_info.set, false_info.possible));
376efe51d0cSJohn Levon }
377efe51d0cSJohn Levon 
match_call_info(struct expression * expr)378efe51d0cSJohn Levon static void match_call_info(struct expression *expr)
379efe51d0cSJohn Levon {
380efe51d0cSJohn Levon 	struct bit_info *binfo, *rl_binfo;
381efe51d0cSJohn Levon 	struct expression *arg;
382efe51d0cSJohn Levon 	struct range_list *rl;
383efe51d0cSJohn Levon 	char buf[64];
384efe51d0cSJohn Levon 	int i;
385efe51d0cSJohn Levon 
386efe51d0cSJohn Levon 	i = -1;
387efe51d0cSJohn Levon 	FOR_EACH_PTR(expr->args, arg) {
388efe51d0cSJohn Levon 		i++;
389efe51d0cSJohn Levon 		binfo = get_bit_info(arg);
390efe51d0cSJohn Levon 		if (!binfo)
391efe51d0cSJohn Levon 			continue;
392efe51d0cSJohn Levon 		if (is_unknown_binfo(get_type(arg), binfo))
393efe51d0cSJohn Levon 			continue;
394efe51d0cSJohn Levon 		if (get_implied_rl(arg, &rl)) {
395efe51d0cSJohn Levon 			rl_binfo = rl_to_binfo(rl);
396efe51d0cSJohn Levon 			if (binfo_equiv(rl_binfo, binfo))
397efe51d0cSJohn Levon 				continue;
398efe51d0cSJohn Levon 		}
399efe51d0cSJohn Levon 		// If is just non-negative continue
400efe51d0cSJohn Levon 		// If ->set == ->possible continue
401efe51d0cSJohn Levon 		snprintf(buf, sizeof(buf), "0x%llx,0x%llx", binfo->set, binfo->possible);
402efe51d0cSJohn Levon 		sql_insert_caller_info(expr, BIT_INFO, i, "$", buf);
403efe51d0cSJohn Levon 	} END_FOR_EACH_PTR(arg);
404efe51d0cSJohn Levon }
405efe51d0cSJohn Levon 
struct_member_callback(struct expression * call,int param,char * printed_name,struct sm_state * sm)406efe51d0cSJohn Levon static void struct_member_callback(struct expression *call, int param, char *printed_name, struct sm_state *sm)
407efe51d0cSJohn Levon {
408efe51d0cSJohn Levon 	struct bit_info *binfo = sm->state->data;
409efe51d0cSJohn Levon 	struct smatch_state *estate;
410efe51d0cSJohn Levon 	struct bit_info *implied_binfo;
411efe51d0cSJohn Levon 	char buf[64];
412efe51d0cSJohn Levon 
413efe51d0cSJohn Levon 	if (!binfo)
414efe51d0cSJohn Levon 		return;
415efe51d0cSJohn Levon 
416efe51d0cSJohn Levon 	/* This means it can only be one value, so it's handled by smatch_extra. */
417efe51d0cSJohn Levon 	if (binfo->set == binfo->possible)
418efe51d0cSJohn Levon 		return;
419efe51d0cSJohn Levon 
420efe51d0cSJohn Levon 	estate = get_state(SMATCH_EXTRA, sm->name, sm->sym);
421efe51d0cSJohn Levon 	if (is_unknown_binfo(estate_type(estate), binfo))
422efe51d0cSJohn Levon 		return;
423efe51d0cSJohn Levon 
424efe51d0cSJohn Levon 	if (estate_rl(estate)) {
425efe51d0cSJohn Levon 		sval_t sval;
426efe51d0cSJohn Levon 
427efe51d0cSJohn Levon 		if (estate_get_single_value(estate, &sval))
428efe51d0cSJohn Levon 			return;
429efe51d0cSJohn Levon 
430efe51d0cSJohn Levon 		implied_binfo = rl_to_binfo(estate_rl(estate));
431efe51d0cSJohn Levon 		if (binfo_equiv(implied_binfo, binfo))
432efe51d0cSJohn Levon 			return;
433efe51d0cSJohn Levon 	}
434efe51d0cSJohn Levon 
435efe51d0cSJohn Levon 	snprintf(buf, sizeof(buf), "0x%llx,0x%llx", binfo->set, binfo->possible);
436efe51d0cSJohn Levon 	sql_insert_caller_info(call, BIT_INFO, param, printed_name, buf);
437efe51d0cSJohn Levon }
438efe51d0cSJohn Levon 
set_param_bits(const char * name,struct symbol * sym,char * key,char * value)439efe51d0cSJohn Levon static void set_param_bits(const char *name, struct symbol *sym, char *key, char *value)
440efe51d0cSJohn Levon {
441efe51d0cSJohn Levon 	char fullname[256];
442efe51d0cSJohn Levon 	unsigned long long set, possible;
443efe51d0cSJohn Levon 
444efe51d0cSJohn Levon 	if (strcmp(key, "*$") == 0)
445efe51d0cSJohn Levon 		snprintf(fullname, sizeof(fullname), "*%s", name);
446efe51d0cSJohn Levon 	else if (strncmp(key, "$", 1) == 0)
447efe51d0cSJohn Levon 		snprintf(fullname, 256, "%s%s", name, key + 1);
448efe51d0cSJohn Levon 	else
449efe51d0cSJohn Levon 		return;
450efe51d0cSJohn Levon 
451efe51d0cSJohn Levon 	set = strtoull(value, &value, 16);
452efe51d0cSJohn Levon 	if (*value != ',')
453efe51d0cSJohn Levon 		return;
454efe51d0cSJohn Levon 	value++;
455efe51d0cSJohn Levon 	possible = strtoull(value, &value, 16);
456efe51d0cSJohn Levon 
457efe51d0cSJohn Levon 	set_state(my_id, fullname, sym, alloc_bstate(set, possible));
458efe51d0cSJohn Levon }
459efe51d0cSJohn Levon 
register_bits(int id)460efe51d0cSJohn Levon void register_bits(int id)
461efe51d0cSJohn Levon {
462efe51d0cSJohn Levon 	my_id = id;
463efe51d0cSJohn Levon 
464efe51d0cSJohn Levon 	set_dynamic_states(my_id);
465efe51d0cSJohn Levon 
466efe51d0cSJohn Levon 	add_unmatched_state_hook(my_id, &unmatched_state);
467efe51d0cSJohn Levon 	add_merge_hook(my_id, &merge_bstates);
468efe51d0cSJohn Levon 
469efe51d0cSJohn Levon 	add_hook(&match_condition, CONDITION_HOOK);
470efe51d0cSJohn Levon 	add_hook(&match_compare, CONDITION_HOOK);
471efe51d0cSJohn Levon 	add_hook(&match_assign, ASSIGNMENT_HOOK);
472efe51d0cSJohn Levon 	add_modification_hook(my_id, &match_modify);
473efe51d0cSJohn Levon 
474efe51d0cSJohn Levon 	add_hook(&match_call_info, FUNCTION_CALL_HOOK);
475efe51d0cSJohn Levon 	add_member_info_callback(my_id, struct_member_callback);
476efe51d0cSJohn Levon 	select_caller_info_hook(set_param_bits, BIT_INFO);
477efe51d0cSJohn Levon }
478