2 * Copyright (C) 2012 Oracle.
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 #include "smatch_extra.h"
20 #include "smatch_slist.h"
26 static int expr_equiv(struct expression
*one
, struct expression
*two
)
28 struct symbol
*one_sym
, *two_sym
;
29 char *one_name
= NULL
;
30 char *two_name
= NULL
;
35 if (one
->type
!= two
->type
)
38 one_name
= expr_to_str_sym(one
, &one_sym
);
39 if (!one_name
|| !one_sym
)
41 two_name
= expr_to_str_sym(two
, &two_sym
);
42 if (!two_name
|| !two_sym
)
44 if (one_sym
!= two_sym
)
46 if (strcmp(one_name
, two_name
) == 0)
49 free_string(one_name
);
50 free_string(two_name
);
54 static struct expression
*get_returned_expr(struct expression
*expr
)
56 struct statement
*stmt
;
58 stmt
= last_ptr_list((struct ptr_list
*)big_statement_stack
);
59 if (!stmt
|| stmt
->type
!= STMT_EXPRESSION
)
61 if (stmt
->expression
->type
!= EXPR_ASSIGNMENT
)
63 if (stmt
->expression
->right
!= expr
)
65 return stmt
->expression
->left
;
68 static struct expression
*remove_dereference(struct expression
*expr
)
70 if (!expr
|| expr
->type
!= EXPR_PREOP
|| expr
->op
!= '*')
73 if (!expr
|| expr
->type
!= EXPR_PREOP
|| expr
->op
!= '*')
78 static int get_buf_number(struct expression
*call
, struct expression
*size_arg
)
80 struct expression
*arg
;
83 size_arg
= strip_expr(size_arg
->cast_expression
);
84 size_arg
= remove_dereference(size_arg
);
86 arg
= get_returned_expr(call
);
87 if (arg
&& expr_equiv(arg
, size_arg
))
90 FOR_EACH_PTR(call
->args
, arg
) {
92 if (expr_equiv(arg
, size_arg
))
94 } END_FOR_EACH_PTR(arg
);
99 static void match_call(struct expression
*call
)
101 struct expression
*arg
;
106 if (call
->fn
->type
!= EXPR_SYMBOL
)
109 name
= expr_to_var(call
->fn
);
110 FOR_EACH_PTR(call
->args
, arg
) {
112 if (arg
->type
!= EXPR_SIZEOF
)
114 buf_nr
= get_buf_number(call
, arg
);
116 sm_msg("info: sizeof_param '%s' %d", name
, i
);
118 sm_msg("info: sizeof_param '%s' %d %d", name
, i
, buf_nr
);
119 } END_FOR_EACH_PTR(arg
);
123 void check_passes_sizeof(int id
)
129 add_hook(&match_call
, FUNCTION_CALL_HOOK
);