[patch 6/many] remove UNDEFINED from last_stmt_val()
[smatch.git] / smatch_helper.c
blob9c6b6858b624e18f96ada2d17e4ab55872c90b9d
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 (!strcmp(show_special(tmp->op), "*")) {
75 tmp = tmp->unop;
77 __get_variable_from_expr(sym_ptr, buf, tmp, len, complicated);
79 tmp = expr->deref;
80 if (!strcmp(show_special(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;
106 tmp = show_special(expr->op);
107 append(buf, tmp, len);
108 __get_variable_from_expr(sym_ptr, buf, expr->unop,
109 len, complicated);
111 if (tmp[0] == '(') {
112 append(buf, ")", len);
115 if ((!strcmp(tmp, "--")) || (!strcmp(tmp, "++")))
116 *complicated = 1;
118 return;
120 case EXPR_POSTOP: {
121 const char *tmp;
123 __get_variable_from_expr(sym_ptr, buf, expr->unop,
124 len, complicated);
125 tmp = show_special(expr->op);
126 append(buf, tmp, len);
128 if ((!strcmp(tmp, "--")) || (!strcmp(tmp, "++")))
129 *complicated = 1;
131 return;
133 case EXPR_BINOP: {
134 const char *tmp;
136 *complicated = 1;
137 append(buf, "(", len);
138 __get_variable_from_expr(NULL, buf, expr->left, len,
139 complicated);
140 tmp = show_special(expr->op);
141 append(buf, tmp, len);
142 __get_variable_from_expr(sym_ptr, buf, expr->right,
143 len, complicated);
144 append(buf, ")", len);
145 return;
147 case EXPR_VALUE: {
148 char tmp[25];
150 snprintf(tmp, 25, "%lld", expr->value);
151 append(buf, tmp, len);
152 return;
154 case EXPR_STRING:
155 append(buf, expr->string->data, len);
156 return;
157 case EXPR_CALL: {
158 struct expression *tmp;
159 int i;
161 *complicated = 1;
162 __get_variable_from_expr(NULL, buf, expr->fn, len,
163 complicated);
164 append(buf, "(", len);
165 i = 0;
166 FOR_EACH_PTR_REVERSE(expr->args, tmp) {
167 if (i++)
168 append(buf, ", ", len);
169 __get_variable_from_expr(NULL, buf, tmp, len,
170 complicated);
171 } END_FOR_EACH_PTR_REVERSE(tmp);
172 append(buf, ")", len);
173 return;
175 case EXPR_CAST:
176 __get_variable_from_expr(sym_ptr, buf,
177 expr->cast_expression, len,
178 complicated);
179 return;
180 case EXPR_SIZEOF: {
181 int size;
182 char tmp[25];
184 if (expr->cast_type && get_base_type(expr->cast_type)) {
185 size = (get_base_type(expr->cast_type))->bit_size;
186 snprintf(tmp, 25, "%d", size);
187 append(buf, tmp, len);
189 return;
191 default:
192 *complicated = 1;
193 //printf("unknown type = %d\n", expr->type);
194 return;
200 * This is returns a stylized "c looking" representation of the
201 * variable name.
203 * It uses the same buffer every time so you have to save the result
204 * yourself if you want to keep it.
208 char *get_variable_from_expr_complex(struct expression *expr, struct symbol **sym_ptr)
210 static char var_name[VAR_LEN];
211 int complicated = 0;
213 if (sym_ptr)
214 *sym_ptr = NULL;
215 var_name[0] = '\0';
217 if (!expr)
218 return NULL;
219 __get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name),
220 &complicated);
221 if (complicated < 2)
222 return alloc_string(var_name);
223 else
224 return NULL;
228 * get_variable_from_expr_simple() only returns simple variables.
229 * If it's a complicated variable like a->foo instead of just 'a'
230 * then it returns NULL.
233 char *get_variable_from_expr(struct expression *expr,
234 struct symbol **sym_ptr)
236 static char var_name[VAR_LEN];
237 int complicated = 0;
239 if (sym_ptr)
240 *sym_ptr = NULL;
241 var_name[0] = '\0';
243 if (!expr)
244 return NULL;
245 expr = strip_expr(expr);
246 __get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name),
247 &complicated);
249 if (complicated) {
250 if (sym_ptr)
251 *sym_ptr = NULL;
252 return NULL;
254 return alloc_string(var_name);
257 struct symbol *get_ptr_type_ptr(struct symbol *sym)
259 if (!sym) {
260 return NULL;
263 if (sym->type != SYM_NODE)
264 return NULL;
265 sym = get_base_type(sym);
266 if (sym->type != SYM_PTR)
267 return NULL;
268 sym = get_base_type(sym);
269 return sym;
272 static struct symbol *get_struct_sym(struct expression *expr)
274 struct symbol *base_type;
275 struct symbol *parent_struct;
276 struct symbol *tmp;
278 if (expr->type != EXPR_PREOP)
279 return NULL;
281 expr = expr->unop;
282 if (expr->type == EXPR_DEREF) {
283 parent_struct = get_struct_sym(expr->deref);
284 if (!parent_struct)
285 return NULL;
286 tmp = NULL;
287 FOR_EACH_PTR(parent_struct->symbol_list, tmp) {
288 if (tmp->ident == expr->member)
289 break;
290 } END_FOR_EACH_PTR(tmp);
291 if (!tmp || tmp->ident != expr->member)
292 return NULL;
293 base_type = get_base_type(tmp);
294 } else if (expr->type == EXPR_SYMBOL) {
295 base_type = get_base_type(expr->symbol);
296 } else {
297 return NULL;
299 if (base_type->type != SYM_PTR)
300 return NULL;
301 base_type = get_base_type(base_type);
302 if (base_type->type != SYM_STRUCT && base_type->type != SYM_UNION)
303 return NULL;
304 return base_type;
307 struct symbol *get_deref_type(struct expression *expr)
309 struct ident *member = expr->member;
310 struct symbol *struct_sym;
311 struct symbol *tmp;
313 struct_sym = get_struct_sym(expr->deref);
314 if (!struct_sym || (struct_sym->type != SYM_STRUCT
315 && struct_sym->type != SYM_UNION))
316 return NULL;
317 FOR_EACH_PTR(struct_sym->symbol_list, tmp) {
318 if (tmp->ident == member)
319 return get_ptr_type_ptr(tmp);
320 } END_FOR_EACH_PTR(tmp);
321 return NULL;
324 struct symbol *get_ptr_type(struct expression *expr)
326 struct symbol *ptr_type = NULL;
328 if (!expr)
329 return NULL;
330 if (expr->type == EXPR_DEREF)
331 ptr_type = get_deref_type(expr);
332 if (expr->type == EXPR_SYMBOL)
333 ptr_type = get_ptr_type_ptr(expr->symbol);
334 return ptr_type;
337 int sym_name_is(const char *name, struct expression *expr)
339 if (!expr)
340 return 0;
341 if (expr->type != EXPR_SYMBOL)
342 return 0;
343 if (!strcmp(expr->symbol_name->name, name))
344 return 1;
345 return 0;
348 #define NOTIMPLIED 0
349 #define IMPLIED 1
351 static int _get_value(struct expression *expr, int *discard, int *undefined, int implied)
353 int dis = 0;
354 long long ret = BOGUS;
356 if (!expr) {
357 *undefined = 1;
358 return BOGUS;
360 if (!discard)
361 discard = &dis;
362 if (*discard) {
363 *undefined = 1;
364 return BOGUS;
367 expr = strip_expr(expr);
369 switch (expr->type){
370 case EXPR_VALUE:
371 ret = expr->value;
372 break;
373 case EXPR_PREOP:
374 if (!strcmp("-", show_special(expr->op))) {
375 ret = - _get_value(expr->unop, discard, undefined, implied);
376 } else {
377 *undefined = 1;
378 *discard = 1;
380 break;
381 case EXPR_BINOP: {
382 int left, right;
384 if (!show_special(expr->op)) {
385 *undefined = 1;
386 *discard = 1;
387 break;
389 left = _get_value(expr->left, discard, undefined, implied);
390 right = _get_value(expr->right, discard, undefined, implied);
391 if (!strcmp("*", show_special(expr->op))) {
392 ret = left * right;
393 } else if (!strcmp("/", show_special(expr->op))) {
394 ret = left / right;
395 } else if (!strcmp("+", show_special(expr->op))) {
396 ret = left + right;
397 } else if (!strcmp("-", show_special(expr->op))) {
398 ret = left - right;
399 } else if (!strcmp("|", show_special(expr->op))) {
400 ret = left | right;
401 } else if (!strcmp("&", show_special(expr->op))) {
402 ret = left & right;
403 } else if (!strcmp(">>", show_special(expr->op))) {
404 ret = left >> right;
405 } else if (!strcmp("<<", show_special(expr->op))) {
406 ret = left << right;
407 } else {
408 *undefined = 1;
409 *discard = 1;
411 break;
413 case EXPR_PTRSIZEOF:
414 case EXPR_SIZEOF:
415 ret = get_expression_value(expr);
416 break;
417 default:
418 if (implied) {
419 if (!get_implied_single_val(expr, &ret)) {
420 *undefined = 1;
421 *discard = 1;
423 } else {
424 *undefined = 1;
425 *discard = 1;
428 if (*discard) {
429 *undefined = 1;
430 return BOGUS;
432 return ret;
435 /* returns UNDEFINED on error */
436 int get_value(struct expression *expr)
438 int undefined = 0;
439 int ret;
441 ret = _get_value(expr, NULL, &undefined, NOTIMPLIED);
442 if (undefined)
443 return UNDEFINED;
444 else
445 return ret;
448 int get_implied_value(struct expression *expr, long long *val)
450 int undefined = 0;
452 *val = _get_value(expr, NULL, &undefined, IMPLIED);
453 return !undefined;
456 int is_zero(struct expression *expr)
458 if (get_value(expr) == 0)
459 return 1;
460 return 0;
463 int is_array(struct expression *expr)
465 expr = strip_expr(expr);
466 if (expr->type != EXPR_PREOP || strcmp(show_special(expr->op), "*"))
467 return 0;
468 expr = expr->unop;
469 if (strcmp(show_special(expr->op), "+"))
470 return 0;
471 return 1;
474 struct expression *get_array_name(struct expression *expr)
476 if (!is_array(expr))
477 return NULL;
478 return expr->unop->left;
481 struct expression *get_array_offset(struct expression *expr)
483 if (!is_array(expr))
484 return NULL;
485 return expr->unop->right;
488 const char *show_state(struct smatch_state *state)
490 if (!state)
491 return NULL;
492 return state->name;
495 struct statement *get_block_thing(struct expression *expr)
497 /* What are those things called? if (({....; ret;})) { ...*/
499 if (expr->type != EXPR_PREOP)
500 return NULL;
501 if (expr->op != '(')
502 return NULL;
503 if (expr->unop->type != EXPR_STATEMENT)
504 return NULL;
505 if (expr->unop->statement->type != STMT_COMPOUND)
506 return NULL;
507 return expr->unop->statement;
510 struct expression *strip_expr(struct expression *expr)
512 if (!expr)
513 return NULL;
515 switch(expr->type) {
516 case EXPR_CAST:
517 return strip_expr(expr->cast_expression);
518 case EXPR_PREOP:
519 if (expr->op == '(' && expr->unop->type == EXPR_STATEMENT &&
520 expr->unop->statement->type == STMT_COMPOUND)
521 return expr;
522 if (expr->op == '(')
523 return strip_expr(expr->unop);
525 return expr;
528 static void delete_state_tracker(struct tracker *t)
530 delete_state(t->owner, t->name, t->sym);
531 __free_tracker(t);
534 void scoped_state(const char *name, int my_id, struct symbol *sym)
536 struct tracker *t;
538 t = alloc_tracker(my_id, name, sym);
539 add_scope_hook((scope_hook *)&delete_state_tracker, t);
542 int is_error_return(struct expression *expr)
544 struct symbol *cur_func = cur_func_sym;
545 int val;
547 if (!expr)
548 return 0;
549 if (cur_func->type != SYM_NODE)
550 return 0;
551 cur_func = get_base_type(cur_func);
552 if (cur_func->type != SYM_FN)
553 return 0;
554 cur_func = get_base_type(cur_func);
555 if (cur_func == &void_ctype)
556 return 0;
557 val = get_value(expr);
558 if (val == UNDEFINED)
559 return 0;
560 if (val < 0)
561 return 1;
562 if (cur_func->type == SYM_PTR && val == 0)
563 return 1;
564 return 0;