Dual pass system [patch #2]
[smatch.git] / check_initializer_deref.c
blob01780a8506dc0e99623c8f534b889607e9bd6dac
1 /*
2 * sparse/check_initializer_deref.c
4 * Copyright (C) 2009 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
10 #include "smatch.h"
12 static int my_id;
14 STATE(derefed);
15 STATE(oktocheck);
17 static void underef(const char *name, struct symbol *sym, struct expression *expr, void *unused)
19 set_state(my_id, name, sym, &oktocheck);
22 static void record_dereferenced_vars(struct expression *expr)
24 struct symbol *sym;
25 char *name;
27 if (!expr || expr->type != EXPR_DEREF)
28 return;
30 expr = expr->deref;
32 if (!strcmp(show_special(expr->op), "*")) {
33 name = get_variable_from_expr(expr->unop, &sym);
34 if (name && sym) {
35 set_state_expr(my_id, expr->unop, &derefed);
36 add_modification_hook(name, &underef, NULL);
38 free_string(name);
40 record_dereferenced_vars(expr->unop);
43 static void match_declarations(struct symbol *sym)
45 if (!sym->initializer)
46 return;
47 record_dereferenced_vars(sym->initializer);
51 static void match_condition(struct expression *expr)
53 struct symbol *sym;
54 char *name;
56 expr = strip_expr(expr);
57 name = get_variable_from_expr(expr, &sym);
58 if (!name || !sym)
59 goto free;
61 if (get_state_expr(my_id, expr) == &derefed) {
62 sm_msg("warn: variable derefenced in initializer '%s'",
63 name);
64 set_state_expr(my_id, expr, &oktocheck);
66 free:
67 free_string(name);
71 void check_initializer_deref(int id)
73 my_id = id;
74 set_default_state(my_id, &oktocheck);
75 add_hook(&match_declarations, DECLARATION_HOOK);
76 add_hook(&match_condition, CONDITION_HOOK);