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
;
31 left_type
= get_type(expr
->left
);
32 if (!left_type
|| left_type
->type
!= SYM_PTR
)
34 left_type
= get_real_base_type(left_type
);
35 if (!left_type
|| left_type
->type
!= SYM_STRUCT
)
38 right_type
= get_type(expr
->right
);
39 if (!right_type
|| right_type
->type
!= SYM_PTR
)
41 right_type
= get_real_base_type(right_type
);
44 if (right_type
!= &void_ctype
&& type_bits(right_type
) != 8)
47 size_expr
= get_size_variable(expr
->right
, &limit_type
);
50 if (limit_type
!= ELEM_COUNT
)
53 get_absolute_min(size_expr
, &min_size
);
54 if (min_size
.value
>= type_bytes(left_type
))
57 set_state_expr(my_id
, expr
->left
, &too_small
);
60 static void match_dereferences(struct expression
*expr
)
62 struct symbol
*left_type
;
63 struct expression
*right
;
64 struct smatch_state
*state
;
66 struct expression
*size_expr
;
70 if (expr
->type
!= EXPR_PREOP
)
73 expr
= strip_expr(expr
->unop
);
74 state
= get_state_expr(my_id
, expr
);
75 if (state
!= &too_small
)
78 left_type
= get_type(expr
);
79 if (!left_type
|| left_type
->type
!= SYM_PTR
)
81 left_type
= get_real_base_type(left_type
);
82 if (!left_type
|| left_type
->type
!= SYM_STRUCT
)
85 right
= get_assigned_expr(expr
);
86 size_expr
= get_size_variable(right
, &limit_type
);
89 if (limit_type
!= ELEM_COUNT
)
92 get_absolute_min(size_expr
, &min_size
);
93 if (min_size
.value
>= type_bytes(left_type
))
96 name
= expr_to_str(right
);
97 sm_warning("is '%s' large enough for 'struct %s'? %s", name
, left_type
->ident
? left_type
->ident
->name
: "<anon>", sval_to_str(min_size
));
99 set_state_expr(my_id
, expr
, &undefined
);
102 void check_buffer_too_small_for_struct(int id
)
106 add_hook(&match_assign
, ASSIGNMENT_HOOK
);
107 add_hook(&match_dereferences
, DEREF_HOOK
);