2 * sparse/check_deference.c
4 * Copyright (C) 2006 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
26 ALLOCATOR(param
, "parameters");
28 struct param
*params
[MAX_PARAMS
];
30 static int merge_func(const char *name
, struct symbol
*sym
, int s1
, int s2
)
39 static struct param
*new_param(struct symbol
*arg
)
43 new = __alloc_param(0);
45 printf("Internal error: Unable to allocate memory in new_param()\n");
53 static void match_function_def(struct symbol
*sym
)
57 FOR_EACH_PTR(sym
->ctype
.base_type
->arguments
, arg
) {
58 set_state("", my_id
, arg
, ARGUMENT
);
59 params
[i
] = new_param(arg
);
61 if (i
>= MAX_PARAMS
- 1) {
62 printf("Error function has too many params.\n");
65 } END_FOR_EACH_PTR(arg
);
69 static void print_unchecked_param(struct symbol
*sym
) {
73 if (params
[i
]->sym
== sym
&& !params
[i
]->used
) {
74 smatch_msg("unchecked param: %s %d", get_function(),
81 static void match_deref(struct expression
*expr
)
84 struct symbol
*sym
= NULL
;
86 deref
= get_variable_from_expr(expr
->deref
, &sym
);
87 switch(get_state("", my_id
, sym
)) {
89 print_unchecked_param(sym
);
90 /* this doesn't actually work because we'll still see
91 the same variable get derefed on other paths */
92 set_state("", my_id
, sym
, IGNORE
);
95 smatch_msg("Error dereferencing NULL: %s", deref
);
102 static void match_function_call_after(struct expression
*expr
)
104 struct expression
*tmp
;
108 FOR_EACH_PTR(expr
->args
, tmp
) {
109 if (tmp
->op
== '&') {
110 get_variable_from_expr(tmp
, &sym
);
111 state
= get_state("", my_id
, sym
);
112 if (state
!= NOTFOUND
) {
113 set_state("", my_id
, sym
, NONNULL
);
116 } END_FOR_EACH_PTR(tmp
);
119 static void match_assign(struct expression
*expr
)
123 /* Since we're only tracking arguments, we only want
125 if (expr
->left
->type
!= EXPR_SYMBOL
)
127 state
= get_state("", my_id
, expr
->left
->symbol
);
128 if (state
== NOTFOUND
)
130 /* probably it's non null */
131 set_state("", my_id
, expr
->left
->symbol
, NONNULL
);
134 static void match_condition(struct expression
*expr
)
138 struct symbol
*sym
= NULL
;
140 if (expr
->left
->type
== EXPR_SYMBOL
) {
141 sym
= expr
->left
->symbol
;
142 if (expr
->right
->type
!= EXPR_VALUE
143 || expr
->right
->value
!= 0)
146 if (expr
->right
->type
== EXPR_SYMBOL
) {
147 sym
= expr
->right
->symbol
;
148 if (expr
->left
->type
!= EXPR_VALUE
149 || expr
->left
->value
!= 0)
155 if (expr
->op
== SPECIAL_EQUAL
)
156 set_true_false_states("", my_id
, sym
, ISNULL
,
158 else if (expr
->op
== SPECIAL_NOTEQUAL
)
159 set_true_false_states("", my_id
, sym
, NONNULL
,
164 if (get_state("", my_id
, expr
->symbol
) == ARGUMENT
) {
165 set_true_false_states("", my_id
, expr
->symbol
,
174 static void end_of_func_cleanup(struct symbol
*sym
)
179 __free_param(params
[i
]);
184 void register_derefed_params(int id
)
187 add_merge_hook(my_id
, &merge_func
);
188 add_hook(&match_function_def
, FUNC_DEF_HOOK
);
189 add_hook(&match_function_call_after
, FUNCTION_CALL_AFTER_HOOK
);
190 add_hook(&match_deref
, DEREF_HOOK
);
191 add_hook(&match_assign
, ASSIGNMENT_HOOK
);
192 add_hook(&match_condition
, CONDITION_HOOK
);
193 add_hook(&end_of_func_cleanup
, END_FUNC_HOOK
);