states: rename unreachable() to is_unreachable()
[smatch.git] / smatch_flow.c
blobe2160feeebc049ddc36e24616d0c255c9cee9127
1 /*
2 * Copyright (C) 2006,2008 Dan Carpenter.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
18 #define _GNU_SOURCE 1
19 #include <unistd.h>
20 #include <stdio.h>
21 #include "token.h"
22 #include "scope.h"
23 #include "smatch.h"
24 #include "smatch_expression_stacks.h"
25 #include "smatch_extra.h"
26 #include "smatch_slist.h"
28 int __in_fake_assign;
29 int __in_fake_struct_assign;
30 int __in_buf_clear;
31 int __in_fake_var_assign;
32 int __fake_state_cnt;
33 int __debug_skip;
34 int in_fake_env;
35 int final_pass;
36 int __inline_call;
37 bool __reparsing_code;
38 struct expression *__inline_fn;
40 int __smatch_lineno = 0;
41 static struct position current_pos;
43 static char *base_file;
44 static const char *filename;
45 static char *pathname;
46 static char *full_filename;
47 static char *full_base_file;
48 static char *cur_func;
49 int base_file_stream;
50 static unsigned int loop_count;
51 static int last_goto_statement_handled;
52 int __expr_stmt_count;
53 int __in_function_def;
54 int __in_unmatched_hook;
55 static struct expression_list *switch_expr_stack = NULL;
56 static struct expression_list *post_op_stack = NULL;
58 static struct ptr_list *fn_data_list;
59 static struct ptr_list *backup;
61 struct expression_list *big_expression_stack;
62 struct statement_list *big_statement_stack;
63 struct statement *__prev_stmt;
64 struct statement *__cur_stmt;
65 struct statement *__next_stmt;
66 static struct expression_list *parsed_calls;
67 static int indent_cnt;
68 int __in_pre_condition = 0;
69 int __bail_on_rest_of_function = 0;
70 static struct timeval fn_start_time;
71 static struct timeval outer_fn_start_time;
72 char *get_function(void) { return cur_func; }
73 int get_lineno(void) { return __smatch_lineno; }
74 int inside_loop(void) { return !!loop_count; }
75 int definitely_inside_loop(void) { return !!(loop_count & ~0x08000000); }
76 struct expression *get_switch_expr(void) { return top_expression(switch_expr_stack); }
77 int in_expression_statement(void) { return !!__expr_stmt_count; }
79 static void split_symlist(struct symbol_list *sym_list);
80 static void split_declaration(struct symbol_list *sym_list);
81 static void split_expr_list(struct expression_list *expr_list, struct expression *parent);
82 static void split_args(struct expression *expr);
83 static struct expression *fake_a_variable_assign(struct symbol *type, struct expression *call, struct expression *expr, int nr);
84 static void add_inline_function(struct symbol *sym);
85 static void parse_inline(struct expression *expr);
87 int option_assume_loops = 0;
88 int option_two_passes = 0;
89 struct symbol *cur_func_sym = NULL;
90 struct stree *global_states;
92 const unsigned long valid_ptr_min = 4096;
93 unsigned long valid_ptr_max = ULONG_MAX & ~(MTAG_OFFSET_MASK);
94 const sval_t valid_ptr_min_sval = {
95 .type = &ptr_ctype,
96 {.value = 4096},
98 sval_t ptr_err_min = { .type = &ptr_ctype };
99 sval_t ptr_err_max = { .type = &ptr_ctype };
100 sval_t ptr_xa_err_min = { .type = &ptr_ctype };
101 sval_t ptr_xa_err_max = { .type = &ptr_ctype };
102 sval_t ulong_ULONG_MAX = { .type = &ulong_ctype };
104 sval_t valid_ptr_max_sval = {
105 .type = &ptr_ctype,
106 {.value = ULONG_MAX & ~(MTAG_OFFSET_MASK)},
108 struct range_list *valid_ptr_rl;
110 void alloc_ptr_constants(void)
112 valid_ptr_max = sval_type_max(&ulong_ctype).value & ~(MTAG_OFFSET_MASK);
113 valid_ptr_max_sval.value = valid_ptr_max;
115 valid_ptr_rl = alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
116 valid_ptr_rl = cast_rl(&ptr_ctype, valid_ptr_rl);
117 valid_ptr_rl = clone_rl_permanent(valid_ptr_rl);
119 ptr_err_min = sval_cast(&ptr_ctype, err_min);
120 ptr_err_max = sval_cast(&ptr_ctype, err_max);
121 ptr_xa_err_min = sval_cast(&ptr_ctype, xa_err_min);
122 ptr_xa_err_max = sval_cast(&ptr_ctype, xa_err_max);
123 ulong_ULONG_MAX = sval_type_max(&ulong_ctype);
126 int outside_of_function(void)
128 return cur_func_sym == NULL;
131 const char *get_filename(void)
133 if (option_info && option_full_path)
134 return full_base_file;
135 if (option_info)
136 return base_file;
137 if (option_full_path)
138 return full_filename;
139 return filename;
142 const char *get_base_file(void)
144 if (option_full_path)
145 return full_base_file;
146 return base_file;
149 unsigned long long get_file_id(void)
151 return str_to_llu_hash(get_filename());
154 unsigned long long get_base_file_id(void)
156 return str_to_llu_hash(get_base_file());
159 static void set_position(struct position pos)
161 int len;
162 static int prev_stream = -1;
164 if (in_fake_env)
165 return;
167 if (pos.stream == 0 && pos.line == 0)
168 return;
170 __smatch_lineno = pos.line;
171 current_pos = pos;
173 if (pos.stream == prev_stream)
174 return;
176 prev_stream = pos.stream;
177 filename = stream_name(pos.stream);
179 free(full_filename);
180 pathname = getcwd(NULL, 0);
181 if (pathname) {
182 len = strlen(pathname) + 1 + strlen(filename) + 1;
183 full_filename = malloc(len);
184 snprintf(full_filename, len, "%s/%s", pathname, filename);
185 } else {
186 full_filename = alloc_string(filename);
188 free(pathname);
191 int is_assigned_call(struct expression *expr)
193 struct expression *parent = expr_get_parent_expr(expr);
195 if (parent &&
196 parent->type == EXPR_ASSIGNMENT &&
197 parent->op == '=' &&
198 strip_expr(parent->right) == expr)
199 return 1;
201 return 0;
204 int is_fake_assigned_call(struct expression *expr)
206 struct expression *parent = expr_get_fake_parent_expr(expr);
208 if (parent &&
209 parent->type == EXPR_ASSIGNMENT &&
210 parent->op == '=' &&
211 strip_expr(parent->right) == expr)
212 return 1;
214 return 0;
217 static bool is_inline_func(struct expression *expr)
219 if (expr->type != EXPR_SYMBOL || !expr->symbol)
220 return false;
221 if (!expr->symbol->definition)
222 return false;
223 if (expr->symbol->definition->ctype.modifiers & MOD_INLINE)
224 return true;
226 return 0;
229 static int is_noreturn_func(struct expression *expr)
231 if (expr->type != EXPR_SYMBOL || !expr->symbol)
232 return 0;
235 * It's almost impossible for Smatch to handle __builtin_constant_p()
236 * the same way that GCC does so Smatch ends up making some functions
237 * as no return functions incorrectly.
240 if (option_project == PROJ_KERNEL && expr->symbol->ident &&
241 strstr(expr->symbol->ident->name, "__compiletime_assert"))
242 return 0;
244 if (expr->symbol->ctype.modifiers & MOD_NORETURN)
245 return 1;
246 return 0;
249 static int save_func_time(void *_rl, int argc, char **argv, char **azColName)
251 unsigned long *rl = _rl;
253 *rl = strtoul(argv[0], NULL, 10);
254 return 0;
257 static int get_func_time(struct symbol *sym)
259 unsigned long time = 0;
261 run_sql(&save_func_time, &time,
262 "select key from return_implies where %s and type = %d;",
263 get_static_filter(sym), FUNC_TIME);
265 return time;
268 static int inline_budget = 20;
270 int inlinable(struct expression *expr)
272 struct symbol *sym;
273 struct statement *last_stmt = NULL;
275 if (__inline_fn) /* don't nest */
276 return 0;
278 if (expr->type != EXPR_SYMBOL || !expr->symbol)
279 return 0;
280 if (is_no_inline_function(expr->symbol->ident->name))
281 return 0;
282 sym = get_base_type(expr->symbol);
283 if (sym->stmt && sym->stmt->type == STMT_COMPOUND) {
284 if (ptr_list_size((struct ptr_list *)sym->stmt->stmts) > 10)
285 return 0;
286 if (sym->stmt->type != STMT_COMPOUND)
287 return 0;
288 last_stmt = last_ptr_list((struct ptr_list *)sym->stmt->stmts);
290 if (sym->inline_stmt && sym->inline_stmt->type == STMT_COMPOUND) {
291 if (ptr_list_size((struct ptr_list *)sym->inline_stmt->stmts) > 10)
292 return 0;
293 if (sym->inline_stmt->type != STMT_COMPOUND)
294 return 0;
295 last_stmt = last_ptr_list((struct ptr_list *)sym->inline_stmt->stmts);
298 if (!last_stmt)
299 return 0;
301 /* the magic numbers in this function are pulled out of my bum. */
302 if (last_stmt->pos.line > sym->pos.line + inline_budget)
303 return 0;
305 if (get_func_time(expr->symbol) >= 2)
306 return 0;
308 return 1;
311 void __process_post_op_stack(void)
313 struct expression *expr;
315 FOR_EACH_PTR(post_op_stack, expr) {
316 __pass_to_client(expr, OP_HOOK);
317 } END_FOR_EACH_PTR(expr);
319 __free_ptr_list((struct ptr_list **)&post_op_stack);
322 static int handle_comma_assigns(struct expression *expr)
324 struct expression *right;
325 struct expression *assign;
327 right = strip_expr(expr->right);
328 if (right->type != EXPR_COMMA)
329 return 0;
331 __split_expr(right->left);
332 __process_post_op_stack();
334 assign = assign_expression(expr->left, '=', right->right);
335 __split_expr(assign);
337 return 1;
340 /* This is to handle *p++ = foo; assignments */
341 static int handle_postop_assigns(struct expression *expr)
343 struct expression *left, *fake_left;
344 struct expression *assign;
346 left = strip_expr(expr->left);
347 if (left->type != EXPR_PREOP || left->op != '*')
348 return 0;
349 left = strip_expr(left->unop);
350 if (left->type != EXPR_POSTOP)
351 return 0;
353 fake_left = deref_expression(strip_expr(left->unop));
354 assign = assign_expression(fake_left, '=', expr->right);
356 __split_expr(assign);
357 __split_expr(expr->left);
359 return 1;
362 static bool parent_is_dereference(struct expression *expr)
364 struct expression *parent;
366 parent = expr;
367 while ((parent = expr_get_parent_expr(parent))) {
368 if (parent->type == EXPR_DEREF)
369 return true;
370 if (parent->type == EXPR_PREOP &&
371 parent->op == '*')
372 return true;
375 return false;
378 static int prev_expression_is_getting_address(struct expression *expr)
380 struct expression *parent;
382 do {
383 parent = expr_get_parent_expr(expr);
385 if (!parent)
386 return 0;
387 if (parent->type == EXPR_PREOP && parent->op == '&') {
388 if (parent_is_dereference(parent))
389 return false;
390 return true;
392 if (parent->type == EXPR_PREOP && parent->op == '(')
393 goto next;
394 if (parent->type == EXPR_DEREF && parent->op == '.')
395 goto next;
396 /* Handle &foo->array[offset] */
397 if (parent->type == EXPR_BINOP && parent->op == '+') {
398 parent = expr_get_parent_expr(parent);
399 if (!parent)
400 return 0;
401 if (parent->type == EXPR_PREOP && parent->op == '*')
402 goto next;
405 return 0;
406 next:
407 expr = parent;
408 } while (1);
411 int __in_builtin_overflow_func;
412 static void handle_builtin_overflow_func(struct expression *expr)
414 struct expression *a, *b, *res, *assign;
415 int op;
417 if (sym_name_is("__builtin_add_overflow", expr->fn))
418 op = '+';
419 else if (sym_name_is("__builtin_sub_overflow", expr->fn))
420 op = '-';
421 else if (sym_name_is("__builtin_mul_overflow", expr->fn))
422 op = '*';
423 else
424 return;
426 a = get_argument_from_call_expr(expr->args, 0);
427 b = get_argument_from_call_expr(expr->args, 1);
428 res = get_argument_from_call_expr(expr->args, 2);
430 assign = assign_expression(deref_expression(res), '=', binop_expression(a, op, b));
432 __in_builtin_overflow_func++;
433 __split_expr(assign);
434 __in_builtin_overflow_func--;
437 static int handle__builtin_choose_expr(struct expression *expr)
439 struct expression *const_expr, *expr1, *expr2;
440 sval_t sval;
442 if (!sym_name_is("__builtin_choose_expr", expr->fn))
443 return 0;
445 const_expr = get_argument_from_call_expr(expr->args, 0);
446 expr1 = get_argument_from_call_expr(expr->args, 1);
447 expr2 = get_argument_from_call_expr(expr->args, 2);
449 if (!get_value(const_expr, &sval) || !expr1 || !expr2)
450 return 0;
451 if (sval.value)
452 __split_expr(expr1);
453 else
454 __split_expr(expr2);
455 return 1;
458 static int handle__builtin_choose_expr_assigns(struct expression *expr)
460 struct expression *const_expr, *right, *expr1, *expr2, *fake;
461 sval_t sval;
464 * We can't use strip_no_cast() because it strips out
465 * __builtin_choose_expr() which turns this function into a no-op.
468 right = strip_parens(expr->right);
469 if (right->type != EXPR_CALL)
470 return 0;
471 if (!sym_name_is("__builtin_choose_expr", right->fn))
472 return 0;
474 const_expr = get_argument_from_call_expr(right->args, 0);
475 expr1 = get_argument_from_call_expr(right->args, 1);
476 expr2 = get_argument_from_call_expr(right->args, 2);
478 if (!get_value(const_expr, &sval) || !expr1 || !expr2)
479 return 0;
481 fake = assign_expression(expr->left, '=', sval.value ? expr1 : expr2);
482 __split_expr(fake);
483 return 1;
486 int is_condition_call(struct expression *expr)
488 struct expression *tmp;
490 FOR_EACH_PTR_REVERSE(big_condition_stack, tmp) {
491 if (expr == tmp || expr_get_parent_expr(expr) == tmp)
492 return 1;
493 if (tmp->pos.line < expr->pos.line)
494 return 0;
495 } END_FOR_EACH_PTR_REVERSE(tmp);
497 return 0;
500 static struct expression *get_parent_assignment(struct expression *expr)
502 struct expression *parent;
503 int cnt = 0;
505 if (expr->type == EXPR_ASSIGNMENT)
506 return NULL;
508 parent = expr;
509 while (true) {
510 parent = expr_get_fake_or_real_parent_expr(parent);
511 if (!parent || ++cnt >= 5)
512 break;
513 if (parent->type == EXPR_CAST)
514 continue;
515 if (parent->type == EXPR_PREOP && parent->op == '(')
516 continue;
517 break;
520 if (parent && parent->type == EXPR_ASSIGNMENT)
521 return parent;
522 return NULL;
525 static bool gen_fake_function_assign(struct expression *expr)
527 static struct expression *parsed;
528 struct expression *assign, *parent;
529 struct symbol *type;
530 char buf[64];
532 /* The rule is that every non-void function call has to be part of an
533 * assignment. TODO: Should we create a fake non-casted assignment
534 * for casted assignments? Also faked assigns for += assignments?
536 type = get_type(expr);
537 if (!type || type == &void_ctype)
538 return false;
540 parent = get_parent_assignment(expr);
541 if (parent && parent->type == EXPR_ASSIGNMENT)
542 return false;
544 parent = expr_get_fake_parent_expr(expr);
545 if (parent) {
546 struct expression *left = parent->left;
548 if (parent == parsed)
549 return false;
550 if (!left || left->type != EXPR_SYMBOL)
551 return false;
552 if (strncmp(left->symbol_name->name, "__fake_assign_", 14) != 0)
553 return false;
554 parsed = parent;
555 __split_expr(parent);
556 return true;
559 // TODO: faked_assign skipping conditions is a hack
560 if (is_condition_call(expr))
561 return false;
563 snprintf(buf, sizeof(buf), "__fake_assign_%p", expr);
564 assign = create_fake_assign(buf, get_type(expr), expr);
566 parsed = assign;
567 __split_expr(assign);
568 return true;
571 static void split_call(struct expression *expr)
573 if (gen_fake_function_assign(expr))
574 return;
576 expr_set_parent_expr(expr->fn, expr);
578 if (sym_name_is("__builtin_constant_p", expr->fn))
579 return;
580 if (handle__builtin_choose_expr(expr))
581 return;
582 __split_expr(expr->fn);
583 split_args(expr);
584 if (is_inline_func(expr->fn))
585 add_inline_function(expr->fn->symbol->definition);
586 if (inlinable(expr->fn))
587 __inline_call = 1;
588 __process_post_op_stack();
589 __pass_to_client(expr, FUNCTION_CALL_HOOK_BEFORE);
590 __pass_to_client(expr, FUNCTION_CALL_HOOK);
591 __inline_call = 0;
592 if (inlinable(expr->fn))
593 parse_inline(expr);
594 __pass_to_client(expr, CALL_HOOK_AFTER_INLINE);
595 if (is_noreturn_func(expr->fn))
596 nullify_path();
597 if (!expr_get_parent_expr(expr) && indent_cnt == 1)
598 __discard_fake_states(expr);
599 handle_builtin_overflow_func(expr);
600 __add_ptr_list((struct ptr_list **)&parsed_calls, expr);
603 static unsigned long skip_split;
604 void parse_assignment(struct expression *expr, bool shallow)
606 struct expression *right;
608 expr_set_parent_expr(expr->left, expr);
609 expr_set_parent_expr(expr->right, expr);
611 right = strip_expr(expr->right);
612 if (!right)
613 return;
615 if (shallow)
616 skip_split++;
618 __pass_to_client(expr, RAW_ASSIGNMENT_HOOK);
620 /* foo = !bar() */
621 if (__handle_condition_assigns(expr))
622 goto after_assign;
623 /* foo = (x < 5 ? foo : 5); */
624 if (__handle_select_assigns(expr))
625 goto after_assign;
626 /* foo = ({frob(); frob(); frob(); 1;}) */
627 if (__handle_expr_statement_assigns(expr))
628 goto done; // FIXME: goto after
629 /* foo = (3, 4); */
630 if (handle_comma_assigns(expr))
631 goto after_assign;
632 if (handle__builtin_choose_expr_assigns(expr))
633 goto after_assign;
634 if (handle_postop_assigns(expr))
635 goto done; /* no need to goto after_assign */
637 __split_expr(expr->right);
638 if (outside_of_function())
639 __pass_to_client(expr, GLOBAL_ASSIGNMENT_HOOK);
640 else
641 __pass_to_client(expr, ASSIGNMENT_HOOK);
644 // FIXME: the ordering of this is tricky
645 __fake_struct_member_assignments(expr);
647 /* Re-examine ->right for inlines. See the commit message */
648 right = strip_expr(expr->right);
649 if (expr->op == '=' && right->type == EXPR_CALL)
650 __pass_to_client(expr, CALL_ASSIGNMENT_HOOK);
652 after_assign:
653 if (get_macro_name(right->pos) &&
654 get_macro_name(expr->left->pos) != get_macro_name(right->pos))
655 __pass_to_client(expr, MACRO_ASSIGNMENT_HOOK);
657 __pass_to_client(expr, ASSIGNMENT_HOOK_AFTER);
658 __split_expr(expr->left);
660 done:
661 if (shallow)
662 skip_split--;
665 static bool skip_split_off(struct expression *expr)
667 if (expr->type == EXPR_CALL &&
668 sym_name_is("__smatch_stop_skip", expr->fn))
669 return true;
670 return false;
673 static bool is_no_parse_macro(struct expression *expr)
675 static struct position prev_pos;
676 static bool prev_ret;
677 bool ret = false;
678 char *macro;
680 if (option_project != PROJ_KERNEL)
681 return false;
683 if (positions_eq(expr->pos, prev_pos))
684 return prev_ret;
685 macro = get_macro_name(expr->pos);
686 if (!macro)
687 goto done;
688 if (strncmp(macro, "CHECK_PACKED_FIELDS_", 20) == 0)
689 ret = true;
690 done:
691 prev_ret = ret;
692 prev_pos = expr->pos;
693 return ret;
696 void __split_expr(struct expression *expr)
698 if (!expr)
699 return;
701 if (skip_split_off(expr))
702 __debug_skip = 0;
703 if (__debug_skip)
704 return;
706 if (skip_split)
707 return;
709 // if (local_debug)
710 // sm_msg("Debug expr_type %d %s expr = '%s'", expr->type, show_special(expr->op), expr_to_str(expr));
712 if (__in_fake_assign && expr->type != EXPR_ASSIGNMENT)
713 return;
714 if (__in_fake_assign >= 4) /* don't allow too much nesting */
715 return;
717 if (is_no_parse_macro(expr))
718 return;
720 push_expression(&big_expression_stack, expr);
721 set_position(expr->pos);
722 __pass_to_client(expr, EXPR_HOOK);
724 switch (expr->type) {
725 case EXPR_PREOP:
726 expr_set_parent_expr(expr->unop, expr);
728 __split_expr(expr->unop);
729 if (expr->op == '*' &&
730 !prev_expression_is_getting_address(expr))
731 __pass_to_client(expr, DEREF_HOOK);
732 __pass_to_client(expr, OP_HOOK);
733 break;
734 case EXPR_POSTOP:
735 expr_set_parent_expr(expr->unop, expr);
737 __split_expr(expr->unop);
738 push_expression(&post_op_stack, expr);
739 break;
740 case EXPR_STATEMENT:
741 __expr_stmt_count++;
742 stmt_set_parent_expr(expr->statement, expr);
743 __split_stmt(expr->statement);
744 __expr_stmt_count--;
745 break;
746 case EXPR_LOGICAL:
747 case EXPR_COMPARE:
748 expr_set_parent_expr(expr->left, expr);
749 expr_set_parent_expr(expr->right, expr);
751 __pass_to_client(expr, LOGIC_HOOK);
752 __handle_logic(expr);
753 break;
754 case EXPR_BINOP:
755 expr_set_parent_expr(expr->left, expr);
756 expr_set_parent_expr(expr->right, expr);
758 __pass_to_client(expr, BINOP_HOOK);
759 __split_expr(expr->left);
760 __split_expr(expr->right);
761 break;
762 case EXPR_COMMA:
763 expr_set_parent_expr(expr->left, expr);
764 expr_set_parent_expr(expr->right, expr);
766 __split_expr(expr->left);
767 __process_post_op_stack();
768 __split_expr(expr->right);
769 break;
770 case EXPR_ASSIGNMENT:
771 parse_assignment(expr, false);
772 break;
773 case EXPR_DEREF:
774 expr_set_parent_expr(expr->deref, expr);
776 __split_expr(expr->deref);
777 __pass_to_client(expr, DEREF_HOOK);
778 break;
779 case EXPR_SLICE:
780 expr_set_parent_expr(expr->base, expr);
782 __split_expr(expr->base);
783 break;
784 case EXPR_CAST:
785 case EXPR_FORCE_CAST:
786 expr_set_parent_expr(expr->cast_expression, expr);
788 __pass_to_client(expr, CAST_HOOK);
789 __split_expr(expr->cast_expression);
790 break;
791 case EXPR_SIZEOF:
792 if (expr->cast_expression)
793 __pass_to_client(strip_parens(expr->cast_expression),
794 SIZEOF_HOOK);
795 break;
796 case EXPR_OFFSETOF:
797 case EXPR_ALIGNOF:
798 break;
799 case EXPR_CONDITIONAL:
800 case EXPR_SELECT:
801 expr_set_parent_expr(expr->conditional, expr);
802 expr_set_parent_expr(expr->cond_true, expr);
803 expr_set_parent_expr(expr->cond_false, expr);
805 if (known_condition_true(expr->conditional)) {
806 __split_expr(expr->cond_true);
807 break;
809 if (known_condition_false(expr->conditional)) {
810 __split_expr(expr->cond_false);
811 break;
813 __pass_to_client(expr, SELECT_HOOK);
814 __split_whole_condition(expr->conditional);
815 __split_expr(expr->cond_true);
816 __push_true_states();
817 __use_false_states();
818 __split_expr(expr->cond_false);
819 __merge_true_states();
820 break;
821 case EXPR_CALL:
822 split_call(expr);
823 break;
824 case EXPR_INITIALIZER:
825 split_expr_list(expr->expr_list, expr);
826 break;
827 case EXPR_IDENTIFIER:
828 expr_set_parent_expr(expr->ident_expression, expr);
829 __split_expr(expr->ident_expression);
830 break;
831 case EXPR_INDEX:
832 expr_set_parent_expr(expr->idx_expression, expr);
833 __split_expr(expr->idx_expression);
834 break;
835 case EXPR_POS:
836 expr_set_parent_expr(expr->init_expr, expr);
837 __split_expr(expr->init_expr);
838 break;
839 case EXPR_SYMBOL:
840 __pass_to_client(expr, SYM_HOOK);
841 break;
842 case EXPR_STRING:
843 __pass_to_client(expr, STRING_HOOK);
844 break;
845 case EXPR_GENERIC: {
846 struct expression *tmp;
848 tmp = strip_Generic(expr);
849 if (tmp != expr)
850 __split_expr(tmp);
851 break;
853 default:
854 break;
856 __pass_to_client(expr, EXPR_HOOK_AFTER);
857 pop_expression(&big_expression_stack);
860 static int is_forever_loop(struct statement *stmt)
862 struct expression *expr;
863 sval_t sval;
865 expr = strip_expr(stmt->iterator_pre_condition);
866 if (!expr)
867 expr = stmt->iterator_post_condition;
868 if (!expr) {
869 /* this is a for(;;) loop... */
870 return 1;
873 if (get_value(expr, &sval) && sval.value != 0)
874 return 1;
876 return 0;
879 static int loop_num;
880 static char *get_loop_name(int num)
882 char buf[256];
884 snprintf(buf, 255, "-loop%d", num);
885 buf[255] = '\0';
886 return alloc_sname(buf);
889 static struct bool_stmt_fn_list *once_through_hooks;
890 void add_once_through_hook(bool_stmt_func *fn)
892 add_ptr_list(&once_through_hooks, fn);
895 static bool call_once_through_hooks(struct statement *stmt)
897 bool_stmt_func *fn;
899 if (option_assume_loops)
900 return true;
902 FOR_EACH_PTR(once_through_hooks, fn) {
903 if ((fn)(stmt))
904 return true;
905 } END_FOR_EACH_PTR(fn);
907 return false;
910 static void do_scope_hooks(void)
912 struct position orig = current_pos;
914 __call_scope_hooks();
915 set_position(orig);
918 static const char *get_scoped_guard_label(struct statement *iterator)
920 struct statement *stmt;
921 bool found = false;
922 int cnt = 0;
924 if (!iterator || iterator->type != STMT_IF)
925 return NULL;
927 stmt = iterator->if_true;
928 if (!stmt || stmt->type != STMT_COMPOUND)
929 return NULL;
931 FOR_EACH_PTR_REVERSE(stmt->stmts, stmt) {
932 if (stmt->type == STMT_LABEL) {
933 found = true;
934 break;
936 if (++cnt > 2)
937 break;
938 } END_FOR_EACH_PTR_REVERSE(stmt);
940 if (!found)
941 return NULL;
943 if (!stmt->label_identifier ||
944 stmt->label_identifier->type != SYM_LABEL ||
945 !stmt->label_identifier->ident)
946 return NULL;
947 return stmt->label_identifier->ident->name;
950 static bool is_scoped_guard_goto(struct statement *iterator, struct statement *post_stmt)
952 struct statement *goto_stmt;
953 struct expression *expr;
954 const char *label;
955 const char *goto_name;
957 if (option_project != PROJ_KERNEL)
958 return false;
960 label = get_scoped_guard_label(iterator);
961 if (!label)
962 return false;
964 if (!post_stmt || post_stmt->type != STMT_EXPRESSION)
965 return false;
967 expr = strip_expr(post_stmt->expression);
968 if (expr->type != EXPR_PREOP ||
969 expr->op != '(' ||
970 expr->unop->type != EXPR_STATEMENT)
971 return false;
973 goto_stmt = expr->unop->statement;
974 if (!goto_stmt || goto_stmt->type != STMT_COMPOUND)
975 return false;
976 goto_stmt = first_ptr_list((struct ptr_list *)goto_stmt->stmts);
977 if (!goto_stmt ||
978 goto_stmt->type != STMT_GOTO ||
979 !goto_stmt->goto_label ||
980 goto_stmt->goto_label->type != SYM_LABEL ||
981 !goto_stmt->goto_label->ident)
982 return false;
983 goto_name = goto_stmt->goto_label->ident->name;
984 if (!goto_name || strcmp(goto_name, label) != 0)
985 return false;
987 return true;
991 * Pre Loops are while and for loops.
993 static void handle_pre_loop(struct statement *stmt)
995 int once_through; /* we go through the loop at least once */
996 struct sm_state *extra_sm = NULL;
997 int unchanged = 0;
998 char *loop_name;
999 struct stree *stree = NULL;
1000 struct sm_state *sm = NULL;
1002 __push_scope_hooks();
1004 loop_name = get_loop_name(loop_num);
1005 loop_num++;
1007 split_declaration(stmt->iterator_syms);
1008 if (stmt->iterator_pre_statement) {
1009 __split_stmt(stmt->iterator_pre_statement);
1010 __prev_stmt = stmt->iterator_pre_statement;
1013 loop_count++;
1014 __push_continues();
1015 __push_breaks();
1017 __merge_gotos(loop_name, NULL);
1019 __pass_to_client(stmt, PRELOOP_HOOK);
1021 extra_sm = __extra_handle_canonical_loops(stmt, &stree);
1022 __in_pre_condition++;
1023 __set_confidence_implied();
1024 __split_whole_condition_tf(stmt->iterator_pre_condition, &once_through);
1025 __unset_confidence();
1026 if (once_through != true)
1027 once_through = call_once_through_hooks(stmt);
1028 __in_pre_condition--;
1029 FOR_EACH_SM(stree, sm) {
1030 set_state(sm->owner, sm->name, sm->sym, sm->state);
1031 } END_FOR_EACH_SM(sm);
1032 free_stree(&stree);
1033 if (extra_sm)
1034 extra_sm = get_sm_state(extra_sm->owner, extra_sm->name, extra_sm->sym);
1036 __split_stmt(stmt->iterator_statement);
1037 if (is_scoped_guard_goto(stmt->iterator_statement, stmt->iterator_post_statement)) {
1038 __merge_continues();
1039 __save_gotos(loop_name, NULL);
1040 if (once_through == true)
1041 __discard_false_states();
1042 else
1043 __merge_false_states();
1045 __pass_to_client(stmt, AFTER_LOOP_NO_BREAKS);
1046 __merge_breaks();
1047 goto done;
1050 if (is_forever_loop(stmt)) {
1051 __merge_continues();
1052 __save_gotos(loop_name, NULL);
1054 __push_fake_cur_stree();
1055 __split_stmt(stmt->iterator_post_statement);
1056 stree = __pop_fake_cur_stree();
1058 __discard_false_states();
1059 __pass_to_client(stmt, AFTER_LOOP_NO_BREAKS);
1060 __use_breaks();
1062 if (!__path_is_null())
1063 __merge_stree_into_cur(stree);
1064 free_stree(&stree);
1065 } else {
1066 __merge_continues();
1067 unchanged = __iterator_unchanged(extra_sm);
1068 __split_stmt(stmt->iterator_post_statement);
1069 __prev_stmt = stmt->iterator_post_statement;
1070 __cur_stmt = stmt;
1072 __save_gotos(loop_name, NULL);
1073 __in_pre_condition++;
1074 __split_whole_condition(stmt->iterator_pre_condition);
1075 __in_pre_condition--;
1076 nullify_path();
1077 __merge_false_states();
1078 if (once_through == true)
1079 __discard_false_states();
1080 else
1081 __merge_false_states();
1083 if (extra_sm && unchanged)
1084 __extra_pre_loop_hook_after(extra_sm,
1085 stmt->iterator_post_statement,
1086 stmt->iterator_pre_condition);
1087 __pass_to_client(stmt, AFTER_LOOP_NO_BREAKS);
1088 __merge_breaks();
1090 done:
1091 loop_count--;
1093 do_scope_hooks();
1097 * Post loops are do {} while();
1099 static void handle_post_loop(struct statement *stmt)
1101 char *loop_name;
1103 loop_name = get_loop_name(loop_num);
1104 loop_num++;
1105 loop_count++;
1107 __pass_to_client(stmt, POSTLOOP_HOOK);
1109 __push_continues();
1110 __push_breaks();
1111 __merge_gotos(loop_name, NULL);
1112 __split_stmt(stmt->iterator_statement);
1113 __merge_continues();
1114 if (!expr_is_zero(stmt->iterator_post_condition))
1115 __save_gotos(loop_name, NULL);
1117 if (is_forever_loop(stmt)) {
1118 __pass_to_client(stmt, AFTER_LOOP_NO_BREAKS);
1119 __use_breaks();
1120 } else {
1121 __split_whole_condition(stmt->iterator_post_condition);
1122 __use_false_states();
1123 __pass_to_client(stmt, AFTER_LOOP_NO_BREAKS);
1124 __merge_breaks();
1126 loop_count--;
1129 static int empty_statement(struct statement *stmt)
1131 if (!stmt)
1132 return 0;
1133 if (stmt->type == STMT_EXPRESSION && !stmt->expression)
1134 return 1;
1135 return 0;
1138 static int last_stmt_on_same_line(void)
1140 struct statement *stmt;
1141 int i = 0;
1143 FOR_EACH_PTR_REVERSE(big_statement_stack, stmt) {
1144 if (!i++)
1145 continue;
1146 if (stmt->pos.line == get_lineno())
1147 return 1;
1148 return 0;
1149 } END_FOR_EACH_PTR_REVERSE(stmt);
1150 return 0;
1153 static void split_asm_ops(struct asm_operand_list *ops)
1155 struct asm_operand *op;
1157 FOR_EACH_PTR(ops, op) {
1158 __split_expr(op->expr);
1159 } END_FOR_EACH_PTR(op);
1162 static int is_case_val(struct statement *stmt, sval_t sval)
1164 sval_t case_sval;
1166 if (stmt->type != STMT_CASE)
1167 return 0;
1168 if (!stmt->case_expression) {
1169 __set_default();
1170 return 1;
1172 if (!get_value(stmt->case_expression, &case_sval))
1173 return 0;
1174 if (case_sval.value == sval.value)
1175 return 1;
1176 return 0;
1179 static struct range_list *get_case_rl(struct expression *switch_expr,
1180 struct expression *case_expr,
1181 struct expression *case_to)
1183 sval_t start, end;
1184 struct range_list *rl = NULL;
1185 struct symbol *switch_type;
1187 switch_type = get_type(switch_expr);
1188 if (get_value(case_to, &end) && get_value(case_expr, &start)) {
1189 start = sval_cast(switch_type, start);
1190 end = sval_cast(switch_type, end);
1191 add_range(&rl, start, end);
1192 } else if (get_value(case_expr, &start)) {
1193 start = sval_cast(switch_type, start);
1194 add_range(&rl, start, start);
1197 return rl;
1200 static void split_known_switch(struct statement *stmt, sval_t sval)
1202 struct statement *tmp;
1203 struct range_list *rl;
1205 __split_expr(stmt->switch_expression);
1206 sval = sval_cast(get_type(stmt->switch_expression), sval);
1208 push_expression(&switch_expr_stack, stmt->switch_expression);
1209 __save_switch_states(top_expression(switch_expr_stack));
1210 nullify_path();
1211 __push_default();
1212 __push_breaks();
1214 stmt = stmt->switch_statement;
1216 __push_scope_hooks();
1217 FOR_EACH_PTR(stmt->stmts, tmp) {
1218 __smatch_lineno = tmp->pos.line;
1219 // FIXME: what if default comes before the known case statement?
1220 if (is_case_val(tmp, sval)) {
1221 rl = alloc_rl(sval, sval);
1222 __merge_switches(top_expression(switch_expr_stack), rl);
1223 __pass_case_to_client(top_expression(switch_expr_stack), rl);
1224 stmt_set_parent_stmt(tmp->case_statement, tmp);
1225 __split_stmt(tmp->case_statement);
1226 goto next;
1228 if (__path_is_null())
1229 continue;
1230 __split_stmt(tmp);
1231 next:
1232 if (__path_is_null()) {
1233 __set_default();
1234 goto out;
1236 } END_FOR_EACH_PTR(tmp);
1237 out:
1238 do_scope_hooks();
1239 if (!__pop_default())
1240 __merge_switches(top_expression(switch_expr_stack), NULL);
1241 __discard_switches();
1242 __merge_breaks();
1243 pop_expression(&switch_expr_stack);
1246 static void split_case(struct statement *stmt)
1248 struct range_list *rl = NULL;
1250 expr_set_parent_stmt(stmt->case_expression, stmt);
1251 expr_set_parent_stmt(stmt->case_to, stmt);
1253 rl = get_case_rl(top_expression(switch_expr_stack),
1254 stmt->case_expression, stmt->case_to);
1255 while (stmt->case_statement->type == STMT_CASE) {
1256 struct range_list *tmp;
1258 tmp = get_case_rl(top_expression(switch_expr_stack),
1259 stmt->case_statement->case_expression,
1260 stmt->case_statement->case_to);
1261 if (!tmp)
1262 goto next;
1263 rl = rl_union(rl, tmp);
1264 if (!stmt->case_expression)
1265 __set_default();
1266 next:
1267 stmt = stmt->case_statement;
1270 __merge_switches(top_expression(switch_expr_stack), rl);
1272 if (!stmt->case_expression)
1273 __set_default();
1275 stmt_set_parent_stmt(stmt->case_statement, stmt);
1276 __split_stmt(stmt->case_statement);
1279 int time_parsing_function(void)
1281 return ms_since(&fn_start_time) / 1000;
1284 bool taking_too_long(void)
1286 if ((ms_since(&outer_fn_start_time) / 1000) > 60 * 5) /* five minutes */
1287 return 1;
1288 return 0;
1291 struct statement *get_last_stmt(void)
1293 struct symbol *fn;
1294 struct statement *stmt;
1296 fn = get_base_type(cur_func_sym);
1297 if (!fn)
1298 return NULL;
1299 stmt = fn->stmt;
1300 if (!stmt)
1301 stmt = fn->inline_stmt;
1302 if (!stmt || stmt->type != STMT_COMPOUND)
1303 return NULL;
1304 stmt = last_ptr_list((struct ptr_list *)stmt->stmts);
1305 if (stmt && stmt->type == STMT_LABEL)
1306 stmt = stmt->label_statement;
1307 return stmt;
1310 int is_last_stmt(struct statement *cur_stmt)
1312 struct statement *last;
1314 last = get_last_stmt();
1315 if (last && last == cur_stmt)
1316 return 1;
1317 return 0;
1320 static bool is_function_scope(struct statement *stmt)
1322 struct symbol *base_type;
1324 if (!cur_func_sym)
1325 return false;
1327 base_type = get_base_type(cur_func_sym);
1328 if (base_type->stmt == stmt ||
1329 base_type->inline_stmt == stmt)
1330 return true;
1332 return false;
1336 * Sometimes people do a little backwards goto as the last statement in a
1337 * function.
1339 * exit:
1340 * return ret;
1341 * free:
1342 * kfree(foo);
1343 * goto exit;
1345 * Smatch generally does a hacky thing where it just parses the code one
1346 * time from top to bottom, but in this case we need to go backwards so that
1347 * we record what "return ret;" returns.
1350 static void handle_backward_goto_at_end(struct statement *goto_stmt)
1352 const char *goto_name, *label_name;
1353 struct statement *func_stmt;
1354 struct symbol *base_type = get_base_type(cur_func_sym);
1355 struct statement *tmp;
1356 int found = 0;
1358 if (!is_last_stmt(goto_stmt))
1359 return;
1360 if (last_goto_statement_handled)
1361 return;
1362 last_goto_statement_handled = 1;
1364 if (!goto_stmt->goto_label ||
1365 goto_stmt->goto_label->type != SYM_LABEL ||
1366 !goto_stmt->goto_label->ident)
1367 return;
1368 goto_name = goto_stmt->goto_label->ident->name;
1370 func_stmt = base_type->stmt;
1371 if (!func_stmt)
1372 func_stmt = base_type->inline_stmt;
1373 if (!func_stmt)
1374 return;
1375 if (func_stmt->type != STMT_COMPOUND)
1376 return;
1378 FOR_EACH_PTR(func_stmt->stmts, tmp) {
1379 if (!found) {
1380 if (tmp->type != STMT_LABEL)
1381 continue;
1382 if (!tmp->label_identifier ||
1383 tmp->label_identifier->type != SYM_LABEL ||
1384 !tmp->label_identifier->ident)
1385 continue;
1386 label_name = tmp->label_identifier->ident->name;
1387 if (strcmp(goto_name, label_name) != 0)
1388 continue;
1389 found = 1;
1390 __reparsing_code = true;
1392 __split_stmt(tmp);
1393 } END_FOR_EACH_PTR(tmp);
1394 __reparsing_code = false;
1397 static void fake_a_return(void)
1399 struct expression *ret = NULL;
1401 nullify_path();
1402 __unnullify_path();
1404 if (cur_func_return_type() != &void_ctype)
1405 ret = unknown_value_expression(NULL);
1407 __pass_to_client(ret, RETURN_HOOK);
1408 nullify_path();
1411 static void split_ret_value(struct expression *expr)
1413 struct symbol *type;
1415 if (!expr)
1416 return;
1418 type = get_real_base_type(cur_func_sym);
1419 type = get_real_base_type(type);
1420 expr = fake_a_variable_assign(type, NULL, expr, -1);
1422 __in_fake_var_assign++;
1423 __split_expr(expr);
1424 __in_fake_var_assign--;
1427 static void fake_an_empty_default(struct position pos)
1429 static struct statement none = {};
1431 none.pos = pos;
1432 none.type = STMT_NONE;
1433 __merge_switches(top_expression(switch_expr_stack), NULL);
1434 __split_stmt(&none);
1437 static void split_compound(struct statement *stmt)
1439 struct statement *prev = NULL;
1440 struct statement *cur = NULL;
1441 struct statement *next;
1443 __push_scope_hooks();
1445 FOR_EACH_PTR(stmt->stmts, next) {
1446 /* just set them all ahead of time */
1447 stmt_set_parent_stmt(next, stmt);
1449 if (cur) {
1450 __prev_stmt = prev;
1451 __next_stmt = next;
1452 __cur_stmt = cur;
1453 __split_stmt(cur);
1455 prev = cur;
1456 cur = next;
1457 } END_FOR_EACH_PTR(next);
1458 if (cur) {
1459 __prev_stmt = prev;
1460 __cur_stmt = cur;
1461 __next_stmt = NULL;
1462 __split_stmt(cur);
1466 * For function scope, then delay calling the scope hooks until the
1467 * end of function hooks can run.
1469 if (!is_function_scope(stmt))
1470 do_scope_hooks();
1473 void __split_label_stmt(struct statement *stmt)
1475 if (stmt->label_identifier &&
1476 stmt->label_identifier->type == SYM_LABEL &&
1477 stmt->label_identifier->ident) {
1478 loop_count |= 0x0800000;
1479 __merge_gotos(stmt->label_identifier->ident->name, stmt->label_identifier);
1483 static void find_asm_gotos(struct statement *stmt)
1485 struct symbol *sym;
1487 FOR_EACH_PTR(stmt->asm_labels, sym) {
1488 __save_gotos(sym->ident->name, sym);
1489 } END_FOR_EACH_PTR(sym);
1492 static void split_if_statement(struct statement *stmt)
1494 int known_tf;
1496 stmt_set_parent_stmt(stmt->if_true, stmt);
1497 stmt_set_parent_stmt(stmt->if_false, stmt);
1498 expr_set_parent_stmt(stmt->if_conditional, stmt);
1500 if (empty_statement(stmt->if_true) &&
1501 last_stmt_on_same_line() &&
1502 !get_macro_name(stmt->if_true->pos))
1503 sm_warning("if();");
1505 __split_whole_condition_tf(stmt->if_conditional, &known_tf);
1506 if (known_tf == true) {
1507 __split_stmt(stmt->if_true);
1508 __discard_false_states();
1509 return;
1510 } else if (known_tf == false) {
1511 __use_false_states();
1512 __split_stmt(stmt->if_false);
1513 return;
1516 __split_stmt(stmt->if_true);
1517 __push_true_states();
1518 __use_false_states();
1519 __split_stmt(stmt->if_false);
1520 __merge_true_states();
1523 static bool already_parsed_call(struct expression *call)
1525 struct expression *expr;
1527 FOR_EACH_PTR(parsed_calls, expr) {
1528 if (expr == call)
1529 return true;
1530 } END_FOR_EACH_PTR(expr);
1531 return false;
1534 static void free_parsed_call_stuff(bool free_fake_states)
1536 free_expression_stack(&parsed_calls);
1537 if (free_fake_states)
1538 __discard_fake_states(NULL);
1541 void __split_stmt(struct statement *stmt)
1543 sval_t sval;
1544 struct timeval start, stop;
1545 bool skip_after = false;
1547 gettimeofday(&start, NULL);
1549 if (!stmt)
1550 goto out;
1552 if (!__in_fake_assign)
1553 __silence_warnings_for_stmt = false;
1555 if (__bail_on_rest_of_function || is_skipped_function())
1556 return;
1558 if (out_of_memory() || taking_too_long()) {
1559 gettimeofday(&start, NULL);
1561 __bail_on_rest_of_function = 1;
1562 final_pass = 1;
1563 sm_perror("Function too hairy. Giving up. %lu seconds",
1564 start.tv_sec - fn_start_time.tv_sec);
1565 fake_a_return();
1566 final_pass = 0; /* turn off sm_msg() from here */
1567 return;
1570 indent_cnt++;
1572 add_ptr_list(&big_statement_stack, stmt);
1573 free_expression_stack(&big_expression_stack);
1574 free_parsed_call_stuff(indent_cnt == 1);
1575 set_position(stmt->pos);
1576 __pass_to_client(stmt, STMT_HOOK);
1578 switch (stmt->type) {
1579 case STMT_DECLARATION:
1580 split_declaration(stmt->declaration);
1581 break;
1582 case STMT_RETURN:
1583 expr_set_parent_stmt(stmt->ret_value, stmt);
1585 split_ret_value(stmt->ret_value);
1586 __process_post_op_stack();
1587 __call_all_scope_hooks();
1588 __pass_to_client(stmt->ret_value, RETURN_HOOK);
1589 nullify_path();
1590 break;
1591 case STMT_EXPRESSION:
1592 expr_set_parent_stmt(stmt->expression, stmt);
1593 expr_set_parent_stmt(stmt->context, stmt);
1595 __split_expr(stmt->expression);
1596 break;
1597 case STMT_COMPOUND:
1598 split_compound(stmt);
1599 break;
1600 case STMT_IF:
1601 split_if_statement(stmt);
1602 break;
1603 case STMT_ITERATOR:
1604 stmt_set_parent_stmt(stmt->iterator_pre_statement, stmt);
1605 stmt_set_parent_stmt(stmt->iterator_statement, stmt);
1606 stmt_set_parent_stmt(stmt->iterator_post_statement, stmt);
1607 expr_set_parent_stmt(stmt->iterator_pre_condition, stmt);
1608 expr_set_parent_stmt(stmt->iterator_post_condition, stmt);
1610 if (stmt->iterator_pre_condition)
1611 handle_pre_loop(stmt);
1612 else if (stmt->iterator_post_condition)
1613 handle_post_loop(stmt);
1614 else {
1615 // these are for(;;) type loops.
1616 handle_pre_loop(stmt);
1618 break;
1619 case STMT_SWITCH:
1620 stmt_set_parent_stmt(stmt->switch_statement, stmt);
1621 expr_set_parent_stmt(stmt->switch_expression, stmt);
1623 if (get_value(stmt->switch_expression, &sval)) {
1624 split_known_switch(stmt, sval);
1625 break;
1627 __split_expr(stmt->switch_expression);
1628 push_expression(&switch_expr_stack, stmt->switch_expression);
1629 __save_switch_states(top_expression(switch_expr_stack));
1630 nullify_path();
1631 __push_default();
1632 __push_breaks();
1633 __split_stmt(stmt->switch_statement);
1634 if (!__pop_default() && have_remaining_cases())
1635 fake_an_empty_default(stmt->pos);
1636 __discard_switches();
1637 __merge_breaks();
1638 pop_expression(&switch_expr_stack);
1639 break;
1640 case STMT_CASE:
1641 split_case(stmt);
1642 break;
1643 case STMT_LABEL:
1644 __split_label_stmt(stmt);
1645 __pass_to_client(stmt, STMT_HOOK_AFTER);
1646 skip_after = true;
1647 __split_stmt(stmt->label_statement);
1648 break;
1649 case STMT_GOTO:
1650 expr_set_parent_stmt(stmt->goto_expression, stmt);
1652 __split_expr(stmt->goto_expression);
1653 if (stmt->goto_label && stmt->goto_label->type == SYM_NODE) {
1654 if (!strcmp(stmt->goto_label->ident->name, "break")) {
1655 __process_breaks();
1656 } else if (!strcmp(stmt->goto_label->ident->name,
1657 "continue")) {
1658 __process_continues();
1660 } else if (stmt->goto_label &&
1661 stmt->goto_label->type == SYM_LABEL &&
1662 stmt->goto_label->ident) {
1663 __save_gotos(stmt->goto_label->ident->name, stmt->goto_label);
1665 handle_backward_goto_at_end(stmt);
1666 nullify_path();
1667 break;
1668 case STMT_NONE:
1669 break;
1670 case STMT_ASM:
1671 expr_set_parent_stmt(stmt->asm_string, stmt);
1673 find_asm_gotos(stmt);
1674 __pass_to_client(stmt, ASM_HOOK);
1675 __split_expr(stmt->asm_string);
1676 split_asm_ops(stmt->asm_outputs);
1677 split_asm_ops(stmt->asm_inputs);
1678 split_expr_list(stmt->asm_clobbers, NULL);
1679 break;
1680 case STMT_CONTEXT:
1681 break;
1682 case STMT_RANGE:
1683 __split_expr(stmt->range_expression);
1684 __split_expr(stmt->range_low);
1685 __split_expr(stmt->range_high);
1686 break;
1688 if (!skip_after)
1689 __pass_to_client(stmt, STMT_HOOK_AFTER);
1690 if (--indent_cnt == 1)
1691 free_parsed_call_stuff(true);
1693 out:
1694 __process_post_op_stack();
1696 gettimeofday(&stop, NULL);
1697 if (option_time_stmt && stmt)
1698 sm_msg("stmt_time%s: %ld",
1699 stmt->type == STMT_COMPOUND ? "_block" : "",
1700 stop.tv_sec - start.tv_sec);
1703 static void split_expr_list(struct expression_list *expr_list, struct expression *parent)
1705 struct expression *expr;
1707 FOR_EACH_PTR(expr_list, expr) {
1708 expr_set_parent_expr(expr, parent);
1709 __split_expr(expr);
1710 __process_post_op_stack();
1711 } END_FOR_EACH_PTR(expr);
1714 static bool cast_arg(struct symbol *type, struct expression *arg)
1716 struct symbol *orig;
1718 if (!type)
1719 return false;
1721 arg = strip_parens(arg);
1722 if (arg != strip_expr(arg))
1723 return true;
1725 orig = get_type(arg);
1726 if (!orig)
1727 return true;
1728 if (types_equiv(orig, type))
1729 return false;
1731 if (orig->type == SYM_ARRAY && type->type == SYM_PTR)
1732 return true;
1735 * I would have expected that we could just do use (orig == type) but I
1736 * guess for pointers we need to get the basetype to do that comparison.
1740 if (orig->type != SYM_PTR ||
1741 type->type != SYM_PTR) {
1742 if (type_fits(type, orig))
1743 return false;
1744 return true;
1746 orig = get_real_base_type(orig);
1747 type = get_real_base_type(type);
1748 if (orig == type)
1749 return false;
1751 return true;
1754 static struct expression *fake_a_variable_assign(struct symbol *type, struct expression *call, struct expression *expr, int nr)
1756 char buf[64];
1757 bool cast;
1759 if (!expr || !cur_func_sym)
1760 return NULL;
1762 if (already_parsed_call(call))
1763 return NULL;
1765 if (expr->type == EXPR_ASSIGNMENT)
1766 return expr;
1768 /* for va_args then we don't know the type */
1769 if (!type)
1770 type = get_type(expr);
1772 cast = cast_arg(type, expr);
1774 * Using expr_to_sym() here is a hack. We want to say that we don't
1775 * need to assign frob(foo) or frob(foo->bar) if the types are right.
1776 * It turns out faking these assignments is way more expensive than I
1777 * would have imagined. I'm not sure why exactly.
1780 if (!cast) {
1782 * if the code is "return *p;" where "p" is a user pointer then
1783 * we want to create a fake assignment so that it sets the state
1784 * in check_kernel_user_data.c.
1787 if (expr->type != EXPR_PREOP &&
1788 expr->op != '*' && expr->op != '&' &&
1789 expr_to_sym(expr))
1790 return expr;
1793 if (nr == -1)
1794 snprintf(buf, sizeof(buf), "__fake_return_%p", expr);
1795 else
1796 snprintf(buf, sizeof(buf), "__fake_param_%p_%d", call, nr);
1798 return create_fake_assign(buf, type, expr);
1801 struct expression *get_fake_return_variable(struct expression *expr)
1803 struct expression *tmp;
1805 tmp = expr_get_fake_parent_expr(expr);
1806 if (!tmp || tmp->type != EXPR_ASSIGNMENT)
1807 return NULL;
1809 return tmp->left;
1812 static void split_args(struct expression *expr)
1814 struct expression *arg, *tmp;
1815 struct symbol *type;
1816 int i;
1818 i = -1;
1819 FOR_EACH_PTR(expr->args, arg) {
1820 i++;
1821 expr_set_parent_expr(arg, expr);
1822 type = get_arg_type(expr->fn, i);
1823 tmp = fake_a_variable_assign(type, expr, arg, i);
1824 if (tmp != arg)
1825 __in_fake_var_assign++;
1826 __split_expr(tmp);
1827 if (tmp != arg)
1828 __in_fake_var_assign--;
1829 __process_post_op_stack();
1830 } END_FOR_EACH_PTR(arg);
1833 static void call_cleanup_fn(void *_sym)
1835 struct symbol *sym = _sym;
1836 struct expression *call, *arg;
1837 struct expression_list *args = NULL;
1838 struct position orig = current_pos;
1840 arg = symbol_expression(sym);
1841 arg = preop_expression(arg, '&');
1842 add_ptr_list(&args, arg);
1843 call = call_expression(sym->cleanup, args);
1845 __split_expr(call);
1846 set_position(orig);
1849 static void add_cleanup_hook(struct symbol *sym)
1851 if (!sym->cleanup)
1852 return;
1853 add_scope_hook(&call_cleanup_fn, sym);
1856 static void split_sym(struct symbol *sym)
1858 if (!sym)
1859 return;
1860 if (!(sym->namespace & NS_SYMBOL))
1861 return;
1863 __split_stmt(sym->stmt);
1864 __split_expr(sym->array_size);
1865 if (sym->cleanup)
1866 add_cleanup_hook(sym);
1867 split_symlist(sym->arguments);
1868 split_symlist(sym->symbol_list);
1869 __split_stmt(sym->inline_stmt);
1870 split_symlist(sym->inline_symbol_list);
1873 static void split_symlist(struct symbol_list *sym_list)
1875 struct symbol *sym;
1877 FOR_EACH_PTR(sym_list, sym) {
1878 split_sym(sym);
1879 } END_FOR_EACH_PTR(sym);
1882 typedef void (fake_cb)(struct expression *expr);
1884 static int member_to_number(struct expression *expr, struct ident *member)
1886 struct symbol *type, *tmp;
1887 char *name;
1888 int i;
1890 if (!member)
1891 return -1;
1892 name = member->name;
1894 type = get_type(expr);
1895 if (!type || type->type != SYM_STRUCT)
1896 return -1;
1898 i = -1;
1899 FOR_EACH_PTR(type->symbol_list, tmp) {
1900 i++;
1901 if (!tmp->ident)
1902 continue;
1903 if (strcmp(name, tmp->ident->name) == 0)
1904 return i;
1905 } END_FOR_EACH_PTR(tmp);
1906 return -1;
1909 static struct ident *number_to_member(struct expression *expr, int num)
1911 struct symbol *type, *member;
1912 int i = 0;
1914 type = get_type(expr);
1915 if (!type || type->type != SYM_STRUCT)
1916 return NULL;
1918 FOR_EACH_PTR(type->symbol_list, member) {
1919 if (i == num)
1920 return member->ident;
1921 i++;
1922 } END_FOR_EACH_PTR(member);
1923 return NULL;
1926 static void fake_element_assigns_helper(struct expression *array, struct expression_list *expr_list, fake_cb *fake_cb);
1928 static void set_inner_struct_members(struct expression *expr, struct symbol *member)
1930 struct expression *edge_member, *assign;
1931 struct symbol *base = get_real_base_type(member);
1932 struct symbol *tmp;
1934 if (member->ident)
1935 expr = member_expression(expr, '.', member->ident);
1937 FOR_EACH_PTR(base->symbol_list, tmp) {
1938 struct symbol *type;
1940 type = get_real_base_type(tmp);
1941 if (!type)
1942 continue;
1944 edge_member = member_expression(expr, '.', tmp->ident);
1945 if (get_extra_state(edge_member))
1946 continue;
1948 if (type->type == SYM_UNION || type->type == SYM_STRUCT) {
1949 set_inner_struct_members(expr, tmp);
1950 continue;
1953 if (!tmp->ident)
1954 continue;
1956 assign = assign_expression(edge_member, '=', zero_expr());
1957 __split_expr(assign);
1958 } END_FOR_EACH_PTR(tmp);
1963 static void set_unset_to_zero(struct symbol *type, struct expression *expr)
1965 struct symbol *tmp;
1966 struct expression *member = NULL;
1967 struct expression *assign;
1969 FOR_EACH_PTR(type->symbol_list, tmp) {
1970 type = get_real_base_type(tmp);
1971 if (!type)
1972 continue;
1974 if (tmp->ident) {
1975 member = member_expression(expr, '.', tmp->ident);
1976 if (get_extra_state(member))
1977 continue;
1980 if (type->type == SYM_UNION || type->type == SYM_STRUCT) {
1981 set_inner_struct_members(expr, tmp);
1982 continue;
1984 if (type->type == SYM_ARRAY)
1985 continue;
1986 if (!tmp->ident)
1987 continue;
1989 assign = assign_expression(member, '=', zero_expr());
1990 __split_expr(assign);
1991 } END_FOR_EACH_PTR(tmp);
1994 static void fake_member_assigns_helper(struct expression *symbol, struct expression_list *members, fake_cb *fake_cb)
1996 struct expression *deref, *assign, *tmp, *right;
1997 struct symbol *struct_type, *type;
1998 struct ident *member;
1999 int member_idx;
2001 struct_type = get_type(symbol);
2002 if (!struct_type ||
2003 (struct_type->type != SYM_STRUCT && struct_type->type != SYM_UNION))
2004 return;
2007 * We're parsing an initializer that could look something like this:
2008 * struct foo foo = {
2009 * 42,
2010 * .whatever.xxx = 11,
2011 * .zzz = 12,
2012 * };
2014 * So what we have here is a list with 42, .whatever, and .zzz. We need
2015 * to break it up into left and right sides of the assignments.
2018 member_idx = 0;
2019 FOR_EACH_PTR(members, tmp) {
2020 deref = NULL;
2021 if (tmp->type == EXPR_IDENTIFIER) {
2022 member_idx = member_to_number(symbol, tmp->expr_ident);
2023 while (tmp->type == EXPR_IDENTIFIER) {
2024 member = tmp->expr_ident;
2025 tmp = tmp->ident_expression;
2026 if (deref)
2027 deref = member_expression(deref, '.', member);
2028 else
2029 deref = member_expression(symbol, '.', member);
2031 } else {
2032 member = number_to_member(symbol, member_idx);
2033 deref = member_expression(symbol, '.', member);
2035 right = tmp;
2036 member_idx++;
2037 if (right->type == EXPR_INITIALIZER) {
2038 type = get_type(deref);
2039 if (type && type->type == SYM_ARRAY)
2040 fake_element_assigns_helper(deref, right->expr_list, fake_cb);
2041 else
2042 fake_member_assigns_helper(deref, right->expr_list, fake_cb);
2043 } else {
2044 assign = assign_expression(deref, '=', right);
2045 fake_cb(assign);
2047 } END_FOR_EACH_PTR(tmp);
2049 set_unset_to_zero(struct_type, symbol);
2052 static void fake_member_assigns(struct symbol *sym, fake_cb *fake_cb)
2054 fake_member_assigns_helper(symbol_expression(sym),
2055 sym->initializer->expr_list, fake_cb);
2058 static void fake_element_assigns_helper(struct expression *array, struct expression_list *expr_list, fake_cb *fake_cb)
2060 struct expression *offset, *binop, *assign, *tmp;
2061 struct symbol *type;
2062 int idx, max;
2064 if (ptr_list_size((struct ptr_list *)expr_list) > 256) {
2065 binop = array_element_expression(array, unknown_value_expression(array));
2066 assign = assign_expression(binop, '=', unknown_value_expression(array));
2067 /* fake_cb is probably call_global_assign_hooks() which is a
2068 * a kind of hacky short cut because it's too expensive to deal
2069 * with huge global arrays. However, we may as well parse this
2070 * one the long way seeing as it's a one time thing.
2072 __split_expr(assign);
2073 return;
2076 max = 0;
2077 idx = 0;
2078 FOR_EACH_PTR(expr_list, tmp) {
2079 if (tmp->type == EXPR_INDEX) {
2080 if (tmp->idx_from != tmp->idx_to)
2081 return;
2082 idx = tmp->idx_from;
2083 if (idx > max)
2084 max = idx;
2085 if (!tmp->idx_expression)
2086 goto next;
2087 tmp = tmp->idx_expression;
2089 offset = value_expr(idx);
2090 binop = array_element_expression(array, offset);
2091 if (tmp->type == EXPR_INITIALIZER) {
2092 type = get_type(binop);
2093 if (type && type->type == SYM_ARRAY)
2094 fake_element_assigns_helper(binop, tmp->expr_list, fake_cb);
2095 else
2096 fake_member_assigns_helper(binop, tmp->expr_list, fake_cb);
2097 } else {
2098 assign = assign_expression(binop, '=', tmp);
2099 fake_cb(assign);
2101 next:
2102 idx++;
2103 if (idx > max)
2104 max = idx;
2105 } END_FOR_EACH_PTR(tmp);
2107 __call_array_initialized_hooks(array, max);
2110 static void fake_element_assigns(struct symbol *sym, fake_cb *fake_cb)
2112 fake_element_assigns_helper(symbol_expression(sym), sym->initializer->expr_list, fake_cb);
2115 static void fake_assign_expr(struct symbol *sym)
2117 struct expression *assign, *symbol;
2119 symbol = symbol_expression(sym);
2120 assign = assign_expression(symbol, '=', sym->initializer);
2121 __split_expr(assign);
2124 static void do_initializer_stuff(struct symbol *sym)
2126 if (!sym->initializer)
2127 return;
2129 if (sym->initializer->type == EXPR_INITIALIZER) {
2130 if (get_real_base_type(sym)->type == SYM_ARRAY)
2131 fake_element_assigns(sym, __split_expr);
2132 else
2133 fake_member_assigns(sym, __split_expr);
2134 } else {
2135 fake_assign_expr(sym);
2139 static void split_declaration(struct symbol_list *sym_list)
2141 struct symbol *sym;
2143 FOR_EACH_PTR(sym_list, sym) {
2144 __pass_to_client(sym, DECLARATION_HOOK);
2145 do_initializer_stuff(sym);
2146 __pass_to_client(sym, DECLARATION_HOOK_AFTER);
2147 split_sym(sym);
2148 } END_FOR_EACH_PTR(sym);
2151 static void call_global_assign_hooks(struct expression *assign)
2153 __pass_to_client(assign, GLOBAL_ASSIGNMENT_HOOK);
2156 static void fake_global_assign(struct symbol *sym)
2158 struct expression *assign, *symbol;
2160 if (get_real_base_type(sym)->type == SYM_ARRAY) {
2161 if (sym->initializer && sym->initializer->type == EXPR_INITIALIZER) {
2162 fake_element_assigns(sym, call_global_assign_hooks);
2163 } else if (sym->initializer) {
2164 symbol = symbol_expression(sym);
2165 assign = assign_expression(symbol, '=', sym->initializer);
2166 __pass_to_client(assign, GLOBAL_ASSIGNMENT_HOOK);
2167 } else {
2168 fake_element_assigns_helper(symbol_expression(sym), NULL, call_global_assign_hooks);
2170 } else if (get_real_base_type(sym)->type == SYM_STRUCT) {
2171 if (sym->initializer && sym->initializer->type == EXPR_INITIALIZER) {
2172 fake_member_assigns(sym, call_global_assign_hooks);
2173 } else if (sym->initializer) {
2174 symbol = symbol_expression(sym);
2175 assign = assign_expression(symbol, '=', sym->initializer);
2176 __pass_to_client(assign, GLOBAL_ASSIGNMENT_HOOK);
2177 } else {
2178 fake_member_assigns_helper(symbol_expression(sym), NULL, call_global_assign_hooks);
2180 } else {
2181 symbol = symbol_expression(sym);
2182 if (sym->initializer) {
2183 assign = assign_expression(symbol, '=', sym->initializer);
2184 __split_expr(assign);
2185 } else {
2186 assign = assign_expression(symbol, '=', zero_expr());
2188 __pass_to_client(assign, GLOBAL_ASSIGNMENT_HOOK);
2192 static void start_function_definition(struct symbol *sym)
2194 __in_function_def = 1;
2195 __pass_to_client(sym, FUNC_DEF_HOOK);
2196 __in_function_def = 0;
2197 __pass_to_client(sym, AFTER_DEF_HOOK);
2201 static void parse_fn_statements(struct symbol *base)
2203 __split_stmt(base->stmt);
2204 __split_stmt(base->inline_stmt);
2207 void add_function_data(unsigned long *fn_data)
2209 __add_ptr_list(&fn_data_list, fn_data);
2212 static void clear_function_data(void)
2214 unsigned long *tmp;
2216 FOR_EACH_PTR(fn_data_list, tmp) {
2217 *tmp = 0;
2218 } END_FOR_EACH_PTR(tmp);
2221 static void record_func_time(void)
2223 struct timeval stop;
2224 int func_time;
2225 char buf[32];
2227 gettimeofday(&stop, NULL);
2228 func_time = stop.tv_sec - fn_start_time.tv_sec;
2229 snprintf(buf, sizeof(buf), "%d", func_time);
2230 sql_insert_return_implies(FUNC_TIME, 0, "", buf);
2231 if (option_time && func_time > 2) {
2232 final_pass++;
2233 sm_msg("func_time: %d", func_time);
2234 final_pass--;
2238 static void split_function(struct symbol *sym)
2240 struct symbol *base_type = get_base_type(sym);
2242 if (!base_type->stmt && !base_type->inline_stmt)
2243 return;
2245 gettimeofday(&outer_fn_start_time, NULL);
2246 gettimeofday(&fn_start_time, NULL);
2247 cur_func_sym = sym;
2248 if (sym->ident)
2249 cur_func = sym->ident->name;
2250 if (option_process_function && cur_func &&
2251 strcmp(option_process_function, cur_func) != 0)
2252 return;
2253 set_position(sym->pos);
2254 clear_function_data();
2255 loop_count = 0;
2256 last_goto_statement_handled = 0;
2257 sm_debug("new function: %s\n", cur_func);
2258 __stree_id = 0;
2259 if (option_two_passes) {
2260 __unnullify_path();
2261 loop_num = 0;
2262 final_pass = 0;
2263 start_function_definition(sym);
2264 parse_fn_statements(base_type);
2265 do_scope_hooks();
2266 nullify_path();
2268 __unnullify_path();
2269 loop_num = 0;
2270 final_pass = 1;
2271 start_function_definition(sym);
2272 parse_fn_statements(base_type);
2273 if (!__path_is_null() &&
2274 cur_func_return_type() == &void_ctype &&
2275 !__bail_on_rest_of_function) {
2276 __call_all_scope_hooks();
2277 __pass_to_client(NULL, RETURN_HOOK);
2278 nullify_path();
2280 __pass_to_client(sym, END_FUNC_HOOK);
2281 __free_scope_hooks();
2282 __pass_to_client(sym, AFTER_FUNC_HOOK);
2283 sym->parsed = true;
2285 clear_all_states();
2287 record_func_time();
2289 cur_func_sym = NULL;
2290 cur_func = NULL;
2291 free_data_info_allocs();
2292 free_expression_stack(&switch_expr_stack);
2293 __free_ptr_list((struct ptr_list **)&big_statement_stack);
2294 __bail_on_rest_of_function = 0;
2297 static void save_flow_state(void)
2299 unsigned long *tmp;
2301 __add_ptr_list(&backup, INT_PTR(loop_num << 2));
2302 __add_ptr_list(&backup, INT_PTR(loop_count << 2));
2303 __add_ptr_list(&backup, INT_PTR(final_pass << 2));
2305 __add_ptr_list(&backup, big_statement_stack);
2306 __add_ptr_list(&backup, big_expression_stack);
2307 __add_ptr_list(&backup, big_condition_stack);
2308 __add_ptr_list(&backup, switch_expr_stack);
2310 __add_ptr_list(&backup, cur_func_sym);
2312 __add_ptr_list(&backup, parsed_calls);
2314 __add_ptr_list(&backup, __prev_stmt);
2315 __add_ptr_list(&backup, __cur_stmt);
2316 __add_ptr_list(&backup, __next_stmt);
2318 FOR_EACH_PTR(fn_data_list, tmp) {
2319 __add_ptr_list(&backup, (void *)*tmp);
2320 } END_FOR_EACH_PTR(tmp);
2323 static void *pop_backup(void)
2325 void *ret;
2327 ret = last_ptr_list(backup);
2328 delete_ptr_list_last(&backup);
2329 return ret;
2332 static void restore_flow_state(void)
2334 unsigned long *tmp;
2336 FOR_EACH_PTR_REVERSE(fn_data_list, tmp) {
2337 *tmp = (unsigned long)pop_backup();
2338 } END_FOR_EACH_PTR_REVERSE(tmp);
2340 __next_stmt = pop_backup();
2341 __cur_stmt = pop_backup();
2342 __prev_stmt = pop_backup();
2344 parsed_calls = pop_backup();
2346 cur_func_sym = pop_backup();
2347 switch_expr_stack = pop_backup();
2348 big_condition_stack = pop_backup();
2349 big_expression_stack = pop_backup();
2350 big_statement_stack = pop_backup();
2351 final_pass = PTR_INT(pop_backup()) >> 2;
2352 loop_count = PTR_INT(pop_backup()) >> 2;
2353 loop_num = PTR_INT(pop_backup()) >> 2;
2356 void parse_inline(struct expression *call)
2358 struct symbol *base_type;
2359 char *cur_func_bak = cur_func; /* not aligned correctly for backup */
2360 struct timeval time_backup = fn_start_time;
2361 struct expression *orig_inline = __inline_fn;
2362 int orig_budget;
2364 if (out_of_memory() || taking_too_long())
2365 return;
2367 if (already_parsed_call(call))
2368 return;
2370 save_flow_state();
2372 gettimeofday(&fn_start_time, NULL);
2373 __pass_to_client(call, INLINE_FN_START);
2374 final_pass = 0; /* don't print anything */
2375 __inline_fn = call;
2376 orig_budget = inline_budget;
2377 inline_budget = inline_budget - 5;
2379 base_type = get_base_type(call->fn->symbol);
2380 cur_func_sym = call->fn->symbol;
2381 if (call->fn->symbol->ident)
2382 cur_func = call->fn->symbol->ident->name;
2383 else
2384 cur_func = NULL;
2385 set_position(call->fn->symbol->pos);
2387 save_all_states();
2388 big_statement_stack = NULL;
2389 big_expression_stack = NULL;
2390 big_condition_stack = NULL;
2391 switch_expr_stack = NULL;
2392 parsed_calls = NULL;
2394 sm_debug("inline function: %s\n", cur_func);
2395 __unnullify_path();
2396 clear_function_data();
2397 loop_num = 0;
2398 loop_count = 0;
2399 start_function_definition(call->fn->symbol);
2400 parse_fn_statements(base_type);
2401 if (!__path_is_null() &&
2402 cur_func_return_type() == &void_ctype &&
2403 !__bail_on_rest_of_function) {
2404 __call_all_scope_hooks();
2405 __pass_to_client(NULL, RETURN_HOOK);
2406 nullify_path();
2408 __pass_to_client(call->fn->symbol, END_FUNC_HOOK);
2409 __free_scope_hooks();
2410 __pass_to_client(call->fn->symbol, AFTER_FUNC_HOOK);
2411 call->fn->symbol->parsed = true;
2413 free_expression_stack(&switch_expr_stack);
2414 __free_ptr_list((struct ptr_list **)&big_statement_stack);
2415 nullify_path();
2416 free_goto_stack();
2418 record_func_time();
2420 restore_flow_state();
2421 fn_start_time = time_backup;
2422 cur_func = cur_func_bak;
2424 restore_all_states();
2425 set_position(call->pos);
2426 __inline_fn = orig_inline;
2427 inline_budget = orig_budget;
2428 __pass_to_client(call, INLINE_FN_END);
2431 static struct symbol_list *inlines_called;
2432 static void add_inline_function(struct symbol *sym)
2434 static struct symbol_list *already_added;
2435 struct symbol *tmp;
2437 FOR_EACH_PTR(already_added, tmp) {
2438 if (tmp == sym)
2439 return;
2440 } END_FOR_EACH_PTR(tmp);
2442 add_ptr_list(&already_added, sym);
2443 add_ptr_list(&inlines_called, sym);
2446 static void process_inlines(void)
2448 struct symbol *tmp;
2450 FOR_EACH_PTR(inlines_called, tmp) {
2451 split_function(tmp);
2452 } END_FOR_EACH_PTR(tmp);
2453 free_ptr_list(&inlines_called);
2456 static struct symbol *get_last_scoped_symbol(struct symbol_list *big_list, int use_static)
2458 struct symbol *sym;
2460 FOR_EACH_PTR_REVERSE(big_list, sym) {
2461 if (!sym->scope)
2462 continue;
2463 if (use_static && sym->ctype.modifiers & MOD_STATIC)
2464 return sym;
2465 if (!use_static && !(sym->ctype.modifiers & MOD_STATIC))
2466 return sym;
2467 } END_FOR_EACH_PTR_REVERSE(sym);
2469 return NULL;
2472 static bool interesting_function(struct symbol *sym)
2474 static int prev_stream = -1;
2475 static bool prev_answer;
2476 const char *filename;
2477 int len;
2479 if (!(sym->ctype.modifiers & MOD_INLINE))
2480 return true;
2482 if (sym->pos.stream == prev_stream)
2483 return prev_answer;
2485 prev_stream = sym->pos.stream;
2486 prev_answer = false;
2488 filename = stream_name(sym->pos.stream);
2489 len = strlen(filename);
2490 if (len > 0 && filename[len - 1] == 'c')
2491 prev_answer = true;
2492 return prev_answer;
2495 static void split_inlines_in_scope(struct symbol *sym)
2497 struct symbol *base;
2498 struct symbol_list *scope_list;
2499 int stream;
2501 scope_list = sym->scope->symbols;
2502 stream = sym->pos.stream;
2504 /* find the last static symbol in the file */
2505 FOR_EACH_PTR_REVERSE(scope_list, sym) {
2506 if (sym->pos.stream != stream)
2507 continue;
2508 if (sym->type != SYM_NODE)
2509 continue;
2510 base = get_base_type(sym);
2511 if (!base)
2512 continue;
2513 if (base->type != SYM_FN)
2514 continue;
2515 if (!base->inline_stmt)
2516 continue;
2517 if (!interesting_function(sym))
2518 continue;
2519 add_inline_function(sym);
2520 } END_FOR_EACH_PTR_REVERSE(sym);
2522 process_inlines();
2525 static void split_inlines(struct symbol_list *sym_list)
2527 struct symbol *sym;
2529 sym = get_last_scoped_symbol(sym_list, 0);
2530 if (sym)
2531 split_inlines_in_scope(sym);
2532 sym = get_last_scoped_symbol(sym_list, 1);
2533 if (sym)
2534 split_inlines_in_scope(sym);
2537 static struct stree *clone_estates_perm(struct stree *orig)
2539 struct stree *ret = NULL;
2540 struct sm_state *tmp;
2542 FOR_EACH_SM(orig, tmp) {
2543 set_state_stree_perm(&ret, tmp->owner, tmp->name, tmp->sym, clone_estate_perm(tmp->state));
2544 } END_FOR_EACH_SM(tmp);
2546 return ret;
2549 struct position last_pos;
2550 static void split_c_file_functions(struct symbol_list *sym_list)
2552 struct symbol *sym;
2554 __unnullify_path();
2555 FOR_EACH_PTR(sym_list, sym) {
2556 set_position(sym->pos);
2557 if (sym->type != SYM_NODE || get_base_type(sym)->type != SYM_FN) {
2558 __pass_to_client(sym, BASE_HOOK);
2559 fake_global_assign(sym);
2560 __pass_to_client(sym, DECLARATION_HOOK_AFTER);
2562 } END_FOR_EACH_PTR(sym);
2563 global_states = clone_estates_perm(get_all_states_stree(SMATCH_EXTRA));
2564 nullify_path();
2566 FOR_EACH_PTR(sym_list, sym) {
2567 set_position(sym->pos);
2568 last_pos = sym->pos;
2569 if (!interesting_function(sym))
2570 continue;
2571 if (sym->type == SYM_NODE && get_base_type(sym)->type == SYM_FN) {
2572 split_function(sym);
2573 process_inlines();
2575 last_pos = sym->pos;
2576 } END_FOR_EACH_PTR(sym);
2577 split_inlines(sym_list);
2578 __pass_to_client(sym_list, END_FILE_HOOK);
2581 static int final_before_fake;
2582 void init_fake_env(void)
2584 if (!in_fake_env)
2585 final_before_fake = final_pass;
2586 in_fake_env++;
2587 __push_fake_cur_stree();
2588 final_pass = 0;
2591 void end_fake_env(void)
2593 __free_fake_cur_stree();
2594 in_fake_env--;
2595 if (!in_fake_env)
2596 final_pass = final_before_fake;
2599 static void open_output_files(char *base_file)
2601 char buf[256];
2603 snprintf(buf, sizeof(buf), "%s.smatch", base_file);
2604 sm_outfd = fopen(buf, "w");
2605 if (!sm_outfd)
2606 sm_fatal("Cannot open %s", buf);
2608 if (!option_info)
2609 return;
2611 snprintf(buf, sizeof(buf), "%s.smatch.sql", base_file);
2612 sql_outfd = fopen(buf, "w");
2613 if (!sql_outfd)
2614 sm_fatal("Error: Cannot open %s", buf);
2616 snprintf(buf, sizeof(buf), "%s.smatch.caller_info", base_file);
2617 caller_info_fd = fopen(buf, "w");
2618 if (!caller_info_fd)
2619 sm_fatal("Error: Cannot open %s", buf);
2622 void smatch(struct string_list *filelist)
2624 struct symbol_list *sym_list;
2625 struct timeval stop, start;
2626 char *path;
2627 int len;
2629 gettimeofday(&start, NULL);
2631 FOR_EACH_PTR_NOTAG(filelist, base_file) {
2632 path = getcwd(NULL, 0);
2633 free(full_base_file);
2634 if (path) {
2635 len = strlen(path) + 1 + strlen(base_file) + 1;
2636 full_base_file = malloc(len);
2637 snprintf(full_base_file, len, "%s/%s", path, base_file);
2638 } else {
2639 full_base_file = alloc_string(base_file);
2641 if (option_file_output)
2642 open_output_files(base_file);
2643 base_file_stream = input_stream_nr;
2644 sym_list = sparse_keep_tokens(base_file);
2645 split_c_file_functions(sym_list);
2646 } END_FOR_EACH_PTR_NOTAG(base_file);
2648 gettimeofday(&stop, NULL);
2650 set_position(last_pos);
2651 final_pass = 1;
2652 if (option_time)
2653 sm_msg("time: %lu", stop.tv_sec - start.tv_sec);
2654 if (option_mem)
2655 sm_msg("mem: %luKb", get_max_memory());