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.
20 #include "smatch_slist.h"
21 #include "smatch_extra.h"
23 __ALLOCATOR(sval_t
, "svals", sval
);
25 sval_t
*sval_alloc(sval_t sval
)
29 ret
= __alloc_sval(0);
34 sval_t
*sval_alloc_permanent(sval_t sval
)
38 ret
= malloc(sizeof(*ret
));
43 sval_t
sval_blank(struct expression
*expr
)
47 ret
.type
= get_type(expr
);
49 ret
.type
= &llong_ctype
;
50 ret
.value
= 123456789;
55 sval_t
sval_from_val(struct expression
*expr
, long long val
)
59 ret
= sval_blank(expr
);
61 ret
= sval_cast(ret
, get_type(expr
));
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
)
80 return sval
.type
->bit_size
;
83 int sval_positive_bits(sval_t sval
)
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
)) {
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
)
122 if (sval_positive_bits(two
) > sval_positive_bits(one
))
124 if (sval_bits(tmp
) >= 32 && sval_unsigned(tmp
)) {
125 if (one
.uvalue
< two
.uvalue
)
127 if (one
.uvalue
== two
.uvalue
)
131 /* fix me handle type promotion and unsigned values */
132 if (one
.value
< two
.value
)
134 if (one
.value
== two
.value
)
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
)
152 if (one
.value
== val
)
157 sval_t
sval_cast(sval_t sval
, struct symbol
*type
)
165 switch (sval_bits(ret
)) {
167 if (sval_unsigned(ret
))
168 ret
.value
= (long long)(unsigned char)sval
.value
;
170 ret
.value
= (long long)(char)sval
.value
;
173 if (sval_unsigned(ret
))
174 ret
.value
= (long long)(unsigned short)sval
.value
;
176 ret
.value
= (long long)(short)sval
.value
;
179 if (sval_unsigned(ret
))
180 ret
.value
= (long long)(unsigned int)sval
.value
;
182 ret
.value
= (long long)(int)sval
.value
;
185 ret
.value
= sval
.value
;
191 sval_t
sval_preop(sval_t sval
, int op
)
195 sval
.value
= !sval
.value
;
198 sval
.value
= ~sval
.value
;
199 /* fixme: should probably cast this here */
202 sval
.value
= -sval
.value
;
208 static sval_t
sval_binop_unsigned(struct symbol
*type
, sval_t left
, int op
, sval_t right
)
215 ret
.uvalue
= left
.uvalue
* right
.uvalue
;
218 if (right
.uvalue
== 0) {
219 sm_msg("debug: %s: divide by zero", __func__
);
220 ret
.uvalue
= 123456789;
222 ret
.uvalue
= left
.uvalue
/ right
.uvalue
;
226 ret
.uvalue
= left
.uvalue
+ right
.uvalue
;
229 ret
.uvalue
= left
.uvalue
- right
.uvalue
;
232 if (right
.uvalue
== 0) {
233 sm_msg("internal error: %s: MOD by zero", __func__
);
234 ret
.uvalue
= 123456789;
236 ret
.uvalue
= left
.uvalue
% right
.uvalue
;
240 ret
.uvalue
= left
.uvalue
| right
.uvalue
;
243 ret
.uvalue
= left
.uvalue
& right
.uvalue
;
245 case SPECIAL_RIGHTSHIFT
:
246 ret
.uvalue
= left
.uvalue
>> right
.uvalue
;
248 case SPECIAL_LEFTSHIFT
:
249 ret
.uvalue
= left
.uvalue
<< right
.uvalue
;
252 ret
.uvalue
= left
.uvalue
^ right
.uvalue
;
255 sm_msg("internal error: %s: unhandled binop %s", __func__
,
257 ret
.uvalue
= 1234567;
263 static sval_t
sval_binop_signed(struct symbol
*type
, sval_t left
, int op
, sval_t right
)
270 ret
.value
= left
.value
* right
.value
;
273 if (right
.value
== 0) {
274 sm_msg("debug: %s: divide by zero", __func__
);
275 ret
.value
= 123456789;
277 ret
.value
= left
.value
/ right
.value
;
281 ret
.value
= left
.value
+ right
.value
;
284 ret
.value
= left
.value
- right
.value
;
287 if (right
.value
== 0) {
288 sm_msg("internal error: %s: MOD by zero", __func__
);
289 ret
.value
= 123456789;
291 ret
.value
= left
.value
% right
.value
;
295 ret
.value
= left
.value
| right
.value
;
298 ret
.value
= left
.value
& right
.value
;
300 case SPECIAL_RIGHTSHIFT
:
301 ret
.value
= left
.value
>> right
.value
;
303 case SPECIAL_LEFTSHIFT
:
304 ret
.value
= left
.value
<< right
.value
;
307 ret
.value
= left
.value
^ right
.value
;
310 sm_msg("internal error: %s: unhandled binop %s", __func__
,
317 sval_t
sval_binop(sval_t left
, int op
, sval_t right
)
323 if (sval_positive_bits(right
) > sval_positive_bits(left
))
325 if (type_positive_bits(type
) < 31)
328 if (type_unsigned(type
))
329 ret
= sval_binop_unsigned(type
, left
, op
, right
);
331 ret
= sval_binop_signed(type
, left
, op
, right
);
335 const char *sval_to_str(sval_t sval
)
339 if (sval
.value
&& sval_bits(sval
) > 8 && sval_is_min(sval
))
341 if (sval_bits(sval
) > 8 && sval_is_max(sval
))
344 if (sval_unsigned(sval
) && sval
.value
== ULLONG_MAX
)
346 if (sval
.value
== LLONG_MAX
)
347 return "max"; // FIXME: should be s64max
348 if (sval_unsigned(sval
) && sval
.value
== UINT_MAX
)
350 if (sval
.value
== INT_MAX
)
352 if (sval_unsigned(sval
) && sval
.value
== USHRT_MAX
)
355 if ((sval
.type
== &sshort_ctype
|| sval
.type
== &short_ctype
) && sval
.value
== SHRT_MIN
)
357 if ((sval
.type
== &sint_ctype
|| sval
.type
== &int_ctype
) && sval
.value
== INT_MIN
)
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
);
367 snprintf(buf
, sizeof(buf
), "%lld", sval
.value
);
369 return alloc_sname(buf
);
372 const char *sval_to_numstr(sval_t sval
)
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
);
381 snprintf(buf
, sizeof(buf
), "%lld", sval
.value
);
383 return alloc_sname(buf
);
386 sval_t
ll_to_sval(long long val
)
390 ret
.type
= &llong_ctype
;
395 static void free_svals(struct symbol
*sym
)
400 void register_sval(int my_id
)
402 add_hook(&free_svals
, END_FUNC_HOOK
);