sval: type: remove debug output in get_select_type()
[smatch.git] / smatch_sval.c
blob484d08c8d1d2f6a4adbe4add22c3f8e643149a90
1 /*
2 * smatch/smatch_sval.c
4 * Copyright (C) 2012 Oracle.
6 * Licensed under the Open Software License version 1.1
9 * Basically the point of sval is that it can hold both ULLONG_MAX and
10 * LLONG_MIN. If it is an unsigned type then we use sval.uvalue or if it is
11 * signed we use sval.value.
13 * I considered just using one bit to store whether the value was signed vs
14 * unsigned but I think it might help to have the type information so we know
15 * how to do type promotion.
19 #include "smatch.h"
20 #include "smatch_slist.h"
21 #include "smatch_extra.h"
23 __ALLOCATOR(sval_t, "svals", sval);
25 sval_t *sval_alloc(sval_t sval)
27 sval_t *ret;
29 ret = __alloc_sval(0);
30 *ret = sval;
31 return ret;
34 sval_t *sval_alloc_permanent(sval_t sval)
36 sval_t *ret;
38 ret = malloc(sizeof(*ret));
39 *ret = sval;
40 return ret;
43 sval_t sval_blank(struct expression *expr)
45 sval_t ret;
47 ret.type = get_type(expr);
48 if (!ret.type)
49 ret.type = &llong_ctype;
50 ret.value = 123456789;
52 return ret;
55 sval_t sval_from_val(struct expression *expr, long long val)
57 sval_t ret;
59 ret = sval_blank(expr);
60 ret.value = val;
61 ret = sval_cast(ret, get_type(expr));
63 return ret;
66 int sval_unsigned(sval_t sval)
68 return type_unsigned(sval.type);
71 int sval_signed(sval_t sval)
73 return !type_unsigned(sval.type);
76 int sval_bits(sval_t sval)
78 if (!sval.type)
79 return 32;
80 return sval.type->bit_size;
83 int sval_positive_bits(sval_t sval)
85 if (!sval.type)
86 return 31;
87 if (sval_signed(sval))
88 return sval.type->bit_size - 1;
89 return sval.type->bit_size;
92 int sval_is_min(sval_t sval)
94 sval_t min = sval_type_min(sval.type);
96 if (sval_unsigned(sval)) {
97 if (sval.uvalue == 0)
98 return 1;
99 return 0;
101 /* return true for less than min as well */
102 return (sval.value <= min.value);
105 int sval_is_max(sval_t sval)
107 sval_t max = sval_type_max(sval.type);
109 if (sval_unsigned(sval))
110 return (sval.uvalue >= max.value);
111 return (sval.value >= max.value);
115 * Returns -1 if one is smaller, 0 if they are the same and 1 if two is larger.
117 int sval_cmp(sval_t one, sval_t two)
119 sval_t tmp;
121 tmp = one;
122 if (sval_positive_bits(two) > sval_positive_bits(one))
123 tmp = two;
124 if (sval_bits(tmp) >= 32 && sval_unsigned(tmp)) {
125 if (one.uvalue < two.uvalue)
126 return -1;
127 if (one.uvalue == two.uvalue)
128 return 0;
129 return 1;
131 /* fix me handle type promotion and unsigned values */
132 if (one.value < two.value)
133 return -1;
134 if (one.value == two.value)
135 return 0;
136 return 1;
139 int sval_cmp_t(struct symbol *type, sval_t one, sval_t two)
141 sval_t one_cast, two_cast;
143 one_cast = sval_cast(one, type);
144 two_cast = sval_cast(two, type);
145 return sval_cmp(one_cast, two_cast);
148 int sval_cmp_val(sval_t one, long long val)
150 if (one.value < val)
151 return -1;
152 if (one.value == val)
153 return 0;
154 return 1;
157 sval_t sval_cast(sval_t sval, struct symbol *type)
159 sval_t ret;
161 if (!type)
162 type = &llong_ctype;
164 ret.type = type;
165 switch (sval_bits(ret)) {
166 case 8:
167 if (sval_unsigned(ret))
168 ret.value = (long long)(unsigned char)sval.value;
169 else
170 ret.value = (long long)(char)sval.value;
171 break;
172 case 16:
173 if (sval_unsigned(ret))
174 ret.value = (long long)(unsigned short)sval.value;
175 else
176 ret.value = (long long)(short)sval.value;
177 break;
178 case 32:
179 if (sval_unsigned(ret))
180 ret.value = (long long)(unsigned int)sval.value;
181 else
182 ret.value = (long long)(int)sval.value;
183 break;
184 default:
185 ret.value = sval.value;
187 return ret;
191 sval_t sval_preop(sval_t sval, int op)
193 switch (op) {
194 case '!':
195 sval.value = !sval.value;
196 break;
197 case '~':
198 sval.value = ~sval.value;
199 /* fixme: should probably cast this here */
200 break;
201 case '-':
202 sval.value = -sval.value;
203 break;
205 return sval;
208 static sval_t sval_binop_unsigned(struct symbol *type, sval_t left, int op, sval_t right)
210 sval_t ret;
212 ret.type = type;
213 switch (op) {
214 case '*':
215 ret.uvalue = left.uvalue * right.uvalue;
216 break;
217 case '/':
218 if (right.uvalue == 0) {
219 sm_msg("debug: %s: divide by zero", __func__);
220 ret.uvalue = 123456789;
221 } else {
222 ret.uvalue = left.uvalue / right.uvalue;
224 break;
225 case '+':
226 ret.uvalue = left.uvalue + right.uvalue;
227 break;
228 case '-':
229 ret.uvalue = left.uvalue - right.uvalue;
230 break;
231 case '%':
232 if (right.uvalue == 0) {
233 sm_msg("internal error: %s: MOD by zero", __func__);
234 ret.uvalue = 123456789;
235 } else {
236 ret.uvalue = left.uvalue % right.uvalue;
238 break;
239 case '|':
240 ret.uvalue = left.uvalue | right.uvalue;
241 break;
242 case '&':
243 ret.uvalue = left.uvalue & right.uvalue;
244 break;
245 case SPECIAL_RIGHTSHIFT:
246 ret.uvalue = left.uvalue >> right.uvalue;
247 break;
248 case SPECIAL_LEFTSHIFT:
249 ret.uvalue = left.uvalue << right.uvalue;
250 break;
251 case '^':
252 ret.uvalue = left.uvalue ^ right.uvalue;
253 break;
254 default:
255 sm_msg("internal error: %s: unhandled binop %s", __func__,
256 show_special(op));
257 ret.uvalue = 1234567;
259 return ret;
263 static sval_t sval_binop_signed(struct symbol *type, sval_t left, int op, sval_t right)
265 sval_t ret;
267 ret.type = type;
268 switch (op) {
269 case '*':
270 ret.value = left.value * right.value;
271 break;
272 case '/':
273 if (right.value == 0) {
274 sm_msg("debug: %s: divide by zero", __func__);
275 ret.value = 123456789;
276 } else {
277 ret.value = left.value / right.value;
279 break;
280 case '+':
281 ret.value = left.value + right.value;
282 break;
283 case '-':
284 ret.value = left.value - right.value;
285 break;
286 case '%':
287 if (right.value == 0) {
288 sm_msg("internal error: %s: MOD by zero", __func__);
289 ret.value = 123456789;
290 } else {
291 ret.value = left.value % right.value;
293 break;
294 case '|':
295 ret.value = left.value | right.value;
296 break;
297 case '&':
298 ret.value = left.value & right.value;
299 break;
300 case SPECIAL_RIGHTSHIFT:
301 ret.value = left.value >> right.value;
302 break;
303 case SPECIAL_LEFTSHIFT:
304 ret.value = left.value << right.value;
305 break;
306 case '^':
307 ret.value = left.value ^ right.value;
308 break;
309 default:
310 sm_msg("internal error: %s: unhandled binop %s", __func__,
311 show_special(op));
312 ret.value = 1234567;
314 return ret;
317 sval_t sval_binop(sval_t left, int op, sval_t right)
319 struct symbol *type;
320 sval_t ret;
322 type = left.type;
323 if (sval_positive_bits(right) > sval_positive_bits(left))
324 type = right.type;
325 if (type_positive_bits(type) < 31)
326 type = &int_ctype;
328 if (type_unsigned(type))
329 ret = sval_binop_unsigned(type, left, op, right);
330 else
331 ret = sval_binop_signed(type, left, op, right);
332 return ret;
335 const char *sval_to_str(sval_t sval)
337 char buf[30];
339 if (sval.value && sval_bits(sval) > 8 && sval_is_min(sval))
340 return "min";
341 if (sval_bits(sval) > 8 && sval_is_max(sval))
342 return "max";
344 if (sval_unsigned(sval) && sval.value == ULLONG_MAX)
345 return "u64max";
346 if (sval.value == LLONG_MAX)
347 return "max"; // FIXME: should be s64max
348 if (sval_unsigned(sval) && sval.value == UINT_MAX)
349 return "u32max";
350 if (sval.value == INT_MAX)
351 return "s32max";
352 if (sval_unsigned(sval) && sval.value == USHRT_MAX)
353 return "u16max";
355 if ((sval.type == &sshort_ctype || sval.type == &short_ctype) && sval.value == SHRT_MIN)
356 return "s16min";
357 if ((sval.type == &sint_ctype || sval.type == &int_ctype) && sval.value == INT_MIN)
358 return "s32min";
359 if (sval_signed(sval) && sval.value == LLONG_MIN)
360 return "min"; // FIXME: should be s64min
362 if (sval_unsigned(sval))
363 snprintf(buf, sizeof(buf), "%llu", sval.value);
364 else if (sval.value < 0)
365 snprintf(buf, sizeof(buf), "(%lld)", sval.value);
366 else
367 snprintf(buf, sizeof(buf), "%lld", sval.value);
369 return alloc_sname(buf);
372 const char *sval_to_numstr(sval_t sval)
374 char buf[30];
376 if (sval_unsigned(sval))
377 snprintf(buf, sizeof(buf), "%llu", sval.value);
378 else if (sval.value < 0)
379 snprintf(buf, sizeof(buf), "(%lld)", sval.value);
380 else
381 snprintf(buf, sizeof(buf), "%lld", sval.value);
383 return alloc_sname(buf);
386 sval_t ll_to_sval(long long val)
388 sval_t ret;
390 ret.type = &llong_ctype;
391 ret.value = val;
392 return ret;
395 static void free_svals(struct symbol *sym)
397 clear_sval_alloc();
400 void register_sval(int my_id)
402 add_hook(&free_svals, END_FUNC_HOOK);