2 * sparse/smatch_helper.c
4 * Copyright (C) 2006 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
11 * Miscellaneous helper functions.
22 char *alloc_string(const char *str
)
28 tmp
= malloc(strlen(str
) + 1);
33 void free_string(char *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
,
51 struct expression
*expr
;
57 FOR_EACH_PTR(args
, expr
) {
61 } END_FOR_EACH_PTR(expr
);
65 static void __get_variable_from_expr(struct symbol
**sym_ptr
, char *buf
,
66 struct expression
*expr
, int len
,
69 struct expression
*tmp
;
77 __get_variable_from_expr(sym_ptr
, buf
, tmp
, len
, complicated
);
81 append(buf
, "->", len
);
83 append(buf
, ".", len
);
85 append(buf
, expr
->member
->name
, len
);
89 if (expr
->symbol_name
)
90 append(buf
, expr
->symbol_name
->name
, len
);
94 *sym_ptr
= expr
->symbol
;
100 if (get_block_thing(expr
)) {
105 tmp
= show_special(expr
->op
);
106 append(buf
, tmp
, len
);
107 __get_variable_from_expr(sym_ptr
, buf
, expr
->unop
,
110 if (expr
->op
== '(') {
111 append(buf
, ")", len
);
114 if (expr
->op
== SPECIAL_DECREMENT
|| expr
->op
== SPECIAL_INCREMENT
)
122 __get_variable_from_expr(sym_ptr
, buf
, expr
->unop
,
124 tmp
= show_special(expr
->op
);
125 append(buf
, tmp
, len
);
127 if (expr
->op
== SPECIAL_DECREMENT
|| expr
->op
== SPECIAL_INCREMENT
)
135 append(buf
, "(", len
);
136 __get_variable_from_expr(NULL
, buf
, expr
->left
, len
,
138 tmp
= show_special(expr
->op
);
139 append(buf
, tmp
, len
);
140 __get_variable_from_expr(sym_ptr
, buf
, expr
->right
,
142 append(buf
, ")", len
);
148 snprintf(tmp
, 25, "%lld", expr
->value
);
149 append(buf
, tmp
, len
);
153 append(buf
, expr
->string
->data
, len
);
156 struct expression
*tmp
;
160 __get_variable_from_expr(NULL
, buf
, expr
->fn
, len
,
162 append(buf
, "(", len
);
164 FOR_EACH_PTR_REVERSE(expr
->args
, tmp
) {
166 append(buf
, ", ", len
);
167 __get_variable_from_expr(NULL
, buf
, tmp
, len
,
169 } END_FOR_EACH_PTR_REVERSE(tmp
);
170 append(buf
, ")", len
);
174 __get_variable_from_expr(sym_ptr
, buf
,
175 expr
->cast_expression
, len
,
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
);
191 //printf("unknown type = %d\n", expr->type);
198 * This is returns a stylized "c looking" representation of the
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
];
217 __get_variable_from_expr(sym_ptr
, var_name
, expr
, sizeof(var_name
),
220 return alloc_string(var_name
);
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
];
243 expr
= strip_expr(expr
);
244 __get_variable_from_expr(sym_ptr
, var_name
, expr
, sizeof(var_name
),
252 return alloc_string(var_name
);
255 int sym_name_is(const char *name
, struct expression
*expr
)
259 if (expr
->type
!= EXPR_SYMBOL
)
261 if (!strcmp(expr
->symbol_name
->name
, name
))
269 static int _get_value(struct expression
*expr
, int *discard
, int *undefined
, int implied
)
272 long long ret
= BOGUS
;
285 expr
= strip_expr(expr
);
292 if (expr
->op
== '-') {
293 ret
= - _get_value(expr
->unop
, discard
, undefined
, implied
);
302 left
= _get_value(expr
->left
, discard
, undefined
, implied
);
303 right
= _get_value(expr
->right
, discard
, undefined
, implied
);
304 if (expr
->op
== '*') {
306 } else if (expr
->op
== '/') {
308 } else if (expr
->op
== '+') {
310 } else if (expr
->op
== '-') {
312 } else if (expr
->op
== '|') {
314 } else if (expr
->op
== '&') {
316 } else if (expr
->op
== SPECIAL_RIGHTSHIFT
) {
318 } else if (expr
->op
== SPECIAL_LEFTSHIFT
) {
328 ret
= get_expression_value(expr
);
332 if (!get_implied_single_val(expr
, &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
)
353 *val
= _get_value(expr
, NULL
, &undefined
, NOTIMPLIED
);
359 int get_implied_value(struct expression
*expr
, long long *val
)
363 *val
= _get_value(expr
, NULL
, &undefined
, IMPLIED
);
367 int is_zero(struct expression
*expr
)
371 if (get_value(expr
, &val
) && val
== 0)
376 int is_array(struct expression
*expr
)
378 expr
= strip_expr(expr
);
379 if (expr
->type
!= EXPR_PREOP
|| expr
->op
!= '*')
387 struct expression
*get_array_name(struct expression
*expr
)
391 return expr
->unop
->left
;
394 struct expression
*get_array_offset(struct expression
*expr
)
398 return expr
->unop
->right
;
401 const char *show_state(struct smatch_state
*state
)
408 struct statement
*get_block_thing(struct expression
*expr
)
410 /* What are those things called? if (({....; ret;})) { ...*/
412 if (expr
->type
!= EXPR_PREOP
)
416 if (expr
->unop
->type
!= EXPR_STATEMENT
)
418 if (expr
->unop
->statement
->type
!= STMT_COMPOUND
)
420 return expr
->unop
->statement
;
423 struct expression
*strip_expr(struct expression
*expr
)
430 return strip_expr(expr
->cast_expression
);
432 if (expr
->op
== '(' && expr
->unop
->type
== EXPR_STATEMENT
&&
433 expr
->unop
->statement
->type
== STMT_COMPOUND
)
436 return strip_expr(expr
->unop
);
441 static void delete_state_tracker(struct tracker
*t
)
443 delete_state(t
->owner
, t
->name
, t
->sym
);
447 void scoped_state(int my_id
, const char *name
, struct symbol
*sym
)
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
;
462 if (cur_func
->type
!= SYM_NODE
)
464 cur_func
= get_base_type(cur_func
);
465 if (cur_func
->type
!= SYM_FN
)
467 cur_func
= get_base_type(cur_func
);
468 if (cur_func
== &void_ctype
)
470 if (!get_value(expr
, &val
))
474 if (cur_func
->type
== SYM_PTR
&& val
== 0)