constraints: equiv: rename smatch_constraints.c to smatch_equiv.c
[smatch.git] / smatch_sval.c
blobf3c2a19fcf4698db140b33f1b426f06666e180eb
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(get_type(expr), ret);
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 return type_bits(sval.type);
90 int sval_positive_bits(sval_t sval)
92 return type_positive_bits(sval.type);
95 int sval_bits_used(sval_t sval)
97 int i;
99 for (i = 64; i >= 1; i--) {
100 if (sval.uvalue & (1ULL << (i - 1)))
101 return i;
103 return 0;
106 int sval_is_negative(sval_t sval)
108 if (sval_cmp_val(sval, 0) < 0)
109 return 1;
110 return 0;
113 int sval_is_positive(sval_t sval)
115 return !sval_is_negative(sval);
118 int sval_is_min(sval_t sval)
120 sval_t min = sval_type_min(sval.type);
122 if (sval_unsigned(sval)) {
123 if (sval.uvalue == 0)
124 return 1;
125 return 0;
127 /* return true for less than min as well */
128 return (sval.value <= min.value);
131 int sval_is_max(sval_t sval)
133 sval_t max = sval_type_max(sval.type);
135 if (sval_unsigned(sval))
136 return (sval.uvalue >= max.value);
137 return (sval.value >= max.value);
140 int sval_is_a_min(sval_t sval)
142 if (sval_signed(sval) && sval.value == SHRT_MIN)
143 return 1;
144 if (sval_signed(sval) && sval.value == INT_MIN)
145 return 1;
146 if (sval_signed(sval) && sval.value == LLONG_MIN)
147 return 1;
148 return 0;
151 int sval_is_a_max(sval_t sval)
153 if (sval.uvalue == SHRT_MAX)
154 return 1;
155 if (sval.uvalue == INT_MAX)
156 return 1;
157 if (sval.uvalue == LLONG_MAX)
158 return 1;
159 if (sval.uvalue == USHRT_MAX)
160 return 1;
161 if (sval.uvalue == UINT_MAX)
162 return 1;
163 if (sval_unsigned(sval) && sval.uvalue == ULLONG_MAX)
164 return 1;
165 return 0;
169 * Returns -1 if one is smaller, 0 if they are the same and 1 if two is larger.
171 int sval_cmp(sval_t one, sval_t two)
173 struct symbol *type;
175 type = one.type;
176 if (sval_positive_bits(two) > sval_positive_bits(one))
177 type = two.type;
178 if (type_bits(type) < 31)
179 type = &int_ctype;
181 one = sval_cast(type, one);
182 two = sval_cast(type, two);
184 if (type_unsigned(type)) {
185 if (one.uvalue < two.uvalue)
186 return -1;
187 if (one.uvalue == two.uvalue)
188 return 0;
189 return 1;
191 /* fix me handle type promotion and unsigned values */
192 if (one.value < two.value)
193 return -1;
194 if (one.value == two.value)
195 return 0;
196 return 1;
199 int sval_cmp_t(struct symbol *type, sval_t one, sval_t two)
201 sval_t one_cast, two_cast;
203 one_cast = sval_cast(type, one);
204 two_cast = sval_cast(type, two);
205 return sval_cmp(one_cast, two_cast);
208 int sval_cmp_val(sval_t one, long long val)
210 sval_t sval;
212 sval = sval_type_val(&llong_ctype, val);
213 return sval_cmp(one, sval);
216 int sval_too_low(struct symbol *type, sval_t sval)
218 if (sval_is_negative(sval) && type_unsigned(type))
219 return 1;
220 if (type_signed(type) && sval_unsigned(sval))
221 return 0;
222 if (sval_cmp(sval, sval_type_min(type)) < 0)
223 return 1;
224 return 0;
227 int sval_too_high(struct symbol *type, sval_t sval)
229 if (sval_is_negative(sval))
230 return 0;
231 if (sval_cmp(sval, sval_type_max(type)) > 0)
232 return 1;
233 return 0;
236 int sval_fits(struct symbol *type, sval_t sval)
238 if (sval_too_low(type, sval))
239 return 0;
240 if (sval_too_high(type, sval))
241 return 0;
242 return 1;
245 sval_t sval_cast(struct symbol *type, sval_t sval)
247 sval_t ret;
249 if (!type)
250 type = &llong_ctype;
252 ret.type = type;
253 switch (sval_bits(ret)) {
254 case 8:
255 if (sval_unsigned(ret))
256 ret.value = (long long)(unsigned char)sval.value;
257 else
258 ret.value = (long long)(char)sval.value;
259 break;
260 case 16:
261 if (sval_unsigned(ret))
262 ret.value = (long long)(unsigned short)sval.value;
263 else
264 ret.value = (long long)(short)sval.value;
265 break;
266 case 32:
267 if (sval_unsigned(ret))
268 ret.value = (long long)(unsigned int)sval.value;
269 else
270 ret.value = (long long)(int)sval.value;
271 break;
272 default:
273 ret.value = sval.value;
275 return ret;
279 sval_t sval_preop(sval_t sval, int op)
281 switch (op) {
282 case '!':
283 sval.value = !sval.value;
284 break;
285 case '~':
286 sval.value = ~sval.value;
287 /* fixme: should probably cast this here */
288 break;
289 case '-':
290 sval.value = -sval.value;
291 break;
293 return sval;
296 static sval_t sval_binop_unsigned(struct symbol *type, sval_t left, int op, sval_t right)
298 sval_t ret;
300 ret.type = type;
301 switch (op) {
302 case '*':
303 ret.uvalue = left.uvalue * right.uvalue;
304 break;
305 case '/':
306 if (right.uvalue == 0) {
307 sm_msg("debug: %s: divide by zero", __func__);
308 ret.uvalue = 123456789;
309 } else {
310 ret.uvalue = left.uvalue / right.uvalue;
312 break;
313 case '+':
314 ret.uvalue = left.uvalue + right.uvalue;
315 break;
316 case '-':
317 ret.uvalue = left.uvalue - right.uvalue;
318 break;
319 case '%':
320 if (right.uvalue == 0) {
321 sm_msg("internal error: %s: MOD by zero", __func__);
322 ret.uvalue = 123456789;
323 } else {
324 ret.uvalue = left.uvalue % right.uvalue;
326 break;
327 case '|':
328 ret.uvalue = left.uvalue | right.uvalue;
329 break;
330 case '&':
331 ret.uvalue = left.uvalue & right.uvalue;
332 break;
333 case SPECIAL_RIGHTSHIFT:
334 ret.uvalue = left.uvalue >> right.uvalue;
335 break;
336 case SPECIAL_LEFTSHIFT:
337 ret.uvalue = left.uvalue << right.uvalue;
338 break;
339 case '^':
340 ret.uvalue = left.uvalue ^ right.uvalue;
341 break;
342 default:
343 sm_msg("internal error: %s: unhandled binop %s", __func__,
344 show_special(op));
345 ret.uvalue = 1234567;
347 return ret;
351 static sval_t sval_binop_signed(struct symbol *type, sval_t left, int op, sval_t right)
353 sval_t ret;
355 ret.type = type;
356 switch (op) {
357 case '*':
358 ret.value = left.value * right.value;
359 break;
360 case '/':
361 if (right.value == 0) {
362 sm_msg("debug: %s: divide by zero", __func__);
363 ret.value = 123456789;
364 } else if (left.value == LLONG_MIN && right.value == -1) {
365 sm_msg("debug: %s: invalid divide LLONG_MIN/-1", __func__);
366 ret.value = 12345678;
367 } else {
368 ret.value = left.value / right.value;
370 break;
371 case '+':
372 ret.value = left.value + right.value;
373 break;
374 case '-':
375 ret.value = left.value - right.value;
376 break;
377 case '%':
378 if (right.value == 0) {
379 sm_msg("internal error: %s: MOD by zero", __func__);
380 ret.value = 123456789;
381 } else {
382 ret.value = left.value % right.value;
384 break;
385 case '|':
386 ret.value = left.value | right.value;
387 break;
388 case '&':
389 ret.value = left.value & right.value;
390 break;
391 case SPECIAL_RIGHTSHIFT:
392 ret.value = left.value >> right.value;
393 break;
394 case SPECIAL_LEFTSHIFT:
395 ret.value = left.value << right.value;
396 break;
397 case '^':
398 ret.value = left.value ^ right.value;
399 break;
400 default:
401 sm_msg("internal error: %s: unhandled binop %s", __func__,
402 show_special(op));
403 ret.value = 1234567;
405 return ret;
408 sval_t sval_binop(sval_t left, int op, sval_t right)
410 struct symbol *type;
411 sval_t ret;
413 type = left.type;
414 if (sval_positive_bits(right) > sval_positive_bits(left))
415 type = right.type;
416 if (type_positive_bits(type) < 31)
417 type = &int_ctype;
419 if (type_unsigned(type))
420 ret = sval_binop_unsigned(type, left, op, right);
421 else
422 ret = sval_binop_signed(type, left, op, right);
423 return ret;
426 int sval_binop_overflows(sval_t left, int op, sval_t right)
428 sval_t max = sval_type_max(left.type);
430 switch (op) {
431 case '+':
432 if (sval_cmp(left, sval_binop(max, '-', right)) > 0)
433 return 1;
434 return 0;
435 case '*':
436 if (sval_cmp(left, sval_binop(max, '/', right)) > 0)
437 return 1;
438 return 0;
440 return 0;
443 const char *sval_to_str(sval_t sval)
445 char buf[30];
447 if (sval_unsigned(sval) && sval.value == ULLONG_MAX)
448 return "u64max";
449 if (sval.value == LLONG_MAX)
450 return "s64max";
451 if (sval_unsigned(sval) && sval.value == UINT_MAX)
452 return "u32max";
453 if (sval.value == INT_MAX)
454 return "s32max";
455 if (sval_unsigned(sval) && sval.value == USHRT_MAX)
456 return "u16max";
457 if (sval.value == SHRT_MAX)
458 return "s16max";
460 if (sval_signed(sval) && sval.value == SHRT_MIN)
461 return "s16min";
462 if (sval_signed(sval) && sval.value == INT_MIN)
463 return "s32min";
464 if (sval_signed(sval) && sval.value == LLONG_MIN)
465 return "s64min";
467 if (sval_unsigned(sval))
468 snprintf(buf, sizeof(buf), "%llu", sval.value);
469 else if (sval.value < 0)
470 snprintf(buf, sizeof(buf), "(%lld)", sval.value);
471 else
472 snprintf(buf, sizeof(buf), "%lld", sval.value);
474 return alloc_sname(buf);
477 const char *sval_to_numstr(sval_t sval)
479 char buf[30];
481 if (sval_unsigned(sval))
482 snprintf(buf, sizeof(buf), "%llu", sval.value);
483 else if (sval.value < 0)
484 snprintf(buf, sizeof(buf), "(%lld)", sval.value);
485 else
486 snprintf(buf, sizeof(buf), "%lld", sval.value);
488 return alloc_sname(buf);
491 sval_t ll_to_sval(long long val)
493 sval_t ret;
495 ret.type = &llong_ctype;
496 ret.value = val;
497 return ret;
500 static void free_svals(struct symbol *sym)
502 clear_sval_alloc();
505 void register_sval(int my_id)
507 add_hook(&free_svals, END_FUNC_HOOK);