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