Create separate smatch_math.c file
[smatch.git] / smatch_math.c
blobfc68a0fa808e5a09d9fb0a736a3a29e7a5032ad0
1 /*
2 * sparse/smatch_helper.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_extra.h"
13 #define BOGUS 12345
15 #define NOTIMPLIED 0
16 #define IMPLIED 1
17 #define FUZZYMAX 2
18 #define FUZZYMIN 3
20 static long long cast_to_type(struct expression *expr, long long val)
22 struct symbol *type = get_type(expr);
24 if (!type)
25 return val;
27 switch (type->bit_size) {
28 case 8:
29 if (type->ctype.modifiers & MOD_UNSIGNED)
30 val = (long long)(unsigned char) val;
31 else
32 val = (long long)(char) val;
33 break;
34 case 16:
35 if (type->ctype.modifiers & MOD_UNSIGNED)
36 val = (long long)(unsigned short) val;
37 else
38 val = (long long)(short) val;
39 break;
40 case 32:
41 if (type->ctype.modifiers & MOD_UNSIGNED)
42 val = (long long)(unsigned int) val;
43 else
44 val = (long long)(int) val;
45 break;
47 return val;
50 static long long _get_value(struct expression *expr, int *discard, int *undefined, int implied)
52 int dis = 0;
53 long long ret = BOGUS;
55 if (!expr) {
56 *undefined = 1;
57 return BOGUS;
59 if (!discard)
60 discard = &dis;
61 if (*discard) {
62 *undefined = 1;
63 return BOGUS;
66 expr = strip_parens(expr);
68 switch (expr->type){
69 case EXPR_VALUE:
70 ret = expr->value;
71 ret = cast_to_type(expr, ret);
72 break;
73 case EXPR_PREOP:
74 switch(expr->op) {
75 case '~':
76 ret = ~ _get_value(expr->unop, discard, undefined, implied);
77 ret = cast_to_type(expr->unop, ret);
78 break;
79 case '-':
80 ret = - _get_value(expr->unop, discard, undefined, implied);
81 break;
82 default:
83 *undefined = 1;
84 *discard = 1;
86 break;
87 case EXPR_CAST:
88 case EXPR_FORCE_CAST:
89 case EXPR_IMPLIED_CAST:
91 struct symbol *type = get_base_type(expr->cast_type);
93 ret = _get_value(expr->cast_expression, discard, undefined, implied);
94 switch (type->bit_size) {
95 case 8:
96 if (type->ctype.modifiers & MOD_UNSIGNED)
97 ret = (long long)(unsigned char) ret;
98 else
99 ret = (long long)(char) ret;
100 break;
101 case 16:
102 if (type->ctype.modifiers & MOD_UNSIGNED)
103 ret = (long long)(unsigned short) ret;
104 else
105 ret = (long long)(short) ret;
106 break;
107 case 32:
108 if (type->ctype.modifiers & MOD_UNSIGNED)
109 ret = (long long)(unsigned int) ret;
110 else
111 ret = (long long)(int) ret;
112 break;
114 return ret;
116 case EXPR_BINOP: {
117 long long left;
118 long long right;
120 left = _get_value(expr->left, discard, undefined, implied);
121 right = _get_value(expr->right, discard, undefined, implied);
122 if (expr->op == '*') {
123 ret = left * right;
124 } else if (expr->op == '/') {
125 ret = left / right;
126 } else if (expr->op == '+') {
127 ret = left + right;
128 } else if (expr->op == '-') {
129 ret = left - right;
130 } else if (expr->op == '|') {
131 ret = left | right;
132 } else if (expr->op == '&') {
133 ret = left & right;
134 } else if (expr->op == SPECIAL_RIGHTSHIFT) {
135 ret = left >> right;
136 } else if (expr->op == SPECIAL_LEFTSHIFT) {
137 ret = left << right;
138 } else if (expr->op == '^') {
139 ret = left ^ right;
140 } else {
141 *undefined = 1;
142 *discard = 1;
144 break;
146 case EXPR_PTRSIZEOF:
147 case EXPR_SIZEOF:
148 ret = get_expression_value(expr);
149 break;
150 default:
151 switch (implied) {
152 case IMPLIED:
153 if (!get_implied_single_val(expr, &ret)) {
154 *undefined = 1;
155 *discard = 1;
157 break;
158 case FUZZYMAX:
159 if (!get_implied_single_fuzzy_max(expr, &ret)) {
160 *undefined = 1;
161 *discard = 1;
163 break;
164 case FUZZYMIN:
165 if (!get_implied_single_fuzzy_min(expr, &ret)) {
166 *undefined = 1;
167 *discard = 1;
169 break;
170 default:
171 *undefined = 1;
172 *discard = 1;
175 if (*discard) {
176 *undefined = 1;
177 return BOGUS;
179 return ret;
182 /* returns 1 if it can get a value literal or else returns 0 */
183 int get_value(struct expression *expr, long long *val)
185 int undefined = 0;
187 *val = _get_value(expr, NULL, &undefined, NOTIMPLIED);
188 if (undefined)
189 return 0;
190 return 1;
193 int get_implied_value(struct expression *expr, long long *val)
195 int undefined = 0;
197 *val = _get_value(expr, NULL, &undefined, IMPLIED);
198 return !undefined;
201 int get_fuzzy_max(struct expression *expr, long long *val)
203 int undefined = 0;
205 *val = _get_value(expr, NULL, &undefined, FUZZYMAX);
206 return !undefined;
209 int get_fuzzy_min(struct expression *expr, long long *val)
211 int undefined = 0;
213 *val = _get_value(expr, NULL, &undefined, FUZZYMIN);
214 return !undefined;