Print this page
11506 smatch resync
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/tools/smatch/src/smatch_extra.c
+++ new/usr/src/tools/smatch/src/smatch_extra.c
1 1 /*
2 2 * Copyright (C) 2008 Dan Carpenter.
3 3 *
4 4 * This program is free software; you can redistribute it and/or
5 5 * modify it under the terms of the GNU General Public License
6 6 * as published by the Free Software Foundation; either version 2
7 7 * of the License, or (at your option) any later version.
8 8 *
9 9 * This program is distributed in the hope that it will be useful,
10 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 * GNU General Public License for more details.
13 13 *
14 14 * You should have received a copy of the GNU General Public License
15 15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
16 16 */
17 17
18 18 /*
19 19 * smatch_extra.c is supposed to track the value of every variable.
20 20 *
21 21 */
22 22
23 23 #define _GNU_SOURCE
24 24 #include <string.h>
25 25
26 26 #include <stdlib.h>
27 27 #include <errno.h>
28 28 #ifndef __USE_ISOC99
↓ open down ↓ |
28 lines elided |
↑ open up ↑ |
29 29 #define __USE_ISOC99
30 30 #endif
31 31 #include <limits.h>
32 32 #include "parse.h"
33 33 #include "smatch.h"
34 34 #include "smatch_slist.h"
35 35 #include "smatch_extra.h"
36 36
37 37 static int my_id;
38 38 static int link_id;
39 +extern int check_assigned_expr_id;
39 40
40 41 static void match_link_modify(struct sm_state *sm, struct expression *mod_expr);
41 42
42 43 struct string_list *__ignored_macros = NULL;
43 -static int in_warn_on_macro(void)
44 +int in_warn_on_macro(void)
44 45 {
45 46 struct statement *stmt;
46 47 char *tmp;
47 48 char *macro;
48 49
49 50 stmt = get_current_statement();
50 51 if (!stmt)
51 52 return 0;
52 53 macro = get_macro_name(stmt->pos);
53 54 if (!macro)
54 55 return 0;
55 56
56 57 FOR_EACH_PTR(__ignored_macros, tmp) {
57 58 if (!strcmp(tmp, macro))
58 59 return 1;
59 60 } END_FOR_EACH_PTR(tmp);
60 61 return 0;
61 62 }
62 63
63 64 typedef void (mod_hook)(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state);
64 65 DECLARE_PTR_LIST(void_fn_list, mod_hook *);
65 66 static struct void_fn_list *extra_mod_hooks;
66 67 static struct void_fn_list *extra_nomod_hooks;
67 68
68 69 void add_extra_mod_hook(mod_hook *fn)
69 70 {
70 71 mod_hook **p = malloc(sizeof(mod_hook *));
71 72 *p = fn;
72 73 add_ptr_list(&extra_mod_hooks, p);
73 74 }
74 75
75 76 void add_extra_nomod_hook(mod_hook *fn)
76 77 {
77 78 mod_hook **p = malloc(sizeof(mod_hook *));
78 79 *p = fn;
79 80 add_ptr_list(&extra_nomod_hooks, p);
80 81 }
81 82
82 83 void call_extra_hooks(struct void_fn_list *hooks, const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
83 84 {
84 85 mod_hook **fn;
85 86
86 87 FOR_EACH_PTR(hooks, fn) {
87 88 (*fn)(name, sym, expr, state);
88 89 } END_FOR_EACH_PTR(fn);
89 90 }
90 91
91 92 void call_extra_mod_hooks(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
92 93 {
93 94 call_extra_hooks(extra_mod_hooks, name, sym, expr, state);
94 95 }
95 96
96 97 void call_extra_nomod_hooks(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
97 98 {
98 99 call_extra_hooks(extra_nomod_hooks, name, sym, expr, state);
99 100 }
100 101
101 102 static bool in_param_set;
102 103 void set_extra_mod_helper(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
103 104 {
104 105 remove_from_equiv(name, sym);
105 106 call_extra_mod_hooks(name, sym, expr, state);
106 107 if ((__in_fake_assign || in_param_set) &&
107 108 estate_is_unknown(state) && !get_state(SMATCH_EXTRA, name, sym))
108 109 return;
109 110 set_state(SMATCH_EXTRA, name, sym, state);
110 111 }
111 112
112 113 static void set_extra_nomod_helper(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
113 114 {
114 115 call_extra_nomod_hooks(name, sym, expr, state);
115 116 set_state(SMATCH_EXTRA, name, sym, state);
116 117 }
117 118
118 119 static char *get_pointed_at(const char *name, struct symbol *sym, struct symbol **new_sym)
119 120 {
120 121 struct expression *assigned;
121 122
122 123 if (name[0] != '*')
123 124 return NULL;
124 125 if (strcmp(name + 1, sym->ident->name) != 0)
125 126 return NULL;
126 127
↓ open down ↓ |
73 lines elided |
↑ open up ↑ |
127 128 assigned = get_assigned_expr_name_sym(sym->ident->name, sym);
128 129 if (!assigned)
129 130 return NULL;
130 131 assigned = strip_parens(assigned);
131 132 if (assigned->type != EXPR_PREOP || assigned->op != '&')
132 133 return NULL;
133 134
134 135 return expr_to_var_sym(assigned->unop, new_sym);
135 136 }
136 137
137 -char *get_other_name_sym(const char *name, struct symbol *sym, struct symbol **new_sym)
138 +char *get_other_name_sym_from_chunk(const char *name, const char *chunk, int len, struct symbol *sym, struct symbol **new_sym)
138 139 {
139 140 struct expression *assigned;
140 141 char *orig_name = NULL;
141 142 char buf[256];
142 - char *ret = NULL;
143 - int skip;
143 + char *ret;
144 144
145 - *new_sym = NULL;
146 -
147 - if (!sym || !sym->ident)
148 - return NULL;
149 -
150 - ret = get_pointed_at(name, sym, new_sym);
151 - if (ret)
152 - return ret;
153 -
154 - skip = strlen(sym->ident->name);
155 - if (name[skip] != '-' || name[skip + 1] != '>')
156 - return NULL;
157 - skip += 2;
158 -
159 - assigned = get_assigned_expr_name_sym(sym->ident->name, sym);
145 + assigned = get_assigned_expr_name_sym(chunk, sym);
160 146 if (!assigned)
161 147 return NULL;
162 148 if (assigned->type == EXPR_CALL)
163 149 return map_call_to_other_name_sym(name, sym, new_sym);
164 - if (assigned->type == EXPR_PREOP || assigned->op == '&') {
150 + if (assigned->type == EXPR_PREOP && assigned->op == '&') {
165 151
166 152 orig_name = expr_to_var_sym(assigned, new_sym);
167 153 if (!orig_name || !*new_sym)
168 154 goto free;
169 155
170 - snprintf(buf, sizeof(buf), "%s.%s", orig_name + 1, name + skip);
156 + snprintf(buf, sizeof(buf), "%s.%s", orig_name + 1, name + len);
171 157 ret = alloc_string(buf);
172 158 free_string(orig_name);
173 159 return ret;
174 160 }
175 161
176 - if (assigned->type != EXPR_DEREF)
177 - goto free;
178 -
179 162 orig_name = expr_to_var_sym(assigned, new_sym);
180 163 if (!orig_name || !*new_sym)
181 164 goto free;
182 165
183 - snprintf(buf, sizeof(buf), "%s->%s", orig_name, name + skip);
166 + snprintf(buf, sizeof(buf), "%s->%s", orig_name, name + len);
184 167 ret = alloc_string(buf);
185 168 free_string(orig_name);
186 169 return ret;
187 -
188 170 free:
189 171 free_string(orig_name);
190 172 return NULL;
191 173 }
192 174
175 +static char *get_long_name_sym(const char *name, struct symbol *sym, struct symbol **new_sym)
176 +{
177 + struct expression *tmp;
178 + struct sm_state *sm;
179 + char buf[256];
180 +
181 + /*
182 + * Just prepend the name with a different name/sym and return that.
183 + * For example, if we set "foo->bar = bar;" then we clamp "bar->baz",
184 + * that also clamps "foo->bar->baz".
185 + *
186 + */
187 +
188 + FOR_EACH_MY_SM(check_assigned_expr_id, __get_cur_stree(), sm) {
189 + tmp = sm->state->data;
190 + if (!tmp || tmp->type != EXPR_SYMBOL)
191 + continue;
192 + if (tmp->symbol == sym)
193 + goto found;
194 + } END_FOR_EACH_SM(sm);
195 +
196 + return NULL;
197 +
198 +found:
199 + snprintf(buf, sizeof(buf), "%s%s", sm->name, name + tmp->symbol->ident->len);
200 + *new_sym = sm->sym;
201 + return alloc_string(buf);
202 +}
203 +
204 +char *get_other_name_sym_helper(const char *name, struct symbol *sym, struct symbol **new_sym, bool use_stack)
205 +{
206 + char buf[256];
207 + char *ret;
208 + int len;
209 +
210 + *new_sym = NULL;
211 +
212 + if (!sym || !sym->ident)
213 + return NULL;
214 +
215 + ret = get_pointed_at(name, sym, new_sym);
216 + if (ret)
217 + return ret;
218 +
219 + ret = map_long_to_short_name_sym(name, sym, new_sym, use_stack);
220 + if (ret)
221 + return ret;
222 +
223 + len = snprintf(buf, sizeof(buf), "%s", name);
224 + if (len >= sizeof(buf) - 2)
225 + return NULL;
226 +
227 + while (len >= 1) {
228 + if (buf[len] == '>' && buf[len - 1] == '-') {
229 + len--;
230 + buf[len] = '\0';
231 + ret = get_other_name_sym_from_chunk(name, buf, len + 2, sym, new_sym);
232 + if (ret)
233 + return ret;
234 + }
235 + len--;
236 + }
237 +
238 + ret = get_long_name_sym(name, sym, new_sym);
239 + if (ret)
240 + return ret;
241 +
242 + return NULL;
243 +}
244 +
245 +char *get_other_name_sym(const char *name, struct symbol *sym, struct symbol **new_sym)
246 +{
247 + return get_other_name_sym_helper(name, sym, new_sym, true);
248 +}
249 +
250 +char *get_other_name_sym_nostack(const char *name, struct symbol *sym, struct symbol **new_sym)
251 +{
252 + return get_other_name_sym_helper(name, sym, new_sym, false);
253 +}
254 +
193 255 void set_extra_mod(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
194 256 {
195 257 char *new_name;
196 258 struct symbol *new_sym;
197 259
198 260 set_extra_mod_helper(name, sym, expr, state);
199 261 new_name = get_other_name_sym(name, sym, &new_sym);
200 262 if (new_name && new_sym)
201 263 set_extra_mod_helper(new_name, new_sym, expr, state);
202 264 free_string(new_name);
203 265 }
204 266
205 267 static struct expression *chunk_get_array_base(struct expression *expr)
206 268 {
207 269 /*
208 270 * The problem with is_array() is that it only returns true for things
209 271 * like foo[1] but not for foo[1].bar.
210 272 *
211 273 */
212 274 expr = strip_expr(expr);
213 275 while (expr && expr->type == EXPR_DEREF)
214 276 expr = strip_expr(expr->deref);
215 277 return get_array_base(expr);
216 278 }
217 279
218 280 static int chunk_has_array(struct expression *expr)
219 281 {
220 282 return !!chunk_get_array_base(expr);
221 283 }
222 284
223 285 static void clear_array_states(struct expression *array)
224 286 {
225 287 struct sm_state *sm;
226 288
227 289 sm = get_sm_state_expr(link_id, array);
228 290 if (sm)
229 291 match_link_modify(sm, NULL);
230 292 }
231 293
232 294 static void set_extra_array_mod(struct expression *expr, struct smatch_state *state)
233 295 {
234 296 struct expression *array;
235 297 struct var_sym_list *vsl;
236 298 struct var_sym *vs;
237 299 char *name;
238 300 struct symbol *sym;
239 301
240 302 array = chunk_get_array_base(expr);
241 303
242 304 name = expr_to_chunk_sym_vsl(expr, &sym, &vsl);
243 305 if (!name || !vsl) {
244 306 clear_array_states(array);
245 307 goto free;
246 308 }
247 309
248 310 FOR_EACH_PTR(vsl, vs) {
249 311 store_link(link_id, vs->var, vs->sym, name, sym);
250 312 } END_FOR_EACH_PTR(vs);
251 313
252 314 call_extra_mod_hooks(name, sym, expr, state);
253 315 set_state(SMATCH_EXTRA, name, sym, state);
254 316 free:
255 317 free_string(name);
256 318 }
257 319
258 320 void set_extra_expr_mod(struct expression *expr, struct smatch_state *state)
259 321 {
260 322 struct symbol *sym;
261 323 char *name;
262 324
263 325 if (chunk_has_array(expr)) {
264 326 set_extra_array_mod(expr, state);
265 327 return;
266 328 }
267 329
268 330 expr = strip_expr(expr);
269 331 name = expr_to_var_sym(expr, &sym);
270 332 if (!name || !sym)
271 333 goto free;
272 334 set_extra_mod(name, sym, expr, state);
273 335 free:
274 336 free_string(name);
275 337 }
276 338
277 339 void set_extra_nomod(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
278 340 {
279 341 char *new_name;
280 342 struct symbol *new_sym;
281 343 struct relation *rel;
282 344 struct smatch_state *orig_state;
283 345
284 346 orig_state = get_state(SMATCH_EXTRA, name, sym);
285 347
286 348 /* don't save unknown states if leaving it blank is the same */
287 349 if (!orig_state && estate_is_unknown(state))
288 350 return;
289 351
290 352 new_name = get_other_name_sym(name, sym, &new_sym);
291 353 if (new_name && new_sym)
292 354 set_extra_nomod_helper(new_name, new_sym, expr, state);
293 355 free_string(new_name);
↓ open down ↓ |
91 lines elided |
↑ open up ↑ |
294 356
295 357 if (!estate_related(orig_state)) {
296 358 set_extra_nomod_helper(name, sym, expr, state);
297 359 return;
298 360 }
299 361
300 362 set_related(state, estate_related(orig_state));
301 363 FOR_EACH_PTR(estate_related(orig_state), rel) {
302 364 struct smatch_state *estate;
303 365
304 - if (option_debug_related)
305 - sm_msg("%s updating related %s to %s", name, rel->name, state->name);
306 366 estate = get_state(SMATCH_EXTRA, rel->name, rel->sym);
307 367 if (!estate)
308 368 continue;
309 369 set_extra_nomod_helper(rel->name, rel->sym, expr, clone_estate_cast(estate_type(estate), state));
310 370 } END_FOR_EACH_PTR(rel);
311 371 }
312 372
313 373 void set_extra_nomod_vsl(const char *name, struct symbol *sym, struct var_sym_list *vsl, struct expression *expr, struct smatch_state *state)
314 374 {
315 375 struct var_sym *vs;
316 376
317 377 FOR_EACH_PTR(vsl, vs) {
318 378 store_link(link_id, vs->var, vs->sym, name, sym);
319 379 } END_FOR_EACH_PTR(vs);
320 380
321 381 set_extra_nomod(name, sym, expr, state);
322 382 }
323 383
324 384 /*
325 385 * This is for return_implies_state() hooks which modify a SMATCH_EXTRA state
326 386 */
327 387 void set_extra_expr_nomod(struct expression *expr, struct smatch_state *state)
328 388 {
329 389 struct var_sym_list *vsl;
330 390 struct var_sym *vs;
331 391 char *name;
332 392 struct symbol *sym;
333 393
334 394 name = expr_to_chunk_sym_vsl(expr, &sym, &vsl);
335 395 if (!name || !vsl)
336 396 goto free;
337 397 FOR_EACH_PTR(vsl, vs) {
338 398 store_link(link_id, vs->var, vs->sym, name, sym);
339 399 } END_FOR_EACH_PTR(vs);
340 400
341 401 set_extra_nomod(name, sym, expr, state);
342 402 free:
343 403 free_string(name);
344 404 }
345 405
346 406 static void set_extra_true_false(const char *name, struct symbol *sym,
347 407 struct smatch_state *true_state,
348 408 struct smatch_state *false_state)
349 409 {
350 410 char *new_name;
351 411 struct symbol *new_sym;
352 412 struct relation *rel;
353 413 struct smatch_state *orig_state;
354 414
355 415 if (!true_state && !false_state)
356 416 return;
357 417
358 418 if (in_warn_on_macro())
359 419 return;
360 420
361 421 new_name = get_other_name_sym(name, sym, &new_sym);
362 422 if (new_name && new_sym)
363 423 set_true_false_states(SMATCH_EXTRA, new_name, new_sym, true_state, false_state);
364 424 free_string(new_name);
365 425
366 426 orig_state = get_state(SMATCH_EXTRA, name, sym);
367 427
368 428 if (!estate_related(orig_state)) {
369 429 set_true_false_states(SMATCH_EXTRA, name, sym, true_state, false_state);
370 430 return;
371 431 }
372 432
373 433 if (true_state)
374 434 set_related(true_state, estate_related(orig_state));
375 435 if (false_state)
376 436 set_related(false_state, estate_related(orig_state));
377 437
378 438 FOR_EACH_PTR(estate_related(orig_state), rel) {
379 439 set_true_false_states(SMATCH_EXTRA, rel->name, rel->sym,
380 440 true_state, false_state);
381 441 } END_FOR_EACH_PTR(rel);
382 442 }
383 443
384 444 static void set_extra_chunk_true_false(struct expression *expr,
385 445 struct smatch_state *true_state,
386 446 struct smatch_state *false_state)
387 447 {
388 448 struct var_sym_list *vsl;
389 449 struct var_sym *vs;
390 450 struct symbol *type;
391 451 char *name;
392 452 struct symbol *sym;
393 453
394 454 if (in_warn_on_macro())
395 455 return;
396 456
397 457 type = get_type(expr);
398 458 if (!type)
399 459 return;
400 460
401 461 name = expr_to_chunk_sym_vsl(expr, &sym, &vsl);
402 462 if (!name || !vsl)
403 463 goto free;
404 464 FOR_EACH_PTR(vsl, vs) {
405 465 store_link(link_id, vs->var, vs->sym, name, sym);
406 466 } END_FOR_EACH_PTR(vs);
407 467
408 468 set_true_false_states(SMATCH_EXTRA, name, sym,
409 469 clone_estate(true_state),
410 470 clone_estate(false_state));
411 471 free:
412 472 free_string(name);
413 473 }
414 474
415 475 static void set_extra_expr_true_false(struct expression *expr,
416 476 struct smatch_state *true_state,
417 477 struct smatch_state *false_state)
418 478 {
419 479 char *name;
420 480 struct symbol *sym;
421 481 sval_t sval;
422 482
423 483 if (!true_state && !false_state)
424 484 return;
425 485
426 486 if (get_value(expr, &sval))
427 487 return;
428 488
429 489 expr = strip_expr(expr);
430 490 name = expr_to_var_sym(expr, &sym);
431 491 if (!name || !sym) {
432 492 free_string(name);
433 493 set_extra_chunk_true_false(expr, true_state, false_state);
434 494 return;
435 495 }
436 496 set_extra_true_false(name, sym, true_state, false_state);
437 497 free_string(name);
438 498 }
439 499
440 500 static int get_countdown_info(struct expression *condition, struct expression **unop, int *op, sval_t *right)
441 501 {
442 502 struct expression *unop_expr;
443 503 int comparison;
444 504 sval_t limit;
445 505
446 506 right->type = &int_ctype;
447 507 right->value = 0;
448 508
449 509 condition = strip_expr(condition);
450 510
451 511 if (condition->type == EXPR_COMPARE) {
452 512 comparison = remove_unsigned_from_comparison(condition->op);
453 513
454 514 if (comparison != SPECIAL_GTE && comparison != '>')
455 515 return 0;
456 516 if (!get_value(condition->right, &limit))
457 517 return 0;
458 518
459 519 unop_expr = condition->left;
460 520 if (unop_expr->type != EXPR_PREOP && unop_expr->type != EXPR_POSTOP)
461 521 return 0;
462 522 if (unop_expr->op != SPECIAL_DECREMENT)
463 523 return 0;
464 524
465 525 *unop = unop_expr;
466 526 *op = comparison;
467 527 *right = limit;
468 528
469 529 return 1;
470 530 }
471 531
472 532 if (condition->type != EXPR_PREOP && condition->type != EXPR_POSTOP)
473 533 return 0;
474 534 if (condition->op != SPECIAL_DECREMENT)
475 535 return 0;
476 536
↓ open down ↓ |
161 lines elided |
↑ open up ↑ |
477 537 *unop = condition;
478 538 *op = '>';
479 539
480 540 return 1;
481 541 }
482 542
483 543 static struct sm_state *handle_canonical_while_count_down(struct statement *loop)
484 544 {
485 545 struct expression *iter_var;
486 546 struct expression *condition, *unop;
547 + struct symbol *type;
487 548 struct sm_state *sm;
488 549 struct smatch_state *estate;
489 550 int op;
490 551 sval_t start, right;
491 552
492 553 right.type = &int_ctype;
493 554 right.value = 0;
494 555
495 556 condition = strip_expr(loop->iterator_pre_condition);
496 557 if (!condition)
497 558 return NULL;
498 559
499 560 if (!get_countdown_info(condition, &unop, &op, &right))
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
500 561 return NULL;
501 562
502 563 iter_var = unop->unop;
503 564
504 565 sm = get_sm_state_expr(SMATCH_EXTRA, iter_var);
505 566 if (!sm)
506 567 return NULL;
507 568 if (sval_cmp(estate_min(sm->state), right) < 0)
508 569 return NULL;
509 570 start = estate_max(sm->state);
571 +
572 + type = get_type(iter_var);
573 + right = sval_cast(type, right);
574 + start = sval_cast(type, start);
575 +
510 576 if (sval_cmp(start, right) <= 0)
511 577 return NULL;
512 578 if (!sval_is_max(start))
513 579 start.value--;
514 580
515 581 if (op == SPECIAL_GTE)
516 582 right.value--;
517 583
518 584 if (unop->type == EXPR_PREOP) {
519 585 right.value++;
520 586 estate = alloc_estate_range(right, start);
521 587 if (estate_has_hard_max(sm->state))
522 588 estate_set_hard_max(estate);
523 589 estate_copy_fuzzy_max(estate, sm->state);
524 590 set_extra_expr_mod(iter_var, estate);
525 591 }
526 592 if (unop->type == EXPR_POSTOP) {
527 593 estate = alloc_estate_range(right, start);
528 594 if (estate_has_hard_max(sm->state))
529 595 estate_set_hard_max(estate);
530 596 estate_copy_fuzzy_max(estate, sm->state);
531 597 set_extra_expr_mod(iter_var, estate);
532 598 }
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
533 599 return get_sm_state_expr(SMATCH_EXTRA, iter_var);
534 600 }
535 601
536 602 static struct sm_state *handle_canonical_for_inc(struct expression *iter_expr,
537 603 struct expression *condition)
538 604 {
539 605 struct expression *iter_var;
540 606 struct sm_state *sm;
541 607 struct smatch_state *estate;
542 608 sval_t start, end, max;
609 + struct symbol *type;
543 610
544 611 iter_var = iter_expr->unop;
545 612 sm = get_sm_state_expr(SMATCH_EXTRA, iter_var);
546 613 if (!sm)
547 614 return NULL;
548 615 if (!estate_get_single_value(sm->state, &start))
549 616 return NULL;
550 - if (get_implied_max(condition->right, &end))
551 - end = sval_cast(get_type(iter_var), end);
552 - else
553 - end = sval_type_max(get_type(iter_var));
617 + if (!get_implied_value(condition->right, &end))
618 + return NULL;
554 619
555 620 if (get_sm_state_expr(SMATCH_EXTRA, condition->left) != sm)
556 621 return NULL;
557 622
558 623 switch (condition->op) {
559 624 case SPECIAL_UNSIGNED_LT:
560 625 case SPECIAL_NOTEQUAL:
561 626 case '<':
562 627 if (!sval_is_min(end))
563 628 end.value--;
564 629 break;
565 630 case SPECIAL_UNSIGNED_LTE:
566 631 case SPECIAL_LTE:
567 632 break;
568 633 default:
569 634 return NULL;
570 635 }
571 636 if (sval_cmp(end, start) < 0)
572 637 return NULL;
638 + type = get_type(iter_var);
639 + start = sval_cast(type, start);
640 + end = sval_cast(type, end);
573 641 estate = alloc_estate_range(start, end);
574 642 if (get_hard_max(condition->right, &max)) {
575 - estate_set_hard_max(estate);
643 + if (!get_macro_name(condition->pos))
644 + estate_set_hard_max(estate);
576 645 if (condition->op == '<' ||
577 646 condition->op == SPECIAL_UNSIGNED_LT ||
578 647 condition->op == SPECIAL_NOTEQUAL)
579 648 max.value--;
649 + max = sval_cast(type, max);
580 650 estate_set_fuzzy_max(estate, max);
581 651 }
582 652 set_extra_expr_mod(iter_var, estate);
583 653 return get_sm_state_expr(SMATCH_EXTRA, iter_var);
584 654 }
585 655
586 656 static struct sm_state *handle_canonical_for_dec(struct expression *iter_expr,
587 657 struct expression *condition)
588 658 {
589 659 struct expression *iter_var;
590 660 struct sm_state *sm;
591 661 struct smatch_state *estate;
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
592 662 sval_t start, end;
593 663
594 664 iter_var = iter_expr->unop;
595 665 sm = get_sm_state_expr(SMATCH_EXTRA, iter_var);
596 666 if (!sm)
597 667 return NULL;
598 668 if (!estate_get_single_value(sm->state, &start))
599 669 return NULL;
600 670 if (!get_implied_min(condition->right, &end))
601 671 end = sval_type_min(get_type(iter_var));
672 + end = sval_cast(estate_type(sm->state), end);
602 673 if (get_sm_state_expr(SMATCH_EXTRA, condition->left) != sm)
603 674 return NULL;
604 675
605 676 switch (condition->op) {
606 677 case SPECIAL_NOTEQUAL:
607 678 case '>':
608 - if (!sval_is_min(end) && !sval_is_max(end))
679 + if (!sval_is_max(end))
609 680 end.value++;
610 681 break;
611 682 case SPECIAL_GTE:
612 683 break;
613 684 default:
614 685 return NULL;
615 686 }
616 687 if (sval_cmp(end, start) > 0)
617 688 return NULL;
618 689 estate = alloc_estate_range(end, start);
619 690 estate_set_hard_max(estate);
620 691 estate_set_fuzzy_max(estate, estate_get_fuzzy_max(estate));
621 692 set_extra_expr_mod(iter_var, estate);
622 693 return get_sm_state_expr(SMATCH_EXTRA, iter_var);
623 694 }
624 695
625 696 static struct sm_state *handle_canonical_for_loops(struct statement *loop)
626 697 {
627 698 struct expression *iter_expr;
628 699 struct expression *condition;
629 700
630 701 if (!loop->iterator_post_statement)
631 702 return NULL;
632 703 if (loop->iterator_post_statement->type != STMT_EXPRESSION)
633 704 return NULL;
634 705 iter_expr = loop->iterator_post_statement->expression;
635 706 if (!loop->iterator_pre_condition)
636 707 return NULL;
637 708 if (loop->iterator_pre_condition->type != EXPR_COMPARE)
638 709 return NULL;
639 710 condition = loop->iterator_pre_condition;
640 711
641 712 if (iter_expr->op == SPECIAL_INCREMENT)
642 713 return handle_canonical_for_inc(iter_expr, condition);
643 714 if (iter_expr->op == SPECIAL_DECREMENT)
644 715 return handle_canonical_for_dec(iter_expr, condition);
645 716 return NULL;
646 717 }
647 718
648 719 struct sm_state *__extra_handle_canonical_loops(struct statement *loop, struct stree **stree)
649 720 {
650 721 struct sm_state *ret;
651 722
652 723 /*
653 724 * Canonical loops are a hack. The proper way to handle this is to
654 725 * use two passes, but unfortunately, doing two passes makes parsing
655 726 * code twice as slow.
656 727 *
657 728 * What we do is we set the inside state here, which overwrites whatever
658 729 * __extra_match_condition() does. Then we set the outside state in
659 730 * __extra_pre_loop_hook_after().
660 731 *
661 732 */
662 733 __push_fake_cur_stree();
663 734 if (!loop->iterator_post_statement)
664 735 ret = handle_canonical_while_count_down(loop);
665 736 else
666 737 ret = handle_canonical_for_loops(loop);
667 738 *stree = __pop_fake_cur_stree();
668 739 return ret;
669 740 }
670 741
671 742 int __iterator_unchanged(struct sm_state *sm)
672 743 {
673 744 if (!sm)
674 745 return 0;
675 746 if (get_sm_state(my_id, sm->name, sm->sym) == sm)
676 747 return 1;
677 748 return 0;
678 749 }
679 750
680 751 static void while_count_down_after(struct sm_state *sm, struct expression *condition)
681 752 {
682 753 struct expression *unop;
683 754 int op;
684 755 sval_t limit, after_value;
685 756
686 757 if (!get_countdown_info(condition, &unop, &op, &limit))
687 758 return;
688 759 after_value = estate_min(sm->state);
689 760 after_value.value--;
690 761 set_extra_mod(sm->name, sm->sym, condition->unop, alloc_estate_sval(after_value));
691 762 }
692 763
693 764 void __extra_pre_loop_hook_after(struct sm_state *sm,
694 765 struct statement *iterator,
695 766 struct expression *condition)
696 767 {
697 768 struct expression *iter_expr;
698 769 sval_t limit;
699 770 struct smatch_state *state;
700 771
701 772 if (!iterator) {
702 773 while_count_down_after(sm, condition);
703 774 return;
704 775 }
705 776
706 777 iter_expr = iterator->expression;
↓ open down ↓ |
88 lines elided |
↑ open up ↑ |
707 778
708 779 if (condition->type != EXPR_COMPARE)
709 780 return;
710 781 if (iter_expr->op == SPECIAL_INCREMENT) {
711 782 limit = sval_binop(estate_max(sm->state), '+',
712 783 sval_type_val(estate_type(sm->state), 1));
713 784 } else {
714 785 limit = sval_binop(estate_min(sm->state), '-',
715 786 sval_type_val(estate_type(sm->state), 1));
716 787 }
788 + limit = sval_cast(estate_type(sm->state), limit);
717 789 if (!estate_has_hard_max(sm->state) && !__has_breaks()) {
718 790 if (iter_expr->op == SPECIAL_INCREMENT)
719 791 state = alloc_estate_range(estate_min(sm->state), limit);
720 792 else
721 793 state = alloc_estate_range(limit, estate_max(sm->state));
722 794 } else {
723 795 state = alloc_estate_sval(limit);
724 796 }
725 797 if (!estate_has_hard_max(sm->state)) {
726 798 estate_clear_hard_max(state);
727 799 }
728 800 if (estate_has_fuzzy_max(sm->state)) {
729 801 sval_t hmax = estate_get_fuzzy_max(sm->state);
730 802 sval_t max = estate_max(sm->state);
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
731 803
732 804 if (sval_cmp(hmax, max) != 0)
733 805 estate_clear_fuzzy_max(state);
734 806 } else if (!estate_has_fuzzy_max(sm->state)) {
735 807 estate_clear_fuzzy_max(state);
736 808 }
737 809
738 810 set_extra_mod(sm->name, sm->sym, iter_expr, state);
739 811 }
740 812
813 +static bool get_global_rl(const char *name, struct symbol *sym, struct range_list **rl)
814 +{
815 + struct expression *expr;
816 +
817 + if (!sym || !(sym->ctype.modifiers & MOD_TOPLEVEL) || !sym->ident)
818 + return false;
819 + if (strcmp(sym->ident->name, name) != 0)
820 + return false;
821 +
822 + expr = symbol_expression(sym);
823 + return get_implied_rl(expr, rl);
824 +}
825 +
741 826 static struct stree *unmatched_stree;
742 827 static struct smatch_state *unmatched_state(struct sm_state *sm)
743 828 {
744 829 struct smatch_state *state;
830 + struct range_list *rl;
745 831
746 832 if (unmatched_stree) {
747 833 state = get_state_stree(unmatched_stree, SMATCH_EXTRA, sm->name, sm->sym);
748 834 if (state)
749 835 return state;
750 836 }
751 837 if (parent_is_gone_var_sym(sm->name, sm->sym))
752 838 return alloc_estate_empty();
839 + if (get_global_rl(sm->name, sm->sym, &rl))
840 + return alloc_estate_rl(rl);
753 841 return alloc_estate_whole(estate_type(sm->state));
754 842 }
755 843
756 844 static void clear_the_pointed_at(struct expression *expr)
757 845 {
758 846 struct stree *stree;
759 847 char *name;
760 848 struct symbol *sym;
761 849 struct sm_state *tmp;
762 850
763 851 name = expr_to_var_sym(expr, &sym);
764 852 if (!name || !sym)
765 853 goto free;
766 854
767 855 stree = __get_cur_stree();
768 856 FOR_EACH_MY_SM(SMATCH_EXTRA, stree, tmp) {
769 857 if (tmp->name[0] != '*')
770 858 continue;
771 859 if (tmp->sym != sym)
772 860 continue;
773 861 if (strcmp(tmp->name + 1, name) != 0)
774 862 continue;
775 863 set_extra_mod(tmp->name, tmp->sym, expr, alloc_estate_whole(estate_type(tmp->state)));
776 864 } END_FOR_EACH_SM(tmp);
777 865
778 866 free:
779 867 free_string(name);
780 868 }
781 869
782 870 static int is_const_param(struct expression *expr, int param)
783 871 {
784 872 struct symbol *type;
785 873
786 874 type = get_arg_type(expr, param);
787 875 if (!type)
788 876 return 0;
789 877 if (type->ctype.modifiers & MOD_CONST)
790 878 return 1;
791 879 return 0;
792 880 }
793 881
794 882 static void match_function_call(struct expression *expr)
795 883 {
796 884 struct expression *arg;
797 885 struct expression *tmp;
798 886 int param = -1;
799 887
800 888 /* if we have the db this is handled in smatch_function_hooks.c */
801 889 if (!option_no_db)
802 890 return;
803 891 if (inlinable(expr->fn))
804 892 return;
805 893
806 894 FOR_EACH_PTR(expr->args, arg) {
807 895 param++;
↓ open down ↓ |
45 lines elided |
↑ open up ↑ |
808 896 if (is_const_param(expr->fn, param))
809 897 continue;
810 898 tmp = strip_expr(arg);
811 899 if (tmp->type == EXPR_PREOP && tmp->op == '&')
812 900 set_extra_expr_mod(tmp->unop, alloc_estate_whole(get_type(tmp->unop)));
813 901 else
814 902 clear_the_pointed_at(tmp);
815 903 } END_FOR_EACH_PTR(arg);
816 904 }
817 905
818 -static int values_fit_type(struct expression *left, struct expression *right)
906 +int values_fit_type(struct expression *left, struct expression *right)
819 907 {
820 908 struct range_list *rl;
821 909 struct symbol *type;
822 910
823 911 type = get_type(left);
824 912 if (!type)
825 913 return 0;
826 914 get_absolute_rl(right, &rl);
915 + if (type == rl_type(rl))
916 + return 1;
827 917 if (type_unsigned(type) && sval_is_negative(rl_min(rl)))
828 918 return 0;
829 919 if (sval_cmp(sval_type_min(type), rl_min(rl)) > 0)
830 920 return 0;
831 921 if (sval_cmp(sval_type_max(type), rl_max(rl)) < 0)
832 922 return 0;
833 923 return 1;
834 924 }
835 925
836 926 static void save_chunk_info(struct expression *left, struct expression *right)
837 927 {
838 928 struct var_sym_list *vsl;
839 929 struct var_sym *vs;
840 930 struct expression *add_expr;
841 931 struct symbol *type;
842 932 sval_t sval;
843 933 char *name;
844 934 struct symbol *sym;
845 935
846 936 if (right->type != EXPR_BINOP || right->op != '-')
847 937 return;
848 938 if (!get_value(right->left, &sval))
849 939 return;
850 940 if (!expr_to_sym(right->right))
851 941 return;
852 942
853 943 add_expr = binop_expression(left, '+', right->right);
854 944 type = get_type(add_expr);
855 945 if (!type)
856 946 return;
857 947 name = expr_to_chunk_sym_vsl(add_expr, &sym, &vsl);
858 948 if (!name || !vsl)
859 949 goto free;
860 950 FOR_EACH_PTR(vsl, vs) {
861 951 store_link(link_id, vs->var, vs->sym, name, sym);
862 952 } END_FOR_EACH_PTR(vs);
863 953
864 954 set_state(SMATCH_EXTRA, name, sym, alloc_estate_sval(sval_cast(type, sval)));
865 955 free:
866 956 free_string(name);
867 957 }
868 958
869 959 static void do_array_assign(struct expression *left, int op, struct expression *right)
870 960 {
871 961 struct range_list *rl;
872 962
873 963 if (op == '=') {
874 964 get_absolute_rl(right, &rl);
875 965 rl = cast_rl(get_type(left), rl);
876 966 } else {
877 967 rl = alloc_whole_rl(get_type(left));
878 968 }
879 969
880 970 set_extra_array_mod(left, alloc_estate_rl(rl));
881 971 }
882 972
883 973 static void match_vanilla_assign(struct expression *left, struct expression *right)
884 974 {
885 975 struct range_list *orig_rl = NULL;
886 976 struct range_list *rl = NULL;
887 977 struct symbol *right_sym;
888 978 struct symbol *left_type;
889 979 struct symbol *right_type;
890 980 char *right_name = NULL;
891 981 struct symbol *sym;
892 982 char *name;
893 983 sval_t sval, max;
894 984 struct smatch_state *state;
895 985 int comparison;
896 986
897 987 if (is_struct(left))
898 988 return;
899 989
900 990 save_chunk_info(left, right);
901 991
902 992 name = expr_to_var_sym(left, &sym);
903 993 if (!name) {
904 994 if (chunk_has_array(left))
905 995 do_array_assign(left, '=', right);
906 996 return;
907 997 }
908 998
909 999 left_type = get_type(left);
910 1000 right_type = get_type(right);
911 1001
912 1002 right_name = expr_to_var_sym(right, &right_sym);
913 1003
914 1004 if (!__in_fake_assign &&
915 1005 !(right->type == EXPR_PREOP && right->op == '&') &&
916 1006 right_name && right_sym &&
917 1007 values_fit_type(left, strip_expr(right)) &&
918 1008 !has_symbol(right, sym)) {
919 1009 set_equiv(left, right);
920 1010 goto free;
921 1011 }
922 1012
923 1013 if (is_pointer(right) && get_address_rl(right, &rl)) {
924 1014 state = alloc_estate_rl(rl);
925 1015 goto done;
926 1016 }
927 1017
928 1018 if (get_implied_value(right, &sval)) {
929 1019 state = alloc_estate_sval(sval_cast(left_type, sval));
930 1020 goto done;
931 1021 }
932 1022
933 1023 if (__in_fake_assign) {
934 1024 struct smatch_state *right_state;
935 1025 sval_t sval;
936 1026
937 1027 if (get_value(right, &sval)) {
938 1028 sval = sval_cast(left_type, sval);
939 1029 state = alloc_estate_sval(sval);
940 1030 goto done;
941 1031 }
942 1032
943 1033 right_state = get_state(SMATCH_EXTRA, right_name, right_sym);
↓ open down ↓ |
107 lines elided |
↑ open up ↑ |
944 1034 if (right_state) {
945 1035 /* simple assignment */
946 1036 state = clone_estate(right_state);
947 1037 goto done;
948 1038 }
949 1039
950 1040 state = alloc_estate_rl(alloc_whole_rl(left_type));
951 1041 goto done;
952 1042 }
953 1043
954 - comparison = get_comparison(left, right);
1044 + comparison = get_comparison_no_extra(left, right);
955 1045 if (comparison) {
956 1046 comparison = flip_comparison(comparison);
957 1047 get_implied_rl(left, &orig_rl);
958 1048 }
959 1049
960 1050 if (get_implied_rl(right, &rl)) {
961 1051 rl = cast_rl(left_type, rl);
962 1052 if (orig_rl)
963 1053 filter_by_comparison(&rl, comparison, orig_rl);
964 1054 state = alloc_estate_rl(rl);
965 1055 if (get_hard_max(right, &max)) {
966 1056 estate_set_hard_max(state);
967 1057 estate_set_fuzzy_max(state, max);
968 1058 }
969 1059 } else {
970 1060 rl = alloc_whole_rl(right_type);
971 1061 rl = cast_rl(left_type, rl);
972 1062 if (orig_rl)
↓ open down ↓ |
8 lines elided |
↑ open up ↑ |
973 1063 filter_by_comparison(&rl, comparison, orig_rl);
974 1064 state = alloc_estate_rl(rl);
975 1065 }
976 1066
977 1067 done:
978 1068 set_extra_mod(name, sym, left, state);
979 1069 free:
980 1070 free_string(right_name);
981 1071 }
982 1072
983 -static int op_remove_assign(int op)
984 -{
985 - switch (op) {
986 - case SPECIAL_ADD_ASSIGN:
987 - return '+';
988 - case SPECIAL_SUB_ASSIGN:
989 - return '-';
990 - case SPECIAL_MUL_ASSIGN:
991 - return '*';
992 - case SPECIAL_DIV_ASSIGN:
993 - return '/';
994 - case SPECIAL_MOD_ASSIGN:
995 - return '%';
996 - case SPECIAL_AND_ASSIGN:
997 - return '&';
998 - case SPECIAL_OR_ASSIGN:
999 - return '|';
1000 - case SPECIAL_XOR_ASSIGN:
1001 - return '^';
1002 - case SPECIAL_SHL_ASSIGN:
1003 - return SPECIAL_LEFTSHIFT;
1004 - case SPECIAL_SHR_ASSIGN:
1005 - return SPECIAL_RIGHTSHIFT;
1006 - default:
1007 - return op;
1008 - }
1009 -}
1010 -
1011 1073 static void match_assign(struct expression *expr)
1012 1074 {
1013 1075 struct range_list *rl = NULL;
1014 1076 struct expression *left;
1015 1077 struct expression *right;
1016 1078 struct expression *binop_expr;
1017 1079 struct symbol *left_type;
1018 1080 struct symbol *sym;
1019 1081 char *name;
1020 - sval_t left_min, left_max;
1021 - sval_t right_min, right_max;
1022 - sval_t res_min, res_max;
1023 1082
1024 1083 left = strip_expr(expr->left);
1025 1084
1026 1085 right = strip_parens(expr->right);
1027 1086 if (right->type == EXPR_CALL && sym_name_is("__builtin_expect", right->fn))
1028 1087 right = get_argument_from_call_expr(right->args, 0);
1029 1088 while (right->type == EXPR_ASSIGNMENT && right->op == '=')
1030 1089 right = strip_parens(right->left);
1031 1090
1032 1091 if (expr->op == '=' && is_condition(expr->right))
1033 1092 return; /* handled in smatch_condition.c */
1034 1093 if (expr->op == '=' && right->type == EXPR_CALL)
1035 1094 return; /* handled in smatch_function_hooks.c */
1036 1095 if (expr->op == '=') {
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
1037 1096 match_vanilla_assign(left, right);
1038 1097 return;
1039 1098 }
1040 1099
1041 1100 name = expr_to_var_sym(left, &sym);
1042 1101 if (!name)
1043 1102 return;
1044 1103
1045 1104 left_type = get_type(left);
1046 1105
1047 - res_min = sval_type_min(left_type);
1048 - res_max = sval_type_max(left_type);
1049 -
1050 1106 switch (expr->op) {
1051 1107 case SPECIAL_ADD_ASSIGN:
1052 - get_absolute_max(left, &left_max);
1053 - get_absolute_max(right, &right_max);
1054 - if (sval_binop_overflows(left_max, '+', sval_cast(left_type, right_max)))
1055 - break;
1056 - if (get_implied_min(left, &left_min) &&
1057 - !sval_is_negative_min(left_min) &&
1058 - get_implied_min(right, &right_min) &&
1059 - !sval_is_negative_min(right_min)) {
1060 - res_min = sval_binop(left_min, '+', right_min);
1061 - res_min = sval_cast(left_type, res_min);
1062 - }
1063 - if (inside_loop()) /* we are assuming loops don't lead to wrapping */
1064 - break;
1065 - res_max = sval_binop(left_max, '+', right_max);
1066 - res_max = sval_cast(left_type, res_max);
1067 - break;
1068 1108 case SPECIAL_SUB_ASSIGN:
1069 - if (get_implied_max(left, &left_max) &&
1070 - !sval_is_max(left_max) &&
1071 - get_implied_min(right, &right_min) &&
1072 - !sval_is_min(right_min)) {
1073 - res_max = sval_binop(left_max, '-', right_min);
1074 - res_max = sval_cast(left_type, res_max);
1075 - }
1076 - if (inside_loop())
1077 - break;
1078 - if (get_implied_min(left, &left_min) &&
1079 - !sval_is_min(left_min) &&
1080 - get_implied_max(right, &right_max) &&
1081 - !sval_is_max(right_max)) {
1082 - res_min = sval_binop(left_min, '-', right_max);
1083 - res_min = sval_cast(left_type, res_min);
1084 - }
1085 - break;
1086 1109 case SPECIAL_AND_ASSIGN:
1087 1110 case SPECIAL_MOD_ASSIGN:
1088 1111 case SPECIAL_SHL_ASSIGN:
1089 1112 case SPECIAL_SHR_ASSIGN:
1090 1113 case SPECIAL_OR_ASSIGN:
1091 1114 case SPECIAL_XOR_ASSIGN:
1092 1115 case SPECIAL_MUL_ASSIGN:
1093 1116 case SPECIAL_DIV_ASSIGN:
1094 1117 binop_expr = binop_expression(expr->left,
1095 1118 op_remove_assign(expr->op),
1096 1119 expr->right);
1097 - if (get_absolute_rl(binop_expr, &rl)) {
1098 - rl = cast_rl(left_type, rl);
1099 - set_extra_mod(name, sym, left, alloc_estate_rl(rl));
1100 - goto free;
1120 + get_absolute_rl(binop_expr, &rl);
1121 + rl = cast_rl(left_type, rl);
1122 + if (inside_loop()) {
1123 + if (expr->op == SPECIAL_ADD_ASSIGN)
1124 + add_range(&rl, rl_max(rl), sval_type_max(rl_type(rl)));
1125 +
1126 + if (expr->op == SPECIAL_SUB_ASSIGN &&
1127 + !sval_is_negative(rl_min(rl))) {
1128 + sval_t zero = { .type = rl_type(rl) };
1129 +
1130 + add_range(&rl, rl_min(rl), zero);
1131 + }
1101 1132 }
1102 - break;
1133 + set_extra_mod(name, sym, left, alloc_estate_rl(rl));
1134 + goto free;
1103 1135 }
1104 - rl = cast_rl(left_type, alloc_rl(res_min, res_max));
1105 - set_extra_mod(name, sym, left, alloc_estate_rl(rl));
1136 + set_extra_mod(name, sym, left, alloc_estate_whole(left_type));
1106 1137 free:
1107 1138 free_string(name);
1108 1139 }
1109 1140
1110 1141 static struct smatch_state *increment_state(struct smatch_state *state)
1111 1142 {
1112 1143 sval_t min = estate_min(state);
1113 1144 sval_t max = estate_max(state);
1114 1145
1115 1146 if (!estate_rl(state))
1116 1147 return NULL;
1117 1148
1118 1149 if (inside_loop())
1119 1150 max = sval_type_max(max.type);
1120 1151
1121 1152 if (!sval_is_min(min) && !sval_is_max(min))
1122 1153 min.value++;
1123 1154 if (!sval_is_min(max) && !sval_is_max(max))
1124 1155 max.value++;
1125 1156 return alloc_estate_range(min, max);
1126 1157 }
1127 1158
1128 1159 static struct smatch_state *decrement_state(struct smatch_state *state)
1129 1160 {
1130 1161 sval_t min = estate_min(state);
1131 1162 sval_t max = estate_max(state);
1132 1163
1133 1164 if (!estate_rl(state))
1134 1165 return NULL;
1135 1166
1136 1167 if (inside_loop())
1137 1168 min = sval_type_min(min.type);
1138 1169
1139 1170 if (!sval_is_min(min) && !sval_is_max(min))
1140 1171 min.value--;
1141 1172 if (!sval_is_min(max) && !sval_is_max(max))
1142 1173 max.value--;
1143 1174 return alloc_estate_range(min, max);
1144 1175 }
1145 1176
1146 1177 static void clear_pointed_at_state(struct expression *expr)
1147 1178 {
1148 1179 struct symbol *type;
1149 1180
1150 1181 /*
1151 1182 * ALERT: This is sort of a mess. If it's is a struct assigment like
1152 1183 * "foo = bar;", then that's handled by smatch_struct_assignment.c.
1153 1184 * the same thing for p++ where "p" is a struct. Most modifications
1154 1185 * are handled by the assignment hook or the db. Smatch_extra.c doesn't
1155 1186 * use smatch_modification.c because we have to get the ordering right
1156 1187 * or something. So if you have p++ where p is a pointer to a standard
1157 1188 * c type then we handle that here. What a mess.
1158 1189 */
1159 1190 expr = strip_expr(expr);
1160 1191 type = get_type(expr);
1161 1192 if (!type || type->type != SYM_PTR)
1162 1193 return;
1163 1194 type = get_real_base_type(type);
1164 1195 if (!type || type->type != SYM_BASETYPE)
1165 1196 return;
1166 1197 set_extra_expr_nomod(deref_expression(expr), alloc_estate_whole(type));
1167 1198 }
1168 1199
1169 1200 static void unop_expr(struct expression *expr)
1170 1201 {
1171 1202 struct smatch_state *state;
1172 1203
1173 1204 if (expr->smatch_flags & Handled)
1174 1205 return;
1175 1206
1176 1207 switch (expr->op) {
1177 1208 case SPECIAL_INCREMENT:
1178 1209 state = get_state_expr(SMATCH_EXTRA, expr->unop);
1179 1210 state = increment_state(state);
1180 1211 if (!state)
1181 1212 state = alloc_estate_whole(get_type(expr));
1182 1213 set_extra_expr_mod(expr->unop, state);
1183 1214 clear_pointed_at_state(expr->unop);
1184 1215 break;
1185 1216 case SPECIAL_DECREMENT:
1186 1217 state = get_state_expr(SMATCH_EXTRA, expr->unop);
1187 1218 state = decrement_state(state);
1188 1219 if (!state)
1189 1220 state = alloc_estate_whole(get_type(expr));
1190 1221 set_extra_expr_mod(expr->unop, state);
1191 1222 clear_pointed_at_state(expr->unop);
1192 1223 break;
1193 1224 default:
1194 1225 return;
1195 1226 }
1196 1227 }
1197 1228
1198 1229 static void asm_expr(struct statement *stmt)
1199 1230 {
1200 1231
1201 1232 struct expression *expr;
1202 1233 struct symbol *type;
1203 1234 int state = 0;
1204 1235
1205 1236 FOR_EACH_PTR(stmt->asm_outputs, expr) {
1206 1237 switch (state) {
1207 1238 case 0: /* identifier */
1208 1239 case 1: /* constraint */
1209 1240 state++;
1210 1241 continue;
1211 1242 case 2: /* expression */
1212 1243 state = 0;
1213 1244 type = get_type(strip_expr(expr));
1214 1245 set_extra_expr_mod(expr, alloc_estate_whole(type));
1215 1246 continue;
1216 1247 }
1217 1248 } END_FOR_EACH_PTR(expr);
1218 1249 }
1219 1250
1220 1251 static void check_dereference(struct expression *expr)
1221 1252 {
1222 1253 struct smatch_state *state;
1223 1254
1224 1255 if (__in_fake_assign)
1225 1256 return;
1226 1257 if (outside_of_function())
↓ open down ↓ |
111 lines elided |
↑ open up ↑ |
1227 1258 return;
1228 1259 state = get_extra_state(expr);
1229 1260 if (state) {
1230 1261 struct range_list *rl;
1231 1262
1232 1263 rl = rl_intersection(estate_rl(state), valid_ptr_rl);
1233 1264 if (rl_equiv(rl, estate_rl(state)))
1234 1265 return;
1235 1266 set_extra_expr_nomod(expr, alloc_estate_rl(rl));
1236 1267 } else {
1237 - set_extra_expr_nomod(expr, alloc_estate_range(valid_ptr_min_sval, valid_ptr_max_sval));
1268 + struct range_list *rl;
1269 +
1270 + if (get_mtag_rl(expr, &rl))
1271 + rl = rl_intersection(rl, valid_ptr_rl);
1272 + else
1273 + rl = clone_rl(valid_ptr_rl);
1274 +
1275 + set_extra_expr_nomod(expr, alloc_estate_rl(rl));
1238 1276 }
1239 1277 }
1240 1278
1241 1279 static void match_dereferences(struct expression *expr)
1242 1280 {
1243 1281 if (expr->type != EXPR_PREOP)
1244 1282 return;
1245 1283 /* it's saying that foo[1] = bar dereferences foo[1] */
1246 1284 if (is_array(expr))
1247 1285 return;
1248 1286 check_dereference(expr->unop);
1249 1287 }
1250 1288
1251 1289 static void match_pointer_as_array(struct expression *expr)
1252 1290 {
1253 1291 if (!is_array(expr))
1254 1292 return;
1255 1293 check_dereference(get_array_base(expr));
1256 1294 }
1257 1295
1258 1296 static void find_dereferences(struct expression *expr)
1259 1297 {
1260 1298 while (expr->type == EXPR_PREOP) {
1261 1299 if (expr->op == '*')
1262 1300 check_dereference(expr->unop);
1263 1301 expr = strip_expr(expr->unop);
1264 1302 }
1265 1303 }
1266 1304
1267 1305 static void set_param_dereferenced(struct expression *call, struct expression *arg, char *key, char *unused)
1268 1306 {
1269 1307 struct symbol *sym;
1270 1308 char *name;
1271 1309
1272 1310 name = get_variable_from_key(arg, key, &sym);
1273 1311 if (name && sym) {
1274 1312 struct smatch_state *orig, *new;
1275 1313 struct range_list *rl;
1276 1314
1277 1315 orig = get_state(SMATCH_EXTRA, name, sym);
1278 1316 if (orig) {
1279 1317 rl = rl_intersection(estate_rl(orig),
1280 1318 alloc_rl(valid_ptr_min_sval,
1281 1319 valid_ptr_max_sval));
1282 1320 new = alloc_estate_rl(rl);
1283 1321 } else {
1284 1322 new = alloc_estate_range(valid_ptr_min_sval, valid_ptr_max_sval);
1285 1323 }
1286 1324
1287 1325 set_extra_nomod(name, sym, NULL, new);
1288 1326 }
1289 1327 free_string(name);
1290 1328
1291 1329 find_dereferences(arg);
1292 1330 }
1293 1331
1294 1332 static sval_t add_one(sval_t sval)
↓ open down ↓ |
47 lines elided |
↑ open up ↑ |
1295 1333 {
1296 1334 sval.value++;
1297 1335 return sval;
1298 1336 }
1299 1337
1300 1338 static int handle_postop_inc(struct expression *left, int op, struct expression *right)
1301 1339 {
1302 1340 struct statement *stmt;
1303 1341 struct expression *cond;
1304 1342 struct smatch_state *true_state, *false_state;
1343 + struct symbol *type;
1305 1344 sval_t start;
1306 1345 sval_t limit;
1307 1346
1308 1347 /*
1309 1348 * If we're decrementing here then that's a canonical while count down
1310 1349 * so it's handled already. We're only handling loops like:
1311 1350 * i = 0;
1312 1351 * do { ... } while (i++ < 3);
1313 1352 */
1314 1353
1315 1354 if (left->type != EXPR_POSTOP || left->op != SPECIAL_INCREMENT)
1316 1355 return 0;
1317 1356
1318 1357 stmt = __cur_stmt->parent;
1319 1358 if (!stmt)
1320 1359 return 0;
1321 1360 if (stmt->type == STMT_COMPOUND)
1322 1361 stmt = stmt->parent;
1323 1362 if (!stmt || stmt->type != STMT_ITERATOR || !stmt->iterator_post_condition)
1324 1363 return 0;
1325 1364
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
1326 1365 cond = strip_expr(stmt->iterator_post_condition);
1327 1366 if (cond->type != EXPR_COMPARE || cond->op != op)
1328 1367 return 0;
1329 1368 if (left != strip_expr(cond->left) || right != strip_expr(cond->right))
1330 1369 return 0;
1331 1370
1332 1371 if (!get_implied_value(left->unop, &start))
1333 1372 return 0;
1334 1373 if (!get_implied_value(right, &limit))
1335 1374 return 0;
1336 -
1375 + type = get_type(left->unop);
1376 + limit = sval_cast(type, limit);
1337 1377 if (sval_cmp(start, limit) > 0)
1338 1378 return 0;
1339 1379
1340 1380 switch (op) {
1341 1381 case '<':
1342 1382 case SPECIAL_UNSIGNED_LT:
1343 1383 break;
1344 1384 case SPECIAL_LTE:
1345 1385 case SPECIAL_UNSIGNED_LTE:
1346 1386 limit = add_one(limit);
1347 1387 default:
1348 1388 return 0;
1349 1389
1350 1390 }
1351 1391
1352 1392 true_state = alloc_estate_range(add_one(start), limit);
1353 1393 false_state = alloc_estate_range(add_one(limit), add_one(limit));
1354 1394
1355 1395 /* Currently we just discard the false state but when two passes is
1356 1396 * implimented correctly then it will use it.
1357 1397 */
1358 1398
1359 1399 set_extra_expr_true_false(left->unop, true_state, false_state);
1360 1400
1361 1401 return 1;
1362 1402 }
1363 1403
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
1364 1404 bool is_impossible_variable(struct expression *expr)
1365 1405 {
1366 1406 struct smatch_state *state;
1367 1407
1368 1408 state = get_extra_state(expr);
1369 1409 if (state && !estate_rl(state))
1370 1410 return true;
1371 1411 return false;
1372 1412 }
1373 1413
1414 +static bool in_macro(struct expression *left, struct expression *right)
1415 +{
1416 + if (!left || !right)
1417 + return 0;
1418 + if (left->pos.line != right->pos.line || left->pos.pos != right->pos.pos)
1419 + return 0;
1420 + if (get_macro_name(left->pos))
1421 + return 1;
1422 + return 0;
1423 +}
1424 +
1374 1425 static void handle_comparison(struct symbol *type, struct expression *left, int op, struct expression *right)
1375 1426 {
1376 1427 struct range_list *left_orig;
1377 1428 struct range_list *left_true;
1378 1429 struct range_list *left_false;
1379 1430 struct range_list *right_orig;
1380 1431 struct range_list *right_true;
1381 1432 struct range_list *right_false;
1382 1433 struct smatch_state *left_true_state;
1383 1434 struct smatch_state *left_false_state;
1384 1435 struct smatch_state *right_true_state;
1385 1436 struct smatch_state *right_false_state;
1386 1437 sval_t dummy, hard_max;
1387 1438 int left_postop = 0;
1388 1439 int right_postop = 0;
1389 1440
1390 1441 if (left->op == SPECIAL_INCREMENT || left->op == SPECIAL_DECREMENT) {
1391 1442 if (left->type == EXPR_POSTOP) {
1392 1443 left->smatch_flags |= Handled;
1393 1444 left_postop = left->op;
1394 1445 if (handle_postop_inc(left, op, right))
1395 1446 return;
1396 1447 }
1397 1448 left = strip_parens(left->unop);
1398 1449 }
1399 1450 while (left->type == EXPR_ASSIGNMENT)
1400 1451 left = strip_parens(left->left);
1401 1452
1402 1453 if (right->op == SPECIAL_INCREMENT || right->op == SPECIAL_DECREMENT) {
1403 1454 if (right->type == EXPR_POSTOP) {
1404 1455 right->smatch_flags |= Handled;
1405 1456 right_postop = right->op;
1406 1457 }
1407 1458 right = strip_parens(right->unop);
1408 1459 }
1409 1460
1410 1461 if (is_impossible_variable(left) || is_impossible_variable(right))
1411 1462 return;
1412 1463
1413 1464 get_real_absolute_rl(left, &left_orig);
1414 1465 left_orig = cast_rl(type, left_orig);
1415 1466
1416 1467 get_real_absolute_rl(right, &right_orig);
1417 1468 right_orig = cast_rl(type, right_orig);
1418 1469
1419 1470 split_comparison_rl(left_orig, op, right_orig, &left_true, &left_false, &right_true, &right_false);
1420 1471
1421 1472 left_true = rl_truncate_cast(get_type(strip_expr(left)), left_true);
1422 1473 left_false = rl_truncate_cast(get_type(strip_expr(left)), left_false);
1423 1474 right_true = rl_truncate_cast(get_type(strip_expr(right)), right_true);
1424 1475 right_false = rl_truncate_cast(get_type(strip_expr(right)), right_false);
1425 1476
1426 1477 if (!left_true || !left_false) {
1427 1478 struct range_list *tmp_true, *tmp_false;
1428 1479
1429 1480 split_comparison_rl(alloc_whole_rl(type), op, right_orig, &tmp_true, &tmp_false, NULL, NULL);
1430 1481 tmp_true = rl_truncate_cast(get_type(strip_expr(left)), tmp_true);
1431 1482 tmp_false = rl_truncate_cast(get_type(strip_expr(left)), tmp_false);
1432 1483 if (tmp_true && tmp_false)
1433 1484 __save_imaginary_state(left, tmp_true, tmp_false);
1434 1485 }
1435 1486
1436 1487 if (!right_true || !right_false) {
1437 1488 struct range_list *tmp_true, *tmp_false;
1438 1489
1439 1490 split_comparison_rl(alloc_whole_rl(type), op, right_orig, NULL, NULL, &tmp_true, &tmp_false);
1440 1491 tmp_true = rl_truncate_cast(get_type(strip_expr(right)), tmp_true);
1441 1492 tmp_false = rl_truncate_cast(get_type(strip_expr(right)), tmp_false);
1442 1493 if (tmp_true && tmp_false)
1443 1494 __save_imaginary_state(right, tmp_true, tmp_false);
1444 1495 }
1445 1496
↓ open down ↓ |
62 lines elided |
↑ open up ↑ |
1446 1497 left_true_state = alloc_estate_rl(left_true);
1447 1498 left_false_state = alloc_estate_rl(left_false);
1448 1499 right_true_state = alloc_estate_rl(right_true);
1449 1500 right_false_state = alloc_estate_rl(right_false);
1450 1501
1451 1502 switch (op) {
1452 1503 case '<':
1453 1504 case SPECIAL_UNSIGNED_LT:
1454 1505 case SPECIAL_UNSIGNED_LTE:
1455 1506 case SPECIAL_LTE:
1456 - if (get_hard_max(right, &dummy))
1507 + if (get_implied_value(right, &dummy) && !in_macro(left, right))
1457 1508 estate_set_hard_max(left_true_state);
1458 - if (get_hard_max(left, &dummy))
1509 + if (get_implied_value(left, &dummy) && !in_macro(left, right))
1459 1510 estate_set_hard_max(right_false_state);
1460 1511 break;
1461 1512 case '>':
1462 1513 case SPECIAL_UNSIGNED_GT:
1463 1514 case SPECIAL_UNSIGNED_GTE:
1464 1515 case SPECIAL_GTE:
1465 - if (get_hard_max(left, &dummy))
1516 + if (get_implied_value(left, &dummy) && !in_macro(left, right))
1466 1517 estate_set_hard_max(right_true_state);
1467 - if (get_hard_max(right, &dummy))
1518 + if (get_implied_value(right, &dummy) && !in_macro(left, right))
1468 1519 estate_set_hard_max(left_false_state);
1469 1520 break;
1470 1521 }
1471 1522
1472 1523 switch (op) {
1473 1524 case '<':
1474 1525 case SPECIAL_UNSIGNED_LT:
1475 1526 case SPECIAL_UNSIGNED_LTE:
1476 1527 case SPECIAL_LTE:
1477 1528 if (get_hard_max(right, &hard_max)) {
1478 1529 if (op == '<' || op == SPECIAL_UNSIGNED_LT)
1479 1530 hard_max.value--;
1480 1531 estate_set_fuzzy_max(left_true_state, hard_max);
1481 1532 }
1482 1533 if (get_implied_value(right, &hard_max)) {
1483 1534 if (op == SPECIAL_UNSIGNED_LTE ||
1484 1535 op == SPECIAL_LTE)
1485 1536 hard_max.value++;
1486 1537 estate_set_fuzzy_max(left_false_state, hard_max);
1487 1538 }
1488 1539 if (get_hard_max(left, &hard_max)) {
1489 1540 if (op == SPECIAL_UNSIGNED_LTE ||
1490 1541 op == SPECIAL_LTE)
1491 1542 hard_max.value--;
1492 1543 estate_set_fuzzy_max(right_false_state, hard_max);
1493 1544 }
1494 1545 if (get_implied_value(left, &hard_max)) {
1495 1546 if (op == '<' || op == SPECIAL_UNSIGNED_LT)
1496 1547 hard_max.value++;
1497 1548 estate_set_fuzzy_max(right_true_state, hard_max);
1498 1549 }
1499 1550 break;
1500 1551 case '>':
1501 1552 case SPECIAL_UNSIGNED_GT:
1502 1553 case SPECIAL_UNSIGNED_GTE:
1503 1554 case SPECIAL_GTE:
1504 1555 if (get_hard_max(left, &hard_max)) {
1505 1556 if (op == '>' || op == SPECIAL_UNSIGNED_GT)
1506 1557 hard_max.value--;
1507 1558 estate_set_fuzzy_max(right_true_state, hard_max);
1508 1559 }
1509 1560 if (get_implied_value(left, &hard_max)) {
1510 1561 if (op == SPECIAL_UNSIGNED_GTE ||
1511 1562 op == SPECIAL_GTE)
1512 1563 hard_max.value++;
1513 1564 estate_set_fuzzy_max(right_false_state, hard_max);
1514 1565 }
1515 1566 if (get_hard_max(right, &hard_max)) {
1516 1567 if (op == SPECIAL_UNSIGNED_LTE ||
1517 1568 op == SPECIAL_LTE)
1518 1569 hard_max.value--;
1519 1570 estate_set_fuzzy_max(left_false_state, hard_max);
1520 1571 }
1521 1572 if (get_implied_value(right, &hard_max)) {
1522 1573 if (op == '>' ||
1523 1574 op == SPECIAL_UNSIGNED_GT)
1524 1575 hard_max.value++;
1525 1576 estate_set_fuzzy_max(left_true_state, hard_max);
1526 1577 }
1527 1578 break;
1528 1579 case SPECIAL_EQUAL:
1529 1580 if (get_hard_max(left, &hard_max))
1530 1581 estate_set_fuzzy_max(right_true_state, hard_max);
1531 1582 if (get_hard_max(right, &hard_max))
1532 1583 estate_set_fuzzy_max(left_true_state, hard_max);
1533 1584 break;
1534 1585 }
1535 1586
1536 1587 if (get_hard_max(left, &hard_max)) {
1537 1588 estate_set_hard_max(left_true_state);
1538 1589 estate_set_hard_max(left_false_state);
1539 1590 }
1540 1591 if (get_hard_max(right, &hard_max)) {
1541 1592 estate_set_hard_max(right_true_state);
1542 1593 estate_set_hard_max(right_false_state);
1543 1594 }
1544 1595
1545 1596 if (left_postop == SPECIAL_INCREMENT) {
1546 1597 left_true_state = increment_state(left_true_state);
1547 1598 left_false_state = increment_state(left_false_state);
1548 1599 }
1549 1600 if (left_postop == SPECIAL_DECREMENT) {
1550 1601 left_true_state = decrement_state(left_true_state);
1551 1602 left_false_state = decrement_state(left_false_state);
1552 1603 }
1553 1604 if (right_postop == SPECIAL_INCREMENT) {
1554 1605 right_true_state = increment_state(right_true_state);
1555 1606 right_false_state = increment_state(right_false_state);
1556 1607 }
1557 1608 if (right_postop == SPECIAL_DECREMENT) {
1558 1609 right_true_state = decrement_state(right_true_state);
1559 1610 right_false_state = decrement_state(right_false_state);
1560 1611 }
1561 1612
1562 1613 if (estate_rl(left_true_state) && estates_equiv(left_true_state, left_false_state)) {
1563 1614 left_true_state = NULL;
1564 1615 left_false_state = NULL;
1565 1616 }
1566 1617
1567 1618 if (estate_rl(right_true_state) && estates_equiv(right_true_state, right_false_state)) {
1568 1619 right_true_state = NULL;
1569 1620 right_false_state = NULL;
1570 1621 }
1571 1622
1572 1623 /* Don't introduce new states for known true/false conditions */
1573 1624 if (rl_equiv(left_orig, estate_rl(left_true_state)))
1574 1625 left_true_state = NULL;
1575 1626 if (rl_equiv(left_orig, estate_rl(left_false_state)))
1576 1627 left_false_state = NULL;
1577 1628 if (rl_equiv(right_orig, estate_rl(right_true_state)))
1578 1629 right_true_state = NULL;
1579 1630 if (rl_equiv(right_orig, estate_rl(right_false_state)))
1580 1631 right_false_state = NULL;
1581 1632
1582 1633 set_extra_expr_true_false(left, left_true_state, left_false_state);
1583 1634 set_extra_expr_true_false(right, right_true_state, right_false_state);
1584 1635 }
1585 1636
1586 1637 static int is_simple_math(struct expression *expr)
1587 1638 {
1588 1639 if (!expr)
1589 1640 return 0;
1590 1641 if (expr->type != EXPR_BINOP)
↓ open down ↓ |
113 lines elided |
↑ open up ↑ |
1591 1642 return 0;
1592 1643 switch (expr->op) {
1593 1644 case '+':
1594 1645 case '-':
1595 1646 case '*':
1596 1647 return 1;
1597 1648 }
1598 1649 return 0;
1599 1650 }
1600 1651
1652 +static int flip_op(int op)
1653 +{
1654 + /* We only care about simple math */
1655 + switch (op) {
1656 + case '+':
1657 + return '-';
1658 + case '-':
1659 + return '+';
1660 + case '*':
1661 + return '/';
1662 + }
1663 + return 0;
1664 +}
1665 +
1666 +static void move_known_to_rl(struct expression **expr_p, struct range_list **rl_p)
1667 +{
1668 + struct expression *expr = *expr_p;
1669 + struct range_list *rl = *rl_p;
1670 + sval_t sval;
1671 +
1672 + if (!is_simple_math(expr))
1673 + return;
1674 +
1675 + if (get_implied_value(expr->right, &sval)) {
1676 + *expr_p = expr->left;
1677 + *rl_p = rl_binop(rl, flip_op(expr->op), alloc_rl(sval, sval));
1678 + move_known_to_rl(expr_p, rl_p);
1679 + return;
1680 + }
1681 + if (expr->op == '-')
1682 + return;
1683 + if (get_implied_value(expr->left, &sval)) {
1684 + *expr_p = expr->right;
1685 + *rl_p = rl_binop(rl, flip_op(expr->op), alloc_rl(sval, sval));
1686 + move_known_to_rl(expr_p, rl_p);
1687 + return;
1688 + }
1689 +}
1690 +
1601 1691 static void move_known_values(struct expression **left_p, struct expression **right_p)
1602 1692 {
1603 1693 struct expression *left = *left_p;
1604 1694 struct expression *right = *right_p;
1605 1695 sval_t sval, dummy;
1606 1696
1607 1697 if (get_implied_value(left, &sval)) {
1608 1698 if (!is_simple_math(right))
1609 1699 return;
1610 1700 if (get_implied_value(right, &dummy))
1611 1701 return;
1612 1702 if (right->op == '*') {
1613 1703 sval_t divisor;
1614 1704
1615 1705 if (!get_value(right->right, &divisor))
1616 1706 return;
1617 1707 if (divisor.value == 0)
1618 1708 return;
1619 1709 *left_p = binop_expression(left, invert_op(right->op), right->right);
1620 1710 *right_p = right->left;
1621 1711 return;
1622 1712 }
1623 1713 if (right->op == '+' && get_value(right->left, &sval)) {
1624 1714 *left_p = binop_expression(left, invert_op(right->op), right->left);
1625 1715 *right_p = right->right;
1626 1716 return;
1627 1717 }
1628 1718 if (get_value(right->right, &sval)) {
1629 1719 *left_p = binop_expression(left, invert_op(right->op), right->right);
1630 1720 *right_p = right->left;
1631 1721 return;
1632 1722 }
1633 1723 return;
1634 1724 }
1635 1725 if (get_implied_value(right, &sval)) {
1636 1726 if (!is_simple_math(left))
1637 1727 return;
1638 1728 if (get_implied_value(left, &dummy))
1639 1729 return;
1640 1730 if (left->op == '*') {
1641 1731 sval_t divisor;
1642 1732
1643 1733 if (!get_value(left->right, &divisor))
1644 1734 return;
1645 1735 if (divisor.value == 0)
1646 1736 return;
1647 1737 *right_p = binop_expression(right, invert_op(left->op), left->right);
1648 1738 *left_p = left->left;
1649 1739 return;
1650 1740 }
1651 1741 if (left->op == '+' && get_value(left->left, &sval)) {
1652 1742 *right_p = binop_expression(right, invert_op(left->op), left->left);
1653 1743 *left_p = left->right;
1654 1744 return;
1655 1745 }
1656 1746
1657 1747 if (get_value(left->right, &sval)) {
1658 1748 *right_p = binop_expression(right, invert_op(left->op), left->right);
1659 1749 *left_p = left->left;
1660 1750 return;
1661 1751 }
1662 1752 return;
1663 1753 }
1664 1754 }
1665 1755
1666 1756 /*
1667 1757 * The reason for do_simple_algebra() is to solve things like:
1668 1758 * if (foo > 66 || foo + bar > 64) {
1669 1759 * "foo" is not really a known variable so it won't be handled by
1670 1760 * move_known_variables() but it's a super common idiom.
1671 1761 *
1672 1762 */
1673 1763 static int do_simple_algebra(struct expression **left_p, struct expression **right_p)
1674 1764 {
1675 1765 struct expression *left = *left_p;
1676 1766 struct expression *right = *right_p;
1677 1767 struct range_list *rl;
1678 1768 sval_t tmp;
1679 1769
1680 1770 if (left->type != EXPR_BINOP || left->op != '+')
1681 1771 return 0;
1682 1772 if (can_integer_overflow(get_type(left), left))
1683 1773 return 0;
1684 1774 if (!get_implied_value(right, &tmp))
1685 1775 return 0;
1686 1776
1687 1777 if (!get_implied_value(left->left, &tmp) &&
1688 1778 get_implied_rl(left->left, &rl) &&
1689 1779 !is_whole_rl(rl)) {
1690 1780 *right_p = binop_expression(right, '-', left->left);
1691 1781 *left_p = left->right;
1692 1782 return 1;
1693 1783 }
1694 1784 if (!get_implied_value(left->right, &tmp) &&
1695 1785 get_implied_rl(left->right, &rl) &&
1696 1786 !is_whole_rl(rl)) {
1697 1787 *right_p = binop_expression(right, '-', left->right);
1698 1788 *left_p = left->left;
↓ open down ↓ |
88 lines elided |
↑ open up ↑ |
1699 1789 return 1;
1700 1790 }
1701 1791
1702 1792 return 0;
1703 1793 }
1704 1794
1705 1795 static int match_func_comparison(struct expression *expr)
1706 1796 {
1707 1797 struct expression *left = strip_expr(expr->left);
1708 1798 struct expression *right = strip_expr(expr->right);
1709 - sval_t sval;
1710 1799
1711 - /*
1712 - * fixme: think about this harder. We should always be trying to limit
1713 - * the non-call side as well. If we can't determine the limitter does
1714 - * that mean we aren't querying the database and are missing important
1715 - * information?
1716 - */
1717 -
1718 - if (left->type == EXPR_CALL) {
1719 - if (get_implied_value(left, &sval)) {
1720 - handle_comparison(get_type(expr), left, expr->op, right);
1721 - return 1;
1722 - }
1800 + if (left->type == EXPR_CALL || right->type == EXPR_CALL) {
1723 1801 function_comparison(left, expr->op, right);
1724 1802 return 1;
1725 1803 }
1726 1804
1727 - if (right->type == EXPR_CALL) {
1728 - if (get_implied_value(right, &sval)) {
1729 - handle_comparison(get_type(expr), left, expr->op, right);
1730 - return 1;
1731 - }
1732 - function_comparison(left, expr->op, right);
1733 - return 1;
1734 - }
1735 -
1736 1805 return 0;
1737 1806 }
1738 1807
1739 1808 /* Handle conditions like "if (foo + bar < foo) {" */
1740 1809 static int handle_integer_overflow_test(struct expression *expr)
1741 1810 {
1742 1811 struct expression *left, *right;
1743 1812 struct symbol *type;
1744 1813 sval_t left_min, right_min, min, max;
1745 1814
1746 1815 if (expr->op != '<' && expr->op != SPECIAL_UNSIGNED_LT)
1747 1816 return 0;
1748 1817
1749 1818 left = strip_parens(expr->left);
1750 1819 right = strip_parens(expr->right);
1751 1820
1752 1821 if (left->op != '+')
1753 1822 return 0;
1754 1823
1755 1824 type = get_type(expr);
1756 1825 if (!type)
1757 1826 return 0;
1758 1827 if (type_positive_bits(type) == 32) {
1759 1828 max.type = &uint_ctype;
1760 1829 max.uvalue = (unsigned int)-1;
1761 1830 } else if (type_positive_bits(type) == 64) {
1762 1831 max.type = &ulong_ctype;
1763 1832 max.value = (unsigned long long)-1;
1764 1833 } else {
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
1765 1834 return 0;
1766 1835 }
1767 1836
1768 1837 if (!expr_equiv(left->left, right) && !expr_equiv(left->right, right))
1769 1838 return 0;
1770 1839
1771 1840 get_absolute_min(left->left, &left_min);
1772 1841 get_absolute_min(left->right, &right_min);
1773 1842 min = sval_binop(left_min, '+', right_min);
1774 1843
1844 + type = get_type(left);
1845 + min = sval_cast(type, min);
1846 + max = sval_cast(type, max);
1847 +
1775 1848 set_extra_chunk_true_false(left, NULL, alloc_estate_range(min, max));
1776 1849 return 1;
1777 1850 }
1778 1851
1779 1852 static void match_comparison(struct expression *expr)
1780 1853 {
1781 1854 struct expression *left_orig = strip_parens(expr->left);
1782 1855 struct expression *right_orig = strip_parens(expr->right);
1783 1856 struct expression *left, *right, *tmp;
1784 1857 struct expression *prev;
1785 1858 struct symbol *type;
1786 1859 int redo, count;
1787 1860
1788 1861 if (match_func_comparison(expr))
1789 1862 return;
1790 1863
1791 1864 type = get_type(expr);
1792 1865 if (!type)
1793 1866 type = &llong_ctype;
1794 1867
1795 1868 if (handle_integer_overflow_test(expr))
1796 1869 return;
1797 1870
1798 1871 left = left_orig;
1799 1872 right = right_orig;
1800 1873 move_known_values(&left, &right);
1801 1874 handle_comparison(type, left, expr->op, right);
1802 1875
1803 1876 left = left_orig;
1804 1877 right = right_orig;
1805 1878 if (do_simple_algebra(&left, &right))
1806 1879 handle_comparison(type, left, expr->op, right);
1807 1880
1808 1881 prev = get_assigned_expr(left_orig);
1809 1882 if (is_simple_math(prev) && has_variable(prev, left_orig) == 0) {
1810 1883 left = prev;
1811 1884 right = right_orig;
1812 1885 move_known_values(&left, &right);
1813 1886 handle_comparison(type, left, expr->op, right);
1814 1887 }
1815 1888
1816 1889 prev = get_assigned_expr(right_orig);
1817 1890 if (is_simple_math(prev) && has_variable(prev, right_orig) == 0) {
1818 1891 left = left_orig;
1819 1892 right = prev;
1820 1893 move_known_values(&left, &right);
1821 1894 handle_comparison(type, left, expr->op, right);
1822 1895 }
1823 1896
1824 1897 redo = 0;
1825 1898 left = left_orig;
1826 1899 right = right_orig;
1827 1900 if (get_last_expr_from_expression_stmt(left_orig)) {
1828 1901 left = get_last_expr_from_expression_stmt(left_orig);
1829 1902 redo = 1;
1830 1903 }
1831 1904 if (get_last_expr_from_expression_stmt(right_orig)) {
1832 1905 right = get_last_expr_from_expression_stmt(right_orig);
1833 1906 redo = 1;
1834 1907 }
1835 1908
1836 1909 if (!redo)
1837 1910 return;
1838 1911
1839 1912 count = 0;
1840 1913 while ((tmp = get_assigned_expr(left))) {
1841 1914 if (count++ > 3)
1842 1915 break;
1843 1916 left = strip_expr(tmp);
1844 1917 }
1845 1918 count = 0;
1846 1919 while ((tmp = get_assigned_expr(right))) {
1847 1920 if (count++ > 3)
1848 1921 break;
1849 1922 right = strip_expr(tmp);
1850 1923 }
1851 1924
1852 1925 handle_comparison(type, left, expr->op, right);
1853 1926 }
1854 1927
1855 1928 static sval_t get_high_mask(sval_t known)
1856 1929 {
1857 1930 sval_t ret;
1858 1931 int i;
1859 1932
1860 1933 ret = known;
1861 1934 ret.value = 0;
1862 1935
↓ open down ↓ |
78 lines elided |
↑ open up ↑ |
1863 1936 for (i = type_bits(known.type) - 1; i >= 0; i--) {
1864 1937 if (known.uvalue & (1ULL << i))
1865 1938 ret.uvalue |= (1ULL << i);
1866 1939 else
1867 1940 return ret;
1868 1941
1869 1942 }
1870 1943 return ret;
1871 1944 }
1872 1945
1946 +static bool handle_bit_test(struct expression *expr)
1947 +{
1948 + struct range_list *orig_rl, *rl;
1949 + struct expression *shift, *mask, *var;
1950 + struct bit_info *bit_info;
1951 + sval_t sval;
1952 + sval_t high = { .type = &int_ctype };
1953 + sval_t low = { .type = &int_ctype };
1954 +
1955 + shift = strip_expr(expr->right);
1956 + mask = strip_expr(expr->left);
1957 + if (shift->type != EXPR_BINOP || shift->op != SPECIAL_LEFTSHIFT) {
1958 + shift = strip_expr(expr->left);
1959 + mask = strip_expr(expr->right);
1960 + if (shift->type != EXPR_BINOP || shift->op != SPECIAL_LEFTSHIFT)
1961 + return false;
1962 + }
1963 + if (!get_implied_value(shift->left, &sval) || sval.value != 1)
1964 + return false;
1965 + var = strip_expr(shift->right);
1966 +
1967 + bit_info = get_bit_info(mask);
1968 + if (!bit_info)
1969 + return false;
1970 + if (!bit_info->possible)
1971 + return false;
1972 +
1973 + get_absolute_rl(var, &orig_rl);
1974 + if (sval_is_negative(rl_min(orig_rl)) ||
1975 + rl_max(orig_rl).uvalue > type_bits(get_type(shift->left)))
1976 + return false;
1977 +
1978 + low.value = ffsll(bit_info->possible);
1979 + high.value = sm_fls64(bit_info->possible);
1980 + rl = alloc_rl(low, high);
1981 + rl = cast_rl(get_type(var), rl);
1982 + rl = rl_intersection(orig_rl, rl);
1983 + if (!rl)
1984 + return false;
1985 +
1986 + set_extra_expr_true_false(shift->right, alloc_estate_rl(rl), NULL);
1987 +
1988 + return true;
1989 +}
1990 +
1873 1991 static void handle_AND_op(struct expression *var, sval_t known)
1874 1992 {
1875 1993 struct range_list *orig_rl;
1876 1994 struct range_list *true_rl = NULL;
1877 1995 struct range_list *false_rl = NULL;
1878 1996 int bit;
1879 1997 sval_t low_mask = known;
1880 1998 sval_t high_mask;
1881 1999 sval_t max;
1882 2000
1883 2001 get_absolute_rl(var, &orig_rl);
1884 2002
1885 2003 if (known.value > 0) {
1886 2004 bit = ffsll(known.value) - 1;
1887 2005 low_mask.uvalue = (1ULL << bit) - 1;
1888 2006 true_rl = remove_range(orig_rl, sval_type_val(known.type, 0), low_mask);
1889 2007 }
1890 2008 high_mask = get_high_mask(known);
1891 2009 if (high_mask.value) {
1892 2010 bit = ffsll(high_mask.value) - 1;
1893 2011 low_mask.uvalue = (1ULL << bit) - 1;
1894 2012
1895 2013 false_rl = orig_rl;
1896 2014 if (sval_is_negative(rl_min(orig_rl)))
1897 2015 false_rl = remove_range(false_rl, sval_type_min(known.type), sval_type_val(known.type, -1));
1898 2016 false_rl = remove_range(false_rl, low_mask, sval_type_max(known.type));
1899 2017 if (type_signed(high_mask.type) && type_unsigned(rl_type(false_rl))) {
1900 2018 false_rl = remove_range(false_rl,
1901 2019 sval_type_val(rl_type(false_rl), sval_type_max(known.type).uvalue),
1902 2020 sval_type_val(rl_type(false_rl), -1));
1903 2021 }
1904 2022 } else if (known.value == 1 &&
1905 2023 get_hard_max(var, &max) &&
1906 2024 sval_cmp(max, rl_max(orig_rl)) == 0 &&
1907 2025 max.value & 1) {
1908 2026 false_rl = remove_range(orig_rl, max, max);
↓ open down ↓ |
26 lines elided |
↑ open up ↑ |
1909 2027 }
1910 2028 set_extra_expr_true_false(var,
1911 2029 true_rl ? alloc_estate_rl(true_rl) : NULL,
1912 2030 false_rl ? alloc_estate_rl(false_rl) : NULL);
1913 2031 }
1914 2032
1915 2033 static void handle_AND_condition(struct expression *expr)
1916 2034 {
1917 2035 sval_t known;
1918 2036
2037 + if (handle_bit_test(expr))
2038 + return;
2039 +
1919 2040 if (get_implied_value(expr->left, &known))
1920 2041 handle_AND_op(expr->right, known);
1921 2042 else if (get_implied_value(expr->right, &known))
1922 2043 handle_AND_op(expr->left, known);
1923 2044 }
1924 2045
1925 2046 static void handle_MOD_condition(struct expression *expr)
1926 2047 {
1927 2048 struct range_list *orig_rl;
1928 2049 struct range_list *true_rl;
1929 2050 struct range_list *false_rl = NULL;
1930 2051 sval_t right;
1931 - sval_t zero;
2052 + sval_t zero = { 0, };
1932 2053
1933 2054 if (!get_implied_value(expr->right, &right) || right.value == 0)
1934 2055 return;
1935 2056 get_absolute_rl(expr->left, &orig_rl);
1936 2057
1937 2058 zero.value = 0;
1938 2059 zero.type = rl_type(orig_rl);
1939 2060
1940 2061 /* We're basically dorking around the min and max here */
1941 2062 true_rl = remove_range(orig_rl, zero, zero);
1942 2063 if (!sval_is_max(rl_max(true_rl)) &&
1943 2064 !(rl_max(true_rl).value % right.value))
1944 2065 true_rl = remove_range(true_rl, rl_max(true_rl), rl_max(true_rl));
1945 2066
1946 2067 if (rl_equiv(true_rl, orig_rl))
1947 2068 true_rl = NULL;
1948 2069
1949 2070 if (sval_is_positive(rl_min(orig_rl)) &&
1950 2071 (rl_max(orig_rl).value - rl_min(orig_rl).value) / right.value < 5) {
1951 2072 sval_t add;
1952 2073 int i;
1953 2074
1954 2075 add = rl_min(orig_rl);
1955 2076 add.value += right.value - (add.value % right.value);
1956 2077 add.value -= right.value;
1957 2078
1958 2079 for (i = 0; i < 5; i++) {
1959 2080 add.value += right.value;
1960 2081 if (add.value > rl_max(orig_rl).value)
1961 2082 break;
1962 2083 add_range(&false_rl, add, add);
1963 2084 }
1964 2085 } else {
1965 2086 if (rl_min(orig_rl).uvalue != 0 &&
1966 2087 rl_min(orig_rl).uvalue < right.uvalue) {
1967 2088 sval_t chop = right;
1968 2089 chop.value--;
1969 2090 false_rl = remove_range(orig_rl, zero, chop);
1970 2091 }
1971 2092
1972 2093 if (!sval_is_max(rl_max(orig_rl)) &&
1973 2094 (rl_max(orig_rl).value % right.value)) {
1974 2095 sval_t chop = rl_max(orig_rl);
1975 2096 chop.value -= chop.value % right.value;
1976 2097 chop.value++;
1977 2098 if (!false_rl)
1978 2099 false_rl = clone_rl(orig_rl);
1979 2100 false_rl = remove_range(false_rl, chop, rl_max(orig_rl));
1980 2101 }
↓ open down ↓ |
39 lines elided |
↑ open up ↑ |
1981 2102 }
1982 2103
1983 2104 set_extra_expr_true_false(expr->left,
1984 2105 true_rl ? alloc_estate_rl(true_rl) : NULL,
1985 2106 false_rl ? alloc_estate_rl(false_rl) : NULL);
1986 2107 }
1987 2108
1988 2109 /* this is actually hooked from smatch_implied.c... it's hacky, yes */
1989 2110 void __extra_match_condition(struct expression *expr)
1990 2111 {
1991 - struct smatch_state *pre_state;
1992 - struct smatch_state *true_state;
1993 - struct smatch_state *false_state;
1994 - struct range_list *pre_rl;
1995 -
1996 2112 expr = strip_expr(expr);
1997 2113 switch (expr->type) {
1998 2114 case EXPR_CALL:
1999 2115 function_comparison(expr, SPECIAL_NOTEQUAL, zero_expr());
2000 2116 return;
2001 2117 case EXPR_PREOP:
2002 2118 case EXPR_SYMBOL:
2003 - case EXPR_DEREF: {
2004 - sval_t zero;
2005 -
2006 - zero = sval_blank(expr);
2007 - zero.value = 0;
2008 -
2009 - pre_state = get_extra_state(expr);
2010 - if (estate_is_empty(pre_state))
2011 - return;
2012 - if (pre_state)
2013 - pre_rl = estate_rl(pre_state);
2014 - else
2015 - get_absolute_rl(expr, &pre_rl);
2016 - if (possibly_true_rl(pre_rl, SPECIAL_EQUAL, rl_zero()))
2017 - false_state = alloc_estate_sval(zero);
2018 - else
2019 - false_state = alloc_estate_empty();
2020 - true_state = alloc_estate_rl(remove_range(pre_rl, zero, zero));
2021 - set_extra_expr_true_false(expr, true_state, false_state);
2119 + case EXPR_DEREF:
2120 + handle_comparison(get_type(expr), expr, SPECIAL_NOTEQUAL, zero_expr());
2022 2121 return;
2023 - }
2024 2122 case EXPR_COMPARE:
2025 2123 match_comparison(expr);
2026 2124 return;
2027 2125 case EXPR_ASSIGNMENT:
2028 2126 __extra_match_condition(expr->left);
2029 2127 return;
2030 2128 case EXPR_BINOP:
2031 2129 if (expr->op == '&')
2032 2130 handle_AND_condition(expr);
2033 2131 if (expr->op == '%')
2034 2132 handle_MOD_condition(expr);
2035 2133 return;
2036 2134 }
2037 2135 }
2038 2136
2039 2137 static void assume_indexes_are_valid(struct expression *expr)
2040 2138 {
2041 2139 struct expression *array_expr;
2042 2140 int array_size;
2043 2141 struct expression *offset;
2044 2142 struct symbol *offset_type;
2045 2143 struct range_list *rl_before;
2046 2144 struct range_list *rl_after;
2047 2145 struct range_list *filter = NULL;
2048 2146 sval_t size;
2049 2147
2050 2148 expr = strip_expr(expr);
2051 2149 if (!is_array(expr))
2052 2150 return;
2053 2151
2054 2152 offset = get_array_offset(expr);
2055 2153 offset_type = get_type(offset);
2056 2154 if (offset_type && type_signed(offset_type)) {
2057 2155 filter = alloc_rl(sval_type_min(offset_type),
2058 2156 sval_type_val(offset_type, -1));
2059 2157 }
2060 2158
2061 2159 array_expr = get_array_base(expr);
2062 2160 array_size = get_real_array_size(array_expr);
2063 2161 if (array_size > 1) {
2064 2162 size = sval_type_val(offset_type, array_size);
2065 2163 add_range(&filter, size, sval_type_max(offset_type));
2066 2164 }
2067 2165
2068 2166 if (!filter)
2069 2167 return;
2070 2168 get_absolute_rl(offset, &rl_before);
2071 2169 rl_after = rl_filter(rl_before, filter);
2072 2170 if (rl_equiv(rl_before, rl_after))
2073 2171 return;
2074 2172 set_extra_expr_nomod(offset, alloc_estate_rl(rl_after));
2075 2173 }
2076 2174
2077 2175 /* returns 1 if it is not possible for expr to be value, otherwise returns 0 */
2078 2176 int implied_not_equal(struct expression *expr, long long val)
2079 2177 {
2080 2178 return !possibly_false(expr, SPECIAL_NOTEQUAL, value_expr(val));
2081 2179 }
2082 2180
2083 2181 int implied_not_equal_name_sym(char *name, struct symbol *sym, long long val)
2084 2182 {
2085 2183 struct smatch_state *estate;
2086 2184
2087 2185 estate = get_state(SMATCH_EXTRA, name, sym);
2088 2186 if (!estate)
2089 2187 return 0;
2090 2188 if (!rl_has_sval(estate_rl(estate), sval_type_val(estate_type(estate), 0)))
2091 2189 return 1;
2092 2190 return 0;
2093 2191 }
2094 2192
2095 2193 int parent_is_null_var_sym(const char *name, struct symbol *sym)
2096 2194 {
2097 2195 char buf[256];
2098 2196 char *start;
2099 2197 char *end;
2100 2198 struct smatch_state *state;
2101 2199
2102 2200 strncpy(buf, name, sizeof(buf) - 1);
2103 2201 buf[sizeof(buf) - 1] = '\0';
2104 2202
2105 2203 start = &buf[0];
2106 2204 while (*start == '*') {
2107 2205 start++;
2108 2206 state = get_state(SMATCH_EXTRA, start, sym);
2109 2207 if (!state)
2110 2208 continue;
2111 2209 if (!estate_rl(state))
2112 2210 return 1;
2113 2211 if (estate_min(state).value == 0 &&
2114 2212 estate_max(state).value == 0)
2115 2213 return 1;
2116 2214 }
2117 2215
2118 2216 start = &buf[0];
2119 2217 while (*start == '&')
2120 2218 start++;
2121 2219
2122 2220 while ((end = strrchr(start, '-'))) {
2123 2221 *end = '\0';
2124 2222 state = __get_state(SMATCH_EXTRA, start, sym);
2125 2223 if (!state)
2126 2224 continue;
2127 2225 if (estate_min(state).value == 0 &&
2128 2226 estate_max(state).value == 0)
2129 2227 return 1;
2130 2228 }
2131 2229 return 0;
2132 2230 }
2133 2231
2134 2232 int parent_is_null(struct expression *expr)
2135 2233 {
2136 2234 struct symbol *sym;
2137 2235 char *var;
2138 2236 int ret = 0;
2139 2237
2140 2238 expr = strip_expr(expr);
2141 2239 var = expr_to_var_sym(expr, &sym);
2142 2240 if (!var || !sym)
2143 2241 goto free;
2144 2242 ret = parent_is_null_var_sym(var, sym);
2145 2243 free:
↓ open down ↓ |
112 lines elided |
↑ open up ↑ |
2146 2244 free_string(var);
2147 2245 return ret;
2148 2246 }
2149 2247
2150 2248 static int param_used_callback(void *found, int argc, char **argv, char **azColName)
2151 2249 {
2152 2250 *(int *)found = 1;
2153 2251 return 0;
2154 2252 }
2155 2253
2156 -static int filter_unused_kzalloc_info(struct expression *call, int param, char *printed_name, struct sm_state *sm)
2254 +static int is_kzalloc_info(struct sm_state *sm)
2157 2255 {
2158 2256 sval_t sval;
2257 +
2258 + /*
2259 + * kzalloc() information is treated as special because so there is just
2260 + * a lot of stuff initialized to zero and it makes building the database
2261 + * take hours and hours.
2262 + *
2263 + * In theory, we should just remove this line and not pass any unused
2264 + * information, but I'm not sure enough that this code works so I want
2265 + * to hold off on that for now.
2266 + */
2267 + if (!estate_get_single_value(sm->state, &sval))
2268 + return 0;
2269 + if (sval.value != 0)
2270 + return 0;
2271 + return 1;
2272 +}
2273 +
2274 +static int is_really_long(struct sm_state *sm)
2275 +{
2276 + const char *p;
2277 + int cnt = 0;
2278 +
2279 + p = sm->name;
2280 + while ((p = strstr(p, "->"))) {
2281 + p += 2;
2282 + cnt++;
2283 + }
2284 +
2285 + if (cnt < 3 ||
2286 + strlen(sm->name) < 40)
2287 + return 0;
2288 + return 1;
2289 +}
2290 +
2291 +static int filter_unused_param_value_info(struct expression *call, int param, char *printed_name, struct sm_state *sm)
2292 +{
2159 2293 int found = 0;
2160 2294
2161 2295 /* for function pointers assume everything is used */
2162 2296 if (call->fn->type != EXPR_SYMBOL)
2163 2297 return 0;
2164 2298
2165 2299 /*
2166 2300 * This is to handle __builtin_mul_overflow(). In an ideal world we
2167 2301 * would only need this for invalid code.
2168 2302 *
2169 2303 */
2170 2304 if (!call->fn->symbol)
2171 2305 return 0;
2172 2306
2173 - /*
2174 - * kzalloc() information is treated as special because so there is just
2175 - * a lot of stuff initialized to zero and it makes building the database
2176 - * take hours and hours.
2177 - *
2178 - * In theory, we should just remove this line and not pass any unused
2179 - * information, but I'm not sure enough that this code works so I want
2180 - * to hold off on that for now.
2181 - */
2182 - if (!estate_get_single_value(sm->state, &sval) || sval.value != 0)
2307 + if (!is_kzalloc_info(sm) && !is_really_long(sm))
2183 2308 return 0;
2184 2309
2185 2310 run_sql(¶m_used_callback, &found,
2186 2311 "select * from return_implies where %s and type = %d and parameter = %d and key = '%s';",
2187 2312 get_static_filter(call->fn->symbol), PARAM_USED, param, printed_name);
2188 2313 if (found)
2189 2314 return 0;
2190 2315
2191 2316 /* If the database is not built yet, then assume everything is used */
2192 2317 run_sql(¶m_used_callback, &found,
2193 2318 "select * from return_implies where %s and type = %d;",
2194 2319 get_static_filter(call->fn->symbol), PARAM_USED);
2195 2320 if (!found)
2196 2321 return 0;
2197 2322
2198 2323 return 1;
2199 2324 }
2200 2325
2201 2326 struct range_list *intersect_with_real_abs_var_sym(const char *name, struct symbol *sym, struct range_list *start)
2202 2327 {
2203 2328 struct smatch_state *state;
2204 2329
2205 2330 /*
2206 2331 * Here is the difference between implied value and real absolute, say
2207 2332 * you have:
2208 2333 *
2209 2334 * int a = (u8)x;
2210 2335 *
2211 2336 * Then you know that a is 0-255. That's real absolute. But you don't
2212 2337 * know for sure that it actually goes up to 255. So it's not implied.
2213 2338 * Implied indicates a degree of certainty.
2214 2339 *
2215 2340 * But then say you cap "a" at 8. That means you know it goes up to
2216 2341 * 8. So now the implied value is s32min-8. But you can combine it
2217 2342 * with the real absolute to say that actually it's 0-8.
2218 2343 *
2219 2344 * We are combining it here. But now that I think about it, this is
2220 2345 * probably not the ideal place to combine it because it should proably
2221 2346 * be done earlier. Oh well, this is an improvement on what was there
2222 2347 * before so I'm going to commit this code.
2223 2348 *
2224 2349 */
2225 2350
2226 2351 state = get_real_absolute_state_var_sym(name, sym);
2227 2352 if (!state || !estate_rl(state))
2228 2353 return start;
2229 2354
2230 2355 return rl_intersection(estate_rl(state), start);
2231 2356 }
2232 2357
2233 2358 struct range_list *intersect_with_real_abs_expr(struct expression *expr, struct range_list *start)
2234 2359 {
2235 2360 struct smatch_state *state;
2236 2361 struct range_list *abs_rl;
2237 2362
2238 2363 state = get_real_absolute_state(expr);
↓ open down ↓ |
46 lines elided |
↑ open up ↑ |
2239 2364 if (!state || !estate_rl(state))
2240 2365 return start;
2241 2366
2242 2367 abs_rl = cast_rl(rl_type(start), estate_rl(state));
2243 2368 return rl_intersection(abs_rl, start);
2244 2369 }
2245 2370
2246 2371 static void struct_member_callback(struct expression *call, int param, char *printed_name, struct sm_state *sm)
2247 2372 {
2248 2373 struct range_list *rl;
2374 + sval_t dummy;
2249 2375
2250 2376 if (estate_is_whole(sm->state))
2251 2377 return;
2252 - if (filter_unused_kzalloc_info(call, param, printed_name, sm))
2378 + if (filter_unused_param_value_info(call, param, printed_name, sm))
2253 2379 return;
2254 2380 rl = estate_rl(sm->state);
2255 2381 rl = intersect_with_real_abs_var_sym(sm->name, sm->sym, rl);
2256 2382 sql_insert_caller_info(call, PARAM_VALUE, param, printed_name, show_rl(rl));
2257 - if (estate_has_fuzzy_max(sm->state))
2258 - sql_insert_caller_info(call, FUZZY_MAX, param, printed_name,
2259 - sval_to_str(estate_get_fuzzy_max(sm->state)));
2383 + if (!estate_get_single_value(sm->state, &dummy)) {
2384 + if (estate_has_hard_max(sm->state))
2385 + sql_insert_caller_info(call, HARD_MAX, param, printed_name,
2386 + sval_to_str(estate_max(sm->state)));
2387 + if (estate_has_fuzzy_max(sm->state))
2388 + sql_insert_caller_info(call, FUZZY_MAX, param, printed_name,
2389 + sval_to_str(estate_get_fuzzy_max(sm->state)));
2390 + }
2260 2391 }
2261 2392
2262 2393 static void returned_struct_members(int return_id, char *return_ranges, struct expression *expr)
2263 2394 {
2264 2395 struct symbol *returned_sym;
2396 + char *returned_name;
2265 2397 struct sm_state *sm;
2266 - const char *param_name;
2267 2398 char *compare_str;
2268 - char buf[256];
2399 + char name_buf[256];
2400 + char val_buf[256];
2401 + int len;
2269 2402
2270 - returned_sym = expr_to_sym(expr);
2271 - if (!returned_sym)
2403 + // FIXME handle *$
2404 +
2405 + if (!is_pointer(expr))
2272 2406 return;
2273 2407
2408 + returned_name = expr_to_var_sym(expr, &returned_sym);
2409 + if (!returned_name || !returned_sym)
2410 + goto free;
2411 + len = strlen(returned_name);
2412 +
2274 2413 FOR_EACH_MY_SM(my_id, __get_cur_stree(), sm) {
2275 2414 if (!estate_rl(sm->state))
2276 2415 continue;
2277 2416 if (returned_sym != sm->sym)
2278 2417 continue;
2279 -
2280 - param_name = get_param_name(sm);
2281 - if (!param_name)
2418 + if (strncmp(returned_name, sm->name, len) != 0)
2282 2419 continue;
2283 - if (strcmp(param_name, "$") == 0)
2420 + if (sm->name[len] != '-')
2284 2421 continue;
2422 +
2423 + snprintf(name_buf, sizeof(name_buf), "$%s", sm->name + len);
2424 +
2285 2425 compare_str = name_sym_to_param_comparison(sm->name, sm->sym);
2286 2426 if (!compare_str && estate_is_whole(sm->state))
2287 2427 continue;
2288 - snprintf(buf, sizeof(buf), "%s%s", sm->state->name, compare_str ?: "");
2428 + snprintf(val_buf, sizeof(val_buf), "%s%s", sm->state->name, compare_str ?: "");
2289 2429
2290 2430 sql_insert_return_states(return_id, return_ranges, PARAM_VALUE,
2291 - -1, param_name, buf);
2431 + -1, name_buf, val_buf);
2292 2432 } END_FOR_EACH_SM(sm);
2433 +
2434 +free:
2435 + free_string(returned_name);
2293 2436 }
2294 2437
2295 2438 static void db_limited_before(void)
2296 2439 {
2297 2440 unmatched_stree = clone_stree(__get_cur_stree());
2298 2441 }
2299 2442
2300 2443 static void db_limited_after(void)
2301 2444 {
2302 2445 free_stree(&unmatched_stree);
2303 2446 }
2304 2447
2305 -static int rl_fits_in_type(struct range_list *rl, struct symbol *type)
2306 -{
2307 - if (type_bits(rl_type(rl)) <= type_bits(type))
2308 - return 1;
2309 - if (sval_cmp(rl_max(rl), sval_type_max(type)) > 0)
2310 - return 0;
2311 - if (sval_is_negative(rl_min(rl)) &&
2312 - sval_cmp(rl_min(rl), sval_type_min(type)) < 0)
2313 - return 0;
2314 - return 1;
2315 -}
2316 -
2317 2448 static int basically_the_same(struct range_list *orig, struct range_list *new)
2318 2449 {
2319 2450 if (rl_equiv(orig, new))
2320 2451 return 1;
2321 2452
2322 2453 /*
2323 2454 * The whole range is essentially the same as 0,4096-27777777777 so
2324 2455 * don't overwrite the implications just to store that.
2325 2456 *
2326 2457 */
2327 2458 if (rl_type(orig)->type == SYM_PTR &&
2328 2459 is_whole_rl(orig) &&
2329 2460 rl_min(new).value == 0 &&
2330 2461 rl_max(new).value == valid_ptr_max)
2331 2462 return 1;
2332 2463 return 0;
2333 2464 }
2334 2465
2335 2466 static void db_param_limit_binops(struct expression *arg, char *key, struct range_list *rl)
2336 2467 {
2337 2468 struct range_list *left_rl;
2338 2469 sval_t zero = { .type = rl_type(rl), };
2339 2470 sval_t sval;
2340 2471
2341 2472 if (arg->op != '*')
2342 2473 return;
2343 2474 if (!get_implied_value(arg->right, &sval))
2344 2475 return;
2345 2476 if (can_integer_overflow(get_type(arg), arg))
2346 2477 return;
2347 2478
2348 2479 left_rl = rl_binop(rl, '/', alloc_rl(sval, sval));
2349 2480 if (!rl_has_sval(rl, zero))
2350 2481 left_rl = remove_range(left_rl, zero, zero);
2351 2482
2352 2483 set_extra_expr_nomod(arg->left, alloc_estate_rl(left_rl));
2353 2484 }
2354 2485
2355 2486 static void db_param_limit_filter(struct expression *expr, int param, char *key, char *value, enum info_type op)
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
2356 2487 {
2357 2488 struct expression *arg;
2358 2489 char *name;
2359 2490 struct symbol *sym;
2360 2491 struct var_sym_list *vsl = NULL;
2361 2492 struct sm_state *sm;
2362 2493 struct symbol *compare_type, *var_type;
2363 2494 struct range_list *rl;
2364 2495 struct range_list *limit;
2365 2496 struct range_list *new;
2366 - char *tmp_name;
2367 - struct symbol *tmp_sym;
2497 + char *other_name;
2498 + struct symbol *other_sym;
2368 2499
2369 2500 while (expr->type == EXPR_ASSIGNMENT)
2370 2501 expr = strip_expr(expr->right);
2371 2502 if (expr->type != EXPR_CALL)
2372 2503 return;
2373 2504
2374 2505 arg = get_argument_from_call_expr(expr->args, param);
2375 2506 if (!arg)
2376 2507 return;
2377 2508
2509 + if (strcmp(key, "$") == 0)
2510 + compare_type = get_arg_type(expr->fn, param);
2511 + else
2512 + compare_type = get_member_type_from_key(arg, key);
2513 +
2514 + call_results_to_rl(expr, compare_type, value, &limit);
2515 + if (strcmp(key, "$") == 0)
2516 + move_known_to_rl(&arg, &limit);
2378 2517 name = get_chunk_from_key(arg, key, &sym, &vsl);
2379 2518 if (!name)
2380 2519 return;
2381 2520 if (op != PARAM_LIMIT && !sym)
2382 2521 goto free;
2383 2522
2384 - if (strcmp(key, "$") == 0)
2385 - compare_type = get_arg_type(expr->fn, param);
2386 - else
2387 - compare_type = get_member_type_from_key(arg, key);
2388 -
2389 2523 sm = get_sm_state(SMATCH_EXTRA, name, sym);
2390 2524 if (sm)
2391 2525 rl = estate_rl(sm->state);
2392 2526 else
2393 2527 rl = alloc_whole_rl(compare_type);
2394 2528
2395 2529 if (op == PARAM_LIMIT && !rl_fits_in_type(rl, compare_type))
2396 2530 goto free;
2397 2531
2398 - call_results_to_rl(expr, compare_type, value, &limit);
2399 2532 new = rl_intersection(rl, limit);
2400 2533
2401 2534 var_type = get_member_type_from_key(arg, key);
2402 2535 new = cast_rl(var_type, new);
2403 2536
2404 2537 /* We want to preserve the implications here */
2405 - if (sm && basically_the_same(estate_rl(sm->state), new))
2538 + if (sm && basically_the_same(rl, new))
2406 2539 goto free;
2407 - tmp_name = map_long_to_short_name_sym(name, sym, &tmp_sym);
2408 - if (tmp_name && tmp_sym) {
2409 - free_string(name);
2410 - name = tmp_name;
2411 - sym = tmp_sym;
2412 - }
2540 + other_name = get_other_name_sym(name, sym, &other_sym);
2413 2541
2414 2542 if (op == PARAM_LIMIT)
2415 2543 set_extra_nomod_vsl(name, sym, vsl, NULL, alloc_estate_rl(new));
2416 2544 else
2417 2545 set_extra_mod(name, sym, NULL, alloc_estate_rl(new));
2418 2546
2547 + if (other_name && other_sym) {
2548 + if (op == PARAM_LIMIT)
2549 + set_extra_nomod_vsl(other_name, other_sym, vsl, NULL, alloc_estate_rl(new));
2550 + else
2551 + set_extra_mod(other_name, other_sym, NULL, alloc_estate_rl(new));
2552 + }
2553 +
2419 2554 if (op == PARAM_LIMIT && arg->type == EXPR_BINOP)
2420 2555 db_param_limit_binops(arg, key, new);
2421 2556 free:
2422 2557 free_string(name);
2423 2558 }
2424 2559
2425 2560 static void db_param_limit(struct expression *expr, int param, char *key, char *value)
2426 2561 {
2427 2562 db_param_limit_filter(expr, param, key, value, PARAM_LIMIT);
2428 2563 }
2429 2564
2430 2565 static void db_param_filter(struct expression *expr, int param, char *key, char *value)
2431 2566 {
2432 2567 db_param_limit_filter(expr, param, key, value, PARAM_FILTER);
2433 2568 }
2434 2569
2435 2570 static void db_param_add_set(struct expression *expr, int param, char *key, char *value, enum info_type op)
2436 2571 {
2437 2572 struct expression *arg;
2438 - char *name, *tmp_name;
2439 - struct symbol *sym, *tmp_sym;
2573 + char *name;
2574 + char *other_name = NULL;
2575 + struct symbol *sym, *other_sym;
2440 2576 struct symbol *param_type, *arg_type;
2441 2577 struct smatch_state *state;
2442 2578 struct range_list *new = NULL;
2443 2579 struct range_list *added = NULL;
2444 2580
2445 2581 while (expr->type == EXPR_ASSIGNMENT)
2446 2582 expr = strip_expr(expr->right);
2447 2583 if (expr->type != EXPR_CALL)
2448 2584 return;
2449 2585
2450 2586 arg = get_argument_from_call_expr(expr->args, param);
2451 2587 if (!arg)
2452 2588 return;
2453 2589
2454 2590 arg_type = get_arg_type_from_key(expr->fn, param, arg, key);
2455 2591 param_type = get_member_type_from_key(arg, key);
2456 2592 name = get_variable_from_key(arg, key, &sym);
2457 2593 if (!name || !sym)
2458 2594 goto free;
2459 2595
2460 2596 state = get_state(SMATCH_EXTRA, name, sym);
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
2461 2597 if (state)
2462 2598 new = estate_rl(state);
2463 2599
2464 2600 call_results_to_rl(expr, arg_type, value, &added);
2465 2601 added = cast_rl(param_type, added);
2466 2602 if (op == PARAM_SET)
2467 2603 new = added;
2468 2604 else
2469 2605 new = rl_union(new, added);
2470 2606
2471 - tmp_name = map_long_to_short_name_sym_nostack(name, sym, &tmp_sym);
2472 - if (tmp_name && tmp_sym) {
2473 - free_string(name);
2474 - name = tmp_name;
2475 - sym = tmp_sym;
2476 - }
2607 + other_name = get_other_name_sym_nostack(name, sym, &other_sym);
2477 2608 set_extra_mod(name, sym, NULL, alloc_estate_rl(new));
2609 + if (other_name && other_sym)
2610 + set_extra_mod(other_name, other_sym, NULL, alloc_estate_rl(new));
2478 2611 free:
2612 + free_string(other_name);
2479 2613 free_string(name);
2480 2614 }
2481 2615
2482 2616 static void db_param_add(struct expression *expr, int param, char *key, char *value)
2483 2617 {
2484 2618 in_param_set = true;
2485 2619 db_param_add_set(expr, param, key, value, PARAM_ADD);
2486 2620 in_param_set = false;
2487 2621 }
2488 2622
2489 2623 static void db_param_set(struct expression *expr, int param, char *key, char *value)
2490 2624 {
2491 2625 in_param_set = true;
2492 2626 db_param_add_set(expr, param, key, value, PARAM_SET);
2493 2627 in_param_set = false;
2494 2628 }
2495 2629
2630 +static void match_lost_param(struct expression *call, int param)
2631 +{
2632 + struct expression *arg;
2633 +
2634 + if (is_const_param(call->fn, param))
2635 + return;
2636 +
2637 + arg = get_argument_from_call_expr(call->args, param);
2638 + if (!arg)
2639 + return;
2640 +
2641 + arg = strip_expr(arg);
2642 + if (arg->type == EXPR_PREOP && arg->op == '&')
2643 + set_extra_expr_mod(arg->unop, alloc_estate_whole(get_type(arg->unop)));
2644 + else
2645 + ; /* if pointer then set struct members, maybe?*/
2646 +}
2647 +
2496 2648 static void db_param_value(struct expression *expr, int param, char *key, char *value)
2497 2649 {
2498 2650 struct expression *call;
2499 2651 char *name;
2500 2652 struct symbol *sym;
2501 2653 struct symbol *type;
2502 2654 struct range_list *rl = NULL;
2503 2655
2504 2656 if (param != -1)
2505 2657 return;
2506 2658
2507 2659 call = expr;
2508 2660 while (call->type == EXPR_ASSIGNMENT)
2509 2661 call = strip_expr(call->right);
2510 2662 if (call->type != EXPR_CALL)
2511 2663 return;
2512 2664
2513 2665 type = get_member_type_from_key(expr->left, key);
2514 2666 name = get_variable_from_key(expr->left, key, &sym);
2515 2667 if (!name || !sym)
2516 2668 goto free;
2517 2669
2518 2670 call_results_to_rl(call, type, value, &rl);
2519 2671
2520 2672 set_extra_mod(name, sym, NULL, alloc_estate_rl(rl));
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
2521 2673 free:
2522 2674 free_string(name);
2523 2675 }
2524 2676
2525 2677 static void match_call_info(struct expression *expr)
2526 2678 {
2527 2679 struct smatch_state *state;
2528 2680 struct range_list *rl = NULL;
2529 2681 struct expression *arg;
2530 2682 struct symbol *type;
2683 + sval_t dummy;
2531 2684 int i = 0;
2532 2685
2533 2686 FOR_EACH_PTR(expr->args, arg) {
2534 2687 type = get_arg_type(expr->fn, i);
2535 2688
2536 2689 get_absolute_rl(arg, &rl);
2537 2690 rl = cast_rl(type, rl);
2538 2691
2539 2692 if (!is_whole_rl(rl)) {
2540 2693 rl = intersect_with_real_abs_expr(arg, rl);
2541 2694 sql_insert_caller_info(expr, PARAM_VALUE, i, "$", show_rl(rl));
2542 2695 }
2543 2696 state = get_state_expr(SMATCH_EXTRA, arg);
2697 + if (!estate_get_single_value(state, &dummy) && estate_has_hard_max(state)) {
2698 + sql_insert_caller_info(expr, HARD_MAX, i, "$",
2699 + sval_to_str(estate_max(state)));
2700 + }
2544 2701 if (estate_has_fuzzy_max(state)) {
2545 2702 sql_insert_caller_info(expr, FUZZY_MAX, i, "$",
2546 2703 sval_to_str(estate_get_fuzzy_max(state)));
2547 2704 }
2548 2705 i++;
2549 2706 } END_FOR_EACH_PTR(arg);
2550 2707 }
2551 2708
2552 2709 static void set_param_value(const char *name, struct symbol *sym, char *key, char *value)
2553 2710 {
2711 + struct expression *expr;
2554 2712 struct range_list *rl = NULL;
2555 2713 struct smatch_state *state;
2556 2714 struct symbol *type;
2557 2715 char fullname[256];
2716 + char *key_orig = key;
2717 + bool add_star = false;
2558 2718 sval_t dummy;
2559 2719
2560 - if (strcmp(key, "*$") == 0)
2561 - snprintf(fullname, sizeof(fullname), "*%s", name);
2562 - else if (strncmp(key, "$", 1) == 0)
2563 - snprintf(fullname, 256, "%s%s", name, key + 1);
2564 - else
2565 - return;
2720 + if (key[0] == '*') {
2721 + add_star = true;
2722 + key++;
2723 + }
2566 2724
2567 - type = get_member_type_from_key(symbol_expression(sym), key);
2725 + snprintf(fullname, 256, "%s%s%s", add_star ? "*" : "", name, key + 1);
2726 +
2727 + expr = symbol_expression(sym);
2728 + type = get_member_type_from_key(expr, key_orig);
2568 2729 str_to_rl(type, value, &rl);
2569 2730 state = alloc_estate_rl(rl);
2570 2731 if (estate_get_single_value(state, &dummy))
2571 2732 estate_set_hard_max(state);
2572 2733 set_state(SMATCH_EXTRA, fullname, sym, state);
2573 2734 }
2574 2735
2575 -static void set_param_hard_max(const char *name, struct symbol *sym, char *key, char *value)
2736 +static void set_param_fuzzy_max(const char *name, struct symbol *sym, char *key, char *value)
2576 2737 {
2577 2738 struct range_list *rl = NULL;
2578 2739 struct smatch_state *state;
2579 2740 struct symbol *type;
2580 2741 char fullname[256];
2581 2742 sval_t max;
2582 2743
2583 2744 if (strcmp(key, "*$") == 0)
2584 2745 snprintf(fullname, sizeof(fullname), "*%s", name);
2585 2746 else if (strncmp(key, "$", 1) == 0)
2586 2747 snprintf(fullname, 256, "%s%s", name, key + 1);
2587 2748 else
2588 2749 return;
2589 2750
2590 2751 state = get_state(SMATCH_EXTRA, fullname, sym);
2591 2752 if (!state)
2592 2753 return;
2593 - type = get_member_type_from_key(symbol_expression(sym), key);
2754 + type = estate_type(state);
2594 2755 str_to_rl(type, value, &rl);
2595 2756 if (!rl_to_sval(rl, &max))
2596 2757 return;
2597 2758 estate_set_fuzzy_max(state, max);
2598 2759 }
2599 2760
2761 +static void set_param_hard_max(const char *name, struct symbol *sym, char *key, char *value)
2762 +{
2763 + struct smatch_state *state;
2764 + char fullname[256];
2765 +
2766 + if (strcmp(key, "*$") == 0)
2767 + snprintf(fullname, sizeof(fullname), "*%s", name);
2768 + else if (strncmp(key, "$", 1) == 0)
2769 + snprintf(fullname, 256, "%s%s", name, key + 1);
2770 + else
2771 + return;
2772 +
2773 + state = get_state(SMATCH_EXTRA, fullname, sym);
2774 + if (!state)
2775 + return;
2776 + estate_set_hard_max(state);
2777 +}
2778 +
2600 2779 struct sm_state *get_extra_sm_state(struct expression *expr)
2601 2780 {
2602 2781 char *name;
2603 2782 struct symbol *sym;
2604 2783 struct sm_state *ret = NULL;
2605 2784
2606 2785 name = expr_to_known_chunk_sym(expr, &sym);
2607 2786 if (!name)
2608 2787 goto free;
2609 2788
2610 2789 ret = get_sm_state(SMATCH_EXTRA, name, sym);
2611 2790 free:
2612 2791 free_string(name);
2613 2792 return ret;
2614 2793 }
2615 2794
2616 2795 struct smatch_state *get_extra_state(struct expression *expr)
2617 2796 {
2618 2797 struct sm_state *sm;
2619 2798
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
2620 2799 sm = get_extra_sm_state(expr);
2621 2800 if (!sm)
2622 2801 return NULL;
2623 2802 return sm->state;
2624 2803 }
2625 2804
2626 2805 void register_smatch_extra(int id)
2627 2806 {
2628 2807 my_id = id;
2629 2808
2809 + set_dynamic_states(my_id);
2630 2810 add_merge_hook(my_id, &merge_estates);
2631 2811 add_unmatched_state_hook(my_id, &unmatched_state);
2632 2812 select_caller_info_hook(set_param_value, PARAM_VALUE);
2633 - select_caller_info_hook(set_param_hard_max, FUZZY_MAX);
2813 + select_caller_info_hook(set_param_fuzzy_max, FUZZY_MAX);
2814 + select_caller_info_hook(set_param_hard_max, HARD_MAX);
2634 2815 select_return_states_before(&db_limited_before);
2635 2816 select_return_states_hook(PARAM_LIMIT, &db_param_limit);
2636 2817 select_return_states_hook(PARAM_FILTER, &db_param_filter);
2637 2818 select_return_states_hook(PARAM_ADD, &db_param_add);
2638 2819 select_return_states_hook(PARAM_SET, &db_param_set);
2820 + add_lost_param_hook(&match_lost_param);
2639 2821 select_return_states_hook(PARAM_VALUE, &db_param_value);
2640 2822 select_return_states_after(&db_limited_after);
2641 2823 }
2642 2824
2643 2825 static void match_link_modify(struct sm_state *sm, struct expression *mod_expr)
2644 2826 {
2645 2827 struct var_sym_list *links;
2646 2828 struct var_sym *tmp;
2647 2829 struct smatch_state *state;
2648 2830
2649 2831 links = sm->state->data;
2650 2832
2651 2833 FOR_EACH_PTR(links, tmp) {
2652 2834 if (sm->sym == tmp->sym &&
2653 2835 strcmp(sm->name, tmp->var) == 0)
2654 2836 continue;
2655 2837 state = get_state(SMATCH_EXTRA, tmp->var, tmp->sym);
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
2656 2838 if (!state)
2657 2839 continue;
2658 2840 set_state(SMATCH_EXTRA, tmp->var, tmp->sym, alloc_estate_whole(estate_type(state)));
2659 2841 } END_FOR_EACH_PTR(tmp);
2660 2842 set_state(link_id, sm->name, sm->sym, &undefined);
2661 2843 }
2662 2844
2663 2845 void register_smatch_extra_links(int id)
2664 2846 {
2665 2847 link_id = id;
2848 + set_dynamic_states(link_id);
2666 2849 }
2667 2850
2668 2851 void register_smatch_extra_late(int id)
2669 2852 {
2670 2853 add_merge_hook(link_id, &merge_link_states);
2671 2854 add_modification_hook(link_id, &match_link_modify);
2672 2855 add_hook(&match_dereferences, DEREF_HOOK);
2673 2856 add_hook(&match_pointer_as_array, OP_HOOK);
2674 2857 select_return_implies_hook(DEREFERENCE, &set_param_dereferenced);
2675 2858 add_hook(&match_function_call, FUNCTION_CALL_HOOK);
2676 2859 add_hook(&match_assign, ASSIGNMENT_HOOK);
2677 2860 add_hook(&match_assign, GLOBAL_ASSIGNMENT_HOOK);
2678 2861 add_hook(&unop_expr, OP_HOOK);
2679 2862 add_hook(&asm_expr, ASM_HOOK);
2680 2863
2681 2864 add_hook(&match_call_info, FUNCTION_CALL_HOOK);
2682 2865 add_member_info_callback(my_id, struct_member_callback);
2683 2866 add_split_return_callback(&returned_struct_members);
2684 2867
2685 2868 // add_hook(&assume_indexes_are_valid, OP_HOOK);
2686 2869 }
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX