sval: remove the _sval() from estate_get_single_value_sval()
[smatch.git] / smatch_sval.c
blob45f025315705a2b9ce284f4c34ac77eca6d11f7a
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_type_val(struct symbol *type, long long val)
57 sval_t ret;
59 ret.type = type;
60 ret.value = val;
61 return ret;
64 sval_t sval_from_val(struct expression *expr, long long val)
66 sval_t ret;
68 ret = sval_blank(expr);
69 ret.value = val;
70 ret = sval_cast(ret, get_type(expr));
72 return ret;
75 int sval_unsigned(sval_t sval)
77 return type_unsigned(sval.type);
80 int sval_signed(sval_t sval)
82 return !type_unsigned(sval.type);
85 int sval_bits(sval_t sval)
87 if (!sval.type)
88 return 32;
89 return sval.type->bit_size;
92 int sval_positive_bits(sval_t sval)
94 if (!sval.type)
95 return 31;
96 if (sval_signed(sval))
97 return sval.type->bit_size - 1;
98 return sval.type->bit_size;
101 int sval_is_min(sval_t sval)
103 sval_t min = sval_type_min(sval.type);
105 if (sval_unsigned(sval)) {
106 if (sval.uvalue == 0)
107 return 1;
108 return 0;
110 /* return true for less than min as well */
111 return (sval.value <= min.value);
114 int sval_is_max(sval_t sval)
116 sval_t max = sval_type_max(sval.type);
118 if (sval_unsigned(sval))
119 return (sval.uvalue >= max.value);
120 return (sval.value >= max.value);
124 * Returns -1 if one is smaller, 0 if they are the same and 1 if two is larger.
126 int sval_cmp(sval_t one, sval_t two)
128 sval_t tmp;
130 tmp = one;
131 if (sval_positive_bits(two) > sval_positive_bits(one))
132 tmp = two;
133 if (sval_bits(tmp) >= 32 && sval_unsigned(tmp)) {
134 if (one.uvalue < two.uvalue)
135 return -1;
136 if (one.uvalue == two.uvalue)
137 return 0;
138 return 1;
140 /* fix me handle type promotion and unsigned values */
141 if (one.value < two.value)
142 return -1;
143 if (one.value == two.value)
144 return 0;
145 return 1;
148 int sval_cmp_t(struct symbol *type, sval_t one, sval_t two)
150 sval_t one_cast, two_cast;
152 one_cast = sval_cast(one, type);
153 two_cast = sval_cast(two, type);
154 return sval_cmp(one_cast, two_cast);
157 int sval_cmp_val(sval_t one, long long val)
159 if (one.value < val)
160 return -1;
161 if (one.value == val)
162 return 0;
163 return 1;
166 sval_t sval_cast(sval_t sval, struct symbol *type)
168 sval_t ret;
170 if (!type)
171 type = &llong_ctype;
173 ret.type = type;
174 switch (sval_bits(ret)) {
175 case 8:
176 if (sval_unsigned(ret))
177 ret.value = (long long)(unsigned char)sval.value;
178 else
179 ret.value = (long long)(char)sval.value;
180 break;
181 case 16:
182 if (sval_unsigned(ret))
183 ret.value = (long long)(unsigned short)sval.value;
184 else
185 ret.value = (long long)(short)sval.value;
186 break;
187 case 32:
188 if (sval_unsigned(ret))
189 ret.value = (long long)(unsigned int)sval.value;
190 else
191 ret.value = (long long)(int)sval.value;
192 break;
193 default:
194 ret.value = sval.value;
196 return ret;
200 sval_t sval_preop(sval_t sval, int op)
202 switch (op) {
203 case '!':
204 sval.value = !sval.value;
205 break;
206 case '~':
207 sval.value = ~sval.value;
208 /* fixme: should probably cast this here */
209 break;
210 case '-':
211 sval.value = -sval.value;
212 break;
214 return sval;
217 static sval_t sval_binop_unsigned(struct symbol *type, sval_t left, int op, sval_t right)
219 sval_t ret;
221 ret.type = type;
222 switch (op) {
223 case '*':
224 ret.uvalue = left.uvalue * right.uvalue;
225 break;
226 case '/':
227 if (right.uvalue == 0) {
228 sm_msg("debug: %s: divide by zero", __func__);
229 ret.uvalue = 123456789;
230 } else {
231 ret.uvalue = left.uvalue / right.uvalue;
233 break;
234 case '+':
235 ret.uvalue = left.uvalue + right.uvalue;
236 break;
237 case '-':
238 ret.uvalue = left.uvalue - right.uvalue;
239 break;
240 case '%':
241 if (right.uvalue == 0) {
242 sm_msg("internal error: %s: MOD by zero", __func__);
243 ret.uvalue = 123456789;
244 } else {
245 ret.uvalue = left.uvalue % right.uvalue;
247 break;
248 case '|':
249 ret.uvalue = left.uvalue | right.uvalue;
250 break;
251 case '&':
252 ret.uvalue = left.uvalue & right.uvalue;
253 break;
254 case SPECIAL_RIGHTSHIFT:
255 ret.uvalue = left.uvalue >> right.uvalue;
256 break;
257 case SPECIAL_LEFTSHIFT:
258 ret.uvalue = left.uvalue << right.uvalue;
259 break;
260 case '^':
261 ret.uvalue = left.uvalue ^ right.uvalue;
262 break;
263 default:
264 sm_msg("internal error: %s: unhandled binop %s", __func__,
265 show_special(op));
266 ret.uvalue = 1234567;
268 return ret;
272 static sval_t sval_binop_signed(struct symbol *type, sval_t left, int op, sval_t right)
274 sval_t ret;
276 ret.type = type;
277 switch (op) {
278 case '*':
279 ret.value = left.value * right.value;
280 break;
281 case '/':
282 if (right.value == 0) {
283 sm_msg("debug: %s: divide by zero", __func__);
284 ret.value = 123456789;
285 } else {
286 ret.value = left.value / right.value;
288 break;
289 case '+':
290 ret.value = left.value + right.value;
291 break;
292 case '-':
293 ret.value = left.value - right.value;
294 break;
295 case '%':
296 if (right.value == 0) {
297 sm_msg("internal error: %s: MOD by zero", __func__);
298 ret.value = 123456789;
299 } else {
300 ret.value = left.value % right.value;
302 break;
303 case '|':
304 ret.value = left.value | right.value;
305 break;
306 case '&':
307 ret.value = left.value & right.value;
308 break;
309 case SPECIAL_RIGHTSHIFT:
310 ret.value = left.value >> right.value;
311 break;
312 case SPECIAL_LEFTSHIFT:
313 ret.value = left.value << right.value;
314 break;
315 case '^':
316 ret.value = left.value ^ right.value;
317 break;
318 default:
319 sm_msg("internal error: %s: unhandled binop %s", __func__,
320 show_special(op));
321 ret.value = 1234567;
323 return ret;
326 sval_t sval_binop(sval_t left, int op, sval_t right)
328 struct symbol *type;
329 sval_t ret;
331 type = left.type;
332 if (sval_positive_bits(right) > sval_positive_bits(left))
333 type = right.type;
334 if (type_positive_bits(type) < 31)
335 type = &int_ctype;
337 if (type_unsigned(type))
338 ret = sval_binop_unsigned(type, left, op, right);
339 else
340 ret = sval_binop_signed(type, left, op, right);
341 return ret;
344 const char *sval_to_str(sval_t sval)
346 char buf[30];
348 if (sval.value && sval_bits(sval) > 8 && sval_is_min(sval))
349 return "min";
350 if (sval_bits(sval) > 8 && sval_is_max(sval))
351 return "max";
353 if (sval_unsigned(sval) && sval.value == ULLONG_MAX)
354 return "u64max";
355 if (sval.value == LLONG_MAX)
356 return "max"; // FIXME: should be s64max
357 if (sval_unsigned(sval) && sval.value == UINT_MAX)
358 return "u32max";
359 if (sval.value == INT_MAX)
360 return "s32max";
361 if (sval_unsigned(sval) && sval.value == USHRT_MAX)
362 return "u16max";
364 if ((sval.type == &sshort_ctype || sval.type == &short_ctype) && sval.value == SHRT_MIN)
365 return "s16min";
366 if ((sval.type == &sint_ctype || sval.type == &int_ctype) && sval.value == INT_MIN)
367 return "s32min";
368 if (sval_signed(sval) && sval.value == LLONG_MIN)
369 return "min"; // FIXME: should be s64min
371 if (sval_unsigned(sval))
372 snprintf(buf, sizeof(buf), "%llu", sval.value);
373 else if (sval.value < 0)
374 snprintf(buf, sizeof(buf), "(%lld)", sval.value);
375 else
376 snprintf(buf, sizeof(buf), "%lld", sval.value);
378 return alloc_sname(buf);
381 const char *sval_to_numstr(sval_t sval)
383 char buf[30];
385 if (sval_unsigned(sval))
386 snprintf(buf, sizeof(buf), "%llu", sval.value);
387 else if (sval.value < 0)
388 snprintf(buf, sizeof(buf), "(%lld)", sval.value);
389 else
390 snprintf(buf, sizeof(buf), "%lld", sval.value);
392 return alloc_sname(buf);
395 sval_t ll_to_sval(long long val)
397 sval_t ret;
399 ret.type = &llong_ctype;
400 ret.value = val;
401 return ret;
404 static void free_svals(struct symbol *sym)
406 clear_sval_alloc();
409 void register_sval(int my_id)
411 add_hook(&free_svals, END_FUNC_HOOK);