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 int is_null(struct expression
*expr
)
65 if (expr
->type
== EXPR_VALUE
&& expr
->value
== 0)
68 return is_null(expr
->unop
);
69 if (expr
->type
== EXPR_CAST
)
70 return is_null(expr
->cast_expression
);
74 static void match_assign(struct expression
*expr
)
79 name
= get_variable_from_expr_simple(expr
->left
, &sym
);
82 name
= alloc_string(name
);
83 if (is_null(expr
->right
))
84 set_state(name
, my_id
, sym
, ISNULL
);
86 set_state(name
, my_id
, sym
, NONNULL
);
90 * set_new_true_false_states is used in the following conditions
91 * if (a) { ... if (a) { ... } }
92 * The problem is that after the second blog a is set to undefined
93 * even though the second condition is meaning less. (The second test
94 * could be a macro for example).
97 static void set_new_true_false_states(const char *name
, int my_id
,
98 struct symbol
*sym
, int true_state
,
103 tmp
= get_state(name
, my_id
, sym
);
105 SM_DEBUG("set_new_stuff called at %d value=%d\n", get_lineno(), tmp
);
107 if (tmp
== NOTFOUND
|| tmp
== UNDEFINED
|| tmp
== ISNULL
)
108 set_true_false_states(name
, my_id
, sym
, true_state
, false_state
);
111 static void match_condition(struct expression
*expr
)
119 name
= get_variable_from_expr_simple(expr
, &sym
);
122 name
= alloc_string(name
);
123 set_new_true_false_states(name
, my_id
, sym
, NONNULL
, ISNULL
);
125 case EXPR_ASSIGNMENT
:
126 match_condition(expr
->left
);
133 static void match_declarations(struct symbol
*sym
)
137 name
= sym
->ident
->name
;
138 if (sym
->initializer
&& is_null(sym
->initializer
))
139 set_state(name
, my_id
, sym
, ISNULL
);
143 static int is_array(struct expression
*expr
)
145 struct symbol
*tmp
= NULL
;
148 name
= get_variable_from_expr_simple(expr
, NULL
);
150 tmp
= get_base_type(expr
->ctype
);
153 if (tmp
->type
== SYM_PTR
)
154 tmp
= get_base_type(tmp
);
157 printf("debug: %s %d\n", name
, tmp
->type
);
159 printf("name %s\n", tmp
->ident
->name
);
162 if (expr
->type
!= EXPR_BINOP
|| expr
->op
!= '+')
164 //if (expr->left->ctype && expr->left->ctype.base_type == &ptr_ctype)
169 static void match_dereferences(struct expression
*expr
)
172 struct symbol
*sym
= NULL
;
174 if (expr
->op
== '*') {
176 } else if (expr
->type
== EXPR_DEREF
&& expr
->deref
->op
== '*')
177 expr
= expr
->deref
->unop
;
180 * Say you have foo->bar.baz.n
181 * In that case we really only care about part to the
184 while (expr
->type
== EXPR_DEREF
&& expr
->deref
->op
!= '*')
187 deref
= get_variable_from_expr_simple(expr
, &sym
);
190 deref
= alloc_string(deref
);
192 switch(get_state(deref
, my_id
, sym
)) {
194 smatch_msg("Dereferencing Undefined: %s", deref
);
195 set_state(deref
, my_id
, sym
, IGNORE
);
198 /* It turns out that you only get false positives from
199 this. Mostly foo = NULL; sizeof(*foo); */
200 /* smatch_msg("Error dereferencing NULL: %s", deref); */
201 set_state(deref
, my_id
, sym
, IGNORE
);
209 void register_null_deref(int id
)
212 add_merge_hook(my_id
, &merge_func
);
213 add_hook(&match_function_call_after
, FUNCTION_CALL_AFTER_HOOK
);
214 add_hook(&match_assign
, ASSIGNMENT_AFTER_HOOK
);
215 add_hook(&match_condition
, CONDITION_HOOK
);
216 add_hook(&match_dereferences
, DEREF_HOOK
);
217 add_hook(&match_declarations
, DECLARATION_HOOK
);