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
)
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 void match_condition(struct expression
*expr
)
67 struct expression
*var
= NULL
;
68 struct symbol
*type
= NULL
;
73 if (expr
->type
!= EXPR_COMPARE
)
76 if (get_value(expr
->left
, &known
)) {
79 } else if (get_value(expr
->right
, &known
)) {
87 if (!type
|| type
->bit_size
>= 32)
94 name
= get_variable_from_expr_complex(var
, NULL
);
97 if (is_unsigned(type
))
98 sm_msg("error: comparing unsigned '%s' to negative", name
);
103 if (!is_unsigned(type
))
107 sm_msg("error: unsigned '%s' cannot be less than 0", name
);
108 if (expr
->op
== SPECIAL_LTE
)
109 sm_msg("warn: unsigned '%s' cannot be less than 0", name
);
113 sm_msg("error: unsigned '%s' cannot be less than 0", name
);
114 if (expr
->op
== SPECIAL_GTE
)
115 sm_msg("warn: unsigned '%s' cannot be less than 0", name
);
121 const char *tf
= "the same";
123 if (expr
->op
== SPECIAL_EQUAL
)
125 if (expr
->op
== SPECIAL_NOTEQUAL
)
127 if (lr
== LEFT
&& (expr
->op
== '<' || expr
->op
== SPECIAL_LTE
))
129 if (lr
== RIGHT
&& (expr
->op
== '>' || expr
->op
== SPECIAL_GTE
))
131 sm_msg("warn: %lld is higher than %lld (max '%s' can be) so this is always %s.",
132 known
, max
, name
, tf
);
138 void check_signed(int id
)
142 add_hook(&match_assign
, ASSIGNMENT_HOOK
);
143 add_hook(&match_condition
, CONDITION_HOOK
);