comparison: improve "foo = min(...);" assignment handling
[smatch.git] / check_signed.c
blob9eff313c4e35caedbfed2db7d7215cb1058bda03
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 #define VAR_ON_RIGHT 0
32 #define VAR_ON_LEFT 1
34 static void match_assign(struct expression *expr)
36 struct symbol *sym;
37 sval_t sval;
38 sval_t max;
39 sval_t min;
40 char *left_name, *right_name;
42 if (expr->op == SPECIAL_AND_ASSIGN || expr->op == SPECIAL_OR_ASSIGN)
43 return;
45 sym = get_type(expr->left);
46 if (!sym || sym->type != SYM_BASETYPE) {
47 //sm_msg("could not get type");
48 return;
50 if (type_bits(sym) < 0 || type_bits(sym) >= 32) /* max_val limits this */
51 return;
52 if (!get_implied_value(expr->right, &sval))
53 return;
54 max = sval_type_max(sym);
55 if (sym != &bool_ctype && sym != &uchar_ctype &&
56 sval_cmp(max, sval) < 0 &&
57 !(sval.value < 256 && max.value == 127)) {
58 left_name = expr_to_str(expr->left);
59 right_name = expr_to_str(expr->right);
60 sm_msg("warn: '%s' %s can't fit into %s '%s'",
61 right_name, sval_to_numstr(sval), sval_to_numstr(max), left_name);
62 free_string(left_name);
64 min = sval_type_min(sym);
65 if (sval_cmp_t(&llong_ctype, min, sval) > 0) {
66 if (min.value == 0 && sval.value == -1) /* assigning -1 to unsigned variables is idiomatic */
67 return;
68 if (expr->right->type == EXPR_PREOP && expr->right->op == '~')
69 return;
70 if (expr->op == SPECIAL_SUB_ASSIGN || expr->op == SPECIAL_ADD_ASSIGN)
71 return;
72 if (sval_positive_bits(sval) == 7)
73 return;
74 left_name = expr_to_str(expr->left);
75 if (min.value == 0) {
76 sm_msg("warn: assigning %s to unsigned variable '%s'",
77 sval_to_str(sval), left_name);
78 } else {
79 sm_msg("warn: value %s can't fit into %s '%s'",
80 sval_to_str(sval), sval_to_str(min), left_name);
82 free_string(left_name);
86 static int cap_gt_zero_and_lt(struct expression *expr)
89 struct expression *var = expr->left;
90 struct expression *tmp;
91 char *name1 = NULL;
92 char *name2 = NULL;
93 sval_t known;
94 int ret = 0;
95 int i;
97 if (!get_value(expr->right, &known) || known.value != 0)
98 return 0;
100 i = 0;
101 FOR_EACH_PTR_REVERSE(big_expression_stack, tmp) {
102 if (!i++)
103 continue;
104 if (tmp->op == SPECIAL_LOGICAL_AND) {
105 struct expression *right = strip_expr(tmp->right);
107 if (right->op != '<' &&
108 right->op != SPECIAL_UNSIGNED_LT &&
109 right->op != SPECIAL_LTE &&
110 right->op != SPECIAL_UNSIGNED_LTE)
111 return 0;
113 name1 = expr_to_str(var);
114 if (!name1)
115 goto free;
117 name2 = expr_to_str(right->left);
118 if (!name2)
119 goto free;
120 if (!strcmp(name1, name2))
121 ret = 1;
122 goto free;
125 return 0;
126 } END_FOR_EACH_PTR_REVERSE(tmp);
128 free:
129 free_string(name1);
130 free_string(name2);
131 return ret;
134 static int cap_lt_zero_or_gt(struct expression *expr)
137 struct expression *var = expr->left;
138 struct expression *tmp;
139 char *name1 = NULL;
140 char *name2 = NULL;
141 sval_t known;
142 int ret = 0;
143 int i;
145 if (!get_value(expr->right, &known) || known.value != 0)
146 return 0;
148 i = 0;
149 FOR_EACH_PTR_REVERSE(big_expression_stack, tmp) {
150 if (!i++)
151 continue;
152 if (tmp->op == SPECIAL_LOGICAL_OR) {
153 struct expression *right = strip_expr(tmp->right);
155 if (right->op != '>' &&
156 right->op != SPECIAL_UNSIGNED_GT &&
157 right->op != SPECIAL_GTE &&
158 right->op != SPECIAL_UNSIGNED_GTE)
159 return 0;
161 name1 = expr_to_str(var);
162 if (!name1)
163 goto free;
165 name2 = expr_to_str(right->left);
166 if (!name2)
167 goto free;
168 if (!strcmp(name1, name2))
169 ret = 1;
170 goto free;
173 return 0;
174 } END_FOR_EACH_PTR_REVERSE(tmp);
176 free:
177 free_string(name1);
178 free_string(name2);
179 return ret;
182 static int cap_both_sides(struct expression *expr)
184 switch (expr->op) {
185 case '<':
186 case SPECIAL_UNSIGNED_LT:
187 case SPECIAL_LTE:
188 case SPECIAL_UNSIGNED_LTE:
189 return cap_lt_zero_or_gt(expr);
190 case '>':
191 case SPECIAL_UNSIGNED_GT:
192 case SPECIAL_GTE:
193 case SPECIAL_UNSIGNED_GTE:
194 return cap_gt_zero_and_lt(expr);
196 return 0;
199 static int compare_against_macro(struct expression *expr)
201 sval_t known;
203 if (expr->op != SPECIAL_UNSIGNED_LT)
204 return 0;
206 if (!get_value(expr->right, &known) || known.value != 0)
207 return 0;
208 return !!get_macro_name(expr->right->pos);
211 static int print_unsigned_never_less_than_zero(struct expression *expr)
213 sval_t known;
214 char *name;
216 if (expr->op != SPECIAL_UNSIGNED_LT)
217 return 0;
219 if (!get_value(expr->right, &known) || known.value != 0)
220 return 0;
222 name = expr_to_str(expr->left);
223 sm_msg("warn: unsigned '%s' is never less than zero.", name);
224 free_string(name);
225 return 1;
228 static void match_condition(struct expression *expr)
230 struct symbol *type;
231 sval_t known;
232 sval_t min, max;
233 struct range_list *rl_left_orig, *rl_right_orig;
234 struct range_list *rl_left, *rl_right;
236 if (expr->type != EXPR_COMPARE)
237 return;
239 type = get_type(expr);
240 if (!type)
241 return;
243 /* screw it. I am writing this to mark yoda code as buggy.
244 * Valid comparisons between an unsigned and zero are:
245 * 1) inside a macro.
246 * 2) foo < LOWER_BOUND where LOWER_BOUND is a macro.
247 * 3) foo < 0 || foo > X in exactly this format. No Yoda.
248 * 4) foo >= 0 && foo < X
250 if (get_macro_name(expr->pos))
251 return;
252 if (compare_against_macro(expr))
253 return;
254 if (cap_both_sides(expr))
255 return;
257 /* This is a special case for the common error */
258 if (print_unsigned_never_less_than_zero(expr))
259 return;
261 /* check that one and only one side is known */
262 if (get_value(expr->left, &known)) {
263 if (get_value(expr->right, &known))
264 return;
265 rl_left_orig = alloc_rl(known, known);
266 rl_left = cast_rl(type, rl_left_orig);
268 min = sval_type_min(get_type(expr->right));
269 max = sval_type_max(get_type(expr->right));
270 rl_right_orig = alloc_rl(min, max);
271 rl_right = cast_rl(type, rl_right_orig);
272 } else if (get_value(expr->right, &known)) {
273 rl_right_orig = alloc_rl(known, known);
274 rl_right = cast_rl(type, rl_right_orig);
276 min = sval_type_min(get_type(expr->left));
277 max = sval_type_max(get_type(expr->left));
278 rl_left_orig = alloc_rl(min, max);
279 rl_left = cast_rl(type, rl_left_orig);
280 } else {
281 return;
284 if (!possibly_true_rl(rl_left, expr->op, rl_right)) {
285 char *name = expr_to_str(expr);
287 sm_msg("warn: impossible condition '(%s) => (%s %s %s)'", name,
288 show_rl(rl_left), show_special(expr->op),
289 show_rl(rl_right));
290 free_string(name);
293 if (!possibly_false_rl(rl_left, expr->op, rl_right)) {
294 char *name = expr_to_str(expr);
296 sm_msg("warn: always true condition '(%s) => (%s %s %s)'", name,
297 show_rl(rl_left_orig), show_special(expr->op),
298 show_rl(rl_right_orig));
299 free_string(name);
303 void check_signed(int id)
305 my_id = id;
307 add_hook(&match_assign, ASSIGNMENT_HOOK);
308 add_hook(&match_condition, CONDITION_HOOK);