2 * sparse/check_precedence.c
4 * Copyright (C) 2010 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
14 static int is_bool(struct expression
*expr
)
18 type
= get_type(expr
);
21 if (type
->bit_size
== 1 && type
->ctype
.modifiers
& MOD_UNSIGNED
)
26 static int is_bool_from_context(struct expression
*expr
)
30 if (!get_implied_max(expr
, &val
) || val
> 1)
32 if (!get_implied_min(expr
, &val
) || val
< 0)
37 static int is_bool_op(struct expression
*expr
)
39 expr
= strip_expr(expr
);
41 if (expr
->type
== EXPR_PREOP
&& expr
->op
== '!')
43 if (expr
->type
== EXPR_COMPARE
)
45 if (expr
->type
== EXPR_LOGICAL
)
50 static void match_condition(struct expression
*expr
)
54 if (expr
->type
== EXPR_COMPARE
) {
55 if (expr
->left
->type
== EXPR_COMPARE
|| expr
->right
->type
== EXPR_COMPARE
)
57 if (expr
->left
->op
== '!') {
58 if (expr
->left
->type
== EXPR_PREOP
&& expr
->left
->unop
->op
== '!')
60 if (expr
->right
->op
== '!')
62 if (is_bool(expr
->right
))
64 if (is_bool(expr
->left
->unop
))
66 if (is_bool_from_context(expr
->left
->unop
))
72 if (expr
->type
== EXPR_BINOP
) {
73 if (expr
->left
->type
== EXPR_COMPARE
|| expr
->right
->type
== EXPR_COMPARE
)
78 sm_msg("warn: add some parenthesis here?");
82 if (expr
->type
== EXPR_BINOP
&& expr
->op
== '&') {
85 if (is_bool_op(expr
->left
))
87 if (is_bool_op(expr
->right
))
90 sm_msg("warn: maybe use && instead of &");
94 static void match_binop(struct expression
*expr
)
98 if (expr
->left
->op
== '!')
99 sm_msg("warn: add some parenthesis here?");
102 void check_precedence(int id
)
106 add_hook(&match_condition
, CONDITION_HOOK
);
107 add_hook(&match_binop
, BINOP_HOOK
);