Print this page
12724 update smatch to 0.6.1-rc1-il-5
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/tools/smatch/src/smatch_expressions.c
+++ new/usr/src/tools/smatch/src/smatch_expressions.c
1 1 #include "smatch.h"
2 2 #include "smatch_extra.h"
3 3
4 4 DECLARE_ALLOCATOR(sname);
5 5 __ALLOCATOR(struct expression, "temporary expr", tmp_expression);
6 6
7 7 static struct position get_cur_pos(void)
8 8 {
9 9 static struct position pos;
10 10 static struct position none;
11 11 struct expression *expr;
12 12 struct statement *stmt;
13 13
14 14 expr = last_ptr_list((struct ptr_list *)big_expression_stack);
15 15 stmt = last_ptr_list((struct ptr_list *)big_statement_stack);
16 16 if (expr)
17 17 pos = expr->pos;
18 18 else if (stmt)
19 19 pos = stmt->pos;
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
20 20 else
21 21 pos = none;
22 22 return pos;
23 23 }
24 24
25 25 struct expression *alloc_tmp_expression(struct position pos, int type)
26 26 {
27 27 struct expression *expr;
28 28
29 29 expr = __alloc_tmp_expression(0);
30 - expr->smatch_flags |= Fake;
30 + expr->smatch_flags |= Tmp;
31 31 expr->type = type;
32 32 expr->pos = pos;
33 33 return expr;
34 34 }
35 35
36 36 void free_tmp_expressions(void)
37 37 {
38 38 clear_tmp_expression_alloc();
39 39 }
40 40
41 41 struct expression *zero_expr(void)
42 42 {
43 43 struct expression *zero;
44 44
45 45 zero = alloc_tmp_expression(get_cur_pos(), EXPR_VALUE);
46 46 zero->value = 0;
47 47 zero->ctype = &int_ctype;
48 48 return zero;
49 49 }
50 50
51 51 struct expression *value_expr(long long val)
52 52 {
53 53 struct expression *expr;
54 54
55 55 if (!val)
56 56 return zero_expr();
57 57
58 58 expr = alloc_tmp_expression(get_cur_pos(), EXPR_VALUE);
59 59 expr->value = val;
60 60 expr->ctype = &llong_ctype;
61 61 return expr;
62 62 }
63 63
64 64 struct expression *member_expression(struct expression *deref, int op, struct ident *member)
65 65 {
66 66 struct expression *expr;
67 67
68 68 expr = alloc_tmp_expression(deref->pos, EXPR_DEREF);
69 69 expr->op = op;
70 70 expr->deref = deref;
71 71 expr->member = member;
72 72 expr->member_offset = -1;
73 73 return expr;
74 74 }
75 75
76 76 struct expression *preop_expression(struct expression *expr, int op)
77 77 {
78 78 struct expression *preop;
79 79
80 80 preop = alloc_tmp_expression(expr->pos, EXPR_PREOP);
81 81 preop->unop = expr;
82 82 preop->op = op;
83 83 return preop;
84 84 }
85 85
86 86 struct expression *deref_expression(struct expression *expr)
87 87 {
88 88 if (expr->type == EXPR_BINOP)
89 89 expr = preop_expression(expr, '(');
90 90 return preop_expression(expr, '*');
91 91 }
92 92
93 93 struct expression *assign_expression(struct expression *left, int op, struct expression *right)
94 94 {
95 95 struct expression *expr;
96 96
97 97 if (!right)
98 98 return NULL;
99 99
100 100 /* FIXME: make this a tmp expression. */
101 101 expr = alloc_expression(right->pos, EXPR_ASSIGNMENT);
102 102 expr->op = op;
103 103 expr->left = left;
104 104 expr->right = right;
105 105 return expr;
106 106 }
107 107
108 108 struct expression *binop_expression(struct expression *left, int op, struct expression *right)
109 109 {
110 110 struct expression *expr;
111 111
112 112 expr = alloc_tmp_expression(right->pos, EXPR_BINOP);
113 113 expr->op = op;
114 114 expr->left = left;
115 115 expr->right = right;
116 116 return expr;
117 117 }
118 118
119 119 struct expression *array_element_expression(struct expression *array, struct expression *offset)
120 120 {
121 121 struct expression *expr;
122 122
123 123 expr = binop_expression(array, '+', offset);
124 124 return deref_expression(expr);
125 125 }
126 126
127 127 struct expression *symbol_expression(struct symbol *sym)
128 128 {
129 129 struct expression *expr;
130 130
131 131 expr = alloc_tmp_expression(sym->pos, EXPR_SYMBOL);
132 132 expr->symbol = sym;
133 133 expr->symbol_name = sym->ident;
134 134 return expr;
135 135 }
136 136
137 137 struct expression *compare_expression(struct expression *left, int op, struct expression *right)
138 138 {
139 139 struct expression *expr;
140 140
141 141 expr = alloc_tmp_expression(get_cur_pos(), EXPR_COMPARE);
142 142 expr->op = op;
143 143 expr->left = left;
144 144 expr->right = right;
145 145 return expr;
146 146 }
147 147
148 148 struct expression *string_expression(char *str)
149 149 {
150 150 struct expression *ret;
151 151 struct string *string;
152 152 int len;
153 153
154 154 len = strlen(str) + 1;
155 155 string = (void *)__alloc_sname(4 + len);
156 156 string->length = len;
157 157 string->immutable = 0;
158 158 memcpy(string->data, str, len);
159 159
160 160 ret = alloc_tmp_expression(get_cur_pos(), EXPR_STRING);
161 161 ret->wide = 0;
162 162 ret->string = string;
163 163
164 164 return ret;
165 165 }
166 166
167 167 struct expression *call_expression(struct expression *fn, struct expression_list *args)
168 168 {
169 169 struct expression *expr;
170 170
171 171 expr = alloc_tmp_expression(fn->pos, EXPR_CALL);
172 172 expr->fn = fn;
173 173 expr->args = args;
174 174
175 175 return expr;
176 176 }
177 177
178 178 static struct expression *get_expression_from_base_and_str(struct expression *base, const char *addition)
179 179 {
180 180 struct expression *ret = NULL;
181 181 struct token *token, *prev, *end;
182 182 char *alloc;
183 183
184 184 if (addition[0] == '\0')
185 185 return base;
186 186
187 187 alloc = alloc_string_newline(addition);
188 188
189 189 token = tokenize_buffer(alloc, strlen(alloc), &end);
190 190 if (!token)
191 191 goto free;
192 192 if (token_type(token) != TOKEN_STREAMBEGIN)
193 193 goto free;
194 194 token = token->next;
195 195
196 196 ret = base;
197 197 while (token_type(token) == TOKEN_SPECIAL &&
198 198 (token->special == SPECIAL_DEREFERENCE || token->special == '.')) {
199 199 prev = token;
200 200 token = token->next;
201 201 if (token_type(token) != TOKEN_IDENT)
202 202 goto free;
203 203 switch (prev->special) {
204 204 case SPECIAL_DEREFERENCE:
205 205 ret = deref_expression(ret);
206 206 ret = member_expression(ret, '*', token->ident);
207 207 break;
208 208 case '.':
209 209 ret = member_expression(ret, '.', token->ident);
210 210 break;
211 211 default:
212 212 goto free;
213 213 }
214 214 token = token->next;
215 215 }
216 216
217 217 if (token_type(token) != TOKEN_STREAMEND)
218 218 goto free;
219 219
220 220 free:
221 221 free_string(alloc);
222 222
223 223 return ret;
224 224 }
225 225
226 226 struct expression *gen_expression_from_name_sym(const char *name, struct symbol *sym)
227 227 {
228 228 struct expression *base;
229 229 int skip = 0;
230 230 struct expression *ret;
231 231
232 232 if (!name || !sym)
233 233 return NULL;
234 234
235 235 base = symbol_expression(sym);
236 236 while (name[skip] != '\0' && name[skip] != '.' && name[skip] != '-')
237 237 skip++;
238 238
239 239 ret = get_expression_from_base_and_str(base, name + skip);
240 240 if (ret) {
241 241 char *new = expr_to_str(ret);
242 242
243 243 /*
244 244 * FIXME: this sometimes changes "foo->bar.a.b->c" into
245 245 * "foo->bar.a.b.c". I don't know why... :(
246 246 *
247 247 */
248 248 if (!new || strcmp(name, new) != 0)
249 249 return NULL;
250 250 }
251 251 return ret;
252 252 }
253 253
254 254 struct expression *gen_expression_from_key(struct expression *arg, const char *key)
255 255 {
256 256 struct expression *ret;
257 257 struct token *token, *prev, *end;
258 258 const char *p = key;
259 259 char buf[4095];
260 260 char *alloc;
261 261 size_t len;
262 262
263 263 /* The idea is that we can parse either $0->foo or $->foo */
264 264 if (key[0] != '$')
265 265 return NULL;
266 266 p++;
267 267 while (*p >= '0' && *p <= '9')
268 268 p++;
269 269 len = snprintf(buf, sizeof(buf), "%s\n", p);
270 270 alloc = alloc_string(buf);
271 271
272 272 token = tokenize_buffer(alloc, len, &end);
273 273 if (!token)
274 274 return NULL;
275 275 if (token_type(token) != TOKEN_STREAMBEGIN)
276 276 return NULL;
277 277 token = token->next;
278 278
279 279 ret = arg;
280 280 while (token_type(token) == TOKEN_SPECIAL &&
281 281 (token->special == SPECIAL_DEREFERENCE || token->special == '.')) {
282 282 prev = token;
283 283 token = token->next;
284 284 if (token_type(token) != TOKEN_IDENT)
285 285 return NULL;
286 286 ret = deref_expression(ret);
287 287 ret = member_expression(ret,
288 288 (prev->special == SPECIAL_DEREFERENCE) ? '*' : '.',
289 289 token->ident);
290 290 token = token->next;
291 291 }
292 292
↓ open down ↓ |
252 lines elided |
↑ open up ↑ |
293 293 if (token_type(token) != TOKEN_STREAMEND)
294 294 return NULL;
295 295
296 296 return ret;
297 297 }
298 298
299 299 void expr_set_parent_expr(struct expression *expr, struct expression *parent)
300 300 {
301 301 if (!expr)
302 302 return;
303 - if (parent->smatch_flags & Fake)
303 + if (parent && parent->smatch_flags & Tmp)
304 304 return;
305 305
306 306 expr->parent = (unsigned long)parent | 0x1UL;
307 307 }
308 308
309 309 void expr_set_parent_stmt(struct expression *expr, struct statement *parent)
310 310 {
311 311 if (!expr)
312 312 return;
313 313 expr->parent = (unsigned long)parent;
314 314 }
315 315
316 316 struct expression *expr_get_parent_expr(struct expression *expr)
317 317 {
318 318 if (!expr)
319 319 return NULL;
320 320 if (!(expr->parent & 0x1UL))
321 321 return NULL;
322 322 return (struct expression *)(expr->parent & ~0x1UL);
323 323 }
324 324
325 325 struct statement *expr_get_parent_stmt(struct expression *expr)
326 326 {
327 327 if (!expr)
328 328 return NULL;
329 329 if (expr->parent & 0x1UL)
330 330 return NULL;
331 331 return (struct statement *)expr->parent;
332 332 }
333 333
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX