preempt_info: add class_raw_spinlock_irq_destructor()
[smatch.git] / check_signed.c
blob9e3ad498fc328fb0394c149c6ee443b796e2503e
1 /*
2 * Copyright (C) 2009 Dan Carpenter.
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 * Check for things which are signed but probably should be unsigned.
21 * Hm... It seems like at this point in the processing, sparse makes all
22 * bitfields unsigned. Which is logical but not what GCC does.
26 #include "smatch.h"
27 #include "smatch_extra.h"
29 static int my_id;
31 static void match_assign(struct expression *expr)
33 struct symbol *sym;
34 sval_t sval;
35 sval_t max;
36 sval_t min;
37 char *left_name, *right_name;
39 if (__in_fake_assign)
40 return;
41 if (is_fake_var_assign(expr))
42 return;
43 if (expr->op == SPECIAL_AND_ASSIGN || expr->op == SPECIAL_OR_ASSIGN)
44 return;
46 sym = get_type(expr->left);
47 if (!sym || sym->type != SYM_BASETYPE) {
48 //sm_msg("could not get type");
49 return;
51 if (type_bits(sym) < 0 || type_bits(sym) >= 32) /* max_val limits this */
52 return;
53 if (!get_implied_value(expr->right, &sval))
54 return;
55 max = sval_type_max(sym);
56 if (sym != &bool_ctype && sym != &uchar_ctype &&
57 sval_cmp(max, sval) < 0 &&
58 !(sval.value < 256 && max.value == 127)) {
59 left_name = expr_to_str(expr->left);
60 right_name = expr_to_str(expr->right);
61 sm_warning("'%s' %s can't fit into %s '%s'",
62 right_name, sval_to_numstr(sval), sval_to_numstr(max), left_name);
63 free_string(left_name);
65 min = sval_type_min(sym);
66 if (sval_cmp_t(&llong_ctype, min, sval) > 0) {
67 if (min.value == 0 && sval.value == -1) /* assigning -1 to unsigned variables is idiomatic */
68 return;
69 if (expr->right->type == EXPR_PREOP && expr->right->op == '~')
70 return;
71 if (expr->op == SPECIAL_SUB_ASSIGN || expr->op == SPECIAL_ADD_ASSIGN)
72 return;
73 if (sval_positive_bits(sval) == 7)
74 return;
75 left_name = expr_to_str(expr->left);
76 if (min.value == 0) {
77 sm_warning("assigning %s to unsigned variable '%s'",
78 sval_to_str(sval), left_name);
79 } else {
80 sm_warning("value %s can't fit into %s '%s'",
81 sval_to_str(sval), sval_to_str(min), left_name);
83 free_string(left_name);
87 void check_signed(int id)
89 my_id = id;
91 add_hook(&match_assign, ASSIGNMENT_HOOK);