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
)
127 name
= sym
->ident
->name
;
128 if (sym
->initializer
) {
129 if (is_zero(sym
->initializer
))
130 set_state(name
, my_id
, sym
, ISNULL
);
132 set_state(name
, my_id
, sym
, NONNULL
);
137 static int is_array(struct expression
*expr
)
139 struct symbol
*tmp
= NULL
;
142 name
= get_variable_from_expr_simple(expr
, NULL
);
144 tmp
= get_base_type(expr
->ctype
);
147 if (tmp
->type
== SYM_PTR
)
148 tmp
= get_base_type(tmp
);
151 printf("debug: %s %d\n", name
, tmp
->type
);
153 printf("name %s\n", tmp
->ident
->name
);
156 if (expr
->type
!= EXPR_BINOP
|| expr
->op
!= '+')
158 //if (expr->left->ctype && expr->left->ctype.base_type == &ptr_ctype)
163 static void match_dereferences(struct expression
*expr
)
166 struct symbol
*sym
= NULL
;
168 if (expr
->op
== '*') {
170 } else if (expr
->type
== EXPR_DEREF
&& expr
->deref
->op
== '*')
171 expr
= expr
->deref
->unop
;
174 * Say you have foo->bar.baz.n
175 * In that case we really only care about part to the
178 while (expr
->type
== EXPR_DEREF
&& expr
->deref
->op
!= '*')
181 deref
= get_variable_from_expr_simple(expr
, &sym
);
184 deref
= alloc_string(deref
);
186 switch(get_state(deref
, my_id
, sym
)) {
188 smatch_msg("Dereferencing Undefined: %s", deref
);
189 set_state(deref
, my_id
, sym
, IGNORE
);
192 /* It turns out that you only get false positives from
193 this. Mostly foo = NULL; sizeof(*foo); */
194 /* smatch_msg("Error dereferencing NULL: %s", deref); */
195 set_state(deref
, my_id
, sym
, IGNORE
);
203 void register_null_deref(int id
)
206 add_merge_hook(my_id
, &merge_func
);
207 add_hook(&match_function_call_after
, FUNCTION_CALL_AFTER_HOOK
);
208 add_hook(&match_assign
, ASSIGNMENT_AFTER_HOOK
);
209 add_hook(&match_condition
, CONDITION_HOOK
);
210 add_hook(&match_dereferences
, DEREF_HOOK
);
211 add_hook(&match_declarations
, DECLARATION_HOOK
);