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 int is_unsigned(struct symbol
*base_type
)
27 if (base_type
->ctype
.modifiers
& MOD_UNSIGNED
)
32 static void match_assign(struct expression
*expr
)
40 sym
= get_type(expr
->left
);
42 //sm_msg("could not get type");
45 if (sym
->bit_size
>= 32) /* max_val limits this */
47 if (!get_implied_value(expr
->right
, &val
))
50 if (max
&& max
< val
) {
51 name
= get_variable_from_expr_complex(expr
->left
, NULL
);
52 sm_msg("warn: value %lld can't fit into %lld '%s'", val
, max
, name
);
57 name
= get_variable_from_expr_complex(expr
->left
, NULL
);
58 sm_msg("warn: value %lld can't fit into %lld '%s'", val
, min
, name
);
64 static const char *get_tf(long long variable
, long long known
, int var_pos
, char op
)
66 if (op
== SPECIAL_EQUAL
)
68 if (op
== SPECIAL_NOTEQUAL
)
70 if (var_pos
== VAR_ON_LEFT
) {
71 if (variable
> known
&& (op
== '<' || op
== SPECIAL_LTE
))
73 if (variable
> known
&& (op
== '>' || op
== SPECIAL_GTE
))
75 if (variable
< known
&& (op
== '<' || op
== SPECIAL_LTE
))
77 if (variable
< known
&& (op
== '>' || op
== SPECIAL_GTE
))
80 if (var_pos
== VAR_ON_RIGHT
) {
81 if (known
> variable
&& (op
== '<' || op
== SPECIAL_LTE
))
83 if (known
> variable
&& (op
== '>' || op
== SPECIAL_GTE
))
85 if (known
< variable
&& (op
== '<' || op
== SPECIAL_LTE
))
87 if (known
< variable
&& (op
== '>' || op
== SPECIAL_GTE
))
93 static void match_condition(struct expression
*expr
)
96 struct expression
*var
= NULL
;
97 struct symbol
*type
= NULL
;
103 if (expr
->type
!= EXPR_COMPARE
)
106 if (get_value(expr
->left
, &known
)) {
109 } else if (get_value(expr
->right
, &known
)) {
116 type
= get_type(var
);
117 if (!type
|| type
->bit_size
>= 32)
120 max
= type_max(type
);
123 min
= type_min(type
);
125 name
= get_variable_from_expr_complex(var
, NULL
);
127 if (known
< 0 && is_unsigned(type
)) {
128 sm_msg("error: comparing unsigned '%s' to negative", name
);
133 if (!is_unsigned(type
))
135 if (lr
== VAR_ON_LEFT
) {
137 sm_msg("error: unsigned '%s' cannot be less than 0", name
);
138 if (expr
->op
== SPECIAL_LTE
)
139 sm_msg("warn: unsigned '%s' cannot be less than 0", name
);
141 if (lr
== VAR_ON_RIGHT
) {
143 sm_msg("error: unsigned '%s' cannot be less than 0", name
);
144 if (expr
->op
== SPECIAL_GTE
)
145 sm_msg("warn: unsigned '%s' cannot be less than 0", name
);
151 const char *tf
= get_tf(max
, known
, lr
, expr
->op
);
153 sm_msg("warn: %lld is more than %lld (max '%s' can be) so this is always %s.",
154 known
, max
, name
, tf
);
158 const char *tf
= get_tf(max
, known
, lr
, expr
->op
);
160 sm_msg("warn: %lld is less than %lld (min '%s' can be) so this is always %s.",
161 known
, min
, name
, tf
);
167 void check_signed(int id
)
171 add_hook(&match_assign
, ASSIGNMENT_HOOK
);
172 add_hook(&match_condition
, CONDITION_HOOK
);