2 * sparse/smatch_helper.c
4 * Copyright (C) 2010 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
11 #include "smatch_slist.h"
12 #include "smatch_extra.h"
14 static long long _get_implied_value(struct expression
*expr
, int *discard
, int *undefined
, int implied
);
15 static long long _get_value(struct expression
*expr
, int *discard
, int *undefined
, int implied
);
28 static long long cast_to_type(struct expression
*expr
, long long val
)
30 struct symbol
*type
= get_type(expr
);
35 switch (type
->bit_size
) {
37 if (type
->ctype
.modifiers
& MOD_UNSIGNED
)
38 val
= (long long)(unsigned char) val
;
40 val
= (long long)(char) val
;
43 if (type
->ctype
.modifiers
& MOD_UNSIGNED
)
44 val
= (long long)(unsigned short) val
;
46 val
= (long long)(short) val
;
49 if (type
->ctype
.modifiers
& MOD_UNSIGNED
)
50 val
= (long long)(unsigned int) val
;
52 val
= (long long)(int) val
;
58 static long long handle_preop(struct expression
*expr
, int *discard
, int *undefined
, int implied
)
60 long long ret
= BOGUS
;
64 ret
= ~ _get_value(expr
->unop
, discard
, undefined
, implied
);
65 ret
= cast_to_type(expr
->unop
, ret
);
68 ret
= - _get_value(expr
->unop
, discard
, undefined
, implied
);
71 ret
= _get_implied_value(expr
, discard
, undefined
, implied
);
80 static long long handle_binop(struct expression
*expr
, int *discard
, int *undefined
, int implied
)
84 long long ret
= BOGUS
;
86 if (expr
->type
!= EXPR_BINOP
) {
92 left
= _get_value(expr
->left
, discard
, undefined
, implied
);
93 right
= _get_value(expr
->right
, discard
, undefined
, implied
);
117 case SPECIAL_RIGHTSHIFT
:
120 case SPECIAL_LEFTSHIFT
:
133 static int get_implied_value_helper(struct expression
*expr
, long long *val
, int what
)
135 struct smatch_state
*state
;
139 if (get_value(expr
, val
))
142 name
= get_variable_from_expr(expr
, &sym
);
145 state
= get_state(SMATCH_EXTRA
, name
, sym
);
147 if (!state
|| !state
->data
)
149 if (what
== VAL_SINGLE
)
150 return get_single_value_from_dinfo(get_dinfo(state
), val
);
151 if (what
== VAL_MAX
) {
152 *val
= get_dinfo_max(get_dinfo(state
));
153 if (*val
== whole_range
.max
) /* this means just guessing */
157 *val
= get_dinfo_min(get_dinfo(state
));
158 if (*val
== whole_range
.min
)
163 static int get_implied_single_fuzzy_max(struct expression
*expr
, long long *max
)
166 struct sm_state
*tmp
;
168 if (get_implied_max(expr
, max
))
171 sm
= get_sm_state_expr(SMATCH_EXTRA
, expr
);
175 *max
= whole_range
.min
;
176 FOR_EACH_PTR(sm
->possible
, tmp
) {
179 new_min
= get_dinfo_min(get_dinfo(tmp
->state
));
182 } END_FOR_EACH_PTR(tmp
);
184 if (*max
> whole_range
.min
)
189 static int get_implied_single_fuzzy_min(struct expression
*expr
, long long *min
)
192 struct sm_state
*tmp
;
194 if (get_implied_min(expr
, min
))
197 sm
= get_sm_state_expr(SMATCH_EXTRA
, expr
);
201 *min
= whole_range
.max
;
202 FOR_EACH_PTR(sm
->possible
, tmp
) {
205 new_max
= get_dinfo_max(get_dinfo(tmp
->state
));
208 } END_FOR_EACH_PTR(tmp
);
210 if (*min
< whole_range
.max
)
215 static long long _get_implied_value(struct expression
*expr
, int *discard
, int *undefined
, int implied
)
217 long long ret
= BOGUS
;
221 if (!get_implied_value_helper(expr
, &ret
, VAL_SINGLE
)) {
227 if (!get_implied_single_fuzzy_max(expr
, &ret
)) {
233 if (!get_implied_single_fuzzy_min(expr
, &ret
)) {
245 static long long _get_value(struct expression
*expr
, int *discard
, int *undefined
, int implied
)
248 long long ret
= BOGUS
;
261 expr
= strip_parens(expr
);
266 ret
= cast_to_type(expr
, ret
);
269 ret
= handle_preop(expr
, discard
, undefined
, implied
);
272 ret
= _get_value(expr
->unop
, discard
, undefined
, implied
);
275 case EXPR_FORCE_CAST
:
276 case EXPR_IMPLIED_CAST
:
277 ret
= _get_value(expr
->cast_expression
, discard
, undefined
, implied
);
278 return cast_to_type(expr
, ret
);
280 ret
= handle_binop(expr
, discard
, undefined
, implied
);
284 ret
= get_expression_value(expr
);
287 ret
= _get_implied_value(expr
, discard
, undefined
, implied
);
296 /* returns 1 if it can get a value literal or else returns 0 */
297 int get_value(struct expression
*expr
, long long *val
)
301 *val
= _get_value(expr
, NULL
, &undefined
, NOTIMPLIED
);
307 int get_implied_max(struct expression
*expr
, long long *val
)
309 return get_implied_value_helper(expr
, val
, VAL_MAX
);
312 int get_implied_min(struct expression
*expr
, long long *val
)
314 return get_implied_value_helper(expr
, val
, VAL_MIN
);
317 int get_implied_value(struct expression
*expr
, long long *val
)
321 *val
= _get_value(expr
, NULL
, &undefined
, IMPLIED
);
325 int get_fuzzy_max(struct expression
*expr
, long long *val
)
329 *val
= _get_value(expr
, NULL
, &undefined
, FUZZYMAX
);
333 int get_fuzzy_min(struct expression
*expr
, long long *val
)
337 *val
= _get_value(expr
, NULL
, &undefined
, FUZZYMIN
);