2 * Copyright (C) 2012 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
19 #include "smatch_extra.h"
23 static void match_shift_mask(struct expression
*expr
)
25 struct expression
*right
, *shifter
;
26 struct range_list
*rl
;
29 expr
= strip_expr(expr
);
30 if (expr
->type
!= EXPR_BINOP
|| expr
->op
!= '&')
33 if (get_type(expr
->left
) != &ullong_ctype
)
36 if (type_bits(get_type(expr
->right
)) == 64)
39 right
= strip_expr(expr
->right
);
40 if (right
->type
!= EXPR_BINOP
|| right
->op
!= SPECIAL_LEFTSHIFT
)
43 shifter
= strip_expr(right
->right
);
44 get_real_absolute_rl(shifter
, &rl
);
45 if (rl_max(rl
).uvalue
< 32)
48 str
= expr_to_str(expr
->right
);
49 sm_warning("should '%s' be a 64 bit type?", str
);
53 static void match_shift_assignment(struct expression
*expr
)
55 struct symbol
*left_type
, *right_type
;
56 struct expression
*right
;
61 right
= strip_expr(expr
->right
);
62 if (right
->type
!= EXPR_BINOP
|| right
->op
!= SPECIAL_LEFTSHIFT
)
65 left_type
= get_type(expr
->left
);
66 if (left_type
!= &llong_ctype
&& left_type
!= &ullong_ctype
)
69 right_type
= get_type(expr
->right
);
71 if (type_bits(right_type
) == 64)
74 if (get_value(right
, &sval
))
77 get_absolute_max(right
->left
, &bits
);
78 get_absolute_max(right
->right
, &shifter
);
80 bits
= sval_cast(&ullong_ctype
, bits
);
81 if (sval_cmp_val(shifter
, 32) < 0) {
82 sval
= sval_binop(bits
, SPECIAL_LEFTSHIFT
, shifter
);
83 if (sval_cmp_val(sval
, UINT_MAX
) < 0)
87 name
= expr_to_str_sym(right
, NULL
);
88 sm_warning("should '%s' be a 64 bit type?", name
);
92 void check_64bit_shift(int id
)
99 add_hook(&match_shift_assignment
, ASSIGNMENT_HOOK
);
100 add_hook(&match_shift_mask
, BINOP_HOOK
);