Print this page
11506 smatch resync
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/tools/smatch/src/smatch_array_values.c
+++ new/usr/src/tools/smatch/src/smatch_array_values.c
1 1 /*
2 2 * Copyright (C) 2018 Oracle. All rights reserved.
3 3 *
4 4 * This program is free software; you can redistribute it and/or
5 5 * modify it under the terms of the GNU General Public License
6 6 * as published by the Free Software Foundation; either version 2
7 7 * of the License, or (at your option) any later version.
8 8 *
9 9 * This program is distributed in the hope that it will be useful,
10 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 * GNU General Public License for more details.
13 13 *
14 14 * You should have received a copy of the GNU General Public License
15 15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
16 16 */
17 17
18 18 #include "smatch.h"
19 19 #include "smatch_extra.h"
20 20 #include "smatch_slist.h"
21 21
22 22 static int my_id;
23 23
24 24 struct db_info {
25 25 int count;
26 26 struct symbol *type;
27 27 struct range_list *rl;
28 28 };
29 29
30 30 static int get_vals(void *_db_info, int argc, char **argv, char **azColName)
31 31 {
32 32 struct db_info *db_info = _db_info;
33 33 struct range_list *rl;
34 34
35 35 str_to_rl(db_info->type, argv[0], &rl);
36 36 db_info->rl = rl_union(db_info->rl, rl);
37 37
38 38 return 0;
39 39 }
40 40
41 41 static int is_file_local(struct expression *array)
42 42 {
43 43 struct symbol *sym = NULL;
44 44 char *name;
45 45
46 46 name = expr_to_str_sym(array, &sym);
47 47 free_string(name);
48 48 if (!sym)
49 49 return 0;
50 50
51 51 if ((sym->ctype.modifiers & MOD_TOPLEVEL) &&
52 52 (sym->ctype.modifiers & MOD_STATIC))
53 53 return 1;
54 54 return 0;
55 55 }
56 56
57 57 static char *get_toplevel_name(struct expression *array)
58 58 {
59 59 char *name;
60 60 char buf[128];
61 61
62 62 if (is_array(array))
63 63 array = get_array_base(array);
64 64
65 65 if (!array || array->type != EXPR_SYMBOL)
66 66 return NULL;
67 67 if (!is_file_local(array))
68 68 return NULL;
69 69
70 70 name = expr_to_str(array);
71 71 snprintf(buf, sizeof(buf), "%s[]", name);
72 72 free_string(name);
73 73
74 74 return alloc_sname(buf);
75 75 }
76 76
77 77 static char *get_member_array(struct expression *array)
78 78 {
79 79 char *name;
80 80 char buf[128];
81 81
82 82 name = get_member_name(array);
83 83 if (!name)
84 84 return NULL;
85 85 snprintf(buf, sizeof(buf), "%s[]", name);
86 86 free_string(name);
87 87 return alloc_sname(buf);
88 88 }
89 89
90 90 static char *get_array_name(struct expression *array)
91 91 {
92 92 struct symbol *type;
93 93 char *name;
94 94
95 95 type = get_type(array);
96 96 if (!type || type->type != SYM_ARRAY)
97 97 return NULL;
98 98
99 99 name = get_toplevel_name(array);
100 100 if (name)
101 101 return name;
102 102 name = get_member_array(array);
103 103 if (name)
104 104 return name;
105 105
106 106 return NULL;
107 107 }
108 108
109 109 int get_array_rl(struct expression *expr, struct range_list **rl)
110 110 {
111 111 struct expression *array;
112 112 struct symbol *type;
113 113 struct db_info db_info = {};
114 114 char *name;
115 115
116 116 type = get_type(expr);
117 117 if (!type || type->type != SYM_BASETYPE)
118 118 return 0;
119 119 db_info.type = type;
120 120
121 121 array = get_array_base(expr);
122 122 name = get_array_name(array);
123 123 if (!name)
124 124 return 0;
125 125
126 126 if (is_file_local(array)) {
127 127 run_sql(&get_vals, &db_info,
128 128 "select value from sink_info where file = '%s' and static = 1 and sink_name = '%s' and type = %d;",
129 129 get_filename(), name, DATA_VALUE);
130 130 } else {
131 131 run_sql(&get_vals, &db_info,
132 132 "select value from sink_info where sink_name = '%s' and type = %d limit 10;",
133 133 name, DATA_VALUE);
134 134 }
135 135 if (!db_info.rl || db_info.count >= 10)
136 136 return 0;
137 137
138 138 *rl = db_info.rl;
139 139 return 1;
140 140 }
141 141
142 142 static struct range_list *get_saved_rl(struct symbol *type, char *name)
143 143 {
144 144 struct db_info db_info = {.type = type};
145 145
146 146 cache_sql(&get_vals, &db_info, "select value from sink_info where sink_name = '%s' and type = %d;",
147 147 name, DATA_VALUE);
148 148 return db_info.rl;
149 149 }
150 150
151 151 static void update_cache(char *name, int is_static, struct range_list *rl)
152 152 {
153 153 cache_sql(NULL, NULL, "delete from sink_info where sink_name = '%s' and type = %d;",
154 154 name, DATA_VALUE);
155 155 cache_sql(NULL, NULL, "insert into sink_info values ('%s', %d, '%s', %d, '', '%s');",
↓ open down ↓ |
155 lines elided |
↑ open up ↑ |
156 156 get_filename(), is_static, name, DATA_VALUE, show_rl(rl));
157 157 }
158 158
159 159 static void match_assign(struct expression *expr)
160 160 {
161 161 struct expression *left, *array;
162 162 struct range_list *orig_rl, *rl;
163 163 struct symbol *type;
164 164 char *name;
165 165
166 - type = get_type(expr->right);
166 + type = get_type(expr->left);
167 167 if (!type || type->type != SYM_BASETYPE)
168 168 return;
169 169
170 170 left = strip_expr(expr->left);
171 171 if (!is_array(left))
172 172 return;
173 173 array = get_array_base(left);
174 174 name = get_array_name(array);
175 175 if (!name)
176 176 return;
177 177
178 178 if (expr->op != '=') {
179 - rl = alloc_whole_rl(type);
179 + rl = alloc_whole_rl(get_type(expr->right));
180 + rl = cast_rl(type, rl);
180 181 } else {
181 182 get_absolute_rl(expr->right, &rl);
182 183 rl = cast_rl(type, rl);
183 184 orig_rl = get_saved_rl(type, name);
184 185 rl = rl_union(orig_rl, rl);
185 186 }
186 187
187 188 update_cache(name, is_file_local(array), rl);
188 189 }
189 190
190 191 void register_array_values(int id)
191 192 {
192 193 my_id = id;
193 194
194 195 add_hook(&match_assign, ASSIGNMENT_HOOK);
195 196 add_hook(&match_assign, GLOBAL_ASSIGNMENT_HOOK);
196 197 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX