2 * sparse/check_deference.c
4 * Copyright (C) 2006 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
21 static int merge_func(const char *name
, struct symbol
*sym
, int s1
, int s2
)
28 static void match_function_call_after(struct expression
*expr
)
30 struct expression
*tmp
;
36 if (expr
->fn
->type
== EXPR_SYMBOL
) {
37 func
= expr
->fn
->symbol_name
->name
;
40 FOR_EACH_PTR(expr
->args
, tmp
) {
42 name
= get_variable_from_expr_simple(tmp
->unop
, &sym
);
44 name
= alloc_string(name
);
45 set_state(name
, my_id
, sym
, NONNULL
);
48 name
= get_variable_from_expr_simple(tmp
, &sym
);
50 int state
= get_state(name
, my_id
, sym
);
52 smatch_msg("Null param %s %d",
54 else if (state
== UNDEFINED
)
55 smatch_msg("Undefined param %s %d",
60 } END_FOR_EACH_PTR(tmp
);
63 static void match_assign(struct expression
*expr
)
68 name
= get_variable_from_expr_simple(expr
->left
, &sym
);
71 name
= alloc_string(name
);
72 if (is_zero(expr
->right
))
73 set_state(name
, my_id
, sym
, ISNULL
);
75 set_state(name
, my_id
, sym
, NONNULL
);
79 * set_new_true_false_states is used in the following conditions
80 * if (a) { ... if (a) { ... } }
81 * The problem is that after the second blog a is set to undefined
82 * even though the second condition is meaning less. (The second test
83 * could be a macro for example).
86 static void set_new_true_false_states(const char *name
, int my_id
,
87 struct symbol
*sym
, int true_state
,
92 tmp
= get_state(name
, my_id
, sym
);
94 SM_DEBUG("set_new_stuff called at %d value=%d\n", get_lineno(), tmp
);
96 if (tmp
== NOTFOUND
|| tmp
== UNDEFINED
|| tmp
== ISNULL
)
97 set_true_false_states(name
, my_id
, sym
, true_state
, false_state
);
100 static void match_condition(struct expression
*expr
)
108 name
= get_variable_from_expr_simple(expr
, &sym
);
111 name
= alloc_string(name
);
112 set_new_true_false_states(name
, my_id
, sym
, NONNULL
, ISNULL
);
114 case EXPR_ASSIGNMENT
:
115 match_condition(expr
->left
);
122 static void match_declarations(struct symbol
*sym
)
126 name
= sym
->ident
->name
;
127 if (sym
->initializer
&& is_zero(sym
->initializer
))
128 set_state(name
, my_id
, sym
, ISNULL
);
132 static int is_array(struct expression
*expr
)
134 struct symbol
*tmp
= NULL
;
137 name
= get_variable_from_expr_simple(expr
, NULL
);
139 tmp
= get_base_type(expr
->ctype
);
142 if (tmp
->type
== SYM_PTR
)
143 tmp
= get_base_type(tmp
);
146 printf("debug: %s %d\n", name
, tmp
->type
);
148 printf("name %s\n", tmp
->ident
->name
);
151 if (expr
->type
!= EXPR_BINOP
|| expr
->op
!= '+')
153 //if (expr->left->ctype && expr->left->ctype.base_type == &ptr_ctype)
158 static void match_dereferences(struct expression
*expr
)
161 struct symbol
*sym
= NULL
;
163 if (expr
->op
== '*') {
165 } else if (expr
->type
== EXPR_DEREF
&& expr
->deref
->op
== '*')
166 expr
= expr
->deref
->unop
;
169 * Say you have foo->bar.baz.n
170 * In that case we really only care about part to the
173 while (expr
->type
== EXPR_DEREF
&& expr
->deref
->op
!= '*')
176 deref
= get_variable_from_expr_simple(expr
, &sym
);
179 deref
= alloc_string(deref
);
181 switch(get_state(deref
, my_id
, sym
)) {
183 smatch_msg("Dereferencing Undefined: %s", deref
);
184 set_state(deref
, my_id
, sym
, IGNORE
);
187 /* It turns out that you only get false positives from
188 this. Mostly foo = NULL; sizeof(*foo); */
189 /* smatch_msg("Error dereferencing NULL: %s", deref); */
190 set_state(deref
, my_id
, sym
, IGNORE
);
198 void register_null_deref(int id
)
201 add_merge_hook(my_id
, &merge_func
);
202 add_hook(&match_function_call_after
, FUNCTION_CALL_AFTER_HOOK
);
203 add_hook(&match_assign
, ASSIGNMENT_AFTER_HOOK
);
204 add_hook(&match_condition
, CONDITION_HOOK
);
205 add_hook(&match_dereferences
, DEREF_HOOK
);
206 add_hook(&match_declarations
, DECLARATION_HOOK
);