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.
25 static unsigned long long max_size(struct symbol
*base_type
)
30 unsigned long long ret = 0xffffffffffffffff;
32 But gcc complained that was too large. What am I doing wrong?
33 Oh well. I expect most of the problems are with smaller
37 unsigned long long ret
= 0xffffffff;
40 bits
= base_type
->bit_size
;
41 if (base_type
->ctype
.modifiers
& MOD_SIGNED
)
47 static int is_unsigned(struct symbol
*base_type
)
49 if (base_type
->ctype
.modifiers
& MOD_UNSIGNED
)
54 static void match_assign(struct expression
*expr
)
61 sym
= get_type(expr
->left
);
63 //sm_msg("could not get type");
66 if (sym
->bit_size
>= 32) /* max_val limits this */
68 if (!get_implied_value(expr
->right
, &val
))
71 if (max
&& max
< val
) {
72 name
= get_variable_from_expr_complex(expr
->left
, NULL
);
73 sm_msg("warn: value %lld can't fit into %lld '%s'", val
, max
, name
);
78 static void match_condition(struct expression
*expr
)
81 struct expression
*var
= NULL
;
82 struct symbol
*type
= NULL
;
87 if (expr
->type
!= EXPR_COMPARE
)
90 if (get_value(expr
->left
, &known
)) {
93 } else if (get_value(expr
->right
, &known
)) {
100 type
= get_type(var
);
101 if (!type
|| type
->bit_size
>= 32)
104 max
= max_size(type
);
108 name
= get_variable_from_expr_complex(var
, NULL
);
111 if (is_unsigned(type
))
112 sm_msg("error: comparing '%s' to negative", name
);
117 if (!is_unsigned(type
))
121 sm_msg("error: unsigned '%s' cannot be less than 0", name
);
122 if (expr
->op
== SPECIAL_LTE
)
123 sm_msg("warn: unsigned '%s' cannot be less than 0", name
);
127 sm_msg("error: unsigned '%s' cannot be less than 0", name
);
128 if (expr
->op
== SPECIAL_GTE
)
129 sm_msg("warn: unsigned '%s' cannot be less than 0", name
);
135 const char *tf
= "the same";
137 if (expr
->op
== SPECIAL_EQUAL
)
139 if (expr
->op
== SPECIAL_NOTEQUAL
)
141 if (lr
== LEFT
&& (expr
->op
== '<' || expr
->op
== SPECIAL_LTE
))
143 if (lr
== RIGHT
&& (expr
->op
== '>' || expr
->op
== SPECIAL_GTE
))
145 sm_msg("warn: %lld is higher than %lld (max '%s' can be) so this is always %s.",
146 known
, max
, name
, tf
);
152 void check_signed(int id
)
156 add_hook(&match_assign
, ASSIGNMENT_HOOK
);
157 add_hook(&match_condition
, CONDITION_HOOK
);