rosenberg: handle bit fields better
[smatch.git] / check_allocation_funcs.c
blobdc5eaf59fd9a9713f1f8d90c4c82618c96bc78ed
1 /*
2 * Copyright (C) 2009 Dan Carpenter.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
18 #include <fcntl.h>
19 #include <unistd.h>
20 #include "parse.h"
21 #include "smatch.h"
22 #include "smatch_slist.h"
24 static int my_id;
27 * Print a list of functions that return newly allocated memory.
30 static struct tracker_list *allocated;
32 static const char *allocation_funcs[] = {
33 "kmalloc",
34 "kmalloc_node",
35 "kzalloc",
36 "kzalloc_node",
37 "vmalloc",
38 "vzalloc",
39 "__vmalloc",
40 "kvmalloc",
41 "kcalloc",
42 "__alloc_skb",
43 "kvcalloc",
44 "kmalloc_array",
45 "devm_kmalloc_array",
46 "sock_kmalloc",
47 "kmemdup",
48 "kmemdup_user",
49 "dma_alloc_attrs",
50 "pci_alloc_consistent",
51 "pci_alloc_coherent",
52 "devm_kmalloc",
53 "devm_kzalloc",
54 "krealloc",
55 "__alloc_bootmem",
56 "alloc_bootmem",
57 "get_zeroed_page",
58 "alloc_page",
59 "alloc_pages",
60 "alloc_pages_current",
61 "__get_free_pages",
62 "dma_alloc_contiguous",
63 "dma_alloc_coherent",
64 NULL,
67 static void match_allocation(const char *fn, struct expression *expr,
68 void *info)
70 char *left_name;
71 struct symbol *left_sym;
73 left_name = expr_to_var_sym(expr->left, &left_sym);
74 if (!left_name || !left_sym)
75 goto free;
76 if (left_sym->ctype.modifiers &
77 (MOD_NONLOCAL | MOD_STATIC | MOD_ADDRESSABLE))
78 goto free;
79 add_tracker(&allocated, my_id, left_name, left_sym);
80 free:
81 free_string(left_name);
84 static int returns_new_stuff = 0;
85 static int returns_old_stuff = 0;
86 static void match_return(struct expression *ret_value)
88 char *name;
89 struct symbol *sym;
90 sval_t tmp;
92 if (__inline_fn)
93 return;
94 if (get_value(ret_value, &tmp) && tmp.value == 0)
95 return;
96 returns_new_stuff = 1;
97 name = expr_to_var_sym(ret_value, &sym);
98 if (!name || !sym) {
99 returns_old_stuff = 1;
100 goto free;
102 if (!in_tracker_list(allocated, my_id, name, sym))
103 returns_old_stuff = 1;
104 free:
105 free_string(name);
108 static void match_end_func(struct symbol *sym)
110 if (__inline_fn)
111 return;
112 if (returns_new_stuff && !returns_old_stuff)
113 sm_info("allocation func");
114 free_trackers_and_list(&allocated);
115 returns_new_stuff = 0;
116 returns_old_stuff = 0;
119 void check_allocation_funcs(int id)
121 int i;
123 if (!option_info || option_project != PROJ_KERNEL)
124 return;
126 my_id = id;
127 add_hook(&match_return, RETURN_HOOK);
128 add_hook(&match_end_func, AFTER_FUNC_HOOK);
129 for (i = 0; allocation_funcs[i]; i++) {
130 add_function_assign_hook(allocation_funcs[i],
131 &match_allocation, NULL);