check_unused_ret.c: fix check for local variables
[smatch.git] / smatch_flow.c
blob6847269d2f196e0ceafccb7be8a8c4616bb3d260
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" // just for sname.
19 int final_pass;
21 static int __smatch_lineno = 0;
23 static char *filename;
24 static char *pathname;
25 static char *full_filename;
26 static char *cur_func;
27 static int line_func_start;
28 static struct expression_list *switch_expr_stack = NULL;
29 struct expression_list *big_expression_stack;
31 char *get_function(void) { return cur_func; }
32 int get_lineno(void) { return __smatch_lineno; }
33 int get_func_pos(void) { return __smatch_lineno - line_func_start; }
35 static void split_symlist(struct symbol_list *sym_list);
36 static void split_declaration(struct symbol_list *sym_list);
37 static void split_expr_list(struct expression_list *expr_list);
39 int option_assume_loops = 0;
40 int option_known_conditions = 0;
41 int option_two_passes = 0;
42 struct symbol *cur_func_sym = NULL;
44 char *get_filename(void)
46 if (option_full_path)
47 return full_filename;
48 return filename;
51 void __split_expr(struct expression *expr)
53 if (!expr)
54 return;
56 // printf("%d Debug expr_type %d %s\n", get_lineno(), expr->type, show_special(expr->op));
58 push_expression(&big_expression_stack, expr);
59 __smatch_lineno = expr->pos.line;
60 __pass_to_client(expr, EXPR_HOOK);
62 switch (expr->type) {
63 case EXPR_PREOP:
64 if (expr->op == '*')
65 __pass_to_client(expr, DEREF_HOOK);
66 case EXPR_POSTOP:
67 __pass_to_client(expr, OP_HOOK);
68 __split_expr(expr->unop);
69 return;
70 case EXPR_STATEMENT:
71 __split_statements(expr->statement);
72 return;
73 case EXPR_LOGICAL:
74 __split_whole_condition(expr);
75 __push_true_states();
76 __use_false_states();
77 __merge_true_states();
78 __pop_false_only_stack();
79 return;
81 return;
82 case EXPR_BINOP:
83 case EXPR_COMMA:
84 case EXPR_COMPARE:
85 __split_expr(expr->left);
86 __split_expr(expr->right);
87 return;
88 case EXPR_ASSIGNMENT: {
89 struct expression *tmp;
91 __split_expr(expr->right);
92 __pass_to_client(expr, ASSIGNMENT_HOOK);
93 tmp = strip_expr(expr->right);
94 if (tmp->type == EXPR_CALL)
95 __pass_to_client(expr, CALL_ASSIGNMENT_HOOK);
96 __split_expr(expr->left);
97 return;
99 case EXPR_DEREF:
100 __pass_to_client(expr, DEREF_HOOK);
101 __split_expr(expr->deref);
102 return;
103 case EXPR_SLICE:
104 __split_expr(expr->base);
105 return;
106 case EXPR_CAST:
107 case EXPR_FORCE_CAST:
108 __split_expr(expr->cast_expression);
109 return;
110 case EXPR_SIZEOF:
111 /* there isn't anything to pass a client from inside a sizeof() */
112 return;
113 case EXPR_CONDITIONAL:
114 case EXPR_SELECT:
115 __split_whole_condition(expr->conditional);
116 __split_expr(expr->cond_true);
117 __push_true_states();
118 __use_false_states();
119 __split_expr(expr->cond_false);
120 __merge_true_states();
121 __pop_false_only_stack();
122 return;
123 case EXPR_CALL:
124 split_expr_list(expr->args);
125 __split_expr(expr->fn);
126 __pass_to_client(expr, FUNCTION_CALL_HOOK);
127 return;
128 case EXPR_INITIALIZER:
129 split_expr_list(expr->expr_list);
130 return;
131 case EXPR_IDENTIFIER:
132 __split_expr(expr->ident_expression);
133 return;
134 case EXPR_INDEX:
135 __split_expr(expr->idx_expression);
136 return;
137 case EXPR_POS:
138 __split_expr(expr->init_expr);
139 return;
140 case EXPR_SYMBOL:
141 __pass_to_client(expr, SYM_HOOK);
142 return;
143 default:
144 return;
148 static int is_forever_loop(struct statement *stmt)
151 struct expression *expr;
153 expr = strip_expr(stmt->iterator_pre_condition);
154 if (!expr)
155 expr = stmt->iterator_post_condition;
156 if (!expr) {
157 /* this is a for(;;) loop... */
158 return 1;
161 if (expr->type == EXPR_VALUE && expr->value == 1) {
162 return 1;
165 return 0;
168 static int loop_num;
169 static char *get_loop_name(int num)
171 char buf[256];
173 snprintf(buf, 255, "-loop%d", num);
174 buf[255] = '\0';
175 return alloc_sname(buf);;
179 * Pre Loops are while and for loops.
182 static void handle_pre_loop(struct statement *stmt)
184 int once_through; /* we go through the loop at least once */
185 struct sm_state *extra_state = NULL;
186 int unchanged = 0;
187 char *loop_name;
189 loop_name = get_loop_name(loop_num);
190 loop_num++;
192 __split_statements(stmt->iterator_pre_statement);
194 once_through = implied_condition_true(stmt->iterator_pre_condition);
196 __push_continues();
197 __push_breaks();
199 __merge_gotos(loop_name);
200 __split_whole_condition(stmt->iterator_pre_condition);
201 if (once_through)
202 extra_state = __extra_pre_loop_hook_before(stmt->iterator_pre_statement);
203 if (option_assume_loops)
204 once_through = 1;
205 __split_statements(stmt->iterator_statement);
207 __warn_on_silly_pre_loops();
208 if (is_forever_loop(stmt)) {
209 __save_gotos(loop_name);
210 __pop_false_only_stack();
211 /* forever loops don't have an iterator_post_statement */
212 __pop_continues();
213 __pop_false_states();
214 __use_breaks();
215 } else if (once_through) {
216 __merge_continues();
217 if (extra_state)
218 unchanged = __iterator_unchanged(extra_state, stmt->iterator_post_statement);
219 __split_statements(stmt->iterator_post_statement);
220 __save_gotos(loop_name);
221 __split_whole_condition(stmt->iterator_pre_condition);
222 nullify_path();
223 __merge_false_states();
224 if (extra_state && unchanged)
225 __extra_pre_loop_hook_after(extra_state,
226 stmt->iterator_post_statement, stmt->iterator_pre_condition);
227 __pop_false_states();
228 __pop_false_only_stack();
229 __pop_false_only_stack();
230 __merge_breaks();
231 } else {
232 __merge_continues();
233 __split_statements(stmt->iterator_post_statement);
234 __save_gotos(loop_name);
235 __merge_false_states();
236 __use_false_only_stack();
237 __merge_breaks();
242 * Post loops are do {} while();
244 static void handle_post_loop(struct statement *stmt)
246 char *loop_name;
248 loop_name = get_loop_name(loop_num);
249 loop_num++;
251 __push_continues();
252 __push_breaks();
253 __merge_gotos(loop_name);
254 __split_statements(stmt->iterator_statement);
255 __merge_continues();
256 if (!is_zero(stmt->iterator_post_condition))
257 __save_gotos(loop_name);
259 if (is_forever_loop(stmt)) {
260 __use_breaks();
261 } else {
262 __split_whole_condition(stmt->iterator_post_condition);
263 __use_false_states();
264 __merge_breaks();
266 __pop_false_only_stack();
269 static void print_unreached(struct statement *stmt)
273 * GCC insists on a return statement even where it is never
274 * reached. Also BUG() sometimes is a forever loop and
275 * sometimes not so people put code after a BUG(). There
276 * are way to many false positives.
278 return;
280 if (__path_is_null()) {
281 switch(stmt->type) {
282 case STMT_COMPOUND: /* after a switch before a case stmt */
283 case STMT_CASE:
284 case STMT_LABEL:
285 case STMT_DECLARATION: /* switch(x) { int a; case foo: ... */
286 break;
287 default:
288 sm_msg("unreachable code. %d", stmt->type);
293 void __split_statements(struct statement *stmt)
295 if (!stmt)
296 return;
298 if (out_of_memory()) {
299 static char *printed = NULL;
301 if (printed != cur_func)
302 sm_msg("Function too big. Giving up.");
303 printed = cur_func;
304 return;
307 free_expression_stack(&big_expression_stack);
308 __smatch_lineno = stmt->pos.line;
309 print_unreached(stmt);
310 __pass_to_client(stmt, STMT_HOOK);
312 switch (stmt->type) {
313 case STMT_DECLARATION:
314 split_declaration(stmt->declaration);
315 return;
316 case STMT_RETURN:
317 __split_expr(stmt->ret_value);
318 __pass_to_client(stmt->ret_value, RETURN_HOOK);
319 nullify_path();
320 return;
321 case STMT_EXPRESSION:
322 __split_expr(stmt->expression);
323 return;
324 case STMT_COMPOUND: {
325 struct statement *s;
326 __push_scope_hooks();
327 FOR_EACH_PTR(stmt->stmts, s) {
328 __split_statements(s);
329 } END_FOR_EACH_PTR(s);
330 __call_scope_hooks();
331 return;
333 case STMT_IF:
334 if (known_condition_true(stmt->if_conditional)) {
335 __split_statements(stmt->if_true);
336 return;
338 if (known_condition_false(stmt->if_conditional)) {
339 __split_statements(stmt->if_false);
340 return;
342 if (option_known_conditions &&
343 implied_condition_true(stmt->if_conditional)) {
344 sm_msg("info: this condition is true.");
345 __split_statements(stmt->if_true);
346 return;
348 if (option_known_conditions &&
349 implied_condition_false(stmt->if_conditional)) {
350 sm_msg("info: this condition is false.");
351 __split_statements(stmt->if_false);
352 return;
354 __split_whole_condition(stmt->if_conditional);
355 __split_statements(stmt->if_true);
356 __push_true_states();
357 __use_false_states();
358 __split_statements(stmt->if_false);
359 __merge_true_states();
360 __pop_false_only_stack();
361 return;
362 case STMT_ITERATOR:
363 if (stmt->iterator_pre_condition)
364 handle_pre_loop(stmt);
365 else if (stmt->iterator_post_condition)
366 handle_post_loop(stmt);
367 else {
368 // these are for(;;) type loops.
369 handle_pre_loop(stmt);
371 return;
372 case STMT_SWITCH:
373 __split_expr(stmt->switch_expression);
374 push_expression(&switch_expr_stack, stmt->switch_expression);
375 __save_switch_states(top_expression(switch_expr_stack));
376 nullify_path();
377 __push_default();
378 __push_breaks();
379 __split_statements(stmt->switch_statement);
380 if (!__pop_default())
381 __merge_switches(top_expression(switch_expr_stack),
382 NULL);
383 __pop_switches();
384 __merge_breaks();
385 pop_expression(&switch_expr_stack);
386 return;
387 case STMT_CASE:
388 __merge_switches(top_expression(switch_expr_stack),
389 stmt->case_expression);
390 __pass_case_to_client(top_expression(switch_expr_stack),
391 stmt->case_expression);
392 if (!stmt->case_expression)
393 __set_default();
394 __split_expr(stmt->case_expression);
395 __split_expr(stmt->case_to);
396 __split_statements(stmt->case_statement);
397 return;
398 case STMT_LABEL:
399 if (stmt->label &&
400 stmt->label->type == SYM_LABEL &&
401 stmt->label->ident) {
402 __merge_gotos(stmt->label->ident->name);
404 __split_statements(stmt->label_statement);
405 return;
406 case STMT_GOTO:
407 __split_expr(stmt->goto_expression);
408 if (stmt->goto_label && stmt->goto_label->type == SYM_NODE) {
409 if (!strcmp(stmt->goto_label->ident->name, "break")) {
410 __process_breaks();
411 } else if (!strcmp(stmt->goto_label->ident->name,
412 "continue")) {
413 __process_continues();
415 } else if (stmt->goto_label &&
416 stmt->goto_label->type == SYM_LABEL &&
417 stmt->goto_label->ident) {
418 __save_gotos(stmt->goto_label->ident->name);
420 nullify_path();
421 return;
422 case STMT_NONE:
423 return;
424 case STMT_ASM:
425 __split_expr(stmt->asm_string);
426 //__split_expr(stmt->asm_outputs);
427 //__split_expr(stmt->asm_inputs);
428 //__split_expr(stmt->asm_clobbers);
429 return;
430 case STMT_CONTEXT:
431 return;
432 case STMT_RANGE:
433 __split_expr(stmt->range_expression);
434 __split_expr(stmt->range_low);
435 __split_expr(stmt->range_high);
436 return;
440 static void split_expr_list(struct expression_list *expr_list)
442 struct expression *expr;
443 FOR_EACH_PTR(expr_list, expr) {
444 __split_expr(expr);
445 } END_FOR_EACH_PTR(expr);
449 static void split_sym(struct symbol *sym)
451 if (!sym)
452 return;
453 if (!(sym->namespace & NS_SYMBOL))
454 return;
456 __split_statements(sym->stmt);
457 __split_expr(sym->array_size);
458 split_symlist(sym->arguments);
459 split_symlist(sym->symbol_list);
460 __split_statements(sym->inline_stmt);
461 split_symlist(sym->inline_symbol_list);
462 __split_expr(sym->initializer);
465 static void split_symlist(struct symbol_list *sym_list)
467 struct symbol *sym;
469 FOR_EACH_PTR(sym_list, sym) {
470 split_sym(sym);
471 } END_FOR_EACH_PTR(sym);
474 static struct expression *fake_assign_expr(struct symbol *sym)
476 struct expression *e_assign, *e_symbol;
478 e_assign = alloc_expression(sym->initializer->pos, EXPR_ASSIGNMENT);
479 e_symbol = alloc_expression(sym->initializer->pos, EXPR_SYMBOL);
480 e_assign->op = (int)'=';
481 e_symbol->symbol = sym;
482 e_symbol->symbol_name = sym->ident;
483 e_assign->left = e_symbol;
484 e_assign->right = sym->initializer;
485 return e_assign;
488 static void split_declaration(struct symbol_list *sym_list)
490 struct symbol *sym;
491 struct expression *assign, *tmp;
493 FOR_EACH_PTR(sym_list, sym) {
494 __pass_to_client(sym, DECLARATION_HOOK);
495 __split_expr(sym->initializer);
496 if(sym->initializer) {
497 assign = fake_assign_expr(sym);
498 __pass_to_client(assign, ASSIGNMENT_HOOK);
499 tmp = strip_expr(assign->right);
500 if (tmp->type == EXPR_CALL)
501 __pass_to_client(assign, CALL_ASSIGNMENT_HOOK);
503 split_sym(sym);
504 } END_FOR_EACH_PTR(sym);
507 static void split_functions(struct symbol_list *sym_list)
509 struct symbol *sym;
511 FOR_EACH_PTR(sym_list, sym) {
512 struct symbol *base_type;
513 base_type = get_base_type(sym);
514 if (sym->type == SYM_NODE && base_type->type == SYM_FN) {
515 cur_func_sym = sym;
516 if (base_type->stmt)
517 line_func_start = base_type->stmt->pos.line;
518 if (sym->ident)
519 cur_func = sym->ident->name;
520 __smatch_lineno = sym->pos.line;
521 sm_debug("new function: %s\n", cur_func);
522 if (option_two_passes) {
523 __unnullify_path();
524 loop_num = 0;
525 final_pass = 0;
526 __pass_to_client(sym, FUNC_DEF_HOOK);
527 __split_statements(base_type->stmt);
528 nullify_path();
530 __unnullify_path();
531 loop_num = 0;
532 final_pass = 1;
533 __pass_to_client(sym, FUNC_DEF_HOOK);
534 __split_statements(base_type->stmt);
535 __pass_to_client(sym, END_FUNC_HOOK);
536 cur_func = NULL;
537 line_func_start = 0;
538 clear_all_states();
539 free_data_info_allocs();
540 free_expression_stack(&switch_expr_stack);
541 } else {
542 __pass_to_client(sym, BASE_HOOK);
544 } END_FOR_EACH_PTR(sym);
545 __pass_to_client_no_data(END_FILE_HOOK);
548 void smatch (int argc, char **argv)
551 struct string_list *filelist = NULL;
552 struct symbol_list *sym_list;
554 if (argc < 2) {
555 printf("Usage: smatch [--debug] <filename.c>\n");
556 exit(1);
558 sparse_initialize(argc, argv, &filelist);
559 FOR_EACH_PTR_NOTAG(filelist, filename) {
560 int len;
562 pathname = get_current_dir_name();
563 if (pathname) {
564 len = strlen(pathname) + 1 + strlen(filename) + 1;
565 full_filename = malloc(len);
566 snprintf(full_filename, len, "%s/%s", pathname, filename);
567 } else {
568 full_filename = filename;
571 sym_list = __sparse(filename);
572 split_functions(sym_list);
574 if (pathname) {
575 free(full_filename);
576 free(pathname);
578 } END_FOR_EACH_PTR_NOTAG(filename);