db: remove untrusted table
[smatch.git] / smatch_type.c
blob2e0a00ceb42d00376bfe9995426a0d584751fe6a
1 /*
2 * sparse/smatch_types.c
4 * Copyright (C) 2009 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
11 * The idea here is that you have an expression and you
12 * want to know what the type is for that.
15 #include "smatch.h"
17 struct symbol *get_real_base_type(struct symbol *sym)
19 struct symbol *ret;
21 ret = get_base_type(sym);
22 if (ret && ret->type == SYM_RESTRICT)
23 return get_real_base_type(ret);
24 return ret;
27 static struct symbol *get_type_symbol(struct expression *expr)
29 if (!expr || expr->type != EXPR_SYMBOL || !expr->symbol)
30 return NULL;
32 return get_real_base_type(expr->symbol);
35 static struct symbol *get_symbol_from_deref(struct expression *expr)
37 struct ident *member;
38 struct symbol *struct_sym;
39 struct symbol *tmp;
41 if (!expr || expr->type != EXPR_DEREF)
42 return NULL;
44 member = expr->member;
45 struct_sym = get_type(expr->deref);
46 if (!struct_sym) {
47 // sm_msg("could not find struct type");
48 return NULL;
50 if (struct_sym->type == SYM_PTR)
51 struct_sym = get_real_base_type(struct_sym);
52 FOR_EACH_PTR(struct_sym->symbol_list, tmp) {
53 if (tmp->ident == member)
54 return get_real_base_type(tmp);
55 } END_FOR_EACH_PTR(tmp);
56 return NULL;
59 static struct symbol *get_return_type(struct expression *expr)
61 struct symbol *tmp;
63 tmp = get_type(expr->fn);
64 if (!tmp)
65 return NULL;
66 return get_real_base_type(tmp);
69 static struct symbol *get_pointer_type(struct expression *expr)
71 struct symbol *sym;
73 sym = get_type(expr);
74 if (!sym || (sym->type != SYM_PTR && sym->type != SYM_ARRAY))
75 return NULL;
76 return get_real_base_type(sym);
79 static struct symbol *fake_pointer_sym(struct expression *expr)
81 struct symbol *sym;
82 struct symbol *base;
84 sym = alloc_symbol(expr->pos, SYM_PTR);
85 expr = expr->unop;
86 base = get_type(expr);
87 if (!base)
88 return NULL;
89 sym->ctype.base_type = base;
90 return sym;
93 struct symbol *get_type(struct expression *expr)
95 struct symbol *tmp;
97 if (!expr)
98 return NULL;
99 expr = strip_parens(expr);
101 switch (expr->type) {
102 case EXPR_SYMBOL:
103 return get_type_symbol(expr);
104 case EXPR_DEREF:
105 return get_symbol_from_deref(expr);
106 case EXPR_PREOP:
107 if (expr->op == '&')
108 return fake_pointer_sym(expr);
109 if (expr->op == '*')
110 return get_pointer_type(expr->unop);
111 return get_type(expr->unop);
112 case EXPR_CAST:
113 case EXPR_FORCE_CAST:
114 case EXPR_IMPLIED_CAST:
115 return get_real_base_type(expr->cast_type);
116 case EXPR_BINOP:
117 if (expr->op != '+')
118 return NULL;
119 tmp = get_type(expr->left);
120 return tmp;
121 case EXPR_CALL:
122 return get_return_type(expr);
123 default:
124 return expr->ctype;
125 // sm_msg("unhandled type %d", expr->type);
129 return NULL;
132 int type_unsigned(struct symbol *base_type)
134 if (!base_type)
135 return 0;
136 if (base_type->ctype.modifiers & MOD_UNSIGNED)
137 return 1;
138 return 0;
141 int returns_unsigned(struct symbol *sym)
143 if (!sym)
144 return 0;
145 sym = get_base_type(sym);
146 if (!sym || sym->type != SYM_FN)
147 return 0;
148 sym = get_base_type(sym);
149 return type_unsigned(sym);
152 int returns_pointer(struct symbol *sym)
154 if (!sym)
155 return 0;
156 sym = get_base_type(sym);
157 if (!sym || sym->type != SYM_FN)
158 return 0;
159 sym = get_base_type(sym);
160 if (sym->type == SYM_PTR)
161 return 1;
162 return 0;
165 long long type_max(struct symbol *base_type)
167 long long ret = whole_range.max;
168 int bits;
170 if (!base_type || !base_type->bit_size)
171 return ret;
172 bits = base_type->bit_size;
173 if (bits == 64)
174 return ret;
175 if (!type_unsigned(base_type))
176 bits--;
177 ret >>= (63 - bits);
178 return ret;
181 long long type_min(struct symbol *base_type)
183 long long ret = whole_range.min;
184 int bits;
186 if (!base_type || !base_type->bit_size)
187 return ret;
188 if (type_unsigned(base_type))
189 return 0;
190 ret = whole_range.max;
191 bits = base_type->bit_size - 1;
192 ret >>= (63 - bits);
193 return -(ret + 1);