Dereferencing a variable doesn't make it undefined.
[smatch.git] / smatch_flow.c
blob8d113ae9223c416ad67c187e44020fa1a149ec5f
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"
16 static int __smatch_lineno = 0;
18 static char *filename;
19 static char *cur_func;
20 static int line_func_start;
21 static struct expression_stack *switch_expr_stack = NULL;
23 char *get_filename(void) { return filename; }
24 char *get_function(void) { return cur_func; }
25 int get_lineno(void) { return __smatch_lineno; }
26 int get_func_pos(void) { return __smatch_lineno - line_func_start; }
28 static void split_symlist(struct symbol_list *sym_list);
29 static void split_declaration(struct symbol_list *sym_list);
30 static void split_expr_list(struct expression_list *expr_list);
32 unsigned int __get_allocations();
34 int option_assume_loops = 0;
35 int option_known_conditions = 0;
37 void __split_expr(struct expression *expr)
39 if (!expr)
40 return;
42 // printf("%d Debug expr_type %d\n", get_lineno(), expr->type);
44 __smatch_lineno = expr->pos.line;
45 __pass_to_client(expr, EXPR_HOOK);
47 switch (expr->type) {
48 case EXPR_PREOP:
49 case EXPR_POSTOP:
50 __pass_to_client(expr, OP_HOOK);
51 __split_expr(expr->unop);
52 return;
53 case EXPR_STATEMENT:
54 __split_statements(expr->statement);
55 return;
56 case EXPR_LOGICAL:
57 __split_whole_condition(expr);
58 __push_true_states();
59 __use_false_states();
60 __merge_true_states();
61 __pop_false_only_stack();
62 return;
64 return;
65 case EXPR_BINOP:
66 case EXPR_COMMA:
67 case EXPR_COMPARE:
68 __split_expr(expr->left);
69 __split_expr(expr->right);
70 return;
71 case EXPR_ASSIGNMENT: {
72 struct expression *tmp;
74 __split_expr(expr->right);
75 __pass_to_client(expr, ASSIGNMENT_HOOK);
76 tmp = strip_expr(expr->right);
77 if (tmp->type == EXPR_CALL)
78 __pass_to_client(expr, CALL_ASSIGNMENT_HOOK);
79 __split_expr(expr->left);
80 return;
82 case EXPR_DEREF:
83 __pass_to_client(expr, DEREF_HOOK);
84 __split_expr(expr->deref);
85 return;
86 case EXPR_SLICE:
87 __split_expr(expr->base);
88 return;
89 case EXPR_CAST:
90 __split_expr(expr->cast_expression);
91 return;
92 case EXPR_SIZEOF:
93 /* there isn't anything to pass a client from inside a sizeof() */
94 return;
95 case EXPR_CONDITIONAL:
96 case EXPR_SELECT:
97 __split_whole_condition(expr->conditional);
98 __split_expr(expr->cond_true);
99 __push_true_states();
100 __use_false_states();
101 __split_expr(expr->cond_false);
102 __merge_true_states();
103 __pop_false_only_stack();
104 return;
105 case EXPR_CALL:
106 split_expr_list(expr->args);
107 __split_expr(expr->fn);
108 __pass_to_client(expr, FUNCTION_CALL_HOOK);
109 return;
110 case EXPR_INITIALIZER:
111 split_expr_list(expr->expr_list);
112 return;
113 case EXPR_IDENTIFIER:
114 __split_expr(expr->ident_expression);
115 return;
116 case EXPR_INDEX:
117 __split_expr(expr->idx_expression);
118 return;
119 case EXPR_POS:
120 __split_expr(expr->init_expr);
121 return;
122 default:
123 return;
127 static int is_forever_loop(struct statement *stmt)
130 struct expression *expr;
132 expr = strip_expr(stmt->iterator_pre_condition);
133 if (!expr)
134 expr = stmt->iterator_post_condition;
135 if (!expr) {
136 /* this is a for(;;) loop... */
137 return 1;
140 if (expr->type == EXPR_VALUE && expr->value == 1) {
141 return 1;
144 return 0;
148 * Pre Loops are while and for loops.
151 static void handle_pre_loop(struct statement *stmt)
153 int once_through; /* we go through the loop at least once */
154 struct sm_state *extra_state = NULL;
155 int unchanged = 0;
158 __split_statements(stmt->iterator_pre_statement);
160 once_through = implied_condition_true(stmt->iterator_pre_condition);
162 __push_continues();
163 __push_breaks();
165 __split_whole_condition(stmt->iterator_pre_condition);
166 if (once_through)
167 extra_state = __extra_pre_loop_hook_before(stmt->iterator_pre_statement);
168 if (option_assume_loops)
169 once_through = 1;
170 __split_statements(stmt->iterator_statement);
172 __warn_on_silly_pre_loops();
173 if (is_forever_loop(stmt)) {
174 __pop_false_only_stack();
175 /* forever loops don't have an iterator_post_statement */
176 __pop_continues();
177 __pop_false_states();
178 __use_breaks();
179 } else if (once_through) {
180 __merge_continues();
181 if (extra_state)
182 unchanged = __iterator_unchanged(extra_state, stmt->iterator_post_statement);
183 __split_statements(stmt->iterator_post_statement);
184 __split_whole_condition(stmt->iterator_pre_condition);
185 nullify_path();
186 __merge_false_states();
187 if (extra_state && unchanged)
188 __extra_pre_loop_hook_after(extra_state,
189 stmt->iterator_post_statement, stmt->iterator_pre_condition);
190 __pop_false_states();
191 __pop_false_only_stack();
192 __pop_false_only_stack();
193 __merge_breaks();
194 } else {
195 __merge_continues();
196 __split_statements(stmt->iterator_post_statement);
197 __merge_false_states();
198 __use_false_only_stack();
199 __merge_breaks();
204 * Post loops are do {} while();
206 static void handle_post_loop(struct statement *stmt)
208 __push_continues();
209 __push_breaks();
210 __split_statements(stmt->iterator_statement);
211 if (is_forever_loop(stmt)) {
212 __pop_continues();
213 __use_breaks();
215 } else {
216 __merge_continues();
217 __split_whole_condition(stmt->iterator_post_condition);
218 __use_false_states();
219 __merge_breaks();
221 __pop_false_only_stack();
224 static void print_unreached(struct statement *stmt)
228 * GCC insists on a return statement even where it is never
229 * reached. Also BUG() sometimes is a forever loop and
230 * sometimes not so people put code after a BUG(). There
231 * are way to many false positives.
233 #ifdef KERNEL
234 return;
235 #endif
236 if (__path_is_null()) {
237 switch(stmt->type) {
238 case STMT_COMPOUND: /* after a switch before a case stmt */
239 case STMT_CASE:
240 case STMT_LABEL:
241 case STMT_DECLARATION: /* switch(x) { int a; case foo: ... */
242 break;
243 default:
244 smatch_msg("unreachable code. %d", stmt->type);
249 void __split_statements(struct statement *stmt)
251 if (!stmt)
252 return;
254 if (__get_allocations() > MAXSMSTATES) {
255 static char *printed = NULL;
257 if (printed != cur_func)
258 smatch_msg("Function too big. Giving up.");
259 printed = cur_func;
260 return;
263 __smatch_lineno = stmt->pos.line;
264 print_unreached(stmt);
265 __pass_to_client(stmt, STMT_HOOK);
267 switch (stmt->type) {
268 case STMT_DECLARATION:
269 split_declaration(stmt->declaration);
270 return;
271 case STMT_RETURN:
272 __split_expr(stmt->ret_value);
273 __pass_to_client(stmt, RETURN_HOOK);
274 nullify_path();
275 return;
276 case STMT_EXPRESSION:
277 __split_expr(stmt->expression);
278 return;
279 case STMT_COMPOUND: {
280 struct statement *s;
281 FOR_EACH_PTR(stmt->stmts, s) {
282 __split_statements(s);
283 } END_FOR_EACH_PTR(s);
284 return;
286 case STMT_IF:
287 if (known_condition_true(stmt->if_conditional)) {
288 __split_statements(stmt->if_true);
289 return;
291 if (known_condition_false(stmt->if_conditional)) {
292 __split_statements(stmt->if_false);
293 return;
295 if (option_known_conditions &&
296 implied_condition_true(stmt->if_conditional)) {
297 smatch_msg("info: this condition is true.");
298 __split_statements(stmt->if_true);
299 return;
301 if (option_known_conditions &&
302 implied_condition_false(stmt->if_conditional)) {
303 smatch_msg("info: this condition is false.");
304 __split_statements(stmt->if_false);
305 return;
307 __split_whole_condition(stmt->if_conditional);
308 __split_statements(stmt->if_true);
309 __push_true_states();
310 __use_false_states();
311 __split_statements(stmt->if_false);
312 __merge_true_states();
313 __pop_false_only_stack();
314 return;
315 case STMT_ITERATOR:
316 if (stmt->iterator_pre_condition)
317 handle_pre_loop(stmt);
318 else if (stmt->iterator_post_condition)
319 handle_post_loop(stmt);
320 else {
321 // these are for(;;) type loops.
322 handle_pre_loop(stmt);
324 return;
325 case STMT_SWITCH:
326 __split_expr(stmt->switch_expression);
327 push_expression(&switch_expr_stack, stmt->switch_expression);
328 __save_switch_states();
329 __push_default();
330 __push_breaks();
331 __split_statements(stmt->switch_statement);
332 if (!__pop_default())
333 __merge_switches();
334 __pop_switches();
335 __merge_breaks();
336 pop_expression(&switch_expr_stack);
337 return;
338 case STMT_CASE:
339 __merge_switches();
340 __pass_case_to_client(top_expression(switch_expr_stack),
341 stmt->case_expression);
342 if (!stmt->case_expression)
343 __set_default();
344 __split_expr(stmt->case_expression);
345 __split_expr(stmt->case_to);
346 __split_statements(stmt->case_statement);
347 return;
348 case STMT_LABEL:
349 if (stmt->label &&
350 stmt->label->type == SYM_LABEL &&
351 stmt->label->ident) {
352 __merge_gotos(stmt->label->ident->name);
354 __split_statements(stmt->label_statement);
355 return;
356 case STMT_GOTO:
357 __split_expr(stmt->goto_expression);
358 if (stmt->goto_label && stmt->goto_label->type == SYM_NODE) {
359 if (!strcmp(stmt->goto_label->ident->name, "break")) {
360 __process_breaks();
361 } else if (!strcmp(stmt->goto_label->ident->name,
362 "continue")) {
363 __process_continues();
365 } else if (stmt->goto_label &&
366 stmt->goto_label->type == SYM_LABEL &&
367 stmt->goto_label->ident) {
368 __save_gotos(stmt->goto_label->ident->name);
370 nullify_path();
371 return;
372 case STMT_NONE:
373 return;
374 case STMT_ASM:
375 __split_expr(stmt->asm_string);
376 //__split_expr(stmt->asm_outputs);
377 //__split_expr(stmt->asm_inputs);
378 //__split_expr(stmt->asm_clobbers);
379 return;
380 case STMT_CONTEXT:
381 return;
382 case STMT_RANGE:
383 __split_expr(stmt->range_expression);
384 __split_expr(stmt->range_low);
385 __split_expr(stmt->range_high);
386 return;
390 static void split_expr_list(struct expression_list *expr_list)
392 struct expression *expr;
393 FOR_EACH_PTR(expr_list, expr) {
394 __split_expr(expr);
395 } END_FOR_EACH_PTR(expr);
399 static void split_sym(struct symbol *sym)
401 if (!sym)
402 return;
403 if (!(sym->namespace & NS_SYMBOL))
404 return;
406 __pass_to_client(sym, SYM_HOOK);
407 __split_statements(sym->stmt);
408 __split_expr(sym->array_size);
409 split_symlist(sym->arguments);
410 split_symlist(sym->symbol_list);
411 __split_statements(sym->inline_stmt);
412 split_symlist(sym->inline_symbol_list);
413 __split_expr(sym->initializer);
416 static void split_symlist(struct symbol_list *sym_list)
418 struct symbol *sym;
420 FOR_EACH_PTR(sym_list, sym) {
421 split_sym(sym);
422 } END_FOR_EACH_PTR(sym);
425 static void split_declaration(struct symbol_list *sym_list)
427 struct symbol *sym;
429 FOR_EACH_PTR(sym_list, sym) {
430 __pass_to_client(sym, DECLARATION_HOOK);
431 __split_expr(sym->initializer);
432 if(sym->initializer && sym->initializer->type == EXPR_CALL) {
433 __match_initializer_call(sym);
435 split_sym(sym);
436 } END_FOR_EACH_PTR(sym);
439 static void split_functions(struct symbol_list *sym_list)
441 struct symbol *sym;
443 FOR_EACH_PTR(sym_list, sym) {
444 struct symbol *base_type;
445 base_type = get_base_type(sym);
446 if (sym->type == SYM_NODE && base_type->type == SYM_FN) {
447 if (base_type->stmt)
448 line_func_start = base_type->stmt->pos.line;
449 if (sym->ident)
450 cur_func = sym->ident->name;
451 __smatch_lineno = sym->pos.line;
452 SM_DEBUG("new function: %s\n", cur_func);
453 __unnullify_path();
454 __pass_to_client(sym, FUNC_DEF_HOOK);
455 __split_statements(base_type->stmt);
456 __pass_to_client(sym, END_FUNC_HOOK);
457 cur_func = NULL;
458 line_func_start = 0;
459 clear_all_states();
460 free_expression_stack(&switch_expr_stack);
461 } else {
462 __pass_to_client(sym, BASE_HOOK);
464 } END_FOR_EACH_PTR(sym);
465 __pass_to_client_no_data(END_FILE_HOOK);
468 void smatch (int argc, char **argv)
471 struct string_list *filelist = NULL;
472 struct symbol_list *sym_list;
474 if (argc < 2) {
475 printf("Usage: smatch [--debug] <filename.c>\n");
476 exit(1);
478 sparse_initialize(argc, argv, &filelist);
479 FOR_EACH_PTR_NOTAG(filelist, filename) {
480 sym_list = __sparse(filename);
481 split_functions(sym_list);
482 } END_FOR_EACH_PTR_NOTAG(filename);