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 int is_unsigned(struct symbol
*base_type
)
27 if (base_type
->ctype
.modifiers
& MOD_UNSIGNED
)
32 static void match_assign(struct expression
*expr
)
39 sym
= get_type(expr
->left
);
41 //sm_msg("could not get type");
44 if (sym
->bit_size
>= 32) /* max_val limits this */
46 if (!get_implied_value(expr
->right
, &val
))
49 if (max
&& max
< val
) {
50 name
= get_variable_from_expr_complex(expr
->left
, NULL
);
51 sm_msg("warn: value %lld can't fit into %lld '%s'", val
, max
, name
);
56 static void match_condition(struct expression
*expr
)
59 struct expression
*var
= NULL
;
60 struct symbol
*type
= NULL
;
65 if (expr
->type
!= EXPR_COMPARE
)
68 if (get_value(expr
->left
, &known
)) {
71 } else if (get_value(expr
->right
, &known
)) {
79 if (!type
|| type
->bit_size
>= 32)
86 name
= get_variable_from_expr_complex(var
, NULL
);
89 if (is_unsigned(type
))
90 sm_msg("error: comparing unsigned '%s' to negative", name
);
95 if (!is_unsigned(type
))
99 sm_msg("error: unsigned '%s' cannot be less than 0", name
);
100 if (expr
->op
== SPECIAL_LTE
)
101 sm_msg("warn: unsigned '%s' cannot be less than 0", name
);
105 sm_msg("error: unsigned '%s' cannot be less than 0", name
);
106 if (expr
->op
== SPECIAL_GTE
)
107 sm_msg("warn: unsigned '%s' cannot be less than 0", name
);
113 const char *tf
= "the same";
115 if (expr
->op
== SPECIAL_EQUAL
)
117 if (expr
->op
== SPECIAL_NOTEQUAL
)
119 if (lr
== LEFT
&& (expr
->op
== '<' || expr
->op
== SPECIAL_LTE
))
121 if (lr
== RIGHT
&& (expr
->op
== '>' || expr
->op
== SPECIAL_GTE
))
123 sm_msg("warn: %lld is higher than %lld (max '%s' can be) so this is always %s.",
124 known
, max
, name
, tf
);
130 void check_signed(int id
)
134 add_hook(&match_assign
, ASSIGNMENT_HOOK
);
135 add_hook(&match_condition
, CONDITION_HOOK
);