sval: add sval_type_min()
[smatch.git] / smatch_type.c
blob2e5cadca04be84b580920719539eedec9709e75a
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 (expr->op == SPECIAL_LEFTSHIFT ||
43 expr->op == SPECIAL_RIGHTSHIFT) {
44 if (type_max(left) < type_max(&int_ctype))
45 return &int_ctype;
46 return left;
49 if (type_max(left) < type_max(&int_ctype) &&
50 type_max(right) < type_max(&int_ctype))
51 return &int_ctype;
53 if (type_max(right) > type_max(left))
54 return right;
55 return left;
58 static struct symbol *get_type_symbol(struct expression *expr)
60 if (!expr || expr->type != EXPR_SYMBOL || !expr->symbol)
61 return NULL;
63 return get_real_base_type(expr->symbol);
66 static struct symbol *get_symbol_from_deref(struct expression *expr)
68 struct ident *member;
69 struct symbol *struct_sym;
70 struct symbol *tmp;
72 if (!expr || expr->type != EXPR_DEREF)
73 return NULL;
75 member = expr->member;
76 struct_sym = get_type(expr->deref);
77 if (!struct_sym) {
78 // sm_msg("could not find struct type");
79 return NULL;
81 if (struct_sym->type == SYM_PTR)
82 struct_sym = get_real_base_type(struct_sym);
83 FOR_EACH_PTR(struct_sym->symbol_list, tmp) {
84 if (tmp->ident == member)
85 return get_real_base_type(tmp);
86 } END_FOR_EACH_PTR(tmp);
87 return NULL;
90 static struct symbol *get_return_type(struct expression *expr)
92 struct symbol *tmp;
94 tmp = get_type(expr->fn);
95 if (!tmp)
96 return NULL;
97 return get_real_base_type(tmp);
100 struct symbol *get_pointer_type(struct expression *expr)
102 struct symbol *sym;
104 sym = get_type(expr);
105 if (!sym || (sym->type != SYM_PTR && sym->type != SYM_ARRAY))
106 return NULL;
107 return get_real_base_type(sym);
110 static struct symbol *fake_pointer_sym(struct expression *expr)
112 struct symbol *sym;
113 struct symbol *base;
115 sym = alloc_symbol(expr->pos, SYM_PTR);
116 expr = expr->unop;
117 base = get_type(expr);
118 if (!base)
119 return NULL;
120 sym->ctype.base_type = base;
121 return sym;
124 struct symbol *get_type(struct expression *expr)
126 if (!expr)
127 return NULL;
128 expr = strip_parens(expr);
130 switch (expr->type) {
131 case EXPR_SYMBOL:
132 return get_type_symbol(expr);
133 case EXPR_DEREF:
134 return get_symbol_from_deref(expr);
135 case EXPR_PREOP:
136 if (expr->op == '&')
137 return fake_pointer_sym(expr);
138 if (expr->op == '*')
139 return get_pointer_type(expr->unop);
140 return get_type(expr->unop);
141 case EXPR_ASSIGNMENT:
142 return get_type(expr->left);
143 case EXPR_CAST:
144 case EXPR_FORCE_CAST:
145 case EXPR_IMPLIED_CAST:
146 return get_real_base_type(expr->cast_type);
147 case EXPR_BINOP:
148 return get_binop_type(expr);
149 case EXPR_CALL:
150 return get_return_type(expr);
151 case EXPR_SIZEOF:
152 return &ulong_ctype;
153 case EXPR_COMPARE:
154 case EXPR_LOGICAL:
155 return &int_ctype;
156 default:
157 return expr->ctype;
158 // sm_msg("unhandled type %d", expr->type);
162 return NULL;
165 int type_unsigned(struct symbol *base_type)
167 if (!base_type)
168 return 0;
169 if (base_type->ctype.modifiers & MOD_UNSIGNED)
170 return 1;
171 return 0;
174 int expr_unsigned(struct expression *expr)
176 struct symbol *sym;
178 sym = get_type(expr);
179 if (!sym)
180 return 0;
181 if (type_unsigned(sym))
182 return 1;
183 return 0;
186 int returns_unsigned(struct symbol *sym)
188 if (!sym)
189 return 0;
190 sym = get_base_type(sym);
191 if (!sym || sym->type != SYM_FN)
192 return 0;
193 sym = get_base_type(sym);
194 return type_unsigned(sym);
197 int is_pointer(struct expression *expr)
199 struct symbol *sym;
201 sym = get_type(expr);
202 if (!sym)
203 return 0;
204 if (sym->type == SYM_PTR)
205 return 1;
206 return 0;
209 int returns_pointer(struct symbol *sym)
211 if (!sym)
212 return 0;
213 sym = get_base_type(sym);
214 if (!sym || sym->type != SYM_FN)
215 return 0;
216 sym = get_base_type(sym);
217 if (sym->type == SYM_PTR)
218 return 1;
219 return 0;
222 long long type_max(struct symbol *base_type)
224 long long ret = whole_range.max;
225 int bits;
227 if (!base_type || !base_type->bit_size)
228 return ret;
229 bits = base_type->bit_size;
230 if (bits == 64)
231 return ret;
232 if (!type_unsigned(base_type))
233 bits--;
234 ret >>= (63 - bits);
235 return ret;
238 sval_t sval_type_max(struct symbol *base_type)
240 sval_t ret;
242 ret.value = (~0ULL) >> 1;
243 ret.type = base_type;
245 if (!base_type || !base_type->bit_size)
246 return ret;
248 if (type_unsigned(base_type))
249 ret.value = (~0ULL) >> (64 - base_type->bit_size);
250 else
251 ret.value = (~0ULL) >> (64 - (base_type->bit_size - 1));
253 return ret;
256 long long type_min(struct symbol *base_type)
258 long long ret = whole_range.min;
259 int bits;
261 if (!base_type || !base_type->bit_size)
262 return ret;
263 if (type_unsigned(base_type))
264 return 0;
265 ret = whole_range.max;
266 bits = base_type->bit_size - 1;
267 ret >>= (63 - bits);
268 return -(ret + 1);
271 sval_t sval_type_min(struct symbol *base_type)
273 sval_t ret;
275 if (!base_type || !base_type->bit_size)
276 base_type = &llong_ctype;
277 ret.type = base_type;
279 if (type_unsigned(base_type)) {
280 ret.value = 0;
281 return ret;
284 ret.value = (~0ULL) << (base_type->bit_size - 1);
286 return ret;
289 int nr_bits(struct expression *expr)
291 struct symbol *type;
293 type = get_type(expr);
294 if (!type)
295 return 0;
296 return type->bit_size;
299 int is_static(struct expression *expr)
301 char *name;
302 struct symbol *sym;
303 int ret = 0;
305 name = get_variable_from_expr_complex(expr, &sym);
306 if (!name || !sym)
307 goto free;
309 if (sym->ctype.modifiers & MOD_STATIC)
310 ret = 1;
311 free:
312 free_string(name);
313 return ret;
316 const char *global_static()
318 if (cur_func_sym->ctype.modifiers & MOD_STATIC)
319 return "static";
320 else
321 return "global";