Branch data Line data Source code
1 : : #include "coerce.h"
2 : :
3 : : /*
4 : : * Be aware that some value variants represents actual values (e.g.
5 : : * vt_int), and others represent a type (e.g. vt_scalar) which holds a
6 : : * type identifier token. Here we implicitly expect a vt_scalar type as
7 : : * first argument, but only receive the token. The second argument is a
8 : : * value literal. Our job is to decide if the value fits within the
9 : : * given type. Our internal representation already ensures that value
10 : : * fits within a 64bit signed or unsigned integer, or double; otherwise
11 : : * the parser would have set vt_invalid type on the value.
12 : : *
13 : : * If the value is invalid, success is returned because the
14 : : * error is presumably already generated. If the value is some other
15 : : * type than expect, an error is generated.
16 : : *
17 : : * Symbolic names are not allowed as values here.
18 : : *
19 : : * Converts positive integers to signed type and unsigned integers to
20 : : * signed type, integers to floats and floats to integers.
21 : : *
22 : : * Optionally allows 1 to be assigned as true and 0 as false, and vice
23 : : * versa when allow_boolean_conversion is enabled.
24 : : *
25 : : * Returns 0 on success, -1 on error.
26 : : */
27 : 288 : int fb_coerce_scalar_type(fb_parser_t *P, fb_symbol_t *sym, fb_scalar_type_t st, fb_value_t *value)
28 : : {
29 : : double d;
30 : : float f;
31 : :
32 [ + - ]: 288 : if (!value->type) {
33 : : return 0;
34 : : }
35 : : /*
36 : : * The parser only produces negative vt_int values, which simplifies
37 : : * the logic, but to make this operation robust against multiple
38 : : * coercion steps, we first convert back to uint if the assumption turns
39 : : * out false.
40 : : */
41 [ + + ][ + + ]: 288 : if (value->type == vt_int && value->i >= 0) {
42 : 70 : value->type = vt_uint;
43 : 70 : value->u = (uint64_t)value->i;
44 : : }
45 [ + - ]: 288 : if (value->type == vt_invalid) {
46 : : /* Silently ignore past errors. */
47 : : return 0;
48 : : }
49 [ + + ][ - + ]: 288 : if (value->type == vt_bool && st != fb_bool && P->opts.allow_boolean_conversion) {
[ # # ]
50 : 0 : value->type = vt_uint;
51 : 0 : value->u = (uint64_t)value->b;
52 : : assert(value->u == 1 || value->u == 0);
53 : : }
54 [ + + + + : 288 : switch (st) {
+ + + + +
+ + - ]
55 : : case fb_ulong:
56 [ - + ]: 16 : if (value->type != vt_uint) {
57 : : error_sym(P, sym, "64-bit uint32_t type only accepts unsigned integers");
58 : 0 : value->type = vt_invalid;
59 : 0 : return -1;
60 : : }
61 : : return 0;
62 : : case fb_uint:
63 [ - + ]: 32 : if (value->type != vt_uint) {
64 : : error_sym(P, sym, "32-bit unsigned int type only accepts unsigned integers");
65 : 0 : value->type = vt_invalid;
66 : 0 : return -1;
67 : : }
68 [ - + ]: 32 : if (value->u > UINT32_MAX) {
69 : : error_sym(P, sym, "32-bit unsigned int overflow");
70 : 0 : value->type = vt_invalid;
71 : 0 : return -1;
72 : : }
73 : : return 0;
74 : : case fb_ushort:
75 [ - + ]: 8 : if (value->type != vt_uint) {
76 : : error_sym(P, sym, "16-bit unsigned short type only accepts unsigned integers");
77 : 0 : value->type = vt_invalid;
78 : 0 : return -1;
79 : : }
80 [ - + ]: 8 : if (value->u > UINT16_MAX) {
81 : : error_sym(P, sym, "16-bit unsigned short overflow");
82 : 0 : value->type = vt_invalid;
83 : 0 : return -1;
84 : : }
85 : : return 0;
86 : : case fb_ubyte:
87 [ - + ]: 31 : if (value->type != vt_uint) {
88 : : error_sym(P, sym, "8-bit unsigned byte type only accepts unsigned integers");
89 : 0 : value->type = vt_invalid;
90 : 0 : return -1;
91 : : }
92 [ - + ]: 31 : if (value->u > UINT8_MAX) {
93 : : error_sym(P, sym, "8-bit unsigned byte overflow");
94 : 0 : value->type = vt_invalid;
95 : 0 : return -1;
96 : : }
97 : : return 0;
98 : : case fb_long:
99 [ + - ]: 65 : if (value->type == vt_int) {
100 : : /* Native format is always ok, or parser would have failed. */
101 : : return 0;
102 : : }
103 [ + - ]: 65 : if (value->type == vt_uint) {
104 [ - + ]: 65 : if (value->u >= (1ULL << 63)) {
105 : : error_sym(P, sym, "64-bit signed int32_t overflow");
106 : 0 : value->type = vt_invalid;
107 : 0 : return -1;
108 : : }
109 : 65 : value->i = (int64_t)value->u;
110 : 65 : value->type = vt_int;
111 : 65 : return 0;
112 : : }
113 : : error_sym(P, sym, "64-bit int32_t type only accepts integers");
114 : 0 : value->type = vt_invalid;
115 : 0 : return -1;
116 : : case fb_int:
117 [ - + ]: 38 : if (value->type == vt_int) {
118 [ # # ]: 0 : if (value->i < INT32_MIN) {
119 : : error_sym(P, sym, "32-bit signed int underflow");
120 : 0 : value->type = vt_invalid;
121 : 0 : return -1;
122 : : }
123 : : return 0;
124 : : }
125 [ + - ]: 38 : if (value->type == vt_uint) {
126 [ - + ]: 38 : if (value->i > INT32_MAX) {
127 : : error_sym(P, sym, "32-bit signed int overflow");
128 : 0 : value->type = vt_invalid;
129 : 0 : return -1;
130 : : }
131 : 38 : value->i = (int64_t)value->u;
132 : 38 : value->type = vt_int;
133 : 38 : return 0;
134 : : }
135 : : error_sym(P, sym, "32-bit signed int type only accepts integers");
136 : 0 : value->type = vt_invalid;
137 : 0 : return -1;
138 : : case fb_short:
139 [ + + ]: 31 : if (value->type == vt_int) {
140 [ - + ]: 1 : if (value->i < INT16_MIN) {
141 : : error_sym(P, sym, "16-bit signed short underflow");
142 : 0 : value->type = vt_invalid;
143 : 0 : return -1;
144 : : }
145 : : return 0;
146 : : }
147 [ + - ]: 30 : if (value->type == vt_uint) {
148 [ - + ]: 30 : if (value->i > INT16_MAX) {
149 : : error_sym(P, sym, "16-bit signed short overflow");
150 : 0 : value->type = vt_invalid;
151 : 0 : return -1;
152 : : }
153 : 30 : value->i = (int64_t)value->u;
154 : 30 : value->type = vt_int;
155 : 30 : return 0;
156 : : }
157 : : error_sym(P, sym, "16-bit signed short type only accepts integers");
158 : 0 : value->type = vt_invalid;
159 : 0 : return -1;
160 : : case fb_byte:
161 [ - + ]: 40 : if (value->type == vt_int) {
162 [ # # ]: 0 : if (value->i < INT8_MIN) {
163 : : error_sym(P, sym, "8-bit signed byte underflow");
164 : 0 : value->type = vt_invalid;
165 : 0 : return -1;
166 : : }
167 : : return 0;
168 : : }
169 [ + - ]: 40 : if (value->type == vt_uint) {
170 [ - + ]: 40 : if (value->i > INT8_MAX) {
171 : : error_sym(P, sym, "8-bit signed byte overflow");
172 : 0 : value->type = vt_invalid;
173 : 0 : return -1;
174 : : }
175 : 40 : value->i = (int64_t)value->u;
176 : 40 : value->type = vt_int;
177 : 40 : return 0;
178 : : }
179 : : error_sym(P, sym, "8-bit signed byte type only accepts integers");
180 : 0 : value->type = vt_invalid;
181 : 0 : return -1;
182 : : case fb_bool:
183 [ + + ][ + - ]: 21 : if (value->type == vt_uint && P->opts.allow_boolean_conversion) {
184 [ - + ]: 9 : if (value->u > 1) {
185 : : error_sym(P, sym, "boolean integer conversion only accepts 0 (false) or 1 (true)");
186 : 0 : value->type = vt_invalid;
187 : 0 : return -1;
188 : : }
189 [ - + ]: 12 : } else if (value->type != vt_bool) {
190 : : error_sym(P, sym, "boolean type only accepts 'true' or 'false' as values");
191 : 0 : value->type = vt_invalid;
192 : 0 : return -1;
193 : : }
194 : : return 0;
195 : : case fb_double:
196 [ - + - + ]: 3 : switch (value->type) {
197 : : case vt_int:
198 : 0 : d = (double)value->i;
199 [ # # ]: 0 : if ((int64_t)d != value->i) {
200 : : /* We could make this a warning. */
201 : : error_sym(P, sym, "precision loss in 64-bit double type assignment");
202 : 0 : value->type = vt_invalid;
203 : 0 : return -1;
204 : : }
205 : 0 : value->f = d;
206 : 0 : value->type = vt_float;
207 : 0 : return 0;
208 : : case vt_uint:
209 : 2 : d = (double)value->u;
210 [ - + ]: 2 : if ((uint64_t)d != value->u) {
211 : : /* We could make this a warning. */
212 : : error_sym(P, sym, "precision loss in 64-bit double type assignment");
213 : 0 : value->type = vt_invalid;
214 : 0 : return -1;
215 : : }
216 : 2 : value->f = d;
217 : 2 : value->type = vt_float;
218 : 2 : return 0;
219 : : case vt_float:
220 : : /* Double is our internal repr., so not loss at this point. */
221 : : return 0;
222 : : default:
223 : : error_sym(P, sym, "64-bit double type only accepts integer and float values");
224 : 0 : value->type = vt_invalid;
225 : 0 : return -1;
226 : : }
227 : : case fb_float:
228 [ - + - - ]: 3 : switch (value->type) {
229 : : case vt_int:
230 : 0 : f = (float)value->i;
231 [ # # ]: 0 : if ((int64_t)f != value->i) {
232 : : /* We could make this a warning. */
233 : : error_sym(P, sym, "precision loss in 32-bit float type assignment");
234 : 0 : value->type = vt_invalid;
235 : 0 : return -1;
236 : : }
237 : 0 : value->f = f;
238 : 0 : value->type = vt_float;
239 : 0 : return 0;
240 : : case vt_uint:
241 : 3 : f = (float)value->u;
242 [ - + ]: 3 : if ((uint64_t)f != value->u) {
243 : : /* We could make this a warning. */
244 : : error_sym(P, sym, "precision loss in 32-bit float type assignment");
245 : 0 : value->type = vt_invalid;
246 : 0 : return -1;
247 : : }
248 : 3 : value->f = f;
249 : 3 : value->type = vt_float;
250 : 3 : return 0;
251 : : case vt_float:
252 : 0 : f = (float)value->f;
253 [ # # ]: 0 : if ((double)f != value->f) {
254 : : /* We could make this a warning. */
255 : : error_sym(P, sym, "precision loss in 32-bit float type assignment");
256 : 0 : value->type = vt_invalid;
257 : 0 : return -1;
258 : : }
259 : : return 0;
260 : : default:
261 : : error_sym(P, sym, "32-bit float type only accepts integer and float values");
262 : 0 : value->type = vt_invalid;
263 : 0 : return -1;
264 : : }
265 : : default:
266 : : error_sym(P, sym, "scalar type expected");
267 : 0 : value->type = vt_invalid;
268 : 0 : return -1;
269 : : }
270 : : }
271 : :
|