Print this page
12166 resync smatch to 0.6.1-rc1-il-3
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;
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 30 expr->smatch_flags |= Fake;
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 {
↓ open down ↓ |
77 lines elided |
↑ open up ↑ |
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 + if (expr->type == EXPR_BINOP)
89 + expr = preop_expression(expr, '(');
88 90 return preop_expression(expr, '*');
89 91 }
90 92
91 93 struct expression *assign_expression(struct expression *left, int op, struct expression *right)
92 94 {
93 95 struct expression *expr;
94 96
95 97 if (!right)
96 98 return NULL;
97 99
98 100 /* FIXME: make this a tmp expression. */
99 101 expr = alloc_expression(right->pos, EXPR_ASSIGNMENT);
100 102 expr->op = op;
101 103 expr->left = left;
102 104 expr->right = right;
103 105 return expr;
104 106 }
105 107
106 108 struct expression *binop_expression(struct expression *left, int op, struct expression *right)
107 109 {
108 110 struct expression *expr;
109 111
110 112 expr = alloc_tmp_expression(right->pos, EXPR_BINOP);
111 113 expr->op = op;
112 114 expr->left = left;
113 115 expr->right = right;
114 116 return expr;
115 117 }
116 118
117 119 struct expression *array_element_expression(struct expression *array, struct expression *offset)
118 120 {
119 121 struct expression *expr;
120 122
121 123 expr = binop_expression(array, '+', offset);
122 124 return deref_expression(expr);
123 125 }
124 126
125 127 struct expression *symbol_expression(struct symbol *sym)
126 128 {
127 129 struct expression *expr;
128 130
129 131 expr = alloc_tmp_expression(sym->pos, EXPR_SYMBOL);
130 132 expr->symbol = sym;
131 133 expr->symbol_name = sym->ident;
132 134 return expr;
133 135 }
134 136
135 137 struct expression *compare_expression(struct expression *left, int op, struct expression *right)
136 138 {
137 139 struct expression *expr;
138 140
139 141 expr = alloc_tmp_expression(get_cur_pos(), EXPR_COMPARE);
140 142 expr->op = op;
141 143 expr->left = left;
142 144 expr->right = right;
143 145 return expr;
144 146 }
145 147
146 148 struct expression *string_expression(char *str)
147 149 {
148 150 struct expression *ret;
149 151 struct string *string;
150 152 int len;
151 153
152 154 len = strlen(str) + 1;
153 155 string = (void *)__alloc_sname(4 + len);
154 156 string->length = len;
↓ open down ↓ |
57 lines elided |
↑ open up ↑ |
155 157 string->immutable = 0;
156 158 memcpy(string->data, str, len);
157 159
158 160 ret = alloc_tmp_expression(get_cur_pos(), EXPR_STRING);
159 161 ret->wide = 0;
160 162 ret->string = string;
161 163
162 164 return ret;
163 165 }
164 166
167 +struct expression *call_expression(struct expression *fn, struct expression_list *args)
168 +{
169 + struct expression *expr;
170 +
171 + expr = alloc_tmp_expression(fn->pos, EXPR_CALL);
172 + expr->fn = fn;
173 + expr->args = args;
174 +
175 + return expr;
176 +}
177 +
165 178 static struct expression *get_expression_from_base_and_str(struct expression *base, const char *addition)
166 179 {
167 180 struct expression *ret = NULL;
168 181 struct token *token, *prev, *end;
169 182 char *alloc;
170 183
171 184 if (addition[0] == '\0')
172 185 return base;
173 186
174 187 alloc = alloc_string_newline(addition);
175 188
176 189 token = tokenize_buffer(alloc, strlen(alloc), &end);
177 190 if (!token)
178 191 goto free;
179 192 if (token_type(token) != TOKEN_STREAMBEGIN)
180 193 goto free;
181 194 token = token->next;
182 195
183 196 ret = base;
184 197 while (token_type(token) == TOKEN_SPECIAL &&
185 198 (token->special == SPECIAL_DEREFERENCE || token->special == '.')) {
186 199 prev = token;
187 200 token = token->next;
188 201 if (token_type(token) != TOKEN_IDENT)
189 202 goto free;
190 203 switch (prev->special) {
191 204 case SPECIAL_DEREFERENCE:
192 205 ret = deref_expression(ret);
193 206 ret = member_expression(ret, '*', token->ident);
194 207 break;
195 208 case '.':
196 209 ret = member_expression(ret, '.', token->ident);
197 210 break;
198 211 default:
199 212 goto free;
200 213 }
201 214 token = token->next;
202 215 }
203 216
204 217 if (token_type(token) != TOKEN_STREAMEND)
205 218 goto free;
206 219
207 220 free:
208 221 free_string(alloc);
209 222
210 223 return ret;
211 224 }
212 225
213 226 struct expression *gen_expression_from_name_sym(const char *name, struct symbol *sym)
214 227 {
215 228 struct expression *base;
216 229 int skip = 0;
217 230 struct expression *ret;
218 231
219 232 if (!name || !sym)
220 233 return NULL;
221 234
222 235 base = symbol_expression(sym);
223 236 while (name[skip] != '\0' && name[skip] != '.' && name[skip] != '-')
224 237 skip++;
225 238
226 239 ret = get_expression_from_base_and_str(base, name + skip);
227 240 if (ret) {
228 241 char *new = expr_to_str(ret);
229 242
230 243 /*
231 244 * FIXME: this sometimes changes "foo->bar.a.b->c" into
232 245 * "foo->bar.a.b.c". I don't know why... :(
233 246 *
234 247 */
235 248 if (!new || strcmp(name, new) != 0)
236 249 return NULL;
237 250 }
238 251 return ret;
239 252 }
240 253
241 254 struct expression *gen_expression_from_key(struct expression *arg, const char *key)
242 255 {
243 256 struct expression *ret;
244 257 struct token *token, *prev, *end;
245 258 const char *p = key;
246 259 char buf[4095];
247 260 char *alloc;
248 261 size_t len;
249 262
250 263 /* The idea is that we can parse either $0->foo or $->foo */
251 264 if (key[0] != '$')
252 265 return NULL;
253 266 p++;
254 267 while (*p >= '0' && *p <= '9')
255 268 p++;
256 269 len = snprintf(buf, sizeof(buf), "%s\n", p);
257 270 alloc = alloc_string(buf);
258 271
259 272 token = tokenize_buffer(alloc, len, &end);
260 273 if (!token)
261 274 return NULL;
262 275 if (token_type(token) != TOKEN_STREAMBEGIN)
263 276 return NULL;
264 277 token = token->next;
265 278
266 279 ret = arg;
267 280 while (token_type(token) == TOKEN_SPECIAL &&
268 281 (token->special == SPECIAL_DEREFERENCE || token->special == '.')) {
269 282 prev = token;
270 283 token = token->next;
271 284 if (token_type(token) != TOKEN_IDENT)
272 285 return NULL;
273 286 ret = deref_expression(ret);
274 287 ret = member_expression(ret,
275 288 (prev->special == SPECIAL_DEREFERENCE) ? '*' : '.',
276 289 token->ident);
277 290 token = token->next;
278 291 }
279 292
280 293 if (token_type(token) != TOKEN_STREAMEND)
281 294 return NULL;
282 295
283 296 return ret;
284 297 }
285 298
286 299 void expr_set_parent_expr(struct expression *expr, struct expression *parent)
287 300 {
288 301 if (!expr)
289 302 return;
290 303 if (parent->smatch_flags & Fake)
291 304 return;
292 305
293 306 expr->parent = (unsigned long)parent | 0x1UL;
294 307 }
295 308
296 309 void expr_set_parent_stmt(struct expression *expr, struct statement *parent)
297 310 {
298 311 if (!expr)
299 312 return;
300 313 expr->parent = (unsigned long)parent;
301 314 }
302 315
303 316 struct expression *expr_get_parent_expr(struct expression *expr)
304 317 {
305 318 if (!expr)
306 319 return NULL;
307 320 if (!(expr->parent & 0x1UL))
308 321 return NULL;
309 322 return (struct expression *)(expr->parent & ~0x1UL);
310 323 }
311 324
312 325 struct statement *expr_get_parent_stmt(struct expression *expr)
313 326 {
314 327 if (!expr)
315 328 return NULL;
316 329 if (expr->parent & 0x1UL)
317 330 return NULL;
318 331 return (struct statement *)expr->parent;
319 332 }
320 333
↓ open down ↓ |
146 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX