2 * Copyright (C) 2006 Dan Carpenter.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
19 * Miscellaneous helper functions.
26 #include "smatch_extra.h"
30 char *alloc_string(const char *str
)
36 tmp
= malloc(strlen(str
) + 1);
41 void free_string(char *str
)
46 void remove_parens(char *str
)
51 while (*src
!= '\0') {
52 if (*src
== '(' || *src
== ')') {
61 struct smatch_state
*alloc_state_num(int num
)
63 struct smatch_state
*state
;
64 static char buff
[256];
66 state
= __alloc_smatch_state(0);
67 snprintf(buff
, 255, "%d", num
);
69 state
->name
= alloc_string(buff
);
70 state
->data
= INT_PTR(num
);
74 struct smatch_state
*alloc_state_str(const char *name
)
76 struct smatch_state
*state
;
78 state
= __alloc_smatch_state(0);
79 state
->name
= alloc_string(name
);
83 void append(char *dest
, const char *data
, int buff_len
)
85 strncat(dest
, data
, buff_len
- strlen(dest
) - 1);
89 * If you have "foo(a, b, 1);" then use
90 * get_argument_from_call_expr(expr, 0) to return the expression for
91 * a. Yes, it does start counting from 0.
93 struct expression
*get_argument_from_call_expr(struct expression_list
*args
,
96 struct expression
*expr
;
102 FOR_EACH_PTR(args
, expr
) {
106 } END_FOR_EACH_PTR(expr
);
110 static struct expression
*get_array_expr(struct expression
*expr
)
114 if (expr
->type
!= EXPR_BINOP
|| expr
->op
!= '+')
117 type
= get_type(expr
->left
);
118 if (!type
|| type
->type
!= SYM_ARRAY
)
123 static void __get_variable_from_expr(struct symbol
**sym_ptr
, char *buf
,
124 struct expression
*expr
, int len
,
125 int *complicated
, int no_parens
)
127 switch (expr
->type
) {
129 struct expression
*deref
;
135 struct expression
*unop
= strip_expr(deref
->unop
);
137 if (unop
->type
== EXPR_PREOP
&& unop
->op
== '&') {
145 __get_variable_from_expr(sym_ptr
, buf
, deref
, len
, complicated
, no_parens
);
148 append(buf
, "->", len
);
150 append(buf
, ".", len
);
153 append(buf
, expr
->member
->name
, len
);
155 append(buf
, "unknown_member", len
);
160 if (expr
->symbol_name
)
161 append(buf
, expr
->symbol_name
->name
, len
);
165 *sym_ptr
= expr
->symbol
;
171 if (get_expression_statement(expr
)) {
176 if (expr
->op
== '(') {
178 append(buf
, "(", len
);
179 } else if (expr
->op
!= '*' || !get_array_expr(expr
->unop
)) {
180 tmp
= show_special(expr
->op
);
181 append(buf
, tmp
, len
);
183 __get_variable_from_expr(sym_ptr
, buf
, expr
->unop
,
184 len
, complicated
, no_parens
);
186 if (expr
->op
== '(' && !no_parens
)
187 append(buf
, ")", len
);
189 if (expr
->op
== SPECIAL_DECREMENT
||
190 expr
->op
== SPECIAL_INCREMENT
)
198 __get_variable_from_expr(sym_ptr
, buf
, expr
->unop
,
199 len
, complicated
, no_parens
);
200 tmp
= show_special(expr
->op
);
201 append(buf
, tmp
, len
);
203 if (expr
->op
== SPECIAL_DECREMENT
|| expr
->op
== SPECIAL_INCREMENT
)
207 case EXPR_ASSIGNMENT
:
212 struct expression
*array_expr
;
215 array_expr
= get_array_expr(expr
);
217 __get_variable_from_expr(sym_ptr
, buf
, array_expr
, len
, complicated
, no_parens
);
218 append(buf
, "[", len
);
220 __get_variable_from_expr(sym_ptr
, buf
, expr
->left
, len
, complicated
, no_parens
);
221 snprintf(tmp
, sizeof(tmp
), " %s ", show_special(expr
->op
));
222 append(buf
, tmp
, len
);
224 __get_variable_from_expr(NULL
, buf
, expr
->right
, len
, complicated
, no_parens
);
226 append(buf
, "]", len
);
233 snprintf(tmp
, 25, "%lld", expr
->value
);
234 append(buf
, tmp
, len
);
238 append(buf
, "\"", len
);
240 append(buf
, expr
->string
->data
, len
);
241 append(buf
, "\"", len
);
244 struct expression
*tmp
;
248 __get_variable_from_expr(NULL
, buf
, expr
->fn
, len
, complicated
, no_parens
);
249 append(buf
, "(", len
);
251 FOR_EACH_PTR(expr
->args
, tmp
) {
253 append(buf
, ", ", len
);
254 __get_variable_from_expr(NULL
, buf
, tmp
, len
, complicated
, no_parens
);
255 } END_FOR_EACH_PTR(tmp
);
256 append(buf
, ")", len
);
260 case EXPR_FORCE_CAST
:
261 __get_variable_from_expr(sym_ptr
, buf
,
262 expr
->cast_expression
, len
,
263 complicated
, no_parens
);
269 if (expr
->cast_type
&& get_base_type(expr
->cast_type
)) {
270 size
= type_bytes(get_base_type(expr
->cast_type
));
271 snprintf(tmp
, 25, "%d", size
);
272 append(buf
, tmp
, len
);
276 case EXPR_IDENTIFIER
:
278 if (expr
->expr_ident
)
279 append(buf
, expr
->expr_ident
->name
, len
);
283 //printf("unknown type = %d\n", expr->type);
289 * This is returns a stylized "c looking" representation of the
292 * It uses the same buffer every time so you have to save the result
293 * yourself if you want to keep it.
297 char *expr_to_str_sym(struct expression
*expr
, struct symbol
**sym_ptr
)
299 static char var_name
[VAR_LEN
];
308 __get_variable_from_expr(sym_ptr
, var_name
, expr
, sizeof(var_name
),
311 return alloc_string(var_name
);
316 char *expr_to_str(struct expression
*expr
)
318 return expr_to_str_sym(expr
, NULL
);
322 * get_variable_from_expr_simple() only returns simple variables.
323 * If it's a complicated variable like a->foo[x] instead of just 'a->foo'
324 * then it returns NULL.
326 char *expr_to_var_sym(struct expression
*expr
,
327 struct symbol
**sym_ptr
)
329 static char var_name
[VAR_LEN
];
338 expr
= strip_expr(expr
);
339 __get_variable_from_expr(sym_ptr
, var_name
, expr
, sizeof(var_name
),
347 return alloc_string(var_name
);
350 char *expr_to_var(struct expression
*expr
)
352 return expr_to_var_sym(expr
, NULL
);
355 struct symbol
*expr_to_sym(struct expression
*expr
)
360 name
= expr_to_var_sym(expr
, &sym
);
365 char *expr_to_chunk_helper(struct expression
*expr
, struct symbol
**sym
, struct var_sym_list
**vsl
)
367 char *name
, *left_name
, *right_name
;
368 struct symbol
*tmp
, *left_sym
, *right_sym
;
374 expr
= strip_parens(expr
);
380 name
= expr_to_var_sym(expr
, &tmp
);
385 *vsl
= expr_to_vsl(expr
);
390 if (expr
->type
!= EXPR_BINOP
)
392 if (expr
->op
!= '-' && expr
->op
!= '+')
396 *vsl
= expr_to_vsl(expr
);
401 left_name
= expr_to_var_sym(expr
->left
, &left_sym
);
402 if (!left_name
|| !left_sym
)
404 right_name
= expr_to_var_sym(expr
->right
, &right_sym
);
405 if (!right_name
|| !right_sym
) {
406 free_string(left_name
);
410 if (expr
->op
== '+') {
411 if (strcmp(left_name
, right_name
) > 0) {
415 left_sym
= right_sym
;
418 tmp_name
= left_name
;
419 left_name
= right_name
;
420 right_name
= tmp_name
;
424 snprintf(buf
, sizeof(buf
), "%s %s %s", left_name
, show_special(expr
->op
), right_name
);
426 free_string(left_name
);
427 free_string(right_name
);
428 return alloc_string(buf
);
431 char *expr_to_known_chunk_sym(struct expression
*expr
, struct symbol
**sym
)
433 return expr_to_chunk_helper(expr
, sym
, NULL
);
436 char *expr_to_chunk_sym_vsl(struct expression
*expr
, struct symbol
**sym
, struct var_sym_list
**vsl
)
438 return expr_to_chunk_helper(expr
, sym
, vsl
);
441 int sym_name_is(const char *name
, struct expression
*expr
)
445 if (expr
->type
!= EXPR_SYMBOL
)
447 if (!strcmp(expr
->symbol_name
->name
, name
))
452 int is_zero(struct expression
*expr
)
456 if (get_value(expr
, &sval
) && sval
.value
== 0)
461 int is_array(struct expression
*expr
)
465 expr
= strip_expr(expr
);
469 if (expr
->type
== EXPR_PREOP
&& expr
->op
== '*') {
470 expr
= strip_expr(expr
->unop
);
471 if (expr
->type
== EXPR_BINOP
&& expr
->op
== '+')
475 if (expr
->type
!= EXPR_BINOP
|| expr
->op
!= '+')
478 type
= get_type(expr
->left
);
479 if (!type
|| type
->type
!= SYM_ARRAY
)
485 struct expression
*get_array_base(struct expression
*expr
)
489 expr
= strip_expr(expr
);
490 if (expr
->type
== EXPR_PREOP
&& expr
->op
== '*')
491 expr
= strip_expr(expr
->unop
);
492 if (expr
->type
!= EXPR_BINOP
|| expr
->op
!= '+')
494 return strip_parens(expr
->left
);
497 struct expression
*get_array_offset(struct expression
*expr
)
501 expr
= strip_expr(expr
);
502 if (expr
->type
== EXPR_PREOP
&& expr
->op
== '*')
503 expr
= strip_expr(expr
->unop
);
504 if (expr
->type
!= EXPR_BINOP
|| expr
->op
!= '+')
506 return strip_parens(expr
->right
);
509 const char *show_state(struct smatch_state
*state
)
516 struct statement
*get_expression_statement(struct expression
*expr
)
518 /* What are those things called? if (({....; ret;})) { ...*/
520 if (expr
->type
!= EXPR_PREOP
)
524 if (expr
->unop
->type
!= EXPR_STATEMENT
)
526 if (expr
->unop
->statement
->type
!= STMT_COMPOUND
)
528 return expr
->unop
->statement
;
531 struct expression
*strip_parens(struct expression
*expr
)
536 if (expr
->type
== EXPR_PREOP
) {
537 if (expr
->op
== '(' && expr
->unop
->type
== EXPR_STATEMENT
&&
538 expr
->unop
->statement
->type
== STMT_COMPOUND
)
541 return strip_parens(expr
->unop
);
546 struct expression
*strip_expr(struct expression
*expr
)
551 switch (expr
->type
) {
552 case EXPR_FORCE_CAST
:
554 return strip_expr(expr
->cast_expression
);
556 struct expression
*unop
;
558 if (expr
->op
== '(' && expr
->unop
->type
== EXPR_STATEMENT
&&
559 expr
->unop
->statement
->type
== STMT_COMPOUND
)
562 unop
= strip_expr(expr
->unop
);
564 if (expr
->op
== '*' &&
565 unop
->type
== EXPR_PREOP
&& unop
->op
== '&') {
566 struct symbol
*type
= get_type(unop
->unop
);
568 if (type
&& type
->type
== SYM_ARRAY
)
570 return strip_expr(unop
->unop
);
578 case EXPR_CONDITIONAL
:
579 if (known_condition_true(expr
->conditional
)) {
581 return strip_expr(expr
->cond_true
);
582 return strip_expr(expr
->conditional
);
584 if (known_condition_false(expr
->conditional
))
585 return strip_expr(expr
->cond_false
);
588 if (sym_name_is("__builtin_expect", expr
->fn
)) {
589 expr
= get_argument_from_call_expr(expr
->args
, 0);
590 return strip_expr(expr
);
597 static void delete_state_tracker(struct tracker
*t
)
599 delete_state(t
->owner
, t
->name
, t
->sym
);
603 void scoped_state(int my_id
, const char *name
, struct symbol
*sym
)
607 t
= alloc_tracker(my_id
, name
, sym
);
608 add_scope_hook((scope_hook
*)&delete_state_tracker
, t
);
611 int is_error_return(struct expression
*expr
)
613 struct symbol
*cur_func
= cur_func_sym
;
618 if (cur_func
->type
!= SYM_NODE
)
620 cur_func
= get_base_type(cur_func
);
621 if (cur_func
->type
!= SYM_FN
)
623 cur_func
= get_base_type(cur_func
);
624 if (cur_func
== &void_ctype
)
626 if (!get_implied_value(expr
, &sval
))
630 if (cur_func
->type
== SYM_PTR
&& sval
.value
== 0)
635 int getting_address(void)
637 struct expression
*tmp
;
641 FOR_EACH_PTR_REVERSE(big_expression_stack
, tmp
) {
644 if (tmp
->type
== EXPR_PREOP
&& tmp
->op
== '(')
646 if (tmp
->op
== '.' && !dot_ops
++)
651 } END_FOR_EACH_PTR_REVERSE(tmp
);
655 char *get_member_name(struct expression
*expr
)
660 expr
= strip_expr(expr
);
661 if (expr
->type
!= EXPR_DEREF
)
666 sym
= get_type(expr
->deref
);
669 if (sym
->type
== SYM_UNION
) {
670 sym
= expr_to_sym(expr
->deref
);
671 sym
= get_real_base_type(sym
);
672 if (sym
&& sym
->type
== SYM_PTR
)
673 sym
= get_real_base_type(sym
);
674 if (!sym
|| !sym
->ident
) {
675 snprintf(buf
, sizeof(buf
), "(union hack)->%s", expr
->member
->name
);
676 return alloc_string(buf
);
681 snprintf(buf
, sizeof(buf
), "(struct %s)->%s", sym
->ident
->name
, expr
->member
->name
);
682 return alloc_string(buf
);
685 int cmp_pos(struct position pos1
, struct position pos2
)
687 /* the stream position is ... */
688 if (pos1
.stream
> pos2
.stream
)
690 if (pos1
.stream
< pos2
.stream
)
693 if (pos1
.line
< pos2
.line
)
695 if (pos1
.line
> pos2
.line
)
698 if (pos1
.pos
< pos2
.pos
)
700 if (pos1
.pos
> pos2
.pos
)
706 int positions_eq(struct position pos1
, struct position pos2
)
708 if (pos1
.line
!= pos2
.line
)
710 if (pos1
.pos
!= pos2
.pos
)
712 if (pos1
.stream
!= pos2
.stream
)
717 struct statement
*get_current_statement(void)
719 struct statement
*prev
, *tmp
;
721 prev
= last_ptr_list((struct ptr_list
*)big_statement_stack
);
723 if (!prev
|| !get_macro_name(prev
->pos
))
726 FOR_EACH_PTR_REVERSE(big_statement_stack
, tmp
) {
727 if (positions_eq(tmp
->pos
, prev
->pos
))
729 if (prev
->pos
.line
> tmp
->pos
.line
)
732 } END_FOR_EACH_PTR_REVERSE(tmp
);
736 struct statement
*get_prev_statement(void)
738 struct statement
*tmp
;
742 FOR_EACH_PTR_REVERSE(big_statement_stack
, tmp
) {
745 } END_FOR_EACH_PTR_REVERSE(tmp
);
749 int get_param_num_from_sym(struct symbol
*sym
)
758 FOR_EACH_PTR(cur_func_sym
->ctype
.base_type
->arguments
, tmp
) {
762 } END_FOR_EACH_PTR(tmp
);
766 int get_param_num(struct expression
*expr
)
773 name
= expr_to_var_sym(expr
, &sym
);
777 return get_param_num_from_sym(sym
);
780 int ms_since(struct timeval
*start
)
785 gettimeofday(&end
, NULL
);
786 diff
= (end
.tv_sec
- start
->tv_sec
) * 1000.0;
787 diff
+= (end
.tv_usec
- start
->tv_usec
) / 1000.0;
791 int parent_is_gone_var_sym(const char *name
, struct symbol
*sym
)
796 if (parent_is_null_var_sym(name
, sym
) ||
797 parent_is_free_var_sym(name
, sym
))
802 int parent_is_gone(struct expression
*expr
)
808 expr
= strip_expr(expr
);
809 var
= expr_to_var_sym(expr
, &sym
);
812 ret
= parent_is_gone_var_sym(var
, sym
);
818 int invert_op(int op
)
829 case SPECIAL_LEFTSHIFT
:
830 return SPECIAL_RIGHTSHIFT
;
831 case SPECIAL_RIGHTSHIFT
:
832 return SPECIAL_LEFTSHIFT
;