try handle do {} while (i-- > 0)
[smatch.git] / smatch_flow.c
blob280098adcbb219c3e72df6e0735cb70fc264118e
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 #include <stdio.h>
11 #include "token.h"
12 #include "smatch.h"
13 #include "smatch_expression_stacks.h"
14 #include "smatch_extra.h"
15 #include "smatch_slist.h" // just for sname.
17 int final_pass;
19 static int __smatch_lineno = 0;
21 static char *filename;
22 static char *cur_func;
23 static int line_func_start;
24 static struct expression_stack *switch_expr_stack = NULL;
26 char *get_filename(void) { return filename; }
27 char *get_function(void) { return cur_func; }
28 int get_lineno(void) { return __smatch_lineno; }
29 int get_func_pos(void) { return __smatch_lineno - line_func_start; }
31 static void split_symlist(struct symbol_list *sym_list);
32 static void split_declaration(struct symbol_list *sym_list);
33 static void split_expr_list(struct expression_list *expr_list);
35 int option_assume_loops = 0;
36 int option_known_conditions = 0;
37 int option_two_passes = 0;
38 struct symbol *cur_func_sym = NULL;
40 void __split_expr(struct expression *expr)
42 if (!expr)
43 return;
45 // printf("%d Debug expr_type %d %s\n", get_lineno(), expr->type, show_special(expr->op));
47 __smatch_lineno = expr->pos.line;
48 __pass_to_client(expr, EXPR_HOOK);
50 switch (expr->type) {
51 case EXPR_PREOP:
52 if (expr->op == '*')
53 __pass_to_client(expr, DEREF_HOOK);
54 case EXPR_POSTOP:
55 __pass_to_client(expr, OP_HOOK);
56 __split_expr(expr->unop);
57 return;
58 case EXPR_STATEMENT:
59 __split_statements(expr->statement);
60 return;
61 case EXPR_LOGICAL:
62 __split_whole_condition(expr);
63 __push_true_states();
64 __use_false_states();
65 __merge_true_states();
66 __pop_false_only_stack();
67 return;
69 return;
70 case EXPR_BINOP:
71 case EXPR_COMMA:
72 case EXPR_COMPARE:
73 __split_expr(expr->left);
74 __split_expr(expr->right);
75 return;
76 case EXPR_ASSIGNMENT: {
77 struct expression *tmp;
79 __split_expr(expr->right);
80 __pass_to_client(expr, ASSIGNMENT_HOOK);
81 tmp = strip_expr(expr->right);
82 if (tmp->type == EXPR_CALL)
83 __pass_to_client(expr, CALL_ASSIGNMENT_HOOK);
84 __split_expr(expr->left);
85 return;
87 case EXPR_DEREF:
88 __pass_to_client(expr, DEREF_HOOK);
89 __split_expr(expr->deref);
90 return;
91 case EXPR_SLICE:
92 __split_expr(expr->base);
93 return;
94 case EXPR_CAST:
95 __split_expr(expr->cast_expression);
96 return;
97 case EXPR_SIZEOF:
98 /* there isn't anything to pass a client from inside a sizeof() */
99 return;
100 case EXPR_CONDITIONAL:
101 case EXPR_SELECT:
102 __split_whole_condition(expr->conditional);
103 __split_expr(expr->cond_true);
104 __push_true_states();
105 __use_false_states();
106 __split_expr(expr->cond_false);
107 __merge_true_states();
108 __pop_false_only_stack();
109 return;
110 case EXPR_CALL:
111 split_expr_list(expr->args);
112 __split_expr(expr->fn);
113 __pass_to_client(expr, FUNCTION_CALL_HOOK);
114 return;
115 case EXPR_INITIALIZER:
116 split_expr_list(expr->expr_list);
117 return;
118 case EXPR_IDENTIFIER:
119 __split_expr(expr->ident_expression);
120 return;
121 case EXPR_INDEX:
122 __split_expr(expr->idx_expression);
123 return;
124 case EXPR_POS:
125 __split_expr(expr->init_expr);
126 return;
127 default:
128 return;
132 static int is_forever_loop(struct statement *stmt)
135 struct expression *expr;
137 expr = strip_expr(stmt->iterator_pre_condition);
138 if (!expr)
139 expr = stmt->iterator_post_condition;
140 if (!expr) {
141 /* this is a for(;;) loop... */
142 return 1;
145 if (expr->type == EXPR_VALUE && expr->value == 1) {
146 return 1;
149 return 0;
152 static int loop_num;
153 static char *get_loop_name(int num)
155 char buf[256];
157 snprintf(buf, 255, "-loop%d", num);
158 buf[255] = '\0';
159 return alloc_sname(buf);;
163 * Pre Loops are while and for loops.
166 static void handle_pre_loop(struct statement *stmt)
168 int once_through; /* we go through the loop at least once */
169 struct sm_state *extra_state = NULL;
170 int unchanged = 0;
171 char *loop_name;
173 loop_name = get_loop_name(loop_num);
174 loop_num++;
176 __split_statements(stmt->iterator_pre_statement);
178 once_through = implied_condition_true(stmt->iterator_pre_condition);
180 __push_continues();
181 __push_breaks();
183 __merge_gotos(loop_name);
184 __split_whole_condition(stmt->iterator_pre_condition);
185 if (once_through)
186 extra_state = __extra_pre_loop_hook_before(stmt->iterator_pre_statement);
187 if (option_assume_loops)
188 once_through = 1;
189 __split_statements(stmt->iterator_statement);
191 __warn_on_silly_pre_loops();
192 if (is_forever_loop(stmt)) {
193 __save_gotos(loop_name);
194 __pop_false_only_stack();
195 /* forever loops don't have an iterator_post_statement */
196 __pop_continues();
197 __pop_false_states();
198 __use_breaks();
199 } else if (once_through) {
200 __merge_continues();
201 if (extra_state)
202 unchanged = __iterator_unchanged(extra_state, stmt->iterator_post_statement);
203 __split_statements(stmt->iterator_post_statement);
204 __save_gotos(loop_name);
205 __split_whole_condition(stmt->iterator_pre_condition);
206 nullify_path();
207 __merge_false_states();
208 if (extra_state && unchanged)
209 __extra_pre_loop_hook_after(extra_state,
210 stmt->iterator_post_statement, stmt->iterator_pre_condition);
211 __pop_false_states();
212 __pop_false_only_stack();
213 __pop_false_only_stack();
214 __merge_breaks();
215 } else {
216 __merge_continues();
217 __split_statements(stmt->iterator_post_statement);
218 __save_gotos(loop_name);
219 __merge_false_states();
220 __use_false_only_stack();
221 __merge_breaks();
226 * Post loops are do {} while();
228 static void handle_post_loop(struct statement *stmt)
230 char *loop_name;
232 loop_name = get_loop_name(loop_num);
233 loop_num++;
235 __push_continues();
236 __push_breaks();
237 __merge_gotos(loop_name);
238 __split_statements(stmt->iterator_statement);
239 __merge_continues();
240 if (!is_zero(stmt->iterator_post_condition))
241 __save_gotos(loop_name);
243 if (is_forever_loop(stmt)) {
244 __use_breaks();
245 } else {
246 __split_whole_condition(stmt->iterator_post_condition);
247 __use_false_states();
248 __merge_breaks();
250 __pop_false_only_stack();
253 static void print_unreached(struct statement *stmt)
257 * GCC insists on a return statement even where it is never
258 * reached. Also BUG() sometimes is a forever loop and
259 * sometimes not so people put code after a BUG(). There
260 * are way to many false positives.
262 #ifdef KERNEL
263 return;
264 #endif
265 if (__path_is_null()) {
266 switch(stmt->type) {
267 case STMT_COMPOUND: /* after a switch before a case stmt */
268 case STMT_CASE:
269 case STMT_LABEL:
270 case STMT_DECLARATION: /* switch(x) { int a; case foo: ... */
271 break;
272 default:
273 sm_msg("unreachable code. %d", stmt->type);
278 void __split_statements(struct statement *stmt)
280 if (!stmt)
281 return;
283 if (out_of_memory()) {
284 static char *printed = NULL;
286 if (printed != cur_func)
287 sm_msg("Function too big. Giving up.");
288 printed = cur_func;
289 return;
292 __smatch_lineno = stmt->pos.line;
293 print_unreached(stmt);
294 __pass_to_client(stmt, STMT_HOOK);
296 switch (stmt->type) {
297 case STMT_DECLARATION:
298 split_declaration(stmt->declaration);
299 return;
300 case STMT_RETURN:
301 __split_expr(stmt->ret_value);
302 __pass_to_client(stmt->ret_value, RETURN_HOOK);
303 nullify_path();
304 return;
305 case STMT_EXPRESSION:
306 __split_expr(stmt->expression);
307 return;
308 case STMT_COMPOUND: {
309 struct statement *s;
310 __push_scope_hooks();
311 FOR_EACH_PTR(stmt->stmts, s) {
312 __split_statements(s);
313 } END_FOR_EACH_PTR(s);
314 __call_scope_hooks();
315 return;
317 case STMT_IF:
318 if (known_condition_true(stmt->if_conditional)) {
319 __split_statements(stmt->if_true);
320 return;
322 if (known_condition_false(stmt->if_conditional)) {
323 __split_statements(stmt->if_false);
324 return;
326 if (option_known_conditions &&
327 implied_condition_true(stmt->if_conditional)) {
328 sm_msg("info: this condition is true.");
329 __split_statements(stmt->if_true);
330 return;
332 if (option_known_conditions &&
333 implied_condition_false(stmt->if_conditional)) {
334 sm_msg("info: this condition is false.");
335 __split_statements(stmt->if_false);
336 return;
338 __split_whole_condition(stmt->if_conditional);
339 __split_statements(stmt->if_true);
340 __push_true_states();
341 __use_false_states();
342 __split_statements(stmt->if_false);
343 __merge_true_states();
344 __pop_false_only_stack();
345 return;
346 case STMT_ITERATOR:
347 if (stmt->iterator_pre_condition)
348 handle_pre_loop(stmt);
349 else if (stmt->iterator_post_condition)
350 handle_post_loop(stmt);
351 else {
352 // these are for(;;) type loops.
353 handle_pre_loop(stmt);
355 return;
356 case STMT_SWITCH:
357 __split_expr(stmt->switch_expression);
358 push_expression(&switch_expr_stack, stmt->switch_expression);
359 __save_switch_states(top_expression(switch_expr_stack));
360 nullify_path();
361 __push_default();
362 __push_breaks();
363 __split_statements(stmt->switch_statement);
364 if (!__pop_default())
365 __merge_switches(top_expression(switch_expr_stack),
366 NULL);
367 __pop_switches();
368 __merge_breaks();
369 pop_expression(&switch_expr_stack);
370 return;
371 case STMT_CASE:
372 __merge_switches(top_expression(switch_expr_stack),
373 stmt->case_expression);
374 __pass_case_to_client(top_expression(switch_expr_stack),
375 stmt->case_expression);
376 if (!stmt->case_expression)
377 __set_default();
378 __split_expr(stmt->case_expression);
379 __split_expr(stmt->case_to);
380 __split_statements(stmt->case_statement);
381 return;
382 case STMT_LABEL:
383 if (stmt->label &&
384 stmt->label->type == SYM_LABEL &&
385 stmt->label->ident) {
386 __merge_gotos(stmt->label->ident->name);
388 __split_statements(stmt->label_statement);
389 return;
390 case STMT_GOTO:
391 __split_expr(stmt->goto_expression);
392 if (stmt->goto_label && stmt->goto_label->type == SYM_NODE) {
393 if (!strcmp(stmt->goto_label->ident->name, "break")) {
394 __process_breaks();
395 } else if (!strcmp(stmt->goto_label->ident->name,
396 "continue")) {
397 __process_continues();
399 } else if (stmt->goto_label &&
400 stmt->goto_label->type == SYM_LABEL &&
401 stmt->goto_label->ident) {
402 __save_gotos(stmt->goto_label->ident->name);
404 nullify_path();
405 return;
406 case STMT_NONE:
407 return;
408 case STMT_ASM:
409 __split_expr(stmt->asm_string);
410 //__split_expr(stmt->asm_outputs);
411 //__split_expr(stmt->asm_inputs);
412 //__split_expr(stmt->asm_clobbers);
413 return;
414 case STMT_CONTEXT:
415 return;
416 case STMT_RANGE:
417 __split_expr(stmt->range_expression);
418 __split_expr(stmt->range_low);
419 __split_expr(stmt->range_high);
420 return;
424 static void split_expr_list(struct expression_list *expr_list)
426 struct expression *expr;
427 FOR_EACH_PTR(expr_list, expr) {
428 __split_expr(expr);
429 } END_FOR_EACH_PTR(expr);
433 static void split_sym(struct symbol *sym)
435 if (!sym)
436 return;
437 if (!(sym->namespace & NS_SYMBOL))
438 return;
440 __pass_to_client(sym, SYM_HOOK);
441 __split_statements(sym->stmt);
442 __split_expr(sym->array_size);
443 split_symlist(sym->arguments);
444 split_symlist(sym->symbol_list);
445 __split_statements(sym->inline_stmt);
446 split_symlist(sym->inline_symbol_list);
447 __split_expr(sym->initializer);
450 static void split_symlist(struct symbol_list *sym_list)
452 struct symbol *sym;
454 FOR_EACH_PTR(sym_list, sym) {
455 split_sym(sym);
456 } END_FOR_EACH_PTR(sym);
459 static struct expression *fake_assign_expr(struct symbol *sym)
461 struct expression *e_assign, *e_symbol;
463 e_assign = alloc_expression(sym->initializer->pos, EXPR_ASSIGNMENT);
464 e_symbol = alloc_expression(sym->initializer->pos, EXPR_SYMBOL);
465 e_symbol->symbol = sym;
466 e_symbol->symbol_name = sym->ident;
467 e_assign->left = e_symbol;
468 e_assign->right = sym->initializer;
469 return e_assign;
472 static void split_declaration(struct symbol_list *sym_list)
474 struct symbol *sym;
475 struct expression *assign, *tmp;
477 FOR_EACH_PTR(sym_list, sym) {
478 __pass_to_client(sym, DECLARATION_HOOK);
479 __split_expr(sym->initializer);
480 if(sym->initializer) {
481 assign = fake_assign_expr(sym);
482 __pass_to_client(assign, ASSIGNMENT_HOOK);
483 tmp = strip_expr(assign->right);
484 if (tmp->type == EXPR_CALL)
485 __pass_to_client(assign, CALL_ASSIGNMENT_HOOK);
487 split_sym(sym);
488 } END_FOR_EACH_PTR(sym);
491 static void split_functions(struct symbol_list *sym_list)
493 struct symbol *sym;
495 FOR_EACH_PTR(sym_list, sym) {
496 struct symbol *base_type;
497 base_type = get_base_type(sym);
498 if (sym->type == SYM_NODE && base_type->type == SYM_FN) {
499 cur_func_sym = sym;
500 if (base_type->stmt)
501 line_func_start = base_type->stmt->pos.line;
502 if (sym->ident)
503 cur_func = sym->ident->name;
504 __smatch_lineno = sym->pos.line;
505 sm_debug("new function: %s\n", cur_func);
506 if (option_two_passes) {
507 __unnullify_path();
508 loop_num = 0;
509 final_pass = 0;
510 __pass_to_client(sym, FUNC_DEF_HOOK);
511 __split_statements(base_type->stmt);
512 nullify_path();
514 __unnullify_path();
515 loop_num = 0;
516 final_pass = 1;
517 __pass_to_client(sym, FUNC_DEF_HOOK);
518 __split_statements(base_type->stmt);
519 __pass_to_client(sym, END_FUNC_HOOK);
520 cur_func = NULL;
521 line_func_start = 0;
522 clear_all_states();
523 free_data_info_allocs();
524 free_expression_stack(&switch_expr_stack);
525 } else {
526 __pass_to_client(sym, BASE_HOOK);
528 } END_FOR_EACH_PTR(sym);
529 __pass_to_client_no_data(END_FILE_HOOK);
532 void smatch (int argc, char **argv)
535 struct string_list *filelist = NULL;
536 struct symbol_list *sym_list;
538 if (argc < 2) {
539 printf("Usage: smatch [--debug] <filename.c>\n");
540 exit(1);
542 sparse_initialize(argc, argv, &filelist);
543 FOR_EACH_PTR_NOTAG(filelist, filename) {
544 sym_list = __sparse(filename);
545 split_functions(sym_list);
546 } END_FOR_EACH_PTR_NOTAG(filename);