2 * sparse/check_or_vs_and.c
4 * Copyright (C) 2012 Oracle.
6 * Licensed under the Open Software License version 1.1
14 static int does_inc_dec(struct expression
*expr
)
16 if (expr
->type
== EXPR_PREOP
|| expr
->type
== EXPR_POSTOP
) {
17 if (expr
->op
== SPECIAL_INCREMENT
|| expr
->op
== SPECIAL_DECREMENT
)
19 return does_inc_dec(expr
->unop
);
24 static int expr_equiv(struct expression
*one
, struct expression
*two
)
26 struct symbol
*one_sym
, *two_sym
;
27 char *one_name
= NULL
;
28 char *two_name
= NULL
;
31 if (does_inc_dec(one
) || does_inc_dec(two
))
34 one_name
= get_variable_from_expr_complex(one
, &one_sym
);
35 if (!one_name
|| !one_sym
)
37 two_name
= get_variable_from_expr_complex(two
, &two_sym
);
38 if (!two_name
|| !two_sym
)
40 if (one_sym
!= two_sym
)
42 if (strcmp(one_name
, two_name
) == 0)
45 free_string(one_name
);
46 free_string(two_name
);
50 static int inconsistent_check(struct expression
*left
, struct expression
*right
)
54 if (get_value(left
->left
, &val
)) {
55 if (get_value(right
->left
, &val
))
56 return expr_equiv(left
->right
, right
->right
);
57 if (get_value(right
->right
, &val
))
58 return expr_equiv(left
->right
, right
->left
);
61 if (get_value(left
->right
, &val
)) {
62 if (get_value(right
->left
, &val
))
63 return expr_equiv(left
->left
, right
->right
);
64 if (get_value(right
->right
, &val
))
65 return expr_equiv(left
->left
, right
->left
);
72 static void check_or(struct expression
*expr
)
74 if (expr
->left
->type
!= EXPR_COMPARE
||
75 expr
->left
->op
!= SPECIAL_NOTEQUAL
)
77 if (expr
->right
->type
!= EXPR_COMPARE
||
78 expr
->right
->op
!= SPECIAL_NOTEQUAL
)
80 if (!inconsistent_check(expr
->left
, expr
->right
))
83 sm_msg("warn: was && intended here instead of ||?");
86 static void check_and(struct expression
*expr
)
88 if (expr
->left
->type
!= EXPR_COMPARE
||
89 expr
->left
->op
!= SPECIAL_EQUAL
)
91 if (expr
->right
->type
!= EXPR_COMPARE
||
92 expr
->right
->op
!= SPECIAL_EQUAL
)
94 if (!inconsistent_check(expr
->left
, expr
->right
))
97 sm_msg("warn: was || intended here instead of &&?");
100 static void match_logic(struct expression
*expr
)
102 if (expr
->type
!= EXPR_LOGICAL
)
105 if (expr
->op
== SPECIAL_LOGICAL_OR
)
107 if (expr
->op
== SPECIAL_LOGICAL_AND
)
111 void check_or_vs_and(int id
)
115 add_hook(&match_logic
, LOGIC_HOOK
);