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 expr_equiv(struct expression
*one
, struct expression
*two
)
16 struct symbol
*one_sym
, *two_sym
;
17 char *one_name
= NULL
;
18 char *two_name
= NULL
;
21 one_name
= get_variable_from_expr_complex(one
, &one_sym
);
22 if (!one_name
|| !one_sym
)
24 two_name
= get_variable_from_expr_complex(two
, &two_sym
);
25 if (!two_name
|| !two_sym
)
27 if (one_sym
!= two_sym
)
29 if (strcmp(one_name
, two_name
) == 0)
32 free_string(one_name
);
33 free_string(two_name
);
37 static int inconsistent_check(struct expression
*left
, struct expression
*right
)
41 if (get_value(left
->left
, &val
)) {
42 if (get_value(right
->left
, &val
))
43 return expr_equiv(left
->right
, right
->right
);
44 if (get_value(right
->right
, &val
))
45 return expr_equiv(left
->right
, right
->left
);
48 if (get_value(left
->right
, &val
)) {
49 if (get_value(right
->left
, &val
))
50 return expr_equiv(left
->left
, right
->right
);
51 if (get_value(right
->right
, &val
))
52 return expr_equiv(left
->left
, right
->left
);
59 static void check_or(struct expression
*expr
)
61 if (expr
->left
->type
!= EXPR_COMPARE
||
62 expr
->left
->op
!= SPECIAL_NOTEQUAL
)
64 if (expr
->right
->type
!= EXPR_COMPARE
||
65 expr
->right
->op
!= SPECIAL_NOTEQUAL
)
67 if (!inconsistent_check(expr
->left
, expr
->right
))
70 sm_msg("warn: was && intended here instead of ||?");
73 static void check_and(struct expression
*expr
)
75 if (expr
->left
->type
!= EXPR_COMPARE
||
76 expr
->left
->op
!= SPECIAL_EQUAL
)
78 if (expr
->right
->type
!= EXPR_COMPARE
||
79 expr
->right
->op
!= SPECIAL_EQUAL
)
81 if (!inconsistent_check(expr
->left
, expr
->right
))
84 sm_msg("warn: was || intended here instead of &&?");
87 static void match_logic(struct expression
*expr
)
89 if (expr
->type
!= EXPR_LOGICAL
)
92 if (expr
->op
== SPECIAL_LOGICAL_OR
)
94 if (expr
->op
== SPECIAL_LOGICAL_AND
)
98 void check_or_vs_and(int id
)
102 add_hook(&match_logic
, LOGIC_HOOK
);