kchecker: Fix --outfile handling
[smatch.git] / smatch_flow.c
blobcef1c53551be52fb9d4bbefeaf34c8b5c664e235
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 struct expression *__inline_fn;
39 int __smatch_lineno = 0;
41 static char *base_file;
42 static const char *filename;
43 static char *pathname;
44 static char *full_filename;
45 static char *full_base_file;
46 static char *cur_func;
47 int base_file_stream;
48 static unsigned int loop_count;
49 static int last_goto_statement_handled;
50 int __expr_stmt_count;
51 int __in_function_def;
52 int __in_unmatched_hook;
53 static struct expression_list *switch_expr_stack = NULL;
54 static struct expression_list *post_op_stack = NULL;
56 static struct ptr_list *fn_data_list;
57 static struct ptr_list *backup;
59 struct expression_list *big_expression_stack;
60 struct statement_list *big_statement_stack;
61 struct statement *__prev_stmt;
62 struct statement *__cur_stmt;
63 struct statement *__next_stmt;
64 static struct expression_list *parsed_calls;
65 static int indent_cnt;
66 int __in_pre_condition = 0;
67 int __bail_on_rest_of_function = 0;
68 static struct timeval fn_start_time;
69 static struct timeval outer_fn_start_time;
70 char *get_function(void) { return cur_func; }
71 int get_lineno(void) { return __smatch_lineno; }
72 int inside_loop(void) { return !!loop_count; }
73 int definitely_inside_loop(void) { return !!(loop_count & ~0x08000000); }
74 struct expression *get_switch_expr(void) { return top_expression(switch_expr_stack); }
75 int in_expression_statement(void) { return !!__expr_stmt_count; }
77 static void split_symlist(struct symbol_list *sym_list);
78 static void split_declaration(struct symbol_list *sym_list);
79 static void split_expr_list(struct expression_list *expr_list, struct expression *parent);
80 static void split_args(struct expression *expr);
81 static struct expression *fake_a_variable_assign(struct symbol *type, struct expression *call, struct expression *expr, int nr);
82 static void add_inline_function(struct symbol *sym);
83 static void parse_inline(struct expression *expr);
85 int option_assume_loops = 0;
86 int option_two_passes = 0;
87 struct symbol *cur_func_sym = NULL;
88 struct stree *global_states;
90 const unsigned long valid_ptr_min = 4096;
91 unsigned long valid_ptr_max = ULONG_MAX & ~(MTAG_OFFSET_MASK);
92 const sval_t valid_ptr_min_sval = {
93 .type = &ptr_ctype,
94 {.value = 4096},
96 sval_t ptr_err_min = { .type = &ptr_ctype };
97 sval_t ptr_err_max = { .type = &ptr_ctype };
98 sval_t ptr_xa_err_min = { .type = &ptr_ctype };
99 sval_t ptr_xa_err_max = { .type = &ptr_ctype };
100 sval_t ulong_ULONG_MAX = { .type = &ulong_ctype };
102 sval_t valid_ptr_max_sval = {
103 .type = &ptr_ctype,
104 {.value = ULONG_MAX & ~(MTAG_OFFSET_MASK)},
106 struct range_list *valid_ptr_rl;
108 void alloc_ptr_constants(void)
110 valid_ptr_max = sval_type_max(&ulong_ctype).value & ~(MTAG_OFFSET_MASK);
111 valid_ptr_max_sval.value = valid_ptr_max;
113 valid_ptr_rl = alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
114 valid_ptr_rl = cast_rl(&ptr_ctype, valid_ptr_rl);
115 valid_ptr_rl = clone_rl_permanent(valid_ptr_rl);
117 ptr_err_min = sval_cast(&ptr_ctype, err_min);
118 ptr_err_max = sval_cast(&ptr_ctype, err_max);
119 ptr_xa_err_min = sval_cast(&ptr_ctype, xa_err_min);
120 ptr_xa_err_max = sval_cast(&ptr_ctype, xa_err_max);
121 ulong_ULONG_MAX = sval_type_max(&ulong_ctype);
124 int outside_of_function(void)
126 return cur_func_sym == NULL;
129 const char *get_filename(void)
131 if (option_info && option_full_path)
132 return full_base_file;
133 if (option_info)
134 return base_file;
135 if (option_full_path)
136 return full_filename;
137 return filename;
140 const char *get_base_file(void)
142 if (option_full_path)
143 return full_base_file;
144 return base_file;
147 unsigned long long get_file_id(void)
149 return str_to_llu_hash(get_filename());
152 unsigned long long get_base_file_id(void)
154 return str_to_llu_hash(get_base_file());
157 static void set_position(struct position pos)
159 int len;
160 static int prev_stream = -1;
162 if (in_fake_env)
163 return;
165 if (pos.stream == 0 && pos.line == 0)
166 return;
168 __smatch_lineno = pos.line;
170 if (pos.stream == prev_stream)
171 return;
173 prev_stream = pos.stream;
174 filename = stream_name(pos.stream);
176 free(full_filename);
177 pathname = getcwd(NULL, 0);
178 if (pathname) {
179 len = strlen(pathname) + 1 + strlen(filename) + 1;
180 full_filename = malloc(len);
181 snprintf(full_filename, len, "%s/%s", pathname, filename);
182 } else {
183 full_filename = alloc_string(filename);
185 free(pathname);
188 int is_assigned_call(struct expression *expr)
190 struct expression *parent = expr_get_parent_expr(expr);
192 if (parent &&
193 parent->type == EXPR_ASSIGNMENT &&
194 parent->op == '=' &&
195 strip_expr(parent->right) == expr)
196 return 1;
198 return 0;
201 int is_fake_assigned_call(struct expression *expr)
203 struct expression *parent = expr_get_fake_parent_expr(expr);
205 if (parent &&
206 parent->type == EXPR_ASSIGNMENT &&
207 parent->op == '=' &&
208 strip_expr(parent->right) == expr)
209 return 1;
211 return 0;
214 static bool is_inline_func(struct expression *expr)
216 if (expr->type != EXPR_SYMBOL || !expr->symbol)
217 return false;
218 if (!expr->symbol->definition)
219 return false;
220 if (expr->symbol->definition->ctype.modifiers & MOD_INLINE)
221 return true;
223 return 0;
226 static int is_noreturn_func(struct expression *expr)
228 if (expr->type != EXPR_SYMBOL || !expr->symbol)
229 return 0;
232 * It's almost impossible for Smatch to handle __builtin_constant_p()
233 * the same way that GCC does so Smatch ends up making some functions
234 * as no return functions incorrectly.
237 if (option_project == PROJ_KERNEL && expr->symbol->ident &&
238 strstr(expr->symbol->ident->name, "__compiletime_assert"))
239 return 0;
241 if (expr->symbol->ctype.modifiers & MOD_NORETURN)
242 return 1;
243 return 0;
246 static int save_func_time(void *_rl, int argc, char **argv, char **azColName)
248 unsigned long *rl = _rl;
250 *rl = strtoul(argv[0], NULL, 10);
251 return 0;
254 static int get_func_time(struct symbol *sym)
256 unsigned long time = 0;
258 run_sql(&save_func_time, &time,
259 "select key from return_implies where %s and type = %d;",
260 get_static_filter(sym), FUNC_TIME);
262 return time;
265 static int inline_budget = 20;
267 int inlinable(struct expression *expr)
269 struct symbol *sym;
270 struct statement *last_stmt = NULL;
272 if (__inline_fn) /* don't nest */
273 return 0;
275 if (expr->type != EXPR_SYMBOL || !expr->symbol)
276 return 0;
277 if (is_no_inline_function(expr->symbol->ident->name))
278 return 0;
279 sym = get_base_type(expr->symbol);
280 if (sym->stmt && sym->stmt->type == STMT_COMPOUND) {
281 if (ptr_list_size((struct ptr_list *)sym->stmt->stmts) > 10)
282 return 0;
283 if (sym->stmt->type != STMT_COMPOUND)
284 return 0;
285 last_stmt = last_ptr_list((struct ptr_list *)sym->stmt->stmts);
287 if (sym->inline_stmt && sym->inline_stmt->type == STMT_COMPOUND) {
288 if (ptr_list_size((struct ptr_list *)sym->inline_stmt->stmts) > 10)
289 return 0;
290 if (sym->inline_stmt->type != STMT_COMPOUND)
291 return 0;
292 last_stmt = last_ptr_list((struct ptr_list *)sym->inline_stmt->stmts);
295 if (!last_stmt)
296 return 0;
298 /* the magic numbers in this function are pulled out of my bum. */
299 if (last_stmt->pos.line > sym->pos.line + inline_budget)
300 return 0;
302 if (get_func_time(expr->symbol) >= 2)
303 return 0;
305 return 1;
308 void __process_post_op_stack(void)
310 struct expression *expr;
312 FOR_EACH_PTR(post_op_stack, expr) {
313 __pass_to_client(expr, OP_HOOK);
314 } END_FOR_EACH_PTR(expr);
316 __free_ptr_list((struct ptr_list **)&post_op_stack);
319 static int handle_comma_assigns(struct expression *expr)
321 struct expression *right;
322 struct expression *assign;
324 right = strip_expr(expr->right);
325 if (right->type != EXPR_COMMA)
326 return 0;
328 __split_expr(right->left);
329 __process_post_op_stack();
331 assign = assign_expression(expr->left, '=', right->right);
332 __split_expr(assign);
334 return 1;
337 /* This is to handle *p++ = foo; assignments */
338 static int handle_postop_assigns(struct expression *expr)
340 struct expression *left, *fake_left;
341 struct expression *assign;
343 left = strip_expr(expr->left);
344 if (left->type != EXPR_PREOP || left->op != '*')
345 return 0;
346 left = strip_expr(left->unop);
347 if (left->type != EXPR_POSTOP)
348 return 0;
350 fake_left = deref_expression(strip_expr(left->unop));
351 assign = assign_expression(fake_left, '=', expr->right);
353 __split_expr(assign);
354 __split_expr(expr->left);
356 return 1;
359 static bool parent_is_dereference(struct expression *expr)
361 struct expression *parent;
363 parent = expr;
364 while ((parent = expr_get_parent_expr(parent))) {
365 if (parent->type == EXPR_DEREF)
366 return true;
367 if (parent->type == EXPR_PREOP &&
368 parent->op == '*')
369 return true;
372 return false;
375 static int prev_expression_is_getting_address(struct expression *expr)
377 struct expression *parent;
379 do {
380 parent = expr_get_parent_expr(expr);
382 if (!parent)
383 return 0;
384 if (parent->type == EXPR_PREOP && parent->op == '&') {
385 if (parent_is_dereference(parent))
386 return false;
387 return true;
389 if (parent->type == EXPR_PREOP && parent->op == '(')
390 goto next;
391 if (parent->type == EXPR_DEREF && parent->op == '.')
392 goto next;
393 /* Handle &foo->array[offset] */
394 if (parent->type == EXPR_BINOP && parent->op == '+') {
395 parent = expr_get_parent_expr(parent);
396 if (!parent)
397 return 0;
398 if (parent->type == EXPR_PREOP && parent->op == '*')
399 goto next;
402 return 0;
403 next:
404 expr = parent;
405 } while (1);
408 int __in_builtin_overflow_func;
409 static void handle_builtin_overflow_func(struct expression *expr)
411 struct expression *a, *b, *res, *assign;
412 int op;
414 if (sym_name_is("__builtin_add_overflow", expr->fn))
415 op = '+';
416 else if (sym_name_is("__builtin_sub_overflow", expr->fn))
417 op = '-';
418 else if (sym_name_is("__builtin_mul_overflow", expr->fn))
419 op = '*';
420 else
421 return;
423 a = get_argument_from_call_expr(expr->args, 0);
424 b = get_argument_from_call_expr(expr->args, 1);
425 res = get_argument_from_call_expr(expr->args, 2);
427 assign = assign_expression(deref_expression(res), '=', binop_expression(a, op, b));
429 __in_builtin_overflow_func++;
430 __split_expr(assign);
431 __in_builtin_overflow_func--;
434 static int handle__builtin_choose_expr(struct expression *expr)
436 struct expression *const_expr, *expr1, *expr2;
437 sval_t sval;
439 if (!sym_name_is("__builtin_choose_expr", expr->fn))
440 return 0;
442 const_expr = get_argument_from_call_expr(expr->args, 0);
443 expr1 = get_argument_from_call_expr(expr->args, 1);
444 expr2 = get_argument_from_call_expr(expr->args, 2);
446 if (!get_value(const_expr, &sval) || !expr1 || !expr2)
447 return 0;
448 if (sval.value)
449 __split_expr(expr1);
450 else
451 __split_expr(expr2);
452 return 1;
455 static int handle__builtin_choose_expr_assigns(struct expression *expr)
457 struct expression *const_expr, *right, *expr1, *expr2, *fake;
458 sval_t sval;
461 * We can't use strip_no_cast() because it strips out
462 * __builtin_choose_expr() which turns this function into a no-op.
465 right = strip_parens(expr->right);
466 if (right->type != EXPR_CALL)
467 return 0;
468 if (!sym_name_is("__builtin_choose_expr", right->fn))
469 return 0;
471 const_expr = get_argument_from_call_expr(right->args, 0);
472 expr1 = get_argument_from_call_expr(right->args, 1);
473 expr2 = get_argument_from_call_expr(right->args, 2);
475 if (!get_value(const_expr, &sval) || !expr1 || !expr2)
476 return 0;
478 fake = assign_expression(expr->left, '=', sval.value ? expr1 : expr2);
479 __split_expr(fake);
480 return 1;
483 int is_condition_call(struct expression *expr)
485 struct expression *tmp;
487 FOR_EACH_PTR_REVERSE(big_condition_stack, tmp) {
488 if (expr == tmp || expr_get_parent_expr(expr) == tmp)
489 return 1;
490 if (tmp->pos.line < expr->pos.line)
491 return 0;
492 } END_FOR_EACH_PTR_REVERSE(tmp);
494 return 0;
497 static struct expression *expr_get_parent_no_parens(struct expression *expr)
499 do {
500 expr = expr_get_parent_expr(expr);
501 } while (expr &&
502 expr->type == EXPR_PREOP &&
503 expr->op == '(');
505 return expr;
508 static bool gen_fake_function_assign(struct expression *expr)
510 static struct expression *parsed;
511 struct expression *assign, *parent;
512 struct symbol *type;
513 char buf[64];
515 /* The rule is that every non-void function call has to be part of an
516 * assignment. TODO: Should we create a fake non-casted assignment
517 * for casted assignments? Also faked assigns for += assignments?
519 type = get_type(expr);
520 if (!type || type == &void_ctype)
521 return false;
523 parent = expr_get_parent_no_parens(expr);
524 if (parent && parent->type == EXPR_ASSIGNMENT)
525 return false;
527 parent = expr_get_fake_parent_expr(expr);
528 if (parent) {
529 struct expression *left = parent->left;
531 if (parent == parsed)
532 return false;
533 if (!left || left->type != EXPR_SYMBOL)
534 return false;
535 if (strncmp(left->symbol_name->name, "__fake_assign_", 14) != 0)
536 return false;
537 parsed = parent;
538 __split_expr(parent);
539 return true;
542 // TODO: faked_assign skipping conditions is a hack
543 if (is_condition_call(expr))
544 return false;
546 snprintf(buf, sizeof(buf), "__fake_assign_%p", expr);
547 assign = create_fake_assign(buf, get_type(expr), expr);
549 parsed = assign;
550 __split_expr(assign);
551 return true;
554 static void split_call(struct expression *expr)
556 if (gen_fake_function_assign(expr))
557 return;
559 expr_set_parent_expr(expr->fn, expr);
561 if (sym_name_is("__builtin_constant_p", expr->fn))
562 return;
563 if (handle__builtin_choose_expr(expr))
564 return;
565 __split_expr(expr->fn);
566 split_args(expr);
567 if (is_inline_func(expr->fn))
568 add_inline_function(expr->fn->symbol->definition);
569 if (inlinable(expr->fn))
570 __inline_call = 1;
571 __process_post_op_stack();
572 __pass_to_client(expr, FUNCTION_CALL_HOOK_BEFORE);
573 __pass_to_client(expr, FUNCTION_CALL_HOOK);
574 __inline_call = 0;
575 if (inlinable(expr->fn))
576 parse_inline(expr);
577 __pass_to_client(expr, CALL_HOOK_AFTER_INLINE);
578 if (is_noreturn_func(expr->fn))
579 nullify_path();
580 if (!expr_get_parent_expr(expr) && indent_cnt == 1)
581 __discard_fake_states(expr);
582 handle_builtin_overflow_func(expr);
583 __add_ptr_list((struct ptr_list **)&parsed_calls, expr);
586 static unsigned long skip_split;
587 void parse_assignment(struct expression *expr, bool shallow)
589 struct expression *right;
591 expr_set_parent_expr(expr->left, expr);
592 expr_set_parent_expr(expr->right, expr);
594 right = strip_expr(expr->right);
595 if (!right)
596 return;
598 if (shallow)
599 skip_split++;
601 __pass_to_client(expr, RAW_ASSIGNMENT_HOOK);
603 /* foo = !bar() */
604 if (__handle_condition_assigns(expr))
605 goto after_assign;
606 /* foo = (x < 5 ? foo : 5); */
607 if (__handle_select_assigns(expr))
608 goto after_assign;
609 /* foo = ({frob(); frob(); frob(); 1;}) */
610 if (__handle_expr_statement_assigns(expr))
611 goto done; // FIXME: goto after
612 /* foo = (3, 4); */
613 if (handle_comma_assigns(expr))
614 goto after_assign;
615 if (handle__builtin_choose_expr_assigns(expr))
616 goto after_assign;
617 if (handle_postop_assigns(expr))
618 goto done; /* no need to goto after_assign */
620 __split_expr(expr->right);
621 if (outside_of_function())
622 __pass_to_client(expr, GLOBAL_ASSIGNMENT_HOOK);
623 else
624 __pass_to_client(expr, ASSIGNMENT_HOOK);
627 // FIXME: the ordering of this is tricky
628 __fake_struct_member_assignments(expr);
630 /* Re-examine ->right for inlines. See the commit message */
631 right = strip_expr(expr->right);
632 if (expr->op == '=' && right->type == EXPR_CALL)
633 __pass_to_client(expr, CALL_ASSIGNMENT_HOOK);
635 after_assign:
636 if (get_macro_name(right->pos) &&
637 get_macro_name(expr->left->pos) != get_macro_name(right->pos))
638 __pass_to_client(expr, MACRO_ASSIGNMENT_HOOK);
640 __pass_to_client(expr, ASSIGNMENT_HOOK_AFTER);
641 __split_expr(expr->left);
643 done:
644 if (shallow)
645 skip_split--;
648 static bool skip_split_off(struct expression *expr)
650 if (expr->type == EXPR_CALL &&
651 sym_name_is("__smatch_stop_skip", expr->fn))
652 return true;
653 return false;
656 void __split_expr(struct expression *expr)
658 if (!expr)
659 return;
661 if (skip_split_off(expr))
662 __debug_skip = 0;
663 if (__debug_skip)
664 return;
666 if (skip_split)
667 return;
669 // if (local_debug)
670 // sm_msg("Debug expr_type %d %s expr = '%s'", expr->type, show_special(expr->op), expr_to_str(expr));
672 if (__in_fake_assign && expr->type != EXPR_ASSIGNMENT)
673 return;
674 if (__in_fake_assign >= 4) /* don't allow too much nesting */
675 return;
677 push_expression(&big_expression_stack, expr);
678 set_position(expr->pos);
679 __pass_to_client(expr, EXPR_HOOK);
681 switch (expr->type) {
682 case EXPR_PREOP:
683 expr_set_parent_expr(expr->unop, expr);
685 __split_expr(expr->unop);
686 if (expr->op == '*' &&
687 !prev_expression_is_getting_address(expr))
688 __pass_to_client(expr, DEREF_HOOK);
689 __pass_to_client(expr, OP_HOOK);
690 break;
691 case EXPR_POSTOP:
692 expr_set_parent_expr(expr->unop, expr);
694 __split_expr(expr->unop);
695 push_expression(&post_op_stack, expr);
696 break;
697 case EXPR_STATEMENT:
698 __expr_stmt_count++;
699 if (expr->statement && !expr->statement) {
700 stmt_set_parent_stmt(expr->statement,
701 last_ptr_list((struct ptr_list *)big_statement_stack));
703 __split_stmt(expr->statement);
704 __expr_stmt_count--;
705 break;
706 case EXPR_LOGICAL:
707 case EXPR_COMPARE:
708 expr_set_parent_expr(expr->left, expr);
709 expr_set_parent_expr(expr->right, expr);
711 __pass_to_client(expr, LOGIC_HOOK);
712 __handle_logic(expr);
713 break;
714 case EXPR_BINOP:
715 expr_set_parent_expr(expr->left, expr);
716 expr_set_parent_expr(expr->right, expr);
718 __pass_to_client(expr, BINOP_HOOK);
719 __split_expr(expr->left);
720 __split_expr(expr->right);
721 break;
722 case EXPR_COMMA:
723 expr_set_parent_expr(expr->left, expr);
724 expr_set_parent_expr(expr->right, expr);
726 __split_expr(expr->left);
727 __process_post_op_stack();
728 __split_expr(expr->right);
729 break;
730 case EXPR_ASSIGNMENT:
731 parse_assignment(expr, false);
732 break;
733 case EXPR_DEREF:
734 expr_set_parent_expr(expr->deref, expr);
736 __split_expr(expr->deref);
737 __pass_to_client(expr, DEREF_HOOK);
738 break;
739 case EXPR_SLICE:
740 expr_set_parent_expr(expr->base, expr);
742 __split_expr(expr->base);
743 break;
744 case EXPR_CAST:
745 case EXPR_FORCE_CAST:
746 expr_set_parent_expr(expr->cast_expression, expr);
748 __pass_to_client(expr, CAST_HOOK);
749 __split_expr(expr->cast_expression);
750 break;
751 case EXPR_SIZEOF:
752 if (expr->cast_expression)
753 __pass_to_client(strip_parens(expr->cast_expression),
754 SIZEOF_HOOK);
755 break;
756 case EXPR_OFFSETOF:
757 case EXPR_ALIGNOF:
758 break;
759 case EXPR_CONDITIONAL:
760 case EXPR_SELECT:
761 expr_set_parent_expr(expr->conditional, expr);
762 expr_set_parent_expr(expr->cond_true, expr);
763 expr_set_parent_expr(expr->cond_false, expr);
765 if (known_condition_true(expr->conditional)) {
766 __split_expr(expr->cond_true);
767 break;
769 if (known_condition_false(expr->conditional)) {
770 __split_expr(expr->cond_false);
771 break;
773 __pass_to_client(expr, SELECT_HOOK);
774 __split_whole_condition(expr->conditional);
775 __split_expr(expr->cond_true);
776 __push_true_states();
777 __use_false_states();
778 __split_expr(expr->cond_false);
779 __merge_true_states();
780 break;
781 case EXPR_CALL:
782 split_call(expr);
783 break;
784 case EXPR_INITIALIZER:
785 split_expr_list(expr->expr_list, expr);
786 break;
787 case EXPR_IDENTIFIER:
788 expr_set_parent_expr(expr->ident_expression, expr);
789 __split_expr(expr->ident_expression);
790 break;
791 case EXPR_INDEX:
792 expr_set_parent_expr(expr->idx_expression, expr);
793 __split_expr(expr->idx_expression);
794 break;
795 case EXPR_POS:
796 expr_set_parent_expr(expr->init_expr, expr);
797 __split_expr(expr->init_expr);
798 break;
799 case EXPR_SYMBOL:
800 __pass_to_client(expr, SYM_HOOK);
801 break;
802 case EXPR_STRING:
803 __pass_to_client(expr, STRING_HOOK);
804 break;
805 case EXPR_GENERIC: {
806 struct expression *tmp;
808 tmp = strip_Generic(expr);
809 if (tmp != expr)
810 __split_expr(tmp);
811 break;
813 default:
814 break;
816 __pass_to_client(expr, EXPR_HOOK_AFTER);
817 pop_expression(&big_expression_stack);
820 static int is_forever_loop(struct statement *stmt)
822 struct expression *expr;
823 sval_t sval;
825 expr = strip_expr(stmt->iterator_pre_condition);
826 if (!expr)
827 expr = stmt->iterator_post_condition;
828 if (!expr) {
829 /* this is a for(;;) loop... */
830 return 1;
833 if (get_value(expr, &sval) && sval.value != 0)
834 return 1;
836 return 0;
839 static int loop_num;
840 static char *get_loop_name(int num)
842 char buf[256];
844 snprintf(buf, 255, "-loop%d", num);
845 buf[255] = '\0';
846 return alloc_sname(buf);
849 static struct bool_stmt_fn_list *once_through_hooks;
850 void add_once_through_hook(bool_stmt_func *fn)
852 add_ptr_list(&once_through_hooks, fn);
855 static bool call_once_through_hooks(struct statement *stmt)
857 bool_stmt_func *fn;
859 if (option_assume_loops)
860 return true;
862 FOR_EACH_PTR(once_through_hooks, fn) {
863 if ((fn)(stmt))
864 return true;
865 } END_FOR_EACH_PTR(fn);
867 return false;
871 * Pre Loops are while and for loops.
873 static void handle_pre_loop(struct statement *stmt)
875 int once_through; /* we go through the loop at least once */
876 struct sm_state *extra_sm = NULL;
877 int unchanged = 0;
878 char *loop_name;
879 struct stree *stree = NULL;
880 struct sm_state *sm = NULL;
882 __push_scope_hooks();
884 loop_name = get_loop_name(loop_num);
885 loop_num++;
887 split_declaration(stmt->iterator_syms);
888 if (stmt->iterator_pre_statement) {
889 __split_stmt(stmt->iterator_pre_statement);
890 __prev_stmt = stmt->iterator_pre_statement;
893 loop_count++;
894 __push_continues();
895 __push_breaks();
897 __merge_gotos(loop_name, NULL);
899 extra_sm = __extra_handle_canonical_loops(stmt, &stree);
900 __in_pre_condition++;
901 __set_confidence_implied();
902 __split_whole_condition_tf(stmt->iterator_pre_condition, &once_through);
903 __unset_confidence();
904 if (once_through != true)
905 once_through = call_once_through_hooks(stmt);
906 __pass_to_client(stmt, PRELOOP_HOOK);
907 __in_pre_condition--;
908 FOR_EACH_SM(stree, sm) {
909 set_state(sm->owner, sm->name, sm->sym, sm->state);
910 } END_FOR_EACH_SM(sm);
911 free_stree(&stree);
912 if (extra_sm)
913 extra_sm = get_sm_state(extra_sm->owner, extra_sm->name, extra_sm->sym);
915 __split_stmt(stmt->iterator_statement);
916 if (is_forever_loop(stmt)) {
917 __merge_continues();
918 __save_gotos(loop_name, NULL);
920 __push_fake_cur_stree();
921 __split_stmt(stmt->iterator_post_statement);
922 stree = __pop_fake_cur_stree();
924 __discard_false_states();
925 __pass_to_client(stmt, AFTER_LOOP_NO_BREAKS);
926 __use_breaks();
928 if (!__path_is_null())
929 __merge_stree_into_cur(stree);
930 free_stree(&stree);
931 } else {
932 __merge_continues();
933 unchanged = __iterator_unchanged(extra_sm);
934 __split_stmt(stmt->iterator_post_statement);
935 __prev_stmt = stmt->iterator_post_statement;
936 __cur_stmt = stmt;
938 __save_gotos(loop_name, NULL);
939 __in_pre_condition++;
940 __split_whole_condition(stmt->iterator_pre_condition);
941 __in_pre_condition--;
942 nullify_path();
943 __merge_false_states();
944 if (once_through == true)
945 __discard_false_states();
946 else
947 __merge_false_states();
949 if (extra_sm && unchanged)
950 __extra_pre_loop_hook_after(extra_sm,
951 stmt->iterator_post_statement,
952 stmt->iterator_pre_condition);
953 __pass_to_client(stmt, AFTER_LOOP_NO_BREAKS);
954 __merge_breaks();
956 loop_count--;
958 __call_scope_hooks();
962 * Post loops are do {} while();
964 static void handle_post_loop(struct statement *stmt)
966 char *loop_name;
968 loop_name = get_loop_name(loop_num);
969 loop_num++;
970 loop_count++;
972 __pass_to_client(stmt, POSTLOOP_HOOK);
974 __push_continues();
975 __push_breaks();
976 __merge_gotos(loop_name, NULL);
977 __split_stmt(stmt->iterator_statement);
978 __merge_continues();
979 if (!expr_is_zero(stmt->iterator_post_condition))
980 __save_gotos(loop_name, NULL);
982 if (is_forever_loop(stmt)) {
983 __pass_to_client(stmt, AFTER_LOOP_NO_BREAKS);
984 __use_breaks();
985 } else {
986 __split_whole_condition(stmt->iterator_post_condition);
987 __use_false_states();
988 __pass_to_client(stmt, AFTER_LOOP_NO_BREAKS);
989 __merge_breaks();
991 loop_count--;
994 static int empty_statement(struct statement *stmt)
996 if (!stmt)
997 return 0;
998 if (stmt->type == STMT_EXPRESSION && !stmt->expression)
999 return 1;
1000 return 0;
1003 static int last_stmt_on_same_line(void)
1005 struct statement *stmt;
1006 int i = 0;
1008 FOR_EACH_PTR_REVERSE(big_statement_stack, stmt) {
1009 if (!i++)
1010 continue;
1011 if (stmt->pos.line == get_lineno())
1012 return 1;
1013 return 0;
1014 } END_FOR_EACH_PTR_REVERSE(stmt);
1015 return 0;
1018 static void split_asm_ops(struct asm_operand_list *ops)
1020 struct asm_operand *op;
1022 FOR_EACH_PTR(ops, op) {
1023 __split_expr(op->expr);
1024 } END_FOR_EACH_PTR(op);
1027 static int is_case_val(struct statement *stmt, sval_t sval)
1029 sval_t case_sval;
1031 if (stmt->type != STMT_CASE)
1032 return 0;
1033 if (!stmt->case_expression) {
1034 __set_default();
1035 return 1;
1037 if (!get_value(stmt->case_expression, &case_sval))
1038 return 0;
1039 if (case_sval.value == sval.value)
1040 return 1;
1041 return 0;
1044 static struct range_list *get_case_rl(struct expression *switch_expr,
1045 struct expression *case_expr,
1046 struct expression *case_to)
1048 sval_t start, end;
1049 struct range_list *rl = NULL;
1050 struct symbol *switch_type;
1052 switch_type = get_type(switch_expr);
1053 if (get_value(case_to, &end) && get_value(case_expr, &start)) {
1054 start = sval_cast(switch_type, start);
1055 end = sval_cast(switch_type, end);
1056 add_range(&rl, start, end);
1057 } else if (get_value(case_expr, &start)) {
1058 start = sval_cast(switch_type, start);
1059 add_range(&rl, start, start);
1062 return rl;
1065 static void split_known_switch(struct statement *stmt, sval_t sval)
1067 struct statement *tmp;
1068 struct range_list *rl;
1070 __split_expr(stmt->switch_expression);
1071 sval = sval_cast(get_type(stmt->switch_expression), sval);
1073 push_expression(&switch_expr_stack, stmt->switch_expression);
1074 __save_switch_states(top_expression(switch_expr_stack));
1075 nullify_path();
1076 __push_default();
1077 __push_breaks();
1079 stmt = stmt->switch_statement;
1081 __push_scope_hooks();
1082 FOR_EACH_PTR(stmt->stmts, tmp) {
1083 __smatch_lineno = tmp->pos.line;
1084 // FIXME: what if default comes before the known case statement?
1085 if (is_case_val(tmp, sval)) {
1086 rl = alloc_rl(sval, sval);
1087 __merge_switches(top_expression(switch_expr_stack), rl);
1088 __pass_case_to_client(top_expression(switch_expr_stack), rl);
1089 stmt_set_parent_stmt(tmp->case_statement, tmp);
1090 __split_stmt(tmp->case_statement);
1091 goto next;
1093 if (__path_is_null())
1094 continue;
1095 __split_stmt(tmp);
1096 next:
1097 if (__path_is_null()) {
1098 __set_default();
1099 goto out;
1101 } END_FOR_EACH_PTR(tmp);
1102 out:
1103 __call_scope_hooks();
1104 if (!__pop_default())
1105 __merge_switches(top_expression(switch_expr_stack), NULL);
1106 __discard_switches();
1107 __merge_breaks();
1108 pop_expression(&switch_expr_stack);
1111 static void split_case(struct statement *stmt)
1113 struct range_list *rl = NULL;
1115 expr_set_parent_stmt(stmt->case_expression, stmt);
1116 expr_set_parent_stmt(stmt->case_to, stmt);
1118 rl = get_case_rl(top_expression(switch_expr_stack),
1119 stmt->case_expression, stmt->case_to);
1120 while (stmt->case_statement->type == STMT_CASE) {
1121 struct range_list *tmp;
1123 tmp = get_case_rl(top_expression(switch_expr_stack),
1124 stmt->case_statement->case_expression,
1125 stmt->case_statement->case_to);
1126 if (!tmp)
1127 goto next;
1128 rl = rl_union(rl, tmp);
1129 if (!stmt->case_expression)
1130 __set_default();
1131 next:
1132 stmt = stmt->case_statement;
1135 __merge_switches(top_expression(switch_expr_stack), rl);
1137 if (!stmt->case_expression)
1138 __set_default();
1140 stmt_set_parent_stmt(stmt->case_statement, stmt);
1141 __split_stmt(stmt->case_statement);
1144 int time_parsing_function(void)
1146 return ms_since(&fn_start_time) / 1000;
1149 bool taking_too_long(void)
1151 if ((ms_since(&outer_fn_start_time) / 1000) > 60 * 5) /* five minutes */
1152 return 1;
1153 return 0;
1156 struct statement *get_last_stmt(void)
1158 struct symbol *fn;
1159 struct statement *stmt;
1161 fn = get_base_type(cur_func_sym);
1162 if (!fn)
1163 return NULL;
1164 stmt = fn->stmt;
1165 if (!stmt)
1166 stmt = fn->inline_stmt;
1167 if (!stmt || stmt->type != STMT_COMPOUND)
1168 return NULL;
1169 stmt = last_ptr_list((struct ptr_list *)stmt->stmts);
1170 if (stmt && stmt->type == STMT_LABEL)
1171 stmt = stmt->label_statement;
1172 return stmt;
1175 int is_last_stmt(struct statement *cur_stmt)
1177 struct statement *last;
1179 last = get_last_stmt();
1180 if (last && last == cur_stmt)
1181 return 1;
1182 return 0;
1185 static bool is_function_scope(struct statement *stmt)
1187 struct symbol *base_type;
1189 if (!cur_func_sym)
1190 return false;
1192 base_type = get_base_type(cur_func_sym);
1193 if (base_type->stmt == stmt ||
1194 base_type->inline_stmt == stmt)
1195 return true;
1197 return false;
1200 static void handle_backward_goto(struct statement *goto_stmt)
1202 const char *goto_name, *label_name;
1203 struct statement *func_stmt;
1204 struct symbol *base_type = get_base_type(cur_func_sym);
1205 struct statement *tmp;
1206 int found = 0;
1208 if (!option_info)
1209 return;
1210 if (last_goto_statement_handled)
1211 return;
1212 last_goto_statement_handled = 1;
1214 if (!goto_stmt->goto_label ||
1215 goto_stmt->goto_label->type != SYM_LABEL ||
1216 !goto_stmt->goto_label->ident)
1217 return;
1218 goto_name = goto_stmt->goto_label->ident->name;
1220 func_stmt = base_type->stmt;
1221 if (!func_stmt)
1222 func_stmt = base_type->inline_stmt;
1223 if (!func_stmt)
1224 return;
1225 if (func_stmt->type != STMT_COMPOUND)
1226 return;
1228 FOR_EACH_PTR(func_stmt->stmts, tmp) {
1229 if (!found) {
1230 if (tmp->type != STMT_LABEL)
1231 continue;
1232 if (!tmp->label_identifier ||
1233 tmp->label_identifier->type != SYM_LABEL ||
1234 !tmp->label_identifier->ident)
1235 continue;
1236 label_name = tmp->label_identifier->ident->name;
1237 if (strcmp(goto_name, label_name) != 0)
1238 continue;
1239 found = 1;
1241 __split_stmt(tmp);
1242 } END_FOR_EACH_PTR(tmp);
1245 static void fake_a_return(void)
1247 struct expression *ret = NULL;
1249 nullify_path();
1250 __unnullify_path();
1252 if (cur_func_return_type() != &void_ctype)
1253 ret = unknown_value_expression(NULL);
1255 __pass_to_client(ret, RETURN_HOOK);
1256 nullify_path();
1259 static void split_ret_value(struct expression *expr)
1261 struct symbol *type;
1263 if (!expr)
1264 return;
1266 type = get_real_base_type(cur_func_sym);
1267 type = get_real_base_type(type);
1268 expr = fake_a_variable_assign(type, NULL, expr, -1);
1270 __in_fake_var_assign++;
1271 __split_expr(expr);
1272 __in_fake_var_assign--;
1275 static void fake_an_empty_default(struct position pos)
1277 static struct statement none = {};
1279 none.pos = pos;
1280 none.type = STMT_NONE;
1281 __merge_switches(top_expression(switch_expr_stack), NULL);
1282 __split_stmt(&none);
1285 static void split_compound(struct statement *stmt)
1287 struct statement *prev = NULL;
1288 struct statement *cur = NULL;
1289 struct statement *next;
1291 __push_scope_hooks();
1293 FOR_EACH_PTR(stmt->stmts, next) {
1294 /* just set them all ahead of time */
1295 stmt_set_parent_stmt(next, stmt);
1297 if (cur) {
1298 __prev_stmt = prev;
1299 __next_stmt = next;
1300 __cur_stmt = cur;
1301 __split_stmt(cur);
1303 prev = cur;
1304 cur = next;
1305 } END_FOR_EACH_PTR(next);
1306 if (cur) {
1307 __prev_stmt = prev;
1308 __cur_stmt = cur;
1309 __next_stmt = NULL;
1310 __split_stmt(cur);
1314 * For function scope, then delay calling the scope hooks until the
1315 * end of function hooks can run.
1317 if (!is_function_scope(stmt))
1318 __call_scope_hooks();
1321 void __split_label_stmt(struct statement *stmt)
1323 if (stmt->label_identifier &&
1324 stmt->label_identifier->type == SYM_LABEL &&
1325 stmt->label_identifier->ident) {
1326 loop_count |= 0x0800000;
1327 __merge_gotos(stmt->label_identifier->ident->name, stmt->label_identifier);
1331 static void find_asm_gotos(struct statement *stmt)
1333 struct symbol *sym;
1335 FOR_EACH_PTR(stmt->asm_labels, sym) {
1336 __save_gotos(sym->ident->name, sym);
1337 } END_FOR_EACH_PTR(sym);
1340 static void split_if_statement(struct statement *stmt)
1342 int known_tf;
1344 stmt_set_parent_stmt(stmt->if_true, stmt);
1345 stmt_set_parent_stmt(stmt->if_false, stmt);
1346 expr_set_parent_stmt(stmt->if_conditional, stmt);
1348 if (empty_statement(stmt->if_true) &&
1349 last_stmt_on_same_line() &&
1350 !get_macro_name(stmt->if_true->pos))
1351 sm_warning("if();");
1353 __split_whole_condition_tf(stmt->if_conditional, &known_tf);
1354 if (known_tf == true) {
1355 __split_stmt(stmt->if_true);
1356 __discard_false_states();
1357 return;
1358 } else if (known_tf == false) {
1359 __use_false_states();
1360 __split_stmt(stmt->if_false);
1361 return;
1364 __split_stmt(stmt->if_true);
1365 __push_true_states();
1366 __use_false_states();
1367 __split_stmt(stmt->if_false);
1368 __merge_true_states();
1371 static bool already_parsed_call(struct expression *call)
1373 struct expression *expr;
1375 FOR_EACH_PTR(parsed_calls, expr) {
1376 if (expr == call)
1377 return true;
1378 } END_FOR_EACH_PTR(expr);
1379 return false;
1382 static void free_parsed_call_stuff(bool free_fake_states)
1384 free_expression_stack(&parsed_calls);
1385 if (free_fake_states)
1386 __discard_fake_states(NULL);
1389 void __split_stmt(struct statement *stmt)
1391 sval_t sval;
1392 struct timeval start, stop;
1393 bool skip_after = false;
1395 gettimeofday(&start, NULL);
1397 if (!stmt)
1398 goto out;
1400 if (!__in_fake_assign)
1401 __silence_warnings_for_stmt = false;
1403 if (__bail_on_rest_of_function || is_skipped_function())
1404 return;
1406 if (out_of_memory() || taking_too_long()) {
1407 gettimeofday(&start, NULL);
1409 __bail_on_rest_of_function = 1;
1410 final_pass = 1;
1411 sm_perror("Function too hairy. Giving up. %lu seconds",
1412 start.tv_sec - fn_start_time.tv_sec);
1413 fake_a_return();
1414 final_pass = 0; /* turn off sm_msg() from here */
1415 return;
1418 indent_cnt++;
1420 add_ptr_list(&big_statement_stack, stmt);
1421 free_expression_stack(&big_expression_stack);
1422 free_parsed_call_stuff(indent_cnt == 1);
1423 set_position(stmt->pos);
1424 __pass_to_client(stmt, STMT_HOOK);
1426 switch (stmt->type) {
1427 case STMT_DECLARATION:
1428 split_declaration(stmt->declaration);
1429 break;
1430 case STMT_RETURN:
1431 expr_set_parent_stmt(stmt->ret_value, stmt);
1433 split_ret_value(stmt->ret_value);
1434 __process_post_op_stack();
1435 __call_all_scope_hooks();
1436 __pass_to_client(stmt->ret_value, RETURN_HOOK);
1437 nullify_path();
1438 break;
1439 case STMT_EXPRESSION:
1440 expr_set_parent_stmt(stmt->expression, stmt);
1441 expr_set_parent_stmt(stmt->context, stmt);
1443 __split_expr(stmt->expression);
1444 break;
1445 case STMT_COMPOUND:
1446 split_compound(stmt);
1447 break;
1448 case STMT_IF:
1449 split_if_statement(stmt);
1450 break;
1451 case STMT_ITERATOR:
1452 stmt_set_parent_stmt(stmt->iterator_pre_statement, stmt);
1453 stmt_set_parent_stmt(stmt->iterator_statement, stmt);
1454 stmt_set_parent_stmt(stmt->iterator_post_statement, stmt);
1455 expr_set_parent_stmt(stmt->iterator_pre_condition, stmt);
1456 expr_set_parent_stmt(stmt->iterator_post_condition, stmt);
1458 if (stmt->iterator_pre_condition)
1459 handle_pre_loop(stmt);
1460 else if (stmt->iterator_post_condition)
1461 handle_post_loop(stmt);
1462 else {
1463 // these are for(;;) type loops.
1464 handle_pre_loop(stmt);
1466 break;
1467 case STMT_SWITCH:
1468 stmt_set_parent_stmt(stmt->switch_statement, stmt);
1469 expr_set_parent_stmt(stmt->switch_expression, stmt);
1471 if (get_value(stmt->switch_expression, &sval)) {
1472 split_known_switch(stmt, sval);
1473 break;
1475 __split_expr(stmt->switch_expression);
1476 push_expression(&switch_expr_stack, stmt->switch_expression);
1477 __save_switch_states(top_expression(switch_expr_stack));
1478 nullify_path();
1479 __push_default();
1480 __push_breaks();
1481 __split_stmt(stmt->switch_statement);
1482 if (!__pop_default() && have_remaining_cases())
1483 fake_an_empty_default(stmt->pos);
1484 __discard_switches();
1485 __merge_breaks();
1486 pop_expression(&switch_expr_stack);
1487 break;
1488 case STMT_CASE:
1489 split_case(stmt);
1490 break;
1491 case STMT_LABEL:
1492 __split_label_stmt(stmt);
1493 __pass_to_client(stmt, STMT_HOOK_AFTER);
1494 skip_after = true;
1495 __split_stmt(stmt->label_statement);
1496 break;
1497 case STMT_GOTO:
1498 expr_set_parent_stmt(stmt->goto_expression, stmt);
1500 __split_expr(stmt->goto_expression);
1501 if (stmt->goto_label && stmt->goto_label->type == SYM_NODE) {
1502 if (!strcmp(stmt->goto_label->ident->name, "break")) {
1503 __process_breaks();
1504 } else if (!strcmp(stmt->goto_label->ident->name,
1505 "continue")) {
1506 __process_continues();
1508 } else if (stmt->goto_label &&
1509 stmt->goto_label->type == SYM_LABEL &&
1510 stmt->goto_label->ident) {
1511 __save_gotos(stmt->goto_label->ident->name, stmt->goto_label);
1513 nullify_path();
1514 if (is_last_stmt(stmt))
1515 handle_backward_goto(stmt);
1516 break;
1517 case STMT_NONE:
1518 break;
1519 case STMT_ASM:
1520 expr_set_parent_stmt(stmt->asm_string, stmt);
1522 find_asm_gotos(stmt);
1523 __pass_to_client(stmt, ASM_HOOK);
1524 __split_expr(stmt->asm_string);
1525 split_asm_ops(stmt->asm_outputs);
1526 split_asm_ops(stmt->asm_inputs);
1527 split_expr_list(stmt->asm_clobbers, NULL);
1528 break;
1529 case STMT_CONTEXT:
1530 break;
1531 case STMT_RANGE:
1532 __split_expr(stmt->range_expression);
1533 __split_expr(stmt->range_low);
1534 __split_expr(stmt->range_high);
1535 break;
1537 if (!skip_after)
1538 __pass_to_client(stmt, STMT_HOOK_AFTER);
1539 if (--indent_cnt == 1)
1540 free_parsed_call_stuff(true);
1542 out:
1543 __process_post_op_stack();
1545 gettimeofday(&stop, NULL);
1546 if (option_time_stmt && stmt)
1547 sm_msg("stmt_time%s: %ld",
1548 stmt->type == STMT_COMPOUND ? "_block" : "",
1549 stop.tv_sec - start.tv_sec);
1552 static void split_expr_list(struct expression_list *expr_list, struct expression *parent)
1554 struct expression *expr;
1556 FOR_EACH_PTR(expr_list, expr) {
1557 expr_set_parent_expr(expr, parent);
1558 __split_expr(expr);
1559 __process_post_op_stack();
1560 } END_FOR_EACH_PTR(expr);
1563 static bool cast_arg(struct symbol *type, struct expression *arg)
1565 struct symbol *orig;
1567 if (!type)
1568 return false;
1570 arg = strip_parens(arg);
1571 if (arg != strip_expr(arg))
1572 return true;
1574 orig = get_type(arg);
1575 if (!orig)
1576 return true;
1577 if (types_equiv(orig, type))
1578 return false;
1580 if (orig->type == SYM_ARRAY && type->type == SYM_PTR)
1581 return true;
1584 * I would have expected that we could just do use (orig == type) but I
1585 * guess for pointers we need to get the basetype to do that comparison.
1589 if (orig->type != SYM_PTR ||
1590 type->type != SYM_PTR) {
1591 if (type_fits(type, orig))
1592 return false;
1593 return true;
1595 orig = get_real_base_type(orig);
1596 type = get_real_base_type(type);
1597 if (orig == type)
1598 return false;
1600 return true;
1603 static struct expression *fake_a_variable_assign(struct symbol *type, struct expression *call, struct expression *expr, int nr)
1605 char buf[64];
1606 bool cast;
1608 if (!expr || !cur_func_sym)
1609 return NULL;
1611 if (already_parsed_call(call))
1612 return NULL;
1614 if (expr->type == EXPR_ASSIGNMENT)
1615 return expr;
1617 /* for va_args then we don't know the type */
1618 if (!type)
1619 type = get_type(expr);
1621 cast = cast_arg(type, expr);
1623 * Using expr_to_sym() here is a hack. We want to say that we don't
1624 * need to assign frob(foo) or frob(foo->bar) if the types are right.
1625 * It turns out faking these assignments is way more expensive than I
1626 * would have imagined. I'm not sure why exactly.
1629 if (!cast) {
1631 * if the code is "return *p;" where "p" is a user pointer then
1632 * we want to create a fake assignment so that it sets the state
1633 * in check_kernel_user_data.c.
1636 if (expr->type != EXPR_PREOP &&
1637 expr->op != '*' && expr->op != '&' &&
1638 expr_to_sym(expr))
1639 return expr;
1642 if (nr == -1)
1643 snprintf(buf, sizeof(buf), "__fake_return_%p", expr);
1644 else
1645 snprintf(buf, sizeof(buf), "__fake_param_%p_%d", call, nr);
1647 return create_fake_assign(buf, type, expr);
1650 static void split_args(struct expression *expr)
1652 struct expression *arg, *tmp;
1653 struct symbol *type;
1654 int i;
1656 i = -1;
1657 FOR_EACH_PTR(expr->args, arg) {
1658 i++;
1659 expr_set_parent_expr(arg, expr);
1660 type = get_arg_type(expr->fn, i);
1661 tmp = fake_a_variable_assign(type, expr, arg, i);
1662 if (tmp != arg)
1663 __in_fake_var_assign++;
1664 __split_expr(tmp);
1665 if (tmp != arg)
1666 __in_fake_var_assign--;
1667 __process_post_op_stack();
1668 } END_FOR_EACH_PTR(arg);
1671 static void call_cleanup_fn(void *_sym)
1673 struct symbol *sym = _sym;
1674 struct expression *call, *arg;
1675 struct expression_list *args = NULL;
1677 arg = symbol_expression(sym);
1678 arg = preop_expression(arg, '&');
1679 add_ptr_list(&args, arg);
1680 call = call_expression(sym->cleanup, args);
1682 __split_expr(call);
1685 static void add_cleanup_hook(struct symbol *sym)
1687 if (!sym->cleanup)
1688 return;
1689 add_scope_hook(&call_cleanup_fn, sym);
1692 static void split_sym(struct symbol *sym)
1694 if (!sym)
1695 return;
1696 if (!(sym->namespace & NS_SYMBOL))
1697 return;
1699 __split_stmt(sym->stmt);
1700 __split_expr(sym->array_size);
1701 if (sym->cleanup)
1702 add_cleanup_hook(sym);
1703 split_symlist(sym->arguments);
1704 split_symlist(sym->symbol_list);
1705 __split_stmt(sym->inline_stmt);
1706 split_symlist(sym->inline_symbol_list);
1709 static void split_symlist(struct symbol_list *sym_list)
1711 struct symbol *sym;
1713 FOR_EACH_PTR(sym_list, sym) {
1714 split_sym(sym);
1715 } END_FOR_EACH_PTR(sym);
1718 typedef void (fake_cb)(struct expression *expr);
1720 static int member_to_number(struct expression *expr, struct ident *member)
1722 struct symbol *type, *tmp;
1723 char *name;
1724 int i;
1726 if (!member)
1727 return -1;
1728 name = member->name;
1730 type = get_type(expr);
1731 if (!type || type->type != SYM_STRUCT)
1732 return -1;
1734 i = -1;
1735 FOR_EACH_PTR(type->symbol_list, tmp) {
1736 i++;
1737 if (!tmp->ident)
1738 continue;
1739 if (strcmp(name, tmp->ident->name) == 0)
1740 return i;
1741 } END_FOR_EACH_PTR(tmp);
1742 return -1;
1745 static struct ident *number_to_member(struct expression *expr, int num)
1747 struct symbol *type, *member;
1748 int i = 0;
1750 type = get_type(expr);
1751 if (!type || type->type != SYM_STRUCT)
1752 return NULL;
1754 FOR_EACH_PTR(type->symbol_list, member) {
1755 if (i == num)
1756 return member->ident;
1757 i++;
1758 } END_FOR_EACH_PTR(member);
1759 return NULL;
1762 static void fake_element_assigns_helper(struct expression *array, struct expression_list *expr_list, fake_cb *fake_cb);
1764 static void set_inner_struct_members(struct expression *expr, struct symbol *member)
1766 struct expression *edge_member, *assign;
1767 struct symbol *base = get_real_base_type(member);
1768 struct symbol *tmp;
1770 if (member->ident)
1771 expr = member_expression(expr, '.', member->ident);
1773 FOR_EACH_PTR(base->symbol_list, tmp) {
1774 struct symbol *type;
1776 type = get_real_base_type(tmp);
1777 if (!type)
1778 continue;
1780 edge_member = member_expression(expr, '.', tmp->ident);
1781 if (get_extra_state(edge_member))
1782 continue;
1784 if (type->type == SYM_UNION || type->type == SYM_STRUCT) {
1785 set_inner_struct_members(expr, tmp);
1786 continue;
1789 if (!tmp->ident)
1790 continue;
1792 assign = assign_expression(edge_member, '=', zero_expr());
1793 __split_expr(assign);
1794 } END_FOR_EACH_PTR(tmp);
1799 static void set_unset_to_zero(struct symbol *type, struct expression *expr)
1801 struct symbol *tmp;
1802 struct expression *member = NULL;
1803 struct expression *assign;
1805 FOR_EACH_PTR(type->symbol_list, tmp) {
1806 type = get_real_base_type(tmp);
1807 if (!type)
1808 continue;
1810 if (tmp->ident) {
1811 member = member_expression(expr, '.', tmp->ident);
1812 if (get_extra_state(member))
1813 continue;
1816 if (type->type == SYM_UNION || type->type == SYM_STRUCT) {
1817 set_inner_struct_members(expr, tmp);
1818 continue;
1820 if (type->type == SYM_ARRAY)
1821 continue;
1822 if (!tmp->ident)
1823 continue;
1825 assign = assign_expression(member, '=', zero_expr());
1826 __split_expr(assign);
1827 } END_FOR_EACH_PTR(tmp);
1830 static void fake_member_assigns_helper(struct expression *symbol, struct expression_list *members, fake_cb *fake_cb)
1832 struct expression *deref, *assign, *tmp, *right;
1833 struct symbol *struct_type, *type;
1834 struct ident *member;
1835 int member_idx;
1837 struct_type = get_type(symbol);
1838 if (!struct_type ||
1839 (struct_type->type != SYM_STRUCT && struct_type->type != SYM_UNION))
1840 return;
1843 * We're parsing an initializer that could look something like this:
1844 * struct foo foo = {
1845 * 42,
1846 * .whatever.xxx = 11,
1847 * .zzz = 12,
1848 * };
1850 * So what we have here is a list with 42, .whatever, and .zzz. We need
1851 * to break it up into left and right sides of the assignments.
1854 member_idx = 0;
1855 FOR_EACH_PTR(members, tmp) {
1856 deref = NULL;
1857 if (tmp->type == EXPR_IDENTIFIER) {
1858 member_idx = member_to_number(symbol, tmp->expr_ident);
1859 while (tmp->type == EXPR_IDENTIFIER) {
1860 member = tmp->expr_ident;
1861 tmp = tmp->ident_expression;
1862 if (deref)
1863 deref = member_expression(deref, '.', member);
1864 else
1865 deref = member_expression(symbol, '.', member);
1867 } else {
1868 member = number_to_member(symbol, member_idx);
1869 deref = member_expression(symbol, '.', member);
1871 right = tmp;
1872 member_idx++;
1873 if (right->type == EXPR_INITIALIZER) {
1874 type = get_type(deref);
1875 if (type && type->type == SYM_ARRAY)
1876 fake_element_assigns_helper(deref, right->expr_list, fake_cb);
1877 else
1878 fake_member_assigns_helper(deref, right->expr_list, fake_cb);
1879 } else {
1880 assign = assign_expression(deref, '=', right);
1881 fake_cb(assign);
1883 } END_FOR_EACH_PTR(tmp);
1885 set_unset_to_zero(struct_type, symbol);
1888 static void fake_member_assigns(struct symbol *sym, fake_cb *fake_cb)
1890 fake_member_assigns_helper(symbol_expression(sym),
1891 sym->initializer->expr_list, fake_cb);
1894 static void fake_element_assigns_helper(struct expression *array, struct expression_list *expr_list, fake_cb *fake_cb)
1896 struct expression *offset, *binop, *assign, *tmp;
1897 struct symbol *type;
1898 int idx, max;
1900 if (ptr_list_size((struct ptr_list *)expr_list) > 256) {
1901 binop = array_element_expression(array, unknown_value_expression(array));
1902 assign = assign_expression(binop, '=', unknown_value_expression(array));
1903 /* fake_cb is probably call_global_assign_hooks() which is a
1904 * a kind of hacky short cut because it's too expensive to deal
1905 * with huge global arrays. However, we may as well parse this
1906 * one the long way seeing as it's a one time thing.
1908 __split_expr(assign);
1909 return;
1912 max = 0;
1913 idx = 0;
1914 FOR_EACH_PTR(expr_list, tmp) {
1915 if (tmp->type == EXPR_INDEX) {
1916 if (tmp->idx_from != tmp->idx_to)
1917 return;
1918 idx = tmp->idx_from;
1919 if (idx > max)
1920 max = idx;
1921 if (!tmp->idx_expression)
1922 goto next;
1923 tmp = tmp->idx_expression;
1925 offset = value_expr(idx);
1926 binop = array_element_expression(array, offset);
1927 if (tmp->type == EXPR_INITIALIZER) {
1928 type = get_type(binop);
1929 if (type && type->type == SYM_ARRAY)
1930 fake_element_assigns_helper(binop, tmp->expr_list, fake_cb);
1931 else
1932 fake_member_assigns_helper(binop, tmp->expr_list, fake_cb);
1933 } else {
1934 assign = assign_expression(binop, '=', tmp);
1935 fake_cb(assign);
1937 next:
1938 idx++;
1939 if (idx > max)
1940 max = idx;
1941 } END_FOR_EACH_PTR(tmp);
1943 __call_array_initialized_hooks(array, max);
1946 static void fake_element_assigns(struct symbol *sym, fake_cb *fake_cb)
1948 fake_element_assigns_helper(symbol_expression(sym), sym->initializer->expr_list, fake_cb);
1951 static void fake_assign_expr(struct symbol *sym)
1953 struct expression *assign, *symbol;
1955 symbol = symbol_expression(sym);
1956 assign = assign_expression(symbol, '=', sym->initializer);
1957 __split_expr(assign);
1960 static void do_initializer_stuff(struct symbol *sym)
1962 if (!sym->initializer)
1963 return;
1965 if (sym->initializer->type == EXPR_INITIALIZER) {
1966 if (get_real_base_type(sym)->type == SYM_ARRAY)
1967 fake_element_assigns(sym, __split_expr);
1968 else
1969 fake_member_assigns(sym, __split_expr);
1970 } else {
1971 fake_assign_expr(sym);
1975 static void split_declaration(struct symbol_list *sym_list)
1977 struct symbol *sym;
1979 FOR_EACH_PTR(sym_list, sym) {
1980 __pass_to_client(sym, DECLARATION_HOOK);
1981 do_initializer_stuff(sym);
1982 __pass_to_client(sym, DECLARATION_HOOK_AFTER);
1983 split_sym(sym);
1984 } END_FOR_EACH_PTR(sym);
1987 static void call_global_assign_hooks(struct expression *assign)
1989 __pass_to_client(assign, GLOBAL_ASSIGNMENT_HOOK);
1992 static void fake_global_assign(struct symbol *sym)
1994 struct expression *assign, *symbol;
1996 if (get_real_base_type(sym)->type == SYM_ARRAY) {
1997 if (sym->initializer && sym->initializer->type == EXPR_INITIALIZER) {
1998 fake_element_assigns(sym, call_global_assign_hooks);
1999 } else if (sym->initializer) {
2000 symbol = symbol_expression(sym);
2001 assign = assign_expression(symbol, '=', sym->initializer);
2002 __pass_to_client(assign, GLOBAL_ASSIGNMENT_HOOK);
2003 } else {
2004 fake_element_assigns_helper(symbol_expression(sym), NULL, call_global_assign_hooks);
2006 } else if (get_real_base_type(sym)->type == SYM_STRUCT) {
2007 if (sym->initializer && sym->initializer->type == EXPR_INITIALIZER) {
2008 fake_member_assigns(sym, call_global_assign_hooks);
2009 } else if (sym->initializer) {
2010 symbol = symbol_expression(sym);
2011 assign = assign_expression(symbol, '=', sym->initializer);
2012 __pass_to_client(assign, GLOBAL_ASSIGNMENT_HOOK);
2013 } else {
2014 fake_member_assigns_helper(symbol_expression(sym), NULL, call_global_assign_hooks);
2016 } else {
2017 symbol = symbol_expression(sym);
2018 if (sym->initializer) {
2019 assign = assign_expression(symbol, '=', sym->initializer);
2020 __split_expr(assign);
2021 } else {
2022 assign = assign_expression(symbol, '=', zero_expr());
2024 __pass_to_client(assign, GLOBAL_ASSIGNMENT_HOOK);
2028 static void start_function_definition(struct symbol *sym)
2030 __in_function_def = 1;
2031 __pass_to_client(sym, FUNC_DEF_HOOK);
2032 __in_function_def = 0;
2033 __pass_to_client(sym, AFTER_DEF_HOOK);
2037 static void parse_fn_statements(struct symbol *base)
2039 __split_stmt(base->stmt);
2040 __split_stmt(base->inline_stmt);
2043 void add_function_data(unsigned long *fn_data)
2045 __add_ptr_list(&fn_data_list, fn_data);
2048 static void clear_function_data(void)
2050 unsigned long *tmp;
2052 FOR_EACH_PTR(fn_data_list, tmp) {
2053 *tmp = 0;
2054 } END_FOR_EACH_PTR(tmp);
2057 static void record_func_time(void)
2059 struct timeval stop;
2060 int func_time;
2061 char buf[32];
2063 gettimeofday(&stop, NULL);
2064 func_time = stop.tv_sec - fn_start_time.tv_sec;
2065 snprintf(buf, sizeof(buf), "%d", func_time);
2066 sql_insert_return_implies(FUNC_TIME, 0, "", buf);
2067 if (option_time && func_time > 2) {
2068 final_pass++;
2069 sm_msg("func_time: %d", func_time);
2070 final_pass--;
2074 static void split_function(struct symbol *sym)
2076 struct symbol *base_type = get_base_type(sym);
2078 if (!base_type->stmt && !base_type->inline_stmt)
2079 return;
2081 gettimeofday(&outer_fn_start_time, NULL);
2082 gettimeofday(&fn_start_time, NULL);
2083 cur_func_sym = sym;
2084 if (sym->ident)
2085 cur_func = sym->ident->name;
2086 if (option_process_function && cur_func &&
2087 strcmp(option_process_function, cur_func) != 0)
2088 return;
2089 set_position(sym->pos);
2090 clear_function_data();
2091 loop_count = 0;
2092 last_goto_statement_handled = 0;
2093 sm_debug("new function: %s\n", cur_func);
2094 __stree_id = 0;
2095 if (option_two_passes) {
2096 __unnullify_path();
2097 loop_num = 0;
2098 final_pass = 0;
2099 start_function_definition(sym);
2100 parse_fn_statements(base_type);
2101 __call_scope_hooks();
2102 nullify_path();
2104 __unnullify_path();
2105 loop_num = 0;
2106 final_pass = 1;
2107 start_function_definition(sym);
2108 parse_fn_statements(base_type);
2109 if (!__path_is_null() &&
2110 cur_func_return_type() == &void_ctype &&
2111 !__bail_on_rest_of_function) {
2112 __call_all_scope_hooks();
2113 __pass_to_client(NULL, RETURN_HOOK);
2114 nullify_path();
2116 __pass_to_client(sym, END_FUNC_HOOK);
2117 __free_scope_hooks();
2118 __pass_to_client(sym, AFTER_FUNC_HOOK);
2119 sym->parsed = true;
2121 clear_all_states();
2123 record_func_time();
2125 cur_func_sym = NULL;
2126 cur_func = NULL;
2127 free_data_info_allocs();
2128 free_expression_stack(&switch_expr_stack);
2129 __free_ptr_list((struct ptr_list **)&big_statement_stack);
2130 __bail_on_rest_of_function = 0;
2133 static void save_flow_state(void)
2135 unsigned long *tmp;
2137 __add_ptr_list(&backup, INT_PTR(loop_num << 2));
2138 __add_ptr_list(&backup, INT_PTR(loop_count << 2));
2139 __add_ptr_list(&backup, INT_PTR(final_pass << 2));
2141 __add_ptr_list(&backup, big_statement_stack);
2142 __add_ptr_list(&backup, big_expression_stack);
2143 __add_ptr_list(&backup, big_condition_stack);
2144 __add_ptr_list(&backup, switch_expr_stack);
2146 __add_ptr_list(&backup, cur_func_sym);
2148 __add_ptr_list(&backup, parsed_calls);
2150 __add_ptr_list(&backup, __prev_stmt);
2151 __add_ptr_list(&backup, __cur_stmt);
2152 __add_ptr_list(&backup, __next_stmt);
2154 FOR_EACH_PTR(fn_data_list, tmp) {
2155 __add_ptr_list(&backup, (void *)*tmp);
2156 } END_FOR_EACH_PTR(tmp);
2159 static void *pop_backup(void)
2161 void *ret;
2163 ret = last_ptr_list(backup);
2164 delete_ptr_list_last(&backup);
2165 return ret;
2168 static void restore_flow_state(void)
2170 unsigned long *tmp;
2172 FOR_EACH_PTR_REVERSE(fn_data_list, tmp) {
2173 *tmp = (unsigned long)pop_backup();
2174 } END_FOR_EACH_PTR_REVERSE(tmp);
2176 __next_stmt = pop_backup();
2177 __cur_stmt = pop_backup();
2178 __prev_stmt = pop_backup();
2180 parsed_calls = pop_backup();
2182 cur_func_sym = pop_backup();
2183 switch_expr_stack = pop_backup();
2184 big_condition_stack = pop_backup();
2185 big_expression_stack = pop_backup();
2186 big_statement_stack = pop_backup();
2187 final_pass = PTR_INT(pop_backup()) >> 2;
2188 loop_count = PTR_INT(pop_backup()) >> 2;
2189 loop_num = PTR_INT(pop_backup()) >> 2;
2192 void parse_inline(struct expression *call)
2194 struct symbol *base_type;
2195 char *cur_func_bak = cur_func; /* not aligned correctly for backup */
2196 struct timeval time_backup = fn_start_time;
2197 struct expression *orig_inline = __inline_fn;
2198 int orig_budget;
2200 if (out_of_memory() || taking_too_long())
2201 return;
2203 if (already_parsed_call(call))
2204 return;
2206 save_flow_state();
2208 __pass_to_client(call, INLINE_FN_START);
2209 final_pass = 0; /* don't print anything */
2210 __inline_fn = call;
2211 orig_budget = inline_budget;
2212 inline_budget = inline_budget - 5;
2214 base_type = get_base_type(call->fn->symbol);
2215 cur_func_sym = call->fn->symbol;
2216 if (call->fn->symbol->ident)
2217 cur_func = call->fn->symbol->ident->name;
2218 else
2219 cur_func = NULL;
2220 set_position(call->fn->symbol->pos);
2222 save_all_states();
2223 big_statement_stack = NULL;
2224 big_expression_stack = NULL;
2225 big_condition_stack = NULL;
2226 switch_expr_stack = NULL;
2227 parsed_calls = NULL;
2229 sm_debug("inline function: %s\n", cur_func);
2230 __unnullify_path();
2231 clear_function_data();
2232 loop_num = 0;
2233 loop_count = 0;
2234 start_function_definition(call->fn->symbol);
2235 parse_fn_statements(base_type);
2236 if (!__path_is_null() &&
2237 cur_func_return_type() == &void_ctype &&
2238 !__bail_on_rest_of_function) {
2239 __call_all_scope_hooks();
2240 __pass_to_client(NULL, RETURN_HOOK);
2241 nullify_path();
2243 __pass_to_client(call->fn->symbol, END_FUNC_HOOK);
2244 __free_scope_hooks();
2245 __pass_to_client(call->fn->symbol, AFTER_FUNC_HOOK);
2246 call->fn->symbol->parsed = true;
2248 free_expression_stack(&switch_expr_stack);
2249 __free_ptr_list((struct ptr_list **)&big_statement_stack);
2250 nullify_path();
2251 free_goto_stack();
2253 restore_flow_state();
2254 fn_start_time = time_backup;
2255 cur_func = cur_func_bak;
2257 restore_all_states();
2258 set_position(call->pos);
2259 __inline_fn = orig_inline;
2260 inline_budget = orig_budget;
2261 __pass_to_client(call, INLINE_FN_END);
2264 static struct symbol_list *inlines_called;
2265 static void add_inline_function(struct symbol *sym)
2267 static struct symbol_list *already_added;
2268 struct symbol *tmp;
2270 FOR_EACH_PTR(already_added, tmp) {
2271 if (tmp == sym)
2272 return;
2273 } END_FOR_EACH_PTR(tmp);
2275 add_ptr_list(&already_added, sym);
2276 add_ptr_list(&inlines_called, sym);
2279 static void process_inlines(void)
2281 struct symbol *tmp;
2283 FOR_EACH_PTR(inlines_called, tmp) {
2284 split_function(tmp);
2285 } END_FOR_EACH_PTR(tmp);
2286 free_ptr_list(&inlines_called);
2289 static struct symbol *get_last_scoped_symbol(struct symbol_list *big_list, int use_static)
2291 struct symbol *sym;
2293 FOR_EACH_PTR_REVERSE(big_list, sym) {
2294 if (!sym->scope)
2295 continue;
2296 if (use_static && sym->ctype.modifiers & MOD_STATIC)
2297 return sym;
2298 if (!use_static && !(sym->ctype.modifiers & MOD_STATIC))
2299 return sym;
2300 } END_FOR_EACH_PTR_REVERSE(sym);
2302 return NULL;
2305 static bool interesting_function(struct symbol *sym)
2307 static int prev_stream = -1;
2308 static bool prev_answer;
2309 const char *filename;
2310 int len;
2312 if (!(sym->ctype.modifiers & MOD_INLINE))
2313 return true;
2315 if (sym->pos.stream == prev_stream)
2316 return prev_answer;
2318 prev_stream = sym->pos.stream;
2319 prev_answer = false;
2321 filename = stream_name(sym->pos.stream);
2322 len = strlen(filename);
2323 if (len > 0 && filename[len - 1] == 'c')
2324 prev_answer = true;
2325 return prev_answer;
2328 static void split_inlines_in_scope(struct symbol *sym)
2330 struct symbol *base;
2331 struct symbol_list *scope_list;
2332 int stream;
2334 scope_list = sym->scope->symbols;
2335 stream = sym->pos.stream;
2337 /* find the last static symbol in the file */
2338 FOR_EACH_PTR_REVERSE(scope_list, sym) {
2339 if (sym->pos.stream != stream)
2340 continue;
2341 if (sym->type != SYM_NODE)
2342 continue;
2343 base = get_base_type(sym);
2344 if (!base)
2345 continue;
2346 if (base->type != SYM_FN)
2347 continue;
2348 if (!base->inline_stmt)
2349 continue;
2350 if (!interesting_function(sym))
2351 continue;
2352 add_inline_function(sym);
2353 } END_FOR_EACH_PTR_REVERSE(sym);
2355 process_inlines();
2358 static void split_inlines(struct symbol_list *sym_list)
2360 struct symbol *sym;
2362 sym = get_last_scoped_symbol(sym_list, 0);
2363 if (sym)
2364 split_inlines_in_scope(sym);
2365 sym = get_last_scoped_symbol(sym_list, 1);
2366 if (sym)
2367 split_inlines_in_scope(sym);
2370 static struct stree *clone_estates_perm(struct stree *orig)
2372 struct stree *ret = NULL;
2373 struct sm_state *tmp;
2375 FOR_EACH_SM(orig, tmp) {
2376 set_state_stree_perm(&ret, tmp->owner, tmp->name, tmp->sym, clone_estate_perm(tmp->state));
2377 } END_FOR_EACH_SM(tmp);
2379 return ret;
2382 struct position last_pos;
2383 static void split_c_file_functions(struct symbol_list *sym_list)
2385 struct symbol *sym;
2387 __unnullify_path();
2388 FOR_EACH_PTR(sym_list, sym) {
2389 set_position(sym->pos);
2390 if (sym->type != SYM_NODE || get_base_type(sym)->type != SYM_FN) {
2391 __pass_to_client(sym, BASE_HOOK);
2392 fake_global_assign(sym);
2393 __pass_to_client(sym, DECLARATION_HOOK_AFTER);
2395 } END_FOR_EACH_PTR(sym);
2396 global_states = clone_estates_perm(get_all_states_stree(SMATCH_EXTRA));
2397 nullify_path();
2399 FOR_EACH_PTR(sym_list, sym) {
2400 set_position(sym->pos);
2401 last_pos = sym->pos;
2402 if (!interesting_function(sym))
2403 continue;
2404 if (sym->type == SYM_NODE && get_base_type(sym)->type == SYM_FN) {
2405 split_function(sym);
2406 process_inlines();
2408 last_pos = sym->pos;
2409 } END_FOR_EACH_PTR(sym);
2410 split_inlines(sym_list);
2411 __pass_to_client(sym_list, END_FILE_HOOK);
2414 static int final_before_fake;
2415 void init_fake_env(void)
2417 if (!in_fake_env)
2418 final_before_fake = final_pass;
2419 in_fake_env++;
2420 __push_fake_cur_stree();
2421 final_pass = 0;
2424 void end_fake_env(void)
2426 __free_fake_cur_stree();
2427 in_fake_env--;
2428 if (!in_fake_env)
2429 final_pass = final_before_fake;
2432 static void open_output_files(char *base_file)
2434 char buf[256];
2436 snprintf(buf, sizeof(buf), "%s.smatch", base_file);
2437 sm_outfd = fopen(buf, "w");
2438 if (!sm_outfd)
2439 sm_fatal("Cannot open %s", buf);
2441 if (!option_info)
2442 return;
2444 snprintf(buf, sizeof(buf), "%s.smatch.sql", base_file);
2445 sql_outfd = fopen(buf, "w");
2446 if (!sql_outfd)
2447 sm_fatal("Error: Cannot open %s", buf);
2449 snprintf(buf, sizeof(buf), "%s.smatch.caller_info", base_file);
2450 caller_info_fd = fopen(buf, "w");
2451 if (!caller_info_fd)
2452 sm_fatal("Error: Cannot open %s", buf);
2455 void smatch(struct string_list *filelist)
2457 struct symbol_list *sym_list;
2458 struct timeval stop, start;
2459 char *path;
2460 int len;
2462 gettimeofday(&start, NULL);
2464 FOR_EACH_PTR_NOTAG(filelist, base_file) {
2465 path = getcwd(NULL, 0);
2466 free(full_base_file);
2467 if (path) {
2468 len = strlen(path) + 1 + strlen(base_file) + 1;
2469 full_base_file = malloc(len);
2470 snprintf(full_base_file, len, "%s/%s", path, base_file);
2471 } else {
2472 full_base_file = alloc_string(base_file);
2474 if (option_file_output)
2475 open_output_files(base_file);
2476 base_file_stream = input_stream_nr;
2477 sym_list = sparse_keep_tokens(base_file);
2478 split_c_file_functions(sym_list);
2479 } END_FOR_EACH_PTR_NOTAG(base_file);
2481 gettimeofday(&stop, NULL);
2483 set_position(last_pos);
2484 final_pass = 1;
2485 if (option_time)
2486 sm_msg("time: %lu", stop.tv_sec - start.tv_sec);
2487 if (option_mem)
2488 sm_msg("mem: %luKb", get_max_memory());