extra: handle "if (a & 0x1)" conditions
[smatch.git] / smatch_recurse.c
blobc86b1160fab661f2a4595db39d07dbeee3f5aa26
1 /*
2 * sparse/smatch_recurse.c
4 * Copyright (C) 2013 Oracle.
6 * Licensed under the Open Software License version 1.1
8 */
10 #include "smatch.h"
12 #define RECURSE_LIMIT 10
14 static int recurse(struct expression *expr,
15 int (func)(struct expression *expr, void *p),
16 void *param, int nr)
18 int ret;
20 if (!expr)
21 return 0;
23 ret = func(expr, param);
24 if (ret)
25 return ret;
27 if (nr > RECURSE_LIMIT)
28 return -1;
29 nr++;
31 switch (expr->type) {
32 case EXPR_PREOP:
33 ret = recurse(expr->unop, func, param, nr);
34 break;
35 case EXPR_POSTOP:
36 ret = recurse(expr->unop, func, param, nr);
37 break;
38 case EXPR_STATEMENT:
39 return -1;
40 break;
41 case EXPR_LOGICAL:
42 case EXPR_COMPARE:
43 case EXPR_BINOP:
44 case EXPR_COMMA:
45 ret = recurse(expr->left, func, param, nr);
46 if (ret)
47 return ret;
48 ret = recurse(expr->right, func, param, nr);
49 break;
50 case EXPR_ASSIGNMENT:
51 ret = recurse(expr->right, func, param, nr);
52 if (ret)
53 return ret;
54 ret = recurse(expr->left, func, param, nr);
55 break;
56 case EXPR_DEREF:
57 ret = recurse(expr->deref, func, param, nr);
58 break;
59 case EXPR_SLICE:
60 ret = recurse(expr->base, func, param, nr);
61 break;
62 case EXPR_CAST:
63 case EXPR_FORCE_CAST:
64 ret = recurse(expr->cast_expression, func, param, nr);
65 break;
66 case EXPR_SIZEOF:
67 case EXPR_OFFSETOF:
68 case EXPR_ALIGNOF:
69 break;
70 case EXPR_CONDITIONAL:
71 case EXPR_SELECT:
72 ret = recurse(expr->conditional, func, param, nr);
73 if (ret)
74 return ret;
75 ret = recurse(expr->cond_true, func, param, nr);
76 if (ret)
77 return ret;
78 ret = recurse(expr->cond_false, func, param, nr);
79 break;
80 case EXPR_CALL:
81 return -1;
82 break;
83 case EXPR_INITIALIZER:
84 return -1;
85 break;
86 case EXPR_IDENTIFIER:
87 ret = recurse(expr->ident_expression, func, param, nr);
88 break;
89 case EXPR_INDEX:
90 ret = recurse(expr->idx_expression, func, param, nr);
91 break;
92 case EXPR_POS:
93 ret = recurse(expr->init_expr, func, param, nr);
94 break;
95 case EXPR_SYMBOL:
96 case EXPR_STRING:
97 case EXPR_VALUE:
98 break;
99 default:
100 return -1;
101 break;
103 return ret;
106 static int has_symbol_helper(struct expression *expr, void *_sym)
108 struct symbol *sym = _sym;
110 if (!expr || expr->type != EXPR_SYMBOL)
111 return 0;
112 if (expr->symbol == sym)
113 return 1;
114 return 0;
117 int has_symbol(struct expression *expr, struct symbol *sym)
119 return recurse(expr, has_symbol_helper, sym, 0);
122 int has_variable(struct expression *expr, struct expression *var)
124 char *name;
125 struct symbol *sym;
127 name = expr_to_var_sym(var, &sym);
128 free_string(name);
129 if (!sym)
130 return -1;
131 return has_symbol(expr, sym);