dma_on_stack: &foo means it's an error too
[smatch.git] / smatch_helper.c
blob7ab2607a562ad45dbb3878dd98f1f200d9ef8e19
1 /*
2 * sparse/smatch_helper.c
4 * Copyright (C) 2006 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
11 * Miscellaneous helper functions.
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include "allocate.h"
17 #include "smatch.h"
19 #define VAR_LEN 512
20 #define BOGUS 12345
22 char *alloc_string(const char *str)
24 char *tmp;
26 if (!str)
27 return NULL;
28 tmp = malloc(strlen(str) + 1);
29 strcpy(tmp, str);
30 return tmp;
33 void free_string(char *str)
35 free(str);
38 static void append(char *dest, const char *data, int buff_len)
40 strncat(dest, data, buff_len - strlen(dest) - 1);
44 * If you have "foo(a, b, 1);" then use
45 * get_argument_from_call_expr(expr, 0) to return the expression for
46 * a. Yes, it does start counting from 0.
48 struct expression *get_argument_from_call_expr(struct expression_list *args,
49 int num)
51 struct expression *expr;
52 int i = 0;
54 if (!args)
55 return NULL;
57 FOR_EACH_PTR(args, expr) {
58 if (i == num)
59 return expr;
60 i++;
61 } END_FOR_EACH_PTR(expr);
62 return NULL;
65 static void __get_variable_from_expr(struct symbol **sym_ptr, char *buf,
66 struct expression *expr, int len,
67 int *complicated)
69 struct expression *tmp;
71 switch(expr->type) {
72 case EXPR_DEREF:
73 tmp = expr->deref;
74 if (tmp->op == '*') {
75 tmp = tmp->unop;
77 __get_variable_from_expr(sym_ptr, buf, tmp, len, complicated);
79 tmp = expr->deref;
80 if (tmp->op == '*') {
81 append(buf, "->", len);
82 } else {
83 append(buf, ".", len);
85 append(buf, expr->member->name, len);
87 return;
88 case EXPR_SYMBOL:
89 if (expr->symbol_name)
90 append(buf, expr->symbol_name->name, len);
91 if (sym_ptr) {
92 if (*sym_ptr)
93 *complicated = 1;
94 *sym_ptr = expr->symbol;
96 return;
97 case EXPR_PREOP: {
98 const char *tmp;
100 if (get_block_thing(expr)) {
101 *complicated = 2;
102 return;
105 tmp = show_special(expr->op);
106 append(buf, tmp, len);
107 __get_variable_from_expr(sym_ptr, buf, expr->unop,
108 len, complicated);
110 if (expr->op == '(') {
111 append(buf, ")", len);
114 if (expr->op == SPECIAL_DECREMENT || expr->op == SPECIAL_INCREMENT)
115 *complicated = 1;
117 return;
119 case EXPR_POSTOP: {
120 const char *tmp;
122 __get_variable_from_expr(sym_ptr, buf, expr->unop,
123 len, complicated);
124 tmp = show_special(expr->op);
125 append(buf, tmp, len);
127 if (expr->op == SPECIAL_DECREMENT || expr->op == SPECIAL_INCREMENT)
128 *complicated = 1;
129 return;
131 case EXPR_BINOP: {
132 const char *tmp;
134 *complicated = 1;
135 append(buf, "(", len);
136 __get_variable_from_expr(NULL, buf, expr->left, len,
137 complicated);
138 tmp = show_special(expr->op);
139 append(buf, tmp, len);
140 __get_variable_from_expr(sym_ptr, buf, expr->right,
141 len, complicated);
142 append(buf, ")", len);
143 return;
145 case EXPR_VALUE: {
146 char tmp[25];
148 snprintf(tmp, 25, "%lld", expr->value);
149 append(buf, tmp, len);
150 return;
152 case EXPR_STRING:
153 append(buf, expr->string->data, len);
154 return;
155 case EXPR_CALL: {
156 struct expression *tmp;
157 int i;
159 *complicated = 1;
160 __get_variable_from_expr(NULL, buf, expr->fn, len,
161 complicated);
162 append(buf, "(", len);
163 i = 0;
164 FOR_EACH_PTR_REVERSE(expr->args, tmp) {
165 if (i++)
166 append(buf, ", ", len);
167 __get_variable_from_expr(NULL, buf, tmp, len,
168 complicated);
169 } END_FOR_EACH_PTR_REVERSE(tmp);
170 append(buf, ")", len);
171 return;
173 case EXPR_CAST:
174 __get_variable_from_expr(sym_ptr, buf,
175 expr->cast_expression, len,
176 complicated);
177 return;
178 case EXPR_SIZEOF: {
179 int size;
180 char tmp[25];
182 if (expr->cast_type && get_base_type(expr->cast_type)) {
183 size = (get_base_type(expr->cast_type))->bit_size;
184 snprintf(tmp, 25, "%d", size);
185 append(buf, tmp, len);
187 return;
189 default:
190 *complicated = 1;
191 //printf("unknown type = %d\n", expr->type);
192 return;
198 * This is returns a stylized "c looking" representation of the
199 * variable name.
201 * It uses the same buffer every time so you have to save the result
202 * yourself if you want to keep it.
206 char *get_variable_from_expr_complex(struct expression *expr, struct symbol **sym_ptr)
208 static char var_name[VAR_LEN];
209 int complicated = 0;
211 if (sym_ptr)
212 *sym_ptr = NULL;
213 var_name[0] = '\0';
215 if (!expr)
216 return NULL;
217 __get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name),
218 &complicated);
219 if (complicated < 2)
220 return alloc_string(var_name);
221 else
222 return NULL;
226 * get_variable_from_expr_simple() only returns simple variables.
227 * If it's a complicated variable like a->foo instead of just 'a'
228 * then it returns NULL.
231 char *get_variable_from_expr(struct expression *expr,
232 struct symbol **sym_ptr)
234 static char var_name[VAR_LEN];
235 int complicated = 0;
237 if (sym_ptr)
238 *sym_ptr = NULL;
239 var_name[0] = '\0';
241 if (!expr)
242 return NULL;
243 expr = strip_expr(expr);
244 __get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name),
245 &complicated);
247 if (complicated) {
248 if (sym_ptr)
249 *sym_ptr = NULL;
250 return NULL;
252 return alloc_string(var_name);
255 int sym_name_is(const char *name, struct expression *expr)
257 if (!expr)
258 return 0;
259 if (expr->type != EXPR_SYMBOL)
260 return 0;
261 if (!strcmp(expr->symbol_name->name, name))
262 return 1;
263 return 0;
266 #define NOTIMPLIED 0
267 #define IMPLIED 1
269 static int _get_value(struct expression *expr, int *discard, int *undefined, int implied)
271 int dis = 0;
272 long long ret = BOGUS;
274 if (!expr) {
275 *undefined = 1;
276 return BOGUS;
278 if (!discard)
279 discard = &dis;
280 if (*discard) {
281 *undefined = 1;
282 return BOGUS;
285 expr = strip_expr(expr);
287 switch (expr->type){
288 case EXPR_VALUE:
289 ret = expr->value;
290 break;
291 case EXPR_PREOP:
292 if (expr->op == '-') {
293 ret = - _get_value(expr->unop, discard, undefined, implied);
294 } else {
295 *undefined = 1;
296 *discard = 1;
298 break;
299 case EXPR_BINOP: {
300 int left, right;
302 left = _get_value(expr->left, discard, undefined, implied);
303 right = _get_value(expr->right, discard, undefined, implied);
304 if (expr->op == '*') {
305 ret = left * right;
306 } else if (expr->op == '/') {
307 ret = left / right;
308 } else if (expr->op == '+') {
309 ret = left + right;
310 } else if (expr->op == '-') {
311 ret = left - right;
312 } else if (expr->op == '|') {
313 ret = left | right;
314 } else if (expr->op == '&') {
315 ret = left & right;
316 } else if (expr->op == SPECIAL_RIGHTSHIFT) {
317 ret = left >> right;
318 } else if (expr->op == SPECIAL_LEFTSHIFT) {
319 ret = left << right;
320 } else {
321 *undefined = 1;
322 *discard = 1;
324 break;
326 case EXPR_PTRSIZEOF:
327 case EXPR_SIZEOF:
328 ret = get_expression_value(expr);
329 break;
330 default:
331 if (implied) {
332 if (!get_implied_single_val(expr, &ret)) {
333 *undefined = 1;
334 *discard = 1;
336 } else {
337 *undefined = 1;
338 *discard = 1;
341 if (*discard) {
342 *undefined = 1;
343 return BOGUS;
345 return ret;
348 /* returns 1 if it can get a value literal or else returns 0 */
349 int get_value(struct expression *expr, long long *val)
351 int undefined = 0;
353 *val = _get_value(expr, NULL, &undefined, NOTIMPLIED);
354 if (undefined)
355 return 0;
356 return 1;
359 int get_implied_value(struct expression *expr, long long *val)
361 int undefined = 0;
363 *val = _get_value(expr, NULL, &undefined, IMPLIED);
364 return !undefined;
367 int is_zero(struct expression *expr)
369 long long val;
371 if (get_value(expr, &val) && val == 0)
372 return 1;
373 return 0;
376 int is_array(struct expression *expr)
378 expr = strip_expr(expr);
379 if (expr->type != EXPR_PREOP || expr->op != '*')
380 return 0;
381 expr = expr->unop;
382 if (expr->op != '+')
383 return 0;
384 return 1;
387 struct expression *get_array_name(struct expression *expr)
389 if (!is_array(expr))
390 return NULL;
391 return expr->unop->left;
394 struct expression *get_array_offset(struct expression *expr)
396 if (!is_array(expr))
397 return NULL;
398 return expr->unop->right;
401 const char *show_state(struct smatch_state *state)
403 if (!state)
404 return NULL;
405 return state->name;
408 struct statement *get_block_thing(struct expression *expr)
410 /* What are those things called? if (({....; ret;})) { ...*/
412 if (expr->type != EXPR_PREOP)
413 return NULL;
414 if (expr->op != '(')
415 return NULL;
416 if (expr->unop->type != EXPR_STATEMENT)
417 return NULL;
418 if (expr->unop->statement->type != STMT_COMPOUND)
419 return NULL;
420 return expr->unop->statement;
423 struct expression *strip_expr(struct expression *expr)
425 if (!expr)
426 return NULL;
428 switch(expr->type) {
429 case EXPR_CAST:
430 return strip_expr(expr->cast_expression);
431 case EXPR_PREOP:
432 if (expr->op == '(' && expr->unop->type == EXPR_STATEMENT &&
433 expr->unop->statement->type == STMT_COMPOUND)
434 return expr;
435 if (expr->op == '(')
436 return strip_expr(expr->unop);
438 return expr;
441 static void delete_state_tracker(struct tracker *t)
443 delete_state(t->owner, t->name, t->sym);
444 __free_tracker(t);
447 void scoped_state(int my_id, const char *name, struct symbol *sym)
449 struct tracker *t;
451 t = alloc_tracker(my_id, name, sym);
452 add_scope_hook((scope_hook *)&delete_state_tracker, t);
455 int is_error_return(struct expression *expr)
457 struct symbol *cur_func = cur_func_sym;
458 long long val;
460 if (!expr)
461 return 0;
462 if (cur_func->type != SYM_NODE)
463 return 0;
464 cur_func = get_base_type(cur_func);
465 if (cur_func->type != SYM_FN)
466 return 0;
467 cur_func = get_base_type(cur_func);
468 if (cur_func == &void_ctype)
469 return 0;
470 if (!get_value(expr, &val))
471 return 0;
472 if (val < 0)
473 return 1;
474 if (cur_func->type == SYM_PTR && val == 0)
475 return 1;
476 return 0;