flow: change how "for (i = 0; ; i++) { ..." is handled
[smatch.git] / check_or_vs_and.c
blob0db557cb9069da76de138a48c1fa8e1211276e9e
1 /*
2 * sparse/check_or_vs_and.c
4 * Copyright (C) 2012 Oracle.
6 * Licensed under the Open Software License version 1.1
8 */
10 #include "smatch.h"
12 static int my_id;
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;
19 int ret = 0;
21 one_name = get_variable_from_expr_complex(one, &one_sym);
22 if (!one_name || !one_sym)
23 goto free;
24 two_name = get_variable_from_expr_complex(two, &two_sym);
25 if (!two_name || !two_sym)
26 goto free;
27 if (one_sym != two_sym)
28 goto free;
29 if (strcmp(one_name, two_name) == 0)
30 ret = 1;
31 free:
32 free_string(one_name);
33 free_string(two_name);
34 return ret;
37 static int inconsistent_check(struct expression *left, struct expression *right)
39 long long val;
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);
46 return 0;
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);
53 return 0;
56 return 0;
59 static void check_or(struct expression *expr)
61 if (expr->left->type != EXPR_COMPARE ||
62 expr->left->op != SPECIAL_NOTEQUAL)
63 return;
64 if (expr->right->type != EXPR_COMPARE ||
65 expr->right->op != SPECIAL_NOTEQUAL)
66 return;
67 if (!inconsistent_check(expr->left, expr->right))
68 return;
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)
77 return;
78 if (expr->right->type != EXPR_COMPARE ||
79 expr->right->op != SPECIAL_EQUAL)
80 return;
81 if (!inconsistent_check(expr->left, expr->right))
82 return;
84 sm_msg("warn: was || intended here instead of &&?");
87 static void match_logic(struct expression *expr)
89 if (expr->type != EXPR_LOGICAL)
90 return;
92 if (expr->op == SPECIAL_LOGICAL_OR)
93 check_or(expr);
94 if (expr->op == SPECIAL_LOGICAL_AND)
95 check_and(expr);
98 void check_or_vs_and(int id)
100 my_id = id;
102 add_hook(&match_logic, LOGIC_HOOK);