smatch_expressions: introduce deref_expression()
[smatch.git] / check_sizeof.c
blob5590126774e29c1380beaa1f1061df8b1f5e2474
1 /*
2 * smatch/check_sizeof.c
4 * Copyright (C) 2012 Oracle.
6 * Licensed under the Open Software License version 1.1
8 */
10 #include "smatch.h"
12 static int my_id;
14 static void check_pointer(struct expression *expr, char *ptr_name)
16 char *name;
17 sval_t sval;
19 if (!expr || expr->type != EXPR_SIZEOF)
20 return;
22 get_value(expr, &sval);
24 expr = strip_expr(expr->cast_expression);
25 name = expr_to_str(expr);
26 if (!name)
27 return;
29 if (strcmp(ptr_name, name) == 0)
30 sm_msg("warn: was 'sizeof(*%s)' intended?", ptr_name);
31 free_string(name);
34 static void match_call_assignment(struct expression *expr)
36 struct expression *call = strip_expr(expr->right);
37 struct expression *arg;
38 char *ptr_name;
40 if (!is_pointer(expr->left))
41 return;
43 ptr_name = expr_to_str(expr->left);
44 if (!ptr_name)
45 return;
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;
57 char *ptr_name;
59 FOR_EACH_PTR(call->args, arg) {
60 ptr_name = expr_to_var(arg);
61 if (!ptr_name)
62 continue;
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;
73 char *name;
75 FOR_EACH_PTR(call->args, arg) {
76 if (arg->type != EXPR_SIZEOF)
77 continue;
78 obj = strip_expr(arg->cast_expression);
79 if (!is_pointer(obj))
80 continue;
81 name = expr_to_var(obj);
82 if (!name)
83 continue;
84 check_passes_pointer(name, call);
85 free_string(name);
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)
102 my_id = 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);