2 * sparse/check_deference.c
4 * Copyright (C) 2006 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
16 static int get_value(struct expression
*expr
, int *discard
)
33 if (show_special(expr
->op
) &&
34 !strcmp("*", show_special(expr
->op
)))
35 ret
= get_value(expr
->left
, discard
)
36 * get_value(expr
->right
, discard
);
39 if (expr
->cast_type
&& get_base_type(expr
->cast_type
))
40 ret
= (get_base_type(expr
->cast_type
))->bit_size
/ 8;
41 if (expr
->cast_expression
)
42 ;//printf("debugs %d\n", expr->cast_expression->type);
45 //printf("ouchies-->%d\n", expr->type);
53 static int malloc_size(struct expression
*expr
)
56 struct expression
*arg
;
61 if (expr
->type
== EXPR_CALL
) {
62 name
= get_variable_from_expr_simple(expr
->fn
, NULL
);
63 if (name
&& !strcmp(name
, "kmalloc")) {
64 arg
= get_argument_from_call_expr(expr
->args
, 0);
65 return get_value(arg
, NULL
);
67 } else if (expr
->type
== EXPR_STRING
&& expr
->string
) {
68 return expr
->string
->length
* 8;
73 static void match_declaration(struct symbol
*sym
)
75 struct symbol
*base_type
;
82 name
= sym
->ident
->name
;
83 base_type
= get_base_type(sym
);
85 if (base_type
->type
== SYM_ARRAY
&& base_type
->bit_size
> 0)
86 set_state(name
, my_id
, NULL
, base_type
->bit_size
/ 8);
88 size
= malloc_size(sym
->initializer
);
90 set_state(name
, my_id
, NULL
, size
);
94 static void match_assignment(struct expression
*expr
)
97 name
= get_variable_from_expr_simple(expr
->left
, NULL
);
98 name
= alloc_string(name
);
101 if (malloc_size(expr
->right
))
102 set_state(name
, my_id
, NULL
, malloc_size(expr
->right
));
105 static void match_fn_call(struct expression
*expr
)
107 struct expression
*dest
;
108 struct expression
*data
;
113 fn_name
= get_variable_from_expr(expr
->fn
, NULL
);
117 if (!strcmp(fn_name
, "strcpy")) {
118 dest
= get_argument_from_call_expr(expr
->args
, 0);
119 dest_name
= get_variable_from_expr(dest
, NULL
);
120 dest_name
= alloc_string(dest_name
);
122 data
= get_argument_from_call_expr(expr
->args
, 1);
123 data_name
= get_variable_from_expr(data
, NULL
);
124 data_name
= alloc_string(data_name
);
126 if (get_state(dest_name
, my_id
, NULL
) < 0)
128 if (get_state(dest_name
, my_id
, NULL
)
129 < get_state(data_name
, my_id
, NULL
))
130 smatch_msg("Error %s too large for %s", data_name
,
132 } else if (!strcmp(fn_name
, "strncpy")) {
136 dest
= get_argument_from_call_expr(expr
->args
, 0);
137 dest_name
= get_variable_from_expr(dest
, NULL
);
138 dest_name
= alloc_string(dest_name
);
140 data
= get_argument_from_call_expr(expr
->args
, 2);
141 needed
= get_value(data
, NULL
);
142 has
= get_state(dest_name
, my_id
, NULL
);
143 if (has
> 0 && has
< needed
)
144 smatch_msg("Error %s too small for %d bytes.",
149 void register_overflow(int id
)
152 add_hook(&match_declaration
, DECLARATION_HOOK
);
153 add_hook(&match_assignment
, ASSIGNMENT_HOOK
);
154 add_hook(&match_fn_call
, FUNCTION_CALL_HOOK
);