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 struct expression
*get_returned_expr(struct expression
*expr
)
28 struct statement
*stmt
;
30 stmt
= last_ptr_list((struct ptr_list
*)big_statement_stack
);
31 if (!stmt
|| stmt
->type
!= STMT_EXPRESSION
|| !stmt
->expression
)
33 if (stmt
->expression
->type
!= EXPR_ASSIGNMENT
)
35 if (stmt
->expression
->right
!= expr
)
37 return stmt
->expression
->left
;
40 static struct expression
*remove_dereference(struct expression
*expr
)
42 if (!expr
|| expr
->type
!= EXPR_PREOP
|| expr
->op
!= '*')
45 if (!expr
|| expr
->type
!= EXPR_PREOP
|| expr
->op
!= '*')
50 static int get_buf_number(struct expression
*call
, struct expression
*size_arg
)
52 struct expression
*arg
;
55 size_arg
= strip_expr(size_arg
->cast_expression
);
56 size_arg
= remove_dereference(size_arg
);
58 arg
= get_returned_expr(call
);
59 if (arg
&& expr_equiv(arg
, size_arg
))
62 FOR_EACH_PTR(call
->args
, arg
) {
64 if (expr_equiv(arg
, size_arg
))
66 } END_FOR_EACH_PTR(arg
);
71 static void match_call(struct expression
*call
)
73 struct expression
*arg
;
78 if (call
->fn
->type
!= EXPR_SYMBOL
)
81 name
= expr_to_var(call
->fn
);
82 FOR_EACH_PTR(call
->args
, arg
) {
84 if (arg
->type
!= EXPR_SIZEOF
)
86 buf_nr
= get_buf_number(call
, arg
);
88 sm_msg("info: sizeof_param '%s' %d", name
, i
);
90 sm_msg("info: sizeof_param '%s' %d %d", name
, i
, buf_nr
);
91 } END_FOR_EACH_PTR(arg
);
95 void check_passes_sizeof(int id
)
101 add_hook(&match_call
, FUNCTION_CALL_HOOK
);