show_unreachable.sh: change the line number format
[smatch.git] / check_precedence.c
blob4483beafe678d412abcb230f6067b99fe7c61351
1 /*
2 * sparse/check_precedence.c
4 * Copyright (C) 2010 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
10 #include "smatch.h"
12 static int my_id;
14 static int is_bool(struct expression *expr)
16 struct symbol *type;
18 type = get_type(expr);
19 if (!type)
20 return 0;
21 if (type->bit_size == 1 && type->ctype.modifiers & MOD_UNSIGNED)
22 return 1;
23 return 0;
26 static int is_bool_from_context(struct expression *expr)
28 sval_t sval;
30 if (!get_implied_max(expr, &sval) || sval.uvalue > 1)
31 return 0;
32 if (!get_implied_min(expr, &sval) || sval.value < 0)
33 return 0;
34 return 1;
37 static int is_bool_op(struct expression *expr)
39 expr = strip_expr(expr);
41 if (expr->type == EXPR_PREOP && expr->op == '!')
42 return 1;
43 if (expr->type == EXPR_COMPARE)
44 return 1;
45 if (expr->type == EXPR_LOGICAL)
46 return 1;
47 return is_bool(expr);
50 static void match_condition(struct expression *expr)
52 int print = 0;
54 if (expr->type == EXPR_COMPARE) {
55 if (expr->left->type == EXPR_COMPARE || expr->right->type == EXPR_COMPARE)
56 print = 1;
57 if (expr->left->type == EXPR_PREOP && expr->left->op == '!') {
58 if (expr->left->type == EXPR_PREOP && expr->left->unop->op == '!')
59 return;
60 if (expr->right->op == '!')
61 return;
62 if (is_bool(expr->right))
63 return;
64 if (is_bool(expr->left->unop))
65 return;
66 if (is_bool_from_context(expr->left->unop))
67 return;
68 print = 1;
72 if (expr->type == EXPR_BINOP) {
73 if (expr->left->type == EXPR_COMPARE || expr->right->type == EXPR_COMPARE)
74 print = 1;
77 if (print) {
78 sm_msg("warn: add some parenthesis here?");
79 return;
82 if (expr->type == EXPR_BINOP && expr->op == '&') {
83 int i = 0;
85 if (is_bool_op(expr->left))
86 i++;
87 if (is_bool_op(expr->right))
88 i++;
89 if (i == 1)
90 sm_msg("warn: maybe use && instead of &");
94 static void match_binop(struct expression *expr)
96 if (expr->op != '&')
97 return;
98 if (expr->left->op == '!')
99 sm_msg("warn: add some parenthesis here?");
102 void check_precedence(int id)
104 my_id = id;
106 add_hook(&match_condition, CONDITION_HOOK);
107 add_hook(&match_binop, BINOP_HOOK);