2 * sparse/check_puts_argument.c
4 * Copyright (C) 2009 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
11 * This script is for finding functions like hcd_buffer_free() which free
12 * their arguments. After running it, add those functions to check_memory.c
16 #include "smatch_slist.h"
22 static struct symbol
*this_func
;
23 static struct tracker_list
*putted_args
= NULL
;
25 static void match_function_def(struct symbol
*sym
)
30 static int parent_is_arg(struct symbol
*sym
)
34 FOR_EACH_PTR(this_func
->ctype
.base_type
->arguments
, arg
) {
37 } END_FOR_EACH_PTR(arg
);
41 static void match_put(const char *fn
, struct expression
*expr
, void *info
)
43 struct expression
*tmp
;
47 tmp
= get_argument_from_call_expr(expr
->args
, 0);
48 tmp
= strip_expr(tmp
);
49 name
= get_variable_from_expr(tmp
, &sym
);
51 if (parent_is_arg(sym
) && sym
->ident
)
52 set_state(my_id
, sym
->ident
->name
, sym
, &putted
);
55 static int return_count
= 0;
56 static void match_return(struct statement
*stmt
)
58 struct state_list
*slist
;
60 struct tracker
*tracker
;
63 slist
= get_all_states(my_id
);
64 FOR_EACH_PTR(slist
, tmp
) {
65 if (tmp
->state
== &putted
)
66 add_tracker(&putted_args
, my_id
, tmp
->name
,
68 } END_FOR_EACH_PTR(tmp
);
71 FOR_EACH_PTR(putted_args
, tracker
) {
72 tmp
= get_sm_state(my_id
, tracker
->name
, tracker
->sym
);
73 if (tmp
&& tmp
->state
!= &putted
)
74 del_tracker(&putted_args
, my_id
, tracker
->name
,
76 } END_FOR_EACH_PTR(tracker
);
81 static void print_arg(struct symbol
*sym
)
86 FOR_EACH_PTR(this_func
->ctype
.base_type
->arguments
, arg
) {
88 sm_printf("info: puts_arg %s %d\n", get_function(), i
);
92 } END_FOR_EACH_PTR(arg
);
95 static void match_end_func(struct symbol
*sym
)
97 struct tracker
*tracker
;
102 FOR_EACH_PTR(putted_args
, tracker
) {
103 print_arg(tracker
->sym
);
104 } END_FOR_EACH_PTR(tracker
);
106 free_trackers_and_list(&putted_args
);
110 void check_puts_argument(int id
)
116 add_hook(&match_function_def
, FUNC_DEF_HOOK
);
117 add_function_hook("kobject_put", &match_put
, NULL
);
118 add_function_hook("kref_put", &match_put
, NULL
);
119 add_hook(&match_return
, RETURN_HOOK
);
120 add_hook(&match_end_func
, END_FUNC_HOOK
);