2 * Copyright (C) 2014 Oracle.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
24 static void match_assign(struct expression
*expr
)
26 struct symbol
*left_type
, *right_type
;
27 struct expression
*size_expr
;
32 left_type
= get_type(expr
->left
);
33 if (!left_type
|| left_type
->type
!= SYM_PTR
)
35 left_type
= get_real_base_type(left_type
);
36 if (!left_type
|| left_type
->type
!= SYM_STRUCT
)
39 right_type
= get_type(expr
->right
);
40 if (!right_type
|| right_type
->type
!= SYM_PTR
)
42 right_type
= get_real_base_type(right_type
);
45 if (right_type
!= &void_ctype
&& type_bits(right_type
) != 8)
48 bytes
= get_array_size_bytes(expr
->right
);
49 if (bytes
>= type_bytes(left_type
))
52 size_expr
= get_size_variable(expr
->right
, &limit_type
);
55 if (limit_type
!= ELEM_COUNT
)
58 get_absolute_min(size_expr
, &min_size
);
59 if (min_size
.value
>= type_bytes(left_type
))
62 set_state_expr(my_id
, expr
->left
, &too_small
);
65 static void match_dereferences(struct expression
*expr
)
67 struct symbol
*left_type
;
68 struct expression
*right
;
69 struct smatch_state
*state
;
71 struct expression
*size_expr
;
75 if (expr
->type
!= EXPR_PREOP
)
78 expr
= strip_expr(expr
->unop
);
79 state
= get_state_expr(my_id
, expr
);
80 if (state
!= &too_small
)
83 left_type
= get_type(expr
);
84 if (!left_type
|| left_type
->type
!= SYM_PTR
)
86 left_type
= get_real_base_type(left_type
);
87 if (!left_type
|| left_type
->type
!= SYM_STRUCT
)
90 right
= get_assigned_expr(expr
);
91 size_expr
= get_size_variable(right
, &limit_type
);
94 if (limit_type
!= ELEM_COUNT
)
97 get_absolute_min(size_expr
, &min_size
);
98 if (min_size
.value
>= type_bytes(left_type
))
101 name
= expr_to_str(right
);
102 sm_warning("is '%s' large enough for 'struct %s'? %s", name
, left_type
->ident
? left_type
->ident
->name
: "<anon>", sval_to_str(min_size
));
104 set_state_expr(my_id
, expr
, &undefined
);
107 void check_buffer_too_small_for_struct(int id
)
111 add_hook(&match_assign
, ASSIGNMENT_HOOK
);
112 add_hook(&match_dereferences
, DEREF_HOOK
);