db: caller info needs to record the -1 parameters
[smatch.git] / smatch_math.c
blob9e392ced04b9903d42beda34731bdf74f64c650f
1 /*
2 * smatch/smatch_math.c
4 * Copyright (C) 2010 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
10 #include "smatch.h"
11 #include "smatch_slist.h"
12 #include "smatch_extra.h"
14 static long long _get_implied_value(struct expression *expr, int *undefined, int implied);
15 static long long _get_value(struct expression *expr, int *undefined, int implied);
17 #define BOGUS 12345
19 #define NOTIMPLIED 0
20 #define IMPLIED 1
21 #define IMPLIED_MIN 2
22 #define IMPLIED_MAX 3
23 #define FUZZYMAX 4
24 #define FUZZYMIN 5
26 static long long cast_to_type(struct expression *expr, long long val)
28 struct symbol *type = get_type(expr);
30 if (!type)
31 return val;
33 switch (type->bit_size) {
34 case 8:
35 if (type->ctype.modifiers & MOD_UNSIGNED)
36 val = (long long)(unsigned char) val;
37 else
38 val = (long long)(char) val;
39 break;
40 case 16:
41 if (type->ctype.modifiers & MOD_UNSIGNED)
42 val = (long long)(unsigned short) val;
43 else
44 val = (long long)(short) val;
45 break;
46 case 32:
47 if (type->ctype.modifiers & MOD_UNSIGNED)
48 val = (long long)(unsigned int) val;
49 else
50 val = (long long)(int) val;
51 break;
53 return val;
56 static int opposite_implied(int implied)
58 if (implied == IMPLIED_MIN)
59 return IMPLIED_MAX;
60 if (implied == IMPLIED_MAX)
61 return IMPLIED_MIN;
62 return implied;
65 static long long handle_preop(struct expression *expr, int *undefined, int implied)
67 long long ret = BOGUS;
69 switch (expr->op) {
70 case '~':
71 ret = ~ _get_value(expr->unop, undefined, implied);
72 ret = cast_to_type(expr->unop, ret);
73 break;
74 case '-':
75 ret = - _get_value(expr->unop, undefined, implied);
76 break;
77 case '*':
78 ret = _get_implied_value(expr, undefined, implied);
79 break;
80 default:
81 *undefined = 1;
83 return ret;
86 static long long handle_divide(struct expression *expr, int *undefined, int implied)
88 long long left;
89 long long right;
90 long long ret = BOGUS;
92 left = _get_value(expr->left, undefined, implied);
93 right = _get_value(expr->right, undefined, opposite_implied(implied));
95 if (right == 0)
96 *undefined = 1;
97 else
98 ret = left / right;
100 return ret;
103 static long long handle_subtract(struct expression *expr, int *undefined, int implied)
105 long long left;
106 long long right;
108 left = _get_value(expr->left, undefined, implied);
109 right = _get_value(expr->right, undefined, opposite_implied(implied));
111 return left - right;
114 static long long handle_binop(struct expression *expr, int *undefined, int implied)
116 long long left;
117 long long right;
118 long long ret = BOGUS;
120 if (expr->type != EXPR_BINOP) {
121 *undefined = 1;
122 return ret;
125 left = _get_value(expr->left, undefined, implied);
126 right = _get_value(expr->right, undefined, implied);
128 switch (expr->op) {
129 case '*':
130 ret = left * right;
131 break;
132 case '/':
133 ret = handle_divide(expr, undefined, implied);
134 break;
135 case '+':
136 ret = left + right;
137 break;
138 case '-':
139 ret = handle_subtract(expr, undefined, implied);
140 break;
141 case '%':
142 if (right == 0)
143 *undefined = 1;
144 else
145 ret = left % right;
146 break;
147 case '|':
148 ret = left | right;
149 break;
150 case '&':
151 ret = left & right;
152 break;
153 case SPECIAL_RIGHTSHIFT:
154 ret = left >> right;
155 break;
156 case SPECIAL_LEFTSHIFT:
157 ret = left << right;
158 break;
159 case '^':
160 ret = left ^ right;
161 break;
162 default:
163 *undefined = 1;
165 return ret;
168 static int get_implied_value_helper(struct expression *expr, long long *val, int what)
170 struct smatch_state *state;
171 struct symbol *sym;
172 char *name;
174 if (get_value(expr, val))
175 return 1;
177 name = get_variable_from_expr(expr, &sym);
178 if (!name)
179 return 0;
180 state = get_state(SMATCH_EXTRA, name, sym);
181 free_string(name);
182 if (!state || !state->data)
183 return 0;
184 if (what == IMPLIED)
185 return get_single_value_from_dinfo(get_dinfo(state), val);
186 if (what == IMPLIED_MAX) {
187 *val = get_dinfo_max(get_dinfo(state));
188 if (*val == whole_range.max) /* this means just guessing */
189 return 0;
190 return 1;
192 *val = get_dinfo_min(get_dinfo(state));
193 if (*val == whole_range.min)
194 return 0;
195 return 1;
198 static int get_fuzzy_max_helper(struct expression *expr, long long *max)
200 struct sm_state *sm;
201 struct sm_state *tmp;
203 if (get_implied_max(expr, max))
204 return 1;
206 sm = get_sm_state_expr(SMATCH_EXTRA, expr);
207 if (!sm)
208 return 0;
210 *max = whole_range.min;
211 FOR_EACH_PTR(sm->possible, tmp) {
212 long long new_min;
214 new_min = get_dinfo_min(get_dinfo(tmp->state));
215 if (new_min > *max)
216 *max = new_min;
217 } END_FOR_EACH_PTR(tmp);
219 if (*max > whole_range.min)
220 return 1;
221 return 0;
224 static int get_fuzzy_min_helper(struct expression *expr, long long *min)
226 struct sm_state *sm;
227 struct sm_state *tmp;
229 if (get_implied_min(expr, min))
230 return 1;
232 sm = get_sm_state_expr(SMATCH_EXTRA, expr);
233 if (!sm)
234 return 0;
236 *min = whole_range.max;
237 FOR_EACH_PTR(sm->possible, tmp) {
238 long long new_max;
240 new_max = get_dinfo_max(get_dinfo(tmp->state));
241 if (new_max < *min)
242 *min = new_max;
243 } END_FOR_EACH_PTR(tmp);
245 if (*min < whole_range.max)
246 return 1;
247 return 0;
250 static long long _get_implied_value(struct expression *expr, int *undefined, int implied)
252 long long ret = BOGUS;
254 switch (implied) {
255 case IMPLIED:
256 case IMPLIED_MAX:
257 case IMPLIED_MIN:
258 if (!get_implied_value_helper(expr, &ret, implied))
259 *undefined = 1;
260 break;
261 case FUZZYMAX:
262 if (!get_fuzzy_max_helper(expr, &ret))
263 *undefined = 1;
264 break;
265 case FUZZYMIN:
266 if (!get_fuzzy_min_helper(expr, &ret))
267 *undefined = 1;
268 break;
269 default:
270 *undefined = 1;
272 return ret;
275 static int get_const_value(struct expression *expr, long long *val)
277 struct symbol *sym;
279 sym = expr->symbol;
280 if (!sym)
281 return 0;
282 if (!(sym->ctype.modifiers & MOD_CONST))
283 return 0;
284 if (get_value(sym->initializer, val))
285 return 1;
286 return 0;
289 static long long _get_value(struct expression *expr, int *undefined, int implied)
291 long long ret = BOGUS;
293 if (!expr) {
294 *undefined = 1;
295 return BOGUS;
297 if (*undefined)
298 return BOGUS;
300 expr = strip_parens(expr);
302 switch (expr->type) {
303 case EXPR_VALUE:
304 ret = expr->value;
305 ret = cast_to_type(expr, ret);
306 break;
307 case EXPR_PREOP:
308 ret = handle_preop(expr, undefined, implied);
309 break;
310 case EXPR_POSTOP:
311 ret = _get_value(expr->unop, undefined, implied);
312 break;
313 case EXPR_CAST:
314 case EXPR_FORCE_CAST:
315 case EXPR_IMPLIED_CAST:
316 ret = _get_value(expr->cast_expression, undefined, implied);
317 return cast_to_type(expr, ret);
318 case EXPR_BINOP:
319 ret = handle_binop(expr, undefined, implied);
320 break;
321 case EXPR_PTRSIZEOF:
322 case EXPR_SIZEOF:
323 ret = get_expression_value(expr);
324 break;
325 case EXPR_SYMBOL:
326 if (get_const_value(expr, &ret))
327 break;
328 default:
329 ret = _get_implied_value(expr, undefined, implied);
331 if (*undefined)
332 return BOGUS;
333 return ret;
336 /* returns 1 if it can get a value literal or else returns 0 */
337 int get_value(struct expression *expr, long long *val)
339 int undefined = 0;
341 *val = _get_value(expr, &undefined, NOTIMPLIED);
342 if (undefined)
343 return 0;
344 return 1;
347 int get_implied_value(struct expression *expr, long long *val)
349 int undefined = 0;
351 *val = _get_value(expr, &undefined, IMPLIED);
352 return !undefined;
355 int get_implied_min(struct expression *expr, long long *val)
357 int undefined = 0;
359 *val = _get_value(expr, &undefined, IMPLIED_MIN);
360 return !undefined;
363 int get_implied_max(struct expression *expr, long long *val)
365 int undefined = 0;
367 *val = _get_value(expr, &undefined, IMPLIED_MAX);
368 return !undefined;
371 int get_fuzzy_min(struct expression *expr, long long *val)
373 int undefined = 0;
375 *val = _get_value(expr, &undefined, FUZZYMIN);
376 return !undefined;
379 int get_fuzzy_max(struct expression *expr, long long *val)
381 int undefined = 0;
383 *val = _get_value(expr, &undefined, FUZZYMAX);
384 return !undefined;
387 int get_absolute_min(struct expression *expr, long long *val)
389 struct symbol *type;
390 long long min;
392 type = get_type(expr);
393 if (!type) {
394 if (get_value(expr, val))
395 return 1;
396 return 0;
398 min = type_min(type);
399 if (!get_implied_min(expr, val) || *val < min)
400 *val = min;
401 return 1;
404 int get_absolute_max(struct expression *expr, long long *val)
406 struct symbol *type;
407 long long max;
409 type = get_type(expr);
410 if (!type) {
411 if (get_value(expr, val))
412 return 1;
413 return 0;
415 max = type_max(type);
416 if (!get_implied_max(expr, val) || *val > max)
417 *val = max;
418 if (*val < type_min(type))
419 *val = max;
420 return 1;