2 * smatch/check_sizeof.c
4 * Copyright (C) 2012 Oracle.
6 * Licensed under the Open Software License version 1.1
14 static void check_pointer(struct expression
*expr
, char *ptr_name
)
19 if (!expr
|| expr
->type
!= EXPR_SIZEOF
)
22 get_value(expr
, &sval
);
24 expr
= strip_expr(expr
->cast_expression
);
25 name
= expr_to_str(expr
);
29 if (strcmp(ptr_name
, name
) == 0)
30 sm_msg("warn: was 'sizeof(*%s)' intended?", ptr_name
);
34 static void match_call_assignment(struct expression
*expr
)
36 struct expression
*call
= strip_expr(expr
->right
);
37 struct expression
*arg
;
40 if (!is_pointer(expr
->left
))
43 ptr_name
= expr_to_str(expr
->left
);
47 FOR_EACH_PTR(call
->args
, arg
) {
48 check_pointer(arg
, ptr_name
);
49 } END_FOR_EACH_PTR(arg
);
51 free_string(ptr_name
);
54 static void check_passes_pointer(char *name
, struct expression
*call
)
56 struct expression
*arg
;
59 FOR_EACH_PTR(call
->args
, arg
) {
60 ptr_name
= expr_to_var(arg
);
63 if (strcmp(name
, ptr_name
) == 0)
64 sm_msg("warn: was 'sizeof(*%s)' intended?", name
);
65 free_string(ptr_name
);
66 } END_FOR_EACH_PTR(arg
);
69 static void match_check_params(struct expression
*call
)
71 struct expression
*arg
;
72 struct expression
*obj
;
75 FOR_EACH_PTR(call
->args
, arg
) {
76 if (arg
->type
!= EXPR_SIZEOF
)
78 obj
= strip_expr(arg
->cast_expression
);
81 name
= expr_to_var(obj
);
84 check_passes_pointer(name
, call
);
86 } END_FOR_EACH_PTR(arg
);
89 static void match_sizeof(struct expression
*expr
)
91 if (expr
->type
== EXPR_PREOP
&& expr
->op
== '&')
92 sm_msg("warn: sizoef(&pointer)?");
93 if (expr
->type
== EXPR_SIZEOF
)
94 sm_msg("warn: sizoef(sizeof())?");
95 /* the ilog2() macro is a valid place to check the size of a binop */
96 if (expr
->type
== EXPR_BINOP
&& !get_macro_name(expr
->pos
))
97 sm_msg("warn: taking sizeof binop");
100 void check_sizeof(int id
)
104 add_hook(&match_call_assignment
, CALL_ASSIGNMENT_HOOK
);
105 add_hook(&match_check_params
, FUNCTION_CALL_HOOK
);
106 add_hook(&match_sizeof
, SIZEOF_HOOK
);