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 struct param
*new_param(struct symbol
*arg
)
34 new = __alloc_param(0);
36 printf("Internal error: Unable to allocate memory in new_param()\n");
44 static void match_function_def(struct symbol
*sym
)
48 FOR_EACH_PTR(sym
->ctype
.base_type
->arguments
, arg
) {
49 set_state("", my_id
, arg
, ARGUMENT
);
50 params
[i
] = new_param(arg
);
52 if (i
>= MAX_PARAMS
- 1) {
53 printf("Error function has too many params.\n");
56 } END_FOR_EACH_PTR(arg
);
60 static void print_unchecked_param(struct symbol
*sym
) {
64 if (params
[i
]->sym
== sym
&& !params
[i
]->used
) {
65 smatch_msg("unchecked param: %s %d", get_function(),
72 static void match_deref(struct expression
*expr
)
75 struct symbol
*sym
= NULL
;
77 deref
= get_variable_from_expr(expr
->deref
, &sym
);
78 switch(get_state("", my_id
, sym
)) {
80 print_unchecked_param(sym
);
81 /* this doesn't actually work because we'll still see
82 the same variable get derefed on other paths */
83 set_state("", my_id
, sym
, IGNORE
);
86 smatch_msg("Error dereferencing NULL: %s", deref
);
93 static void match_function_call_after(struct expression
*expr
)
95 struct expression
*tmp
;
99 FOR_EACH_PTR(expr
->args
, tmp
) {
100 if (tmp
->op
== '&') {
101 get_variable_from_expr(tmp
, &sym
);
102 state
= get_state("", my_id
, sym
);
103 if (state
!= NOTFOUND
) {
104 set_state("", my_id
, sym
, NONNULL
);
107 } END_FOR_EACH_PTR(tmp
);
110 static void match_assign(struct expression
*expr
)
114 /* Since we're only tracking arguments, we only want
116 if (expr
->left
->type
!= EXPR_SYMBOL
)
118 state
= get_state("", my_id
, expr
->left
->symbol
);
119 if (state
== NOTFOUND
)
121 /* probably it's non null */
122 set_state("", my_id
, expr
->left
->symbol
, NONNULL
);
125 static void match_condition(struct expression
*expr
)
129 struct symbol
*sym
= NULL
;
131 if (expr
->left
->type
== EXPR_SYMBOL
) {
132 sym
= expr
->left
->symbol
;
133 if (expr
->right
->type
!= EXPR_VALUE
134 || expr
->right
->value
!= 0)
137 if (expr
->right
->type
== EXPR_SYMBOL
) {
138 sym
= expr
->right
->symbol
;
139 if (expr
->left
->type
!= EXPR_VALUE
140 || expr
->left
->value
!= 0)
146 if (expr
->op
== SPECIAL_EQUAL
)
147 set_true_false_states("", my_id
, sym
, ISNULL
,
149 else if (expr
->op
== SPECIAL_NOTEQUAL
)
150 set_true_false_states("", my_id
, sym
, NONNULL
,
155 if (get_state("", my_id
, expr
->symbol
) == ARGUMENT
) {
156 set_true_false_states("", my_id
, expr
->symbol
,
165 static void end_of_func_cleanup(struct symbol
*sym
)
170 __free_param(params
[i
]);
175 void register_derefed_params(int id
)
178 add_hook(&match_function_def
, FUNC_DEF_HOOK
);
179 add_hook(&match_function_call_after
, FUNCTION_CALL_AFTER_HOOK
);
180 add_hook(&match_deref
, DEREF_HOOK
);
181 add_hook(&match_assign
, ASSIGNMENT_HOOK
);
182 add_hook(&match_condition
, CONDITION_HOOK
);
183 add_hook(&end_of_func_cleanup
, END_FUNC_HOOK
);