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 struct smatch_state
*alloc_state_num(int num
)
40 struct smatch_state
*state
;
41 static char buff
[256];
43 state
= __alloc_smatch_state(0);
44 snprintf(buff
, 255, "%d", num
);
46 state
->name
= alloc_string(buff
);
47 state
->data
= (void *)num
;
51 static void append(char *dest
, const char *data
, int buff_len
)
53 strncat(dest
, data
, buff_len
- strlen(dest
) - 1);
57 * If you have "foo(a, b, 1);" then use
58 * get_argument_from_call_expr(expr, 0) to return the expression for
59 * a. Yes, it does start counting from 0.
61 struct expression
*get_argument_from_call_expr(struct expression_list
*args
,
64 struct expression
*expr
;
70 FOR_EACH_PTR(args
, expr
) {
74 } END_FOR_EACH_PTR(expr
);
78 static struct expression
*get_array_expr(struct expression
*expr
)
82 if (expr
->type
!= EXPR_BINOP
|| expr
->op
!= '+')
85 type
= get_type(expr
->left
);
86 if (!type
|| type
->type
!= SYM_ARRAY
)
91 static void __get_variable_from_expr(struct symbol
**sym_ptr
, char *buf
,
92 struct expression
*expr
, int len
,
95 struct expression
*tmp
;
100 if (tmp
->op
== '*') {
103 __get_variable_from_expr(sym_ptr
, buf
, tmp
, len
, complicated
);
106 if (tmp
->op
== '*') {
107 append(buf
, "->", len
);
109 append(buf
, ".", len
);
111 append(buf
, expr
->member
->name
, len
);
115 if (expr
->symbol_name
)
116 append(buf
, expr
->symbol_name
->name
, len
);
120 *sym_ptr
= expr
->symbol
;
126 if (get_block_thing(expr
)) {
131 if (expr
->op
!= '*' || !get_array_expr(expr
->unop
)) {
132 tmp
= show_special(expr
->op
);
133 append(buf
, tmp
, len
);
135 __get_variable_from_expr(sym_ptr
, buf
, expr
->unop
,
138 if (expr
->op
== '(') {
139 append(buf
, ")", len
);
142 if (expr
->op
== SPECIAL_DECREMENT
|| expr
->op
== SPECIAL_INCREMENT
)
150 __get_variable_from_expr(sym_ptr
, buf
, expr
->unop
,
152 tmp
= show_special(expr
->op
);
153 append(buf
, tmp
, len
);
155 if (expr
->op
== SPECIAL_DECREMENT
|| expr
->op
== SPECIAL_INCREMENT
)
161 struct expression
*array_expr
;
164 array_expr
= get_array_expr(expr
);
166 __get_variable_from_expr(NULL
, buf
, array_expr
, len
, complicated
);
167 append(buf
, "[", len
);
169 append(buf
, "(", len
);
170 __get_variable_from_expr(NULL
, buf
, expr
->left
, len
,
172 tmp
= show_special(expr
->op
);
173 append(buf
, tmp
, len
);
175 __get_variable_from_expr(sym_ptr
, buf
, expr
->right
,
178 append(buf
, "]", len
);
180 append(buf
, ")", len
);
186 snprintf(tmp
, 25, "%lld", expr
->value
);
187 append(buf
, tmp
, len
);
191 append(buf
, "\"", len
);
192 append(buf
, expr
->string
->data
, len
);
193 append(buf
, "\"", len
);
196 struct expression
*tmp
;
200 __get_variable_from_expr(NULL
, buf
, expr
->fn
, len
,
202 append(buf
, "(", len
);
204 FOR_EACH_PTR_REVERSE(expr
->args
, tmp
) {
206 append(buf
, ", ", len
);
207 __get_variable_from_expr(NULL
, buf
, tmp
, len
,
209 } END_FOR_EACH_PTR_REVERSE(tmp
);
210 append(buf
, ")", len
);
214 __get_variable_from_expr(sym_ptr
, buf
,
215 expr
->cast_expression
, len
,
222 if (expr
->cast_type
&& get_base_type(expr
->cast_type
)) {
223 size
= (get_base_type(expr
->cast_type
))->bit_size
;
224 snprintf(tmp
, 25, "%d", size
);
225 append(buf
, tmp
, len
);
231 //printf("unknown type = %d\n", expr->type);
238 * This is returns a stylized "c looking" representation of the
241 * It uses the same buffer every time so you have to save the result
242 * yourself if you want to keep it.
246 char *get_variable_from_expr_complex(struct expression
*expr
, struct symbol
**sym_ptr
)
248 static char var_name
[VAR_LEN
];
257 __get_variable_from_expr(sym_ptr
, var_name
, expr
, sizeof(var_name
),
260 return alloc_string(var_name
);
266 * get_variable_from_expr_simple() only returns simple variables.
267 * If it's a complicated variable like a->foo instead of just 'a'
268 * then it returns NULL.
271 char *get_variable_from_expr(struct expression
*expr
,
272 struct symbol
**sym_ptr
)
274 static char var_name
[VAR_LEN
];
283 expr
= strip_expr(expr
);
284 __get_variable_from_expr(sym_ptr
, var_name
, expr
, sizeof(var_name
),
292 return alloc_string(var_name
);
295 int sym_name_is(const char *name
, struct expression
*expr
)
299 if (expr
->type
!= EXPR_SYMBOL
)
301 if (!strcmp(expr
->symbol_name
->name
, name
))
310 static long long _get_value(struct expression
*expr
, int *discard
, int *undefined
, int implied
)
313 long long ret
= BOGUS
;
326 expr
= strip_parens(expr
);
333 if (expr
->op
== '-') {
334 ret
= - _get_value(expr
->unop
, discard
, undefined
, implied
);
341 case EXPR_FORCE_CAST
:
342 case EXPR_IMPLIED_CAST
:
344 struct symbol
*type
= get_base_type(expr
->cast_type
);
346 ret
= _get_value(expr
->cast_expression
, discard
, undefined
, implied
);
347 switch (type
->bit_size
) {
349 if (type
->ctype
.modifiers
& MOD_UNSIGNED
)
350 ret
= (int)(unsigned char) ret
;
352 ret
= (int)(char) ret
;
355 if (type
->ctype
.modifiers
& MOD_UNSIGNED
)
356 ret
= (int)(unsigned short) ret
;
358 ret
= (int)(short) ret
;
361 if (type
->ctype
.modifiers
& MOD_UNSIGNED
)
362 ret
= (int)(unsigned int) ret
;
364 ret
= (int)(int) ret
;
372 left
= _get_value(expr
->left
, discard
, undefined
, implied
);
373 right
= _get_value(expr
->right
, discard
, undefined
, implied
);
374 if (expr
->op
== '*') {
376 } else if (expr
->op
== '/') {
378 } else if (expr
->op
== '+') {
380 } else if (expr
->op
== '-') {
382 } else if (expr
->op
== '|') {
384 } else if (expr
->op
== '&') {
386 } else if (expr
->op
== SPECIAL_RIGHTSHIFT
) {
388 } else if (expr
->op
== SPECIAL_LEFTSHIFT
) {
398 ret
= get_expression_value(expr
);
401 if (implied
== IMPLIED
) {
402 if (!get_implied_single_val(expr
, &ret
)) {
406 } else if (implied
== FUZZYMAX
) {
407 if (!get_implied_single_fuzzy_max(expr
, &ret
)) {
423 /* returns 1 if it can get a value literal or else returns 0 */
424 int get_value(struct expression
*expr
, long long *val
)
428 *val
= _get_value(expr
, NULL
, &undefined
, NOTIMPLIED
);
434 int get_implied_value(struct expression
*expr
, long long *val
)
438 *val
= _get_value(expr
, NULL
, &undefined
, IMPLIED
);
442 int get_fuzzy_max(struct expression
*expr
, long long *val
)
446 *val
= _get_value(expr
, NULL
, &undefined
, FUZZYMAX
);
450 int is_zero(struct expression
*expr
)
454 if (get_value(expr
, &val
) && val
== 0)
459 int is_array(struct expression
*expr
)
461 expr
= strip_expr(expr
);
462 if (expr
->type
!= EXPR_PREOP
|| expr
->op
!= '*')
470 struct expression
*get_array_name(struct expression
*expr
)
474 return strip_expr(expr
->unop
->left
);
477 struct expression
*get_array_offset(struct expression
*expr
)
481 return expr
->unop
->right
;
484 const char *show_state(struct smatch_state
*state
)
491 struct statement
*get_block_thing(struct expression
*expr
)
493 /* What are those things called? if (({....; ret;})) { ...*/
495 if (expr
->type
!= EXPR_PREOP
)
499 if (expr
->unop
->type
!= EXPR_STATEMENT
)
501 if (expr
->unop
->statement
->type
!= STMT_COMPOUND
)
503 return expr
->unop
->statement
;
506 struct expression
*strip_parens(struct expression
*expr
)
511 if (expr
->type
== EXPR_PREOP
) {
512 if (expr
->op
== '(' && expr
->unop
->type
== EXPR_STATEMENT
&&
513 expr
->unop
->statement
->type
== STMT_COMPOUND
)
516 return strip_parens(expr
->unop
);
521 struct expression
*strip_expr(struct expression
*expr
)
526 switch (expr
->type
) {
528 return strip_expr(expr
->cast_expression
);
530 if (expr
->op
== '(' && expr
->unop
->type
== EXPR_STATEMENT
&&
531 expr
->unop
->statement
->type
== STMT_COMPOUND
)
534 return strip_expr(expr
->unop
);
539 static void delete_state_tracker(struct tracker
*t
)
541 delete_state(t
->owner
, t
->name
, t
->sym
);
545 void scoped_state(int my_id
, const char *name
, struct symbol
*sym
)
549 t
= alloc_tracker(my_id
, name
, sym
);
550 add_scope_hook((scope_hook
*)&delete_state_tracker
, t
);
553 int is_error_return(struct expression
*expr
)
555 struct symbol
*cur_func
= cur_func_sym
;
560 if (cur_func
->type
!= SYM_NODE
)
562 cur_func
= get_base_type(cur_func
);
563 if (cur_func
->type
!= SYM_FN
)
565 cur_func
= get_base_type(cur_func
);
566 if (cur_func
== &void_ctype
)
568 if (!get_value(expr
, &val
))
572 if (cur_func
->type
== SYM_PTR
&& val
== 0)
577 int getting_address(void)
579 struct expression
*tmp
;
583 FOR_EACH_PTR_REVERSE(big_expression_stack
, tmp
) {
586 if (tmp
->type
== EXPR_PREOP
&& tmp
->op
== '(')
588 if (tmp
->op
== '.' && !dot_ops
++)
593 } END_FOR_EACH_PTR_REVERSE(tmp
);