2 * sparse/check_deference.c
4 * Copyright (C) 2006 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
16 static int malloc_size(struct expression
*expr
)
19 struct expression
*arg
;
24 if (expr
->type
== EXPR_CALL
) {
25 name
= get_variable_from_expr_simple(expr
->fn
, NULL
);
26 if (name
&& !strcmp(name
, "kmalloc")) {
27 arg
= get_argument_from_call_expr(expr
->args
, 0);
28 return get_value(arg
, NULL
);
30 } else if (expr
->type
== EXPR_STRING
&& expr
->string
) {
31 return expr
->string
->length
* 8;
36 static void match_declaration(struct symbol
*sym
)
38 struct symbol
*base_type
;
45 name
= sym
->ident
->name
;
46 base_type
= get_base_type(sym
);
48 if (base_type
->type
== SYM_ARRAY
&& base_type
->bit_size
> 0)
49 set_state(name
, my_id
, NULL
, base_type
->bit_size
/ 8);
51 size
= malloc_size(sym
->initializer
);
53 set_state(name
, my_id
, NULL
, size
);
57 static void match_assignment(struct expression
*expr
)
60 name
= get_variable_from_expr_simple(expr
->left
, NULL
);
61 name
= alloc_string(name
);
64 if (malloc_size(expr
->right
) > 0)
65 set_state(name
, my_id
, NULL
, malloc_size(expr
->right
));
68 static void match_fn_call(struct expression
*expr
)
70 struct expression
*dest
;
71 struct expression
*data
;
76 fn_name
= get_variable_from_expr(expr
->fn
, NULL
);
80 if (!strcmp(fn_name
, "strcpy")) {
81 dest
= get_argument_from_call_expr(expr
->args
, 0);
82 dest_name
= get_variable_from_expr(dest
, NULL
);
83 dest_name
= alloc_string(dest_name
);
85 data
= get_argument_from_call_expr(expr
->args
, 1);
86 data_name
= get_variable_from_expr(data
, NULL
);
87 data_name
= alloc_string(data_name
);
89 if (get_state(dest_name
, my_id
, NULL
) < 0)
91 if (get_state(dest_name
, my_id
, NULL
)
92 < get_state(data_name
, my_id
, NULL
))
93 smatch_msg("Error %s too large for %s", data_name
,
95 } else if (!strcmp(fn_name
, "strncpy")) {
99 dest
= get_argument_from_call_expr(expr
->args
, 0);
100 dest_name
= get_variable_from_expr(dest
, NULL
);
101 dest_name
= alloc_string(dest_name
);
103 data
= get_argument_from_call_expr(expr
->args
, 2);
104 needed
= get_value(data
, NULL
);
105 has
= get_state(dest_name
, my_id
, NULL
);
106 if (has
> 0 && has
< needed
)
107 smatch_msg("Error %s too small for %d bytes.",
112 void register_overflow(int id
)
115 add_hook(&match_declaration
, DECLARATION_HOOK
);
116 add_hook(&match_assignment
, ASSIGNMENT_HOOK
);
117 add_hook(&match_fn_call
, FUNCTION_CALL_HOOK
);