2 * sparse/check_signed.c
4 * Copyright (C) 2009 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
11 * Check for things which are signed but probably should be unsigned.
13 * Hm... It seems like at this point in the processing, sparse makes all
14 * bitfields unsigned. Which is logical but not what GCC does.
22 #define VAR_ON_RIGHT 0
25 static long long eqneq_max(struct symbol
*base_type
)
27 long long ret
= whole_range
.max
;
30 if (!base_type
|| !base_type
->bit_size
)
32 bits
= base_type
->bit_size
;
36 return type_max(base_type
);
41 static long long eqneq_min(struct symbol
*base_type
)
43 long long ret
= whole_range
.min
;
46 if (!base_type
|| !base_type
->bit_size
)
48 if (base_type
->bit_size
< 32)
49 return type_min(base_type
);
50 ret
= whole_range
.max
;
51 bits
= base_type
->bit_size
- 1;
56 static void match_assign(struct expression
*expr
)
64 if (expr
->op
== SPECIAL_AND_ASSIGN
|| expr
->op
== SPECIAL_OR_ASSIGN
)
67 sym
= get_type(expr
->left
);
69 //sm_msg("could not get type");
72 if (sym
->bit_size
>= 32) /* max_val limits this */
74 if (!get_implied_value(expr
->right
, &val
))
77 if (max
< val
&& !(val
< 256 && max
== 127)) {
78 name
= get_variable_from_expr_complex(expr
->left
, NULL
);
79 sm_msg("warn: value %lld can't fit into %lld '%s'", val
, max
, name
);
84 if (min
== 0 && val
== -1) /* assigning -1 to unsigned variables is idiomatic */
86 if (expr
->right
->type
== EXPR_PREOP
&& expr
->right
->op
== '~')
88 if (expr
->op
== SPECIAL_SUB_ASSIGN
|| expr
->op
== SPECIAL_ADD_ASSIGN
)
90 name
= get_variable_from_expr_complex(expr
->left
, NULL
);
92 sm_msg("warn: assigning %lld to unsigned variable '%s'", val
, name
);
94 sm_msg("warn: value %lld can't fit into %lld '%s'", val
, min
, name
);
100 static const char *get_tf(long long variable
, long long known
, int var_pos
, int op
)
102 if (op
== SPECIAL_EQUAL
)
104 if (op
== SPECIAL_NOTEQUAL
)
106 if (var_pos
== VAR_ON_LEFT
) {
107 if (variable
> known
&& (op
== '<' || op
== SPECIAL_LTE
))
109 if (variable
> known
&& (op
== '>' || op
== SPECIAL_GTE
))
111 if (variable
< known
&& (op
== '<' || op
== SPECIAL_LTE
))
113 if (variable
< known
&& (op
== '>' || op
== SPECIAL_GTE
))
116 if (var_pos
== VAR_ON_RIGHT
) {
117 if (known
> variable
&& (op
== '<' || op
== SPECIAL_LTE
))
119 if (known
> variable
&& (op
== '>' || op
== SPECIAL_GTE
))
121 if (known
< variable
&& (op
== '<' || op
== SPECIAL_LTE
))
123 if (known
< variable
&& (op
== '>' || op
== SPECIAL_GTE
))
129 static int compare_against_macro(int lr
, struct expression
*expr
)
131 struct expression
*known
= expr
->left
;
133 if (lr
== VAR_ON_LEFT
)
136 return !!get_macro_name(known
->pos
);
139 static int cap_both_size(int lr
, struct expression
*expr
)
142 struct expression
*var
= expr
->left
;
143 struct expression
*tmp
;
149 /* screw it. I am writing this to mark yoda code as buggy.
150 * Valid comparisons between an unsigned and zero are:
152 * 2) foo < LOWER_BOUND where LOWER_BOUND is a macro.
153 * 3) foo < 0 || foo > X in exactly this format. No Yoda.
156 if (lr
!= VAR_ON_LEFT
)
158 if (expr
->op
!= '<') /* this is implied by lr == VAR_ON_LEFT */
162 FOR_EACH_PTR_REVERSE(big_expression_stack
, tmp
) {
165 if (tmp
->op
== SPECIAL_LOGICAL_OR
) {
166 if (tmp
->right
->op
!= '>' &&
167 tmp
->right
->op
!= SPECIAL_GTE
&&
168 tmp
->right
->op
!= SPECIAL_UNSIGNED_GTE
)
171 name1
= get_variable_from_expr_complex(var
, NULL
);
175 name2
= get_variable_from_expr_complex(tmp
->right
->left
, NULL
);
178 if (!strcmp(name1
, name2
))
184 } END_FOR_EACH_PTR_REVERSE(tmp
);
192 static void match_condition(struct expression
*expr
)
195 struct expression
*var
= NULL
;
196 struct symbol
*var_type
= NULL
;
197 struct symbol
*known_type
= NULL
;
203 if (expr
->type
!= EXPR_COMPARE
)
206 if (get_value(expr
->left
, &known
)) {
207 if (get_value(expr
->right
, &max
))
208 return; /* both sides known */
211 known_type
= get_type(expr
->left
);
212 } else if (get_value(expr
->right
, &known
)) {
215 known_type
= get_type(expr
->right
);
220 var_type
= get_type(var
);
223 if (var_type
->bit_size
>= 32 && !option_spammy
)
226 name
= get_variable_from_expr_complex(var
, NULL
);
228 if (expr
->op
== SPECIAL_EQUAL
|| expr
->op
== SPECIAL_NOTEQUAL
) {
229 if (eqneq_max(var_type
) < known
|| eqneq_min(var_type
) > known
)
230 sm_msg("error: %s is never equal to %lld (wrong type %lld - %lld).",
231 name
, known
, eqneq_min(var_type
), eqneq_max(var_type
));
235 max
= type_max(var_type
);
236 min
= type_min(var_type
);
239 const char *tf
= get_tf(max
, known
, lr
, expr
->op
);
241 sm_msg("warn: %lld is more than %lld (max '%s' can be) so this is always %s.",
242 known
, max
, name
, tf
);
245 if (known
== 0 && type_unsigned(var_type
)) {
246 if ((lr
&& expr
->op
== '<') || (!lr
&& expr
->op
== '>')) {
247 if (!compare_against_macro(lr
, expr
) && !cap_both_size(lr
, expr
)) {
248 sm_msg("warn: unsigned '%s' is never less than zero.", name
);
254 if (type_unsigned(var_type
) && known_type
&& !type_unsigned(known_type
) && known
< 0) {
255 sm_msg("warn: unsigned '%s' is never less than zero (%lld).", name
, known
);
259 if (min
< 0 && min
> known
) {
260 const char *tf
= get_tf(min
, known
, lr
, expr
->op
);
262 sm_msg("warn: %lld is less than %lld (min '%s' can be) so this is always %s.",
263 known
, min
, name
, tf
);
269 void check_signed(int id
)
273 add_hook(&match_assign
, ASSIGNMENT_HOOK
);
274 add_hook(&match_condition
, CONDITION_HOOK
);