math: improve how known logical operations are handled
[smatch.git] / smatch_type.c
blob8e808a6b9b917af33fe892a1daf7a0ace98463b7
1 /*
2 * sparse/smatch_types.c
4 * Copyright (C) 2009 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
11 * The idea here is that you have an expression and you
12 * want to know what the type is for that.
15 #include "smatch.h"
17 struct symbol *get_real_base_type(struct symbol *sym)
19 struct symbol *ret;
21 ret = get_base_type(sym);
22 if (ret && ret->type == SYM_RESTRICT)
23 return get_real_base_type(ret);
24 return ret;
27 static struct symbol *get_binop_type(struct expression *expr)
29 struct symbol *left, *right;
31 left = get_type(expr->left);
32 right = get_type(expr->right);
34 if (!left || !right)
35 return NULL;
37 if (left->type == SYM_PTR || left->type == SYM_ARRAY)
38 return left;
39 if (right->type == SYM_PTR || right->type == SYM_ARRAY)
40 return right;
42 if (type_max(left) < type_max(&int_ctype) &&
43 type_max(right) < type_max(&int_ctype))
44 return &int_ctype;
46 if (type_max(right) > type_max(left))
47 return right;
48 return left;
51 static struct symbol *get_type_symbol(struct expression *expr)
53 if (!expr || expr->type != EXPR_SYMBOL || !expr->symbol)
54 return NULL;
56 return get_real_base_type(expr->symbol);
59 static struct symbol *get_symbol_from_deref(struct expression *expr)
61 struct ident *member;
62 struct symbol *struct_sym;
63 struct symbol *tmp;
65 if (!expr || expr->type != EXPR_DEREF)
66 return NULL;
68 member = expr->member;
69 struct_sym = get_type(expr->deref);
70 if (!struct_sym) {
71 // sm_msg("could not find struct type");
72 return NULL;
74 if (struct_sym->type == SYM_PTR)
75 struct_sym = get_real_base_type(struct_sym);
76 FOR_EACH_PTR(struct_sym->symbol_list, tmp) {
77 if (tmp->ident == member)
78 return get_real_base_type(tmp);
79 } END_FOR_EACH_PTR(tmp);
80 return NULL;
83 static struct symbol *get_return_type(struct expression *expr)
85 struct symbol *tmp;
87 tmp = get_type(expr->fn);
88 if (!tmp)
89 return NULL;
90 return get_real_base_type(tmp);
93 struct symbol *get_pointer_type(struct expression *expr)
95 struct symbol *sym;
97 sym = get_type(expr);
98 if (!sym || (sym->type != SYM_PTR && sym->type != SYM_ARRAY))
99 return NULL;
100 return get_real_base_type(sym);
103 static struct symbol *fake_pointer_sym(struct expression *expr)
105 struct symbol *sym;
106 struct symbol *base;
108 sym = alloc_symbol(expr->pos, SYM_PTR);
109 expr = expr->unop;
110 base = get_type(expr);
111 if (!base)
112 return NULL;
113 sym->ctype.base_type = base;
114 return sym;
117 struct symbol *get_type(struct expression *expr)
119 if (!expr)
120 return NULL;
121 expr = strip_parens(expr);
123 switch (expr->type) {
124 case EXPR_SYMBOL:
125 return get_type_symbol(expr);
126 case EXPR_DEREF:
127 return get_symbol_from_deref(expr);
128 case EXPR_PREOP:
129 if (expr->op == '&')
130 return fake_pointer_sym(expr);
131 if (expr->op == '*')
132 return get_pointer_type(expr->unop);
133 return get_type(expr->unop);
134 case EXPR_CAST:
135 case EXPR_FORCE_CAST:
136 case EXPR_IMPLIED_CAST:
137 return get_real_base_type(expr->cast_type);
138 case EXPR_BINOP:
139 return get_binop_type(expr);
140 case EXPR_CALL:
141 return get_return_type(expr);
142 case EXPR_SIZEOF:
143 return &ulong_ctype;
144 default:
145 return expr->ctype;
146 // sm_msg("unhandled type %d", expr->type);
150 return NULL;
153 int type_unsigned(struct symbol *base_type)
155 if (!base_type)
156 return 0;
157 if (base_type->ctype.modifiers & MOD_UNSIGNED)
158 return 1;
159 return 0;
162 int expr_unsigned(struct expression *expr)
164 struct symbol *sym;
166 sym = get_type(expr);
167 if (!sym)
168 return 0;
169 if (type_unsigned(sym))
170 return 1;
171 return 0;
174 int returns_unsigned(struct symbol *sym)
176 if (!sym)
177 return 0;
178 sym = get_base_type(sym);
179 if (!sym || sym->type != SYM_FN)
180 return 0;
181 sym = get_base_type(sym);
182 return type_unsigned(sym);
185 int is_pointer(struct expression *expr)
187 struct symbol *sym;
189 sym = get_type(expr);
190 if (!sym)
191 return 0;
192 if (sym->type == SYM_PTR)
193 return 1;
194 return 0;
197 int returns_pointer(struct symbol *sym)
199 if (!sym)
200 return 0;
201 sym = get_base_type(sym);
202 if (!sym || sym->type != SYM_FN)
203 return 0;
204 sym = get_base_type(sym);
205 if (sym->type == SYM_PTR)
206 return 1;
207 return 0;
210 long long type_max(struct symbol *base_type)
212 long long ret = whole_range.max;
213 int bits;
215 if (!base_type || !base_type->bit_size)
216 return ret;
217 bits = base_type->bit_size;
218 if (bits == 64)
219 return ret;
220 if (!type_unsigned(base_type))
221 bits--;
222 ret >>= (63 - bits);
223 return ret;
226 long long type_min(struct symbol *base_type)
228 long long ret = whole_range.min;
229 int bits;
231 if (!base_type || !base_type->bit_size)
232 return ret;
233 if (type_unsigned(base_type))
234 return 0;
235 ret = whole_range.max;
236 bits = base_type->bit_size - 1;
237 ret >>= (63 - bits);
238 return -(ret + 1);
241 int nr_bits(struct expression *expr)
243 struct symbol *type;
245 type = get_type(expr);
246 if (!type)
247 return 0;
248 return type->bit_size;
251 int is_static(struct expression *expr)
253 char *name;
254 struct symbol *sym;
255 int ret = 0;
257 name = get_variable_from_expr_complex(expr, &sym);
258 if (!name || !sym)
259 goto free;
261 if (sym->ctype.modifiers & MOD_STATIC)
262 ret = 1;
263 free:
264 free_string(name);
265 return ret;
268 const char *global_static()
270 if (cur_func_sym->ctype.modifiers & MOD_STATIC)
271 return "static";
272 else
273 return "global";