user_data: improve tracking set vs passed in user data
[smatch.git] / check_release_resource.c
blob55ff09bd0c29ee05a7bfa80ba8552316489cc390
1 /*
2 * smatch/check_release_resource.c
4 * Copyright (C) 2010 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
11 * I found a bug where someone released the wrong resource and wanted to
12 * prevent that from happening again.
16 #include "smatch.h"
18 static int my_id;
20 static struct tracker_list *resource_list;
22 static void match_request(const char *fn, struct expression *expr, void *_arg_no)
24 struct expression *arg_expr;
25 int arg_no = PTR_INT(_arg_no);
26 char *name;
27 struct symbol *sym;
29 arg_expr = get_argument_from_call_expr(expr->args, arg_no);
30 arg_expr = strip_expr(arg_expr);
32 name = expr_to_var_sym(arg_expr, &sym);
33 if (!name || !sym)
34 goto free;
35 add_tracker(&resource_list, my_id, name, sym);
36 free:
37 free_string(name);
40 static void match_release(const char *fn, struct expression *expr, void *_arg_no)
42 struct expression *arg_expr;
43 int arg_no = PTR_INT(_arg_no);
44 char *name;
45 struct symbol *sym;
47 arg_expr = get_argument_from_call_expr(expr->args, arg_no);
48 arg_expr = strip_expr(arg_expr);
50 if (!resource_list)
51 return;
53 name = expr_to_var_sym(arg_expr, &sym);
54 if (!name || !sym)
55 goto free;
56 if (in_tracker_list(resource_list, my_id, name, sym))
57 goto free;
58 sm_msg("warn: '%s' was not one of the resources you requested", name);
59 free:
60 free_string(name);
63 static void match_end_func(struct symbol *sym)
65 if (__inline_fn)
66 return;
67 free_trackers_and_list(&resource_list);
70 void check_release_resource(int id)
72 my_id = id;
74 if (option_project != PROJ_KERNEL)
75 return;
77 add_function_hook("request_resource", &match_request, (void *)1);
78 add_function_hook("release_resource", &match_release, (void *)0);
79 add_function_hook("request_mem_resource", &match_request, (void *)0);
80 add_function_hook("release_mem_resource", &match_release, (void *)0);
81 add_hook(&match_end_func, END_FUNC_HOOK);