2 * smatch/check_passes_sizeof.c
4 * Copyright (C) 2012 Oracle.
6 * Licensed under the Open Software License version 1.1
11 #include "smatch_extra.h"
12 #include "smatch_slist.h"
18 static int expr_equiv(struct expression
*one
, struct expression
*two
)
20 struct symbol
*one_sym
, *two_sym
;
21 char *one_name
= NULL
;
22 char *two_name
= NULL
;
27 if (one
->type
!= two
->type
)
30 one_name
= get_variable_from_expr_complex(one
, &one_sym
);
31 if (!one_name
|| !one_sym
)
33 two_name
= get_variable_from_expr_complex(two
, &two_sym
);
34 if (!two_name
|| !two_sym
)
36 if (one_sym
!= two_sym
)
38 if (strcmp(one_name
, two_name
) == 0)
41 free_string(one_name
);
42 free_string(two_name
);
46 static struct expression
*get_returned_expr(struct expression
*expr
)
48 struct statement
*stmt
;
50 stmt
= last_ptr_list((struct ptr_list
*)big_statement_stack
);
51 if (!stmt
|| stmt
->type
!= STMT_EXPRESSION
)
53 if (stmt
->expression
->type
!= EXPR_ASSIGNMENT
)
55 if (stmt
->expression
->right
!= expr
)
57 return stmt
->expression
->left
;
60 static struct expression
*remove_dereference(struct expression
*expr
)
62 if (!expr
|| expr
->type
!= EXPR_PREOP
|| expr
->op
!= '*')
65 if (!expr
|| expr
->type
!= EXPR_PREOP
|| expr
->op
!= '*')
70 static int get_buf_number(struct expression
*call
, struct expression
*size_arg
)
72 struct expression
*arg
;
75 size_arg
= strip_expr(size_arg
->cast_expression
);
76 size_arg
= remove_dereference(size_arg
);
78 arg
= get_returned_expr(call
);
79 if (arg
&& expr_equiv(arg
, size_arg
))
82 FOR_EACH_PTR(call
->args
, arg
) {
84 if (expr_equiv(arg
, size_arg
))
86 } END_FOR_EACH_PTR(arg
);
91 static void match_call(struct expression
*call
)
93 struct expression
*arg
;
98 if (call
->fn
->type
!= EXPR_SYMBOL
)
101 name
= get_variable_from_expr(call
->fn
, NULL
);
102 FOR_EACH_PTR(call
->args
, arg
) {
104 if (arg
->type
!= EXPR_SIZEOF
)
106 buf_nr
= get_buf_number(call
, arg
);
108 sm_msg("info: sizeof_param '%s' %d", name
, i
);
110 sm_msg("info: sizeof_param '%s' %d %d", name
, i
, buf_nr
);
111 } END_FOR_EACH_PTR(arg
);
115 void check_passes_sizeof(int id
)
121 add_hook(&match_call
, FUNCTION_CALL_HOOK
);