related: rename dinfo->equiv to dinfo->related
[smatch.git] / smatch_flow.c
blobca1acb0d19b6b44d7d4b68d52a9bace6161f8ac0
1 /*
2 * sparse/smatch_flow.c
4 * Copyright (C) 2006,2008 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
10 #define _GNU_SOURCE 1
11 #include <unistd.h>
12 #include <stdio.h>
13 #include "token.h"
14 #include "smatch.h"
15 #include "smatch_expression_stacks.h"
16 #include "smatch_extra.h"
17 #include "smatch_slist.h"
19 int final_pass;
21 static int __smatch_lineno = 0;
23 static const char *filename;
24 static char *pathname;
25 static char *full_filename;
26 static char *cur_func;
27 static int line_func_start;
28 static int loop_count;
29 int __expr_stmt_count;
30 static struct expression_list *switch_expr_stack = NULL;
32 struct expression_list *big_expression_stack;
33 struct statement_list *big_statement_stack;
34 int __in_pre_condition = 0;
35 int __bail_on_rest_of_function = 0;
36 char *get_function(void) { return cur_func; }
37 int get_lineno(void) { return __smatch_lineno; }
38 int get_func_pos(void) { return __smatch_lineno - line_func_start; }
39 int inside_loop(void) { return !!loop_count; }
40 int in_expression_statement(void) { return !!__expr_stmt_count; }
42 static void split_symlist(struct symbol_list *sym_list);
43 static void split_declaration(struct symbol_list *sym_list);
44 static void split_expr_list(struct expression_list *expr_list);
46 int option_assume_loops = 0;
47 int option_known_conditions = 0;
48 int option_two_passes = 0;
49 struct symbol *cur_func_sym = NULL;
51 const char *get_filename(void)
53 if (option_full_path)
54 return full_filename;
55 return filename;
58 static void set_position(struct expression *expr)
60 int len;
61 static int prev_stream = -1;
63 __smatch_lineno = expr->pos.line;
65 if (expr->pos.stream == prev_stream)
66 return;
68 filename = stream_name(expr->pos.stream);
70 free(full_filename);
71 pathname = getcwd(NULL, 0);
72 if (pathname) {
73 len = strlen(pathname) + 1 + strlen(filename) + 1;
74 full_filename = malloc(len);
75 snprintf(full_filename, len, "%s/%s", pathname, filename);
76 } else {
77 full_filename = alloc_string(filename);
79 free(pathname);
82 void __split_expr(struct expression *expr)
84 if (!expr)
85 return;
87 // sm_msg(" Debug expr_type %d %s", expr->type, show_special(expr->op));
89 push_expression(&big_expression_stack, expr);
90 set_position(expr);
91 __pass_to_client(expr, EXPR_HOOK);
93 switch (expr->type) {
94 case EXPR_PREOP:
95 if (expr->op == '*')
96 __pass_to_client(expr, DEREF_HOOK);
97 case EXPR_POSTOP:
98 __pass_to_client(expr, OP_HOOK);
99 __split_expr(expr->unop);
100 break;
101 case EXPR_STATEMENT:
102 __expr_stmt_count++;
103 __split_stmt(expr->statement);
104 __expr_stmt_count--;
105 break;
106 case EXPR_LOGICAL:
107 case EXPR_COMPARE:
108 __pass_to_client(expr, LOGIC_HOOK);
109 __handle_logic(expr);
110 break;
111 case EXPR_BINOP:
112 __pass_to_client(expr, BINOP_HOOK);
113 case EXPR_COMMA:
114 __split_expr(expr->left);
115 __split_expr(expr->right);
116 break;
117 case EXPR_ASSIGNMENT: {
118 struct expression *tmp;
120 /* foo = !bar() */
121 if (__handle_condition_assigns(expr))
122 break;
124 /* foo = (x < 5 ? foo : 5); */
125 if (__handle_select_assigns(expr))
126 break;
128 /* foo = ({frob(); frob(); frob(); 1;}) */
129 if (__handle_expr_statement_assigns(expr))
130 break;
132 __split_expr(expr->right);
133 __pass_to_client(expr, ASSIGNMENT_HOOK);
134 tmp = strip_expr(expr->right);
135 if (tmp->type == EXPR_CALL)
136 __pass_to_client(expr, CALL_ASSIGNMENT_HOOK);
137 __split_expr(expr->left);
138 break;
140 case EXPR_DEREF:
141 __pass_to_client(expr, DEREF_HOOK);
142 __split_expr(expr->deref);
143 break;
144 case EXPR_SLICE:
145 __split_expr(expr->base);
146 break;
147 case EXPR_CAST:
148 case EXPR_FORCE_CAST:
149 __split_expr(expr->cast_expression);
150 break;
151 case EXPR_SIZEOF:
152 /* there isn't anything to pass a client from inside a sizeof() */
153 break;
154 case EXPR_CONDITIONAL:
155 case EXPR_SELECT:
156 __split_whole_condition(expr->conditional);
157 __split_expr(expr->cond_true);
158 __push_true_states();
159 __use_false_states();
160 __split_expr(expr->cond_false);
161 __merge_true_states();
162 break;
163 case EXPR_CALL:
164 split_expr_list(expr->args);
165 __split_expr(expr->fn);
166 __pass_to_client(expr, FUNCTION_CALL_HOOK);
167 break;
168 case EXPR_INITIALIZER:
169 split_expr_list(expr->expr_list);
170 break;
171 case EXPR_IDENTIFIER:
172 __split_expr(expr->ident_expression);
173 break;
174 case EXPR_INDEX:
175 __split_expr(expr->idx_expression);
176 break;
177 case EXPR_POS:
178 __split_expr(expr->init_expr);
179 break;
180 case EXPR_SYMBOL:
181 __pass_to_client(expr, SYM_HOOK);
182 break;
183 case EXPR_STRING:
184 __pass_to_client(expr, STRING_HOOK);
185 break;
186 default:
187 break;
189 pop_expression(&big_expression_stack);
192 static int is_forever_loop(struct statement *stmt)
195 struct expression *expr;
197 expr = strip_expr(stmt->iterator_pre_condition);
198 if (!expr)
199 expr = stmt->iterator_post_condition;
200 if (!expr) {
201 /* this is a for(;;) loop... */
202 return 1;
205 if (expr->type == EXPR_VALUE && expr->value == 1) {
206 return 1;
209 return 0;
212 static int loop_num;
213 static char *get_loop_name(int num)
215 char buf[256];
217 snprintf(buf, 255, "-loop%d", num);
218 buf[255] = '\0';
219 return alloc_sname(buf);;
223 * Pre Loops are while and for loops.
226 static void handle_pre_loop(struct statement *stmt)
228 int once_through; /* we go through the loop at least once */
229 struct sm_state *extra_sm = NULL;
230 int unchanged = 0;
231 char *loop_name;
232 struct state_list *slist = NULL;
233 struct sm_state *sm = NULL;
235 loop_name = get_loop_name(loop_num);
236 loop_num++;
238 __split_stmt(stmt->iterator_pre_statement);
240 once_through = implied_condition_true(stmt->iterator_pre_condition);
242 loop_count++;
243 __push_continues();
244 __push_breaks();
246 __merge_gotos(loop_name);
248 extra_sm = __extra_handle_canonical_loops(stmt, &slist);
249 __in_pre_condition++;
250 __split_whole_condition(stmt->iterator_pre_condition);
251 __in_pre_condition--;
252 FOR_EACH_PTR(slist, sm) {
253 set_state(sm->owner, sm->name, sm->sym, sm->state);
254 } END_FOR_EACH_PTR(sm);
255 free_slist(&slist);
256 if (extra_sm)
257 extra_sm = get_sm_state(extra_sm->owner, extra_sm->name, extra_sm->sym);
259 if (option_assume_loops)
260 once_through = 1;
262 __split_stmt(stmt->iterator_statement);
263 __warn_on_silly_pre_loops();
264 if (is_forever_loop(stmt)) {
265 __save_gotos(loop_name);
266 /* forever loops don't have an iterator_post_statement */
267 __discard_continues();
268 __discard_false_states();
269 __use_breaks();
270 } else {
271 __merge_continues();
272 unchanged = __iterator_unchanged(extra_sm);
273 __split_stmt(stmt->iterator_post_statement);
274 __save_gotos(loop_name);
275 __split_whole_condition(stmt->iterator_pre_condition);
276 nullify_path();
277 __merge_false_states();
278 if (once_through) {
279 __discard_false_states();
280 } else {
281 __merge_false_states();
284 if (extra_sm && unchanged)
285 __extra_pre_loop_hook_after(extra_sm,
286 stmt->iterator_post_statement,
287 stmt->iterator_pre_condition);
288 __merge_breaks();
290 loop_count--;
294 * Post loops are do {} while();
296 static void handle_post_loop(struct statement *stmt)
298 char *loop_name;
300 loop_name = get_loop_name(loop_num);
301 loop_num++;
302 loop_count++;
304 __push_continues();
305 __push_breaks();
306 __merge_gotos(loop_name);
307 __split_stmt(stmt->iterator_statement);
308 __merge_continues();
309 if (!is_zero(stmt->iterator_post_condition))
310 __save_gotos(loop_name);
312 if (is_forever_loop(stmt)) {
313 __use_breaks();
314 } else {
315 __split_whole_condition(stmt->iterator_post_condition);
316 __use_false_states();
317 __merge_breaks();
319 loop_count--;
322 static int empty_statement(struct statement *stmt)
324 if (!stmt)
325 return 0;
326 if (stmt->type == STMT_EXPRESSION && !stmt->expression)
327 return 1;
328 return 0;
331 static int last_stmt_on_same_line()
333 struct statement *stmt;
334 int i = 0;
336 FOR_EACH_PTR_REVERSE(big_statement_stack, stmt) {
337 if (!i++)
338 continue;
339 if (stmt->pos.line == get_lineno())
340 return 1;
341 return 0;
342 } END_FOR_EACH_PTR_REVERSE(stmt);
343 return 0;
346 static struct statement *last_stmt;
347 static int is_last_stmt(struct statement *stmt)
349 if (stmt == last_stmt)
350 return 1;
351 return 0;
354 static void print_unreached_initializers(struct symbol_list *sym_list)
356 struct symbol *sym;
358 FOR_EACH_PTR(sym_list, sym) {
359 if(sym->initializer)
360 sm_msg("info: '%s' is not actually initialized (unreached code).",
361 (sym->ident ? sym->ident->name : "this variable"));
362 } END_FOR_EACH_PTR(sym);
365 static void print_unreached(struct statement *stmt)
368 static int print = 1;
370 if (!__path_is_null()) {
371 print = 1;
372 return;
374 if (!print)
375 return;
377 switch (stmt->type) {
378 case STMT_COMPOUND: /* after a switch before a case stmt */
379 case STMT_RANGE:
380 case STMT_CASE:
381 case STMT_LABEL:
382 return;
383 case STMT_DECLARATION: /* switch (x) { int a; case foo: ... */
384 print_unreached_initializers(stmt->declaration);
385 return;
386 case STMT_RETURN: /* gcc complains if you don't have a return statement */
387 if (is_last_stmt(stmt))
388 return;
389 break;
390 case STMT_GOTO:
391 if (!option_spammy)
392 return;
393 break;
394 default:
395 break;
397 if (!option_spammy && empty_statement(stmt))
398 return;
399 sm_msg("info: ignoring unreachable code.");
400 print = 0;
403 void __split_stmt(struct statement *stmt)
405 if (!stmt)
406 return;
408 if (out_of_memory() || __bail_on_rest_of_function) {
409 static char *printed = NULL;
411 if (printed != cur_func)
412 sm_msg("Function too hairy. Giving up.");
413 printed = cur_func;
414 return;
417 add_ptr_list(&big_statement_stack, stmt);
418 free_expression_stack(&big_expression_stack);
419 __smatch_lineno = stmt->pos.line;
420 print_unreached(stmt);
421 __pass_to_client(stmt, STMT_HOOK);
423 switch (stmt->type) {
424 case STMT_DECLARATION:
425 split_declaration(stmt->declaration);
426 return;
427 case STMT_RETURN:
428 __split_expr(stmt->ret_value);
429 __pass_to_client(stmt->ret_value, RETURN_HOOK);
430 nullify_path();
431 return;
432 case STMT_EXPRESSION:
433 __split_expr(stmt->expression);
434 return;
435 case STMT_COMPOUND: {
436 struct statement *tmp;
438 if (!last_stmt)
439 last_stmt = last_ptr_list((struct ptr_list *)stmt->stmts);
440 __push_scope_hooks();
441 FOR_EACH_PTR(stmt->stmts, tmp) {
442 __split_stmt(tmp);
443 } END_FOR_EACH_PTR(tmp);
444 __call_scope_hooks();
445 return;
447 case STMT_IF:
448 if (known_condition_true(stmt->if_conditional)) {
449 __split_stmt(stmt->if_true);
450 return;
452 if (known_condition_false(stmt->if_conditional)) {
453 __split_stmt(stmt->if_false);
454 return;
456 if (option_known_conditions &&
457 implied_condition_true(stmt->if_conditional)) {
458 sm_info("this condition is true.");
459 __split_stmt(stmt->if_true);
460 return;
462 if (option_known_conditions &&
463 implied_condition_false(stmt->if_conditional)) {
464 sm_info("this condition is false.");
465 __split_stmt(stmt->if_false);
466 return;
468 __split_whole_condition(stmt->if_conditional);
469 __split_stmt(stmt->if_true);
470 if (empty_statement(stmt->if_true) &&
471 last_stmt_on_same_line() &&
472 !get_macro_name(&stmt->if_true->pos))
473 sm_msg("warn: if();");
474 __push_true_states();
475 __use_false_states();
476 __split_stmt(stmt->if_false);
477 __merge_true_states();
478 return;
479 case STMT_ITERATOR:
480 if (stmt->iterator_pre_condition)
481 handle_pre_loop(stmt);
482 else if (stmt->iterator_post_condition)
483 handle_post_loop(stmt);
484 else {
485 // these are for(;;) type loops.
486 handle_pre_loop(stmt);
488 return;
489 case STMT_SWITCH:
490 __split_expr(stmt->switch_expression);
491 push_expression(&switch_expr_stack, stmt->switch_expression);
492 __save_switch_states(top_expression(switch_expr_stack));
493 nullify_path();
494 __push_default();
495 __push_breaks();
496 __split_stmt(stmt->switch_statement);
497 if (!__pop_default())
498 __merge_switches(top_expression(switch_expr_stack),
499 NULL);
500 __discard_switches();
501 __merge_breaks();
502 pop_expression(&switch_expr_stack);
503 return;
504 case STMT_CASE:
505 __merge_switches(top_expression(switch_expr_stack),
506 stmt->case_expression);
507 __pass_case_to_client(top_expression(switch_expr_stack),
508 stmt->case_expression);
509 if (!stmt->case_expression)
510 __set_default();
511 __split_expr(stmt->case_expression);
512 __split_expr(stmt->case_to);
513 __split_stmt(stmt->case_statement);
514 return;
515 case STMT_LABEL:
516 if (stmt->label &&
517 stmt->label->type == SYM_LABEL &&
518 stmt->label->ident) {
519 loop_count = 1000000;
520 __merge_gotos(stmt->label->ident->name);
522 __split_stmt(stmt->label_statement);
523 return;
524 case STMT_GOTO:
525 __split_expr(stmt->goto_expression);
526 if (stmt->goto_label && stmt->goto_label->type == SYM_NODE) {
527 if (!strcmp(stmt->goto_label->ident->name, "break")) {
528 __process_breaks();
529 } else if (!strcmp(stmt->goto_label->ident->name,
530 "continue")) {
531 __process_continues();
533 } else if (stmt->goto_label &&
534 stmt->goto_label->type == SYM_LABEL &&
535 stmt->goto_label->ident) {
536 __save_gotos(stmt->goto_label->ident->name);
538 nullify_path();
539 return;
540 case STMT_NONE:
541 return;
542 case STMT_ASM:
543 __split_expr(stmt->asm_string);
544 split_expr_list(stmt->asm_outputs);
545 split_expr_list(stmt->asm_inputs);
546 split_expr_list(stmt->asm_clobbers);
547 return;
548 case STMT_CONTEXT:
549 return;
550 case STMT_RANGE:
551 __split_expr(stmt->range_expression);
552 __split_expr(stmt->range_low);
553 __split_expr(stmt->range_high);
554 return;
558 static void split_expr_list(struct expression_list *expr_list)
560 struct expression *expr;
561 FOR_EACH_PTR(expr_list, expr) {
562 __split_expr(expr);
563 } END_FOR_EACH_PTR(expr);
567 static void split_sym(struct symbol *sym)
569 if (!sym)
570 return;
571 if (!(sym->namespace & NS_SYMBOL))
572 return;
574 __split_stmt(sym->stmt);
575 __split_expr(sym->array_size);
576 split_symlist(sym->arguments);
577 split_symlist(sym->symbol_list);
578 __split_stmt(sym->inline_stmt);
579 split_symlist(sym->inline_symbol_list);
582 static void split_symlist(struct symbol_list *sym_list)
584 struct symbol *sym;
586 FOR_EACH_PTR(sym_list, sym) {
587 split_sym(sym);
588 } END_FOR_EACH_PTR(sym);
591 static struct expression *fake_assign_expr(struct symbol *sym)
593 struct expression *e_assign, *e_symbol;
595 e_assign = alloc_expression(sym->initializer->pos, EXPR_ASSIGNMENT);
596 e_symbol = alloc_expression(sym->initializer->pos, EXPR_SYMBOL);
597 e_assign->op = (int)'=';
598 e_symbol->symbol = sym;
599 e_symbol->symbol_name = sym->ident;
600 e_assign->left = e_symbol;
601 e_assign->right = sym->initializer;
602 return e_assign;
605 static void do_initializer_stuff(struct symbol *sym)
607 struct expression *assign;
609 if(!sym->initializer)
610 return;
611 assign = fake_assign_expr(sym);
612 __split_expr(assign);
615 static void split_declaration(struct symbol_list *sym_list)
617 struct symbol *sym;
619 FOR_EACH_PTR(sym_list, sym) {
620 __pass_to_client(sym, DECLARATION_HOOK);
621 do_initializer_stuff(sym);
622 split_sym(sym);
623 } END_FOR_EACH_PTR(sym);
626 static void split_function(struct symbol *sym)
628 struct symbol *base_type = get_base_type(sym);
630 cur_func_sym = sym;
631 if (base_type->stmt)
632 line_func_start = base_type->stmt->pos.line;
633 if (sym->ident)
634 cur_func = sym->ident->name;
635 __smatch_lineno = sym->pos.line;
636 last_stmt = NULL;
637 loop_count = 0;
638 sm_debug("new function: %s\n", cur_func);
639 if (option_two_passes) {
640 __unnullify_path();
641 loop_num = 0;
642 final_pass = 0;
643 __pass_to_client(sym, FUNC_DEF_HOOK);
644 __split_stmt(base_type->stmt);
645 nullify_path();
647 __unnullify_path();
648 loop_num = 0;
649 final_pass = 1;
650 __pass_to_client(sym, FUNC_DEF_HOOK);
651 __split_stmt(base_type->stmt);
652 __pass_to_client(sym, END_FUNC_HOOK);
653 cur_func = NULL;
654 line_func_start = 0;
655 clear_all_states();
656 free_data_info_allocs();
657 free_expression_stack(&switch_expr_stack);
658 __free_ptr_list((struct ptr_list **)&big_statement_stack);
659 __bail_on_rest_of_function = 0;
662 static void split_functions(struct symbol_list *sym_list)
664 struct symbol *sym;
666 FOR_EACH_PTR(sym_list, sym) {
667 if (sym->type == SYM_NODE && get_base_type(sym)->type == SYM_FN) {
668 split_function(sym);
669 } else {
670 __pass_to_client(sym, BASE_HOOK);
672 } END_FOR_EACH_PTR(sym);
673 __pass_to_client_no_data(END_FILE_HOOK);
676 void smatch (int argc, char **argv)
679 struct string_list *filelist = NULL;
680 struct symbol_list *sym_list;
681 char *file;
683 if (argc < 2) {
684 printf("Usage: smatch [--debug] <filename.c>\n");
685 exit(1);
687 sparse_initialize(argc, argv, &filelist);
688 FOR_EACH_PTR_NOTAG(filelist, file) {
689 sym_list = sparse_keep_tokens(file);
690 split_functions(sym_list);
691 } END_FOR_EACH_PTR_NOTAG(file);