2 * sparse/check_deference.c
4 * Copyright (C) 2006 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
22 static void match_function_call_after(struct expression
*expr
)
24 struct expression
*tmp
;
30 if (expr
->fn
->type
== EXPR_SYMBOL
) {
31 func
= expr
->fn
->symbol_name
->name
;
34 FOR_EACH_PTR(expr
->args
, tmp
) {
36 name
= get_variable_from_expr_simple(tmp
->unop
, &sym
);
38 name
= alloc_string(name
);
39 set_state(name
, my_id
, sym
, NONNULL
);
42 name
= get_variable_from_expr_simple(tmp
, &sym
);
44 int state
= get_state(name
, my_id
, sym
);
46 smatch_msg("Null param %s %d",
48 else if (state
== UNDEFINED
)
49 smatch_msg("Undefined param %s %d",
54 } END_FOR_EACH_PTR(tmp
);
57 static int is_null(struct expression
*expr
)
59 if (expr
->type
== EXPR_VALUE
&& expr
->value
== 0)
62 return is_null(expr
->unop
);
63 if (expr
->type
== EXPR_CAST
)
64 return is_null(expr
->cast_expression
);
68 static void match_assign(struct expression
*expr
)
73 name
= get_variable_from_expr_simple(expr
->left
, &sym
);
76 name
= alloc_string(name
);
77 if (is_null(expr
->right
))
78 set_state(name
, my_id
, sym
, ISNULL
);
80 set_state(name
, my_id
, sym
, NONNULL
);
83 static void match_condition(struct expression
*expr
)
85 struct symbol
*sym_left
;
86 struct symbol
*sym_right
;
92 left
= get_variable_from_expr_simple(expr
->left
, &sym_left
);
95 left
= alloc_string(left
);
96 right
= get_variable_from_expr_simple(expr
->right
, &sym_right
);
99 right
= alloc_string(right
);
101 if (is_null(expr
->right
)) {
102 if (expr
->op
== SPECIAL_EQUAL
)
103 set_true_false_states(left
, my_id
, sym_left
,
105 else if (expr
->op
== SPECIAL_NOTEQUAL
)
106 set_true_false_states(left
, my_id
, sym_left
,
112 if (is_null(expr
->left
)) {
113 if (expr
->op
== SPECIAL_EQUAL
)
114 set_true_false_states(right
, my_id
, sym_right
,
116 else if (expr
->op
== SPECIAL_NOTEQUAL
)
117 set_true_false_states(right
, my_id
, sym_right
,
128 left
= get_variable_from_expr_simple(expr
, &sym_left
);
131 left
= alloc_string(left
);
132 set_true_false_states(left
, my_id
, sym_left
, NONNULL
, ISNULL
);
134 case EXPR_ASSIGNMENT
:
135 match_condition(expr
->left
);
142 static void match_declarations(struct symbol
*sym
)
146 name
= sym
->ident
->name
;
147 if (sym
->initializer
&& is_null(sym
->initializer
))
148 set_state(name
, my_id
, sym
, ISNULL
);
152 static int is_array(struct expression
*expr
)
154 struct symbol
*tmp
= NULL
;
157 name
= get_variable_from_expr_simple(expr
, NULL
);
159 tmp
= get_base_type(expr
->ctype
);
162 if (tmp
->type
== SYM_PTR
)
163 tmp
= get_base_type(tmp
);
166 printf("debug: %s %d\n", name
, tmp
->type
);
168 printf("name %s\n", tmp
->ident
->name
);
171 if (expr
->type
!= EXPR_BINOP
|| expr
->op
!= '+')
173 //if (expr->left->ctype && expr->left->ctype.base_type == &ptr_ctype)
178 static void match_dereferences(struct expression
*expr
)
181 struct symbol
*sym
= NULL
;
183 if (expr
->op
== '*') {
185 } else if (expr
->type
== EXPR_DEREF
&& expr
->deref
->op
== '*')
186 expr
= expr
->deref
->unop
;
189 * Say you have foo->bar.baz.n
190 * In that case we really only care about part to the
193 while (expr
->type
== EXPR_DEREF
&& expr
->deref
->op
!= '*')
196 deref
= get_variable_from_expr_simple(expr
, &sym
);
199 deref
= alloc_string(deref
);
201 switch(get_state(deref
, my_id
, sym
)) {
203 smatch_msg("Dereferencing Undefined: %s", deref
);
204 set_state(deref
, my_id
, sym
, IGNORE
);
207 /* It turns out that you only get false positives from
208 this. Mostly foo = NULL; sizeof(*foo); */
209 /* smatch_msg("Error dereferencing NULL: %s", deref); */
210 set_state(deref
, my_id
, sym
, IGNORE
);
218 void register_null_deref(int id
)
221 add_hook(&match_function_call_after
, FUNCTION_CALL_AFTER_HOOK
);
222 add_hook(&match_assign
, ASSIGNMENT_AFTER_HOOK
);
223 add_hook(&match_condition
, CONDITION_HOOK
);
224 add_hook(&match_dereferences
, DEREF_HOOK
);
225 add_hook(&match_declarations
, DECLARATION_HOOK
);