File: | build/gcc/fortran/arith.cc |
Warning: | line 1749, column 3 Undefined or garbage value returned to caller |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* Compiler arithmetic | |||
2 | Copyright (C) 2000-2023 Free Software Foundation, Inc. | |||
3 | Contributed by Andy Vaught | |||
4 | ||||
5 | This file is part of GCC. | |||
6 | ||||
7 | GCC is free software; you can redistribute it and/or modify it under | |||
8 | the terms of the GNU General Public License as published by the Free | |||
9 | Software Foundation; either version 3, or (at your option) any later | |||
10 | version. | |||
11 | ||||
12 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |||
13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
15 | for more details. | |||
16 | ||||
17 | You should have received a copy of the GNU General Public License | |||
18 | along with GCC; see the file COPYING3. If not see | |||
19 | <http://www.gnu.org/licenses/>. */ | |||
20 | ||||
21 | /* Since target arithmetic must be done on the host, there has to | |||
22 | be some way of evaluating arithmetic expressions as the host | |||
23 | would evaluate them. We use the GNU MP library and the MPFR | |||
24 | library to do arithmetic, and this file provides the interface. */ | |||
25 | ||||
26 | #include "config.h" | |||
27 | #include "system.h" | |||
28 | #include "coretypes.h" | |||
29 | #include "options.h" | |||
30 | #include "gfortran.h" | |||
31 | #include "arith.h" | |||
32 | #include "target-memory.h" | |||
33 | #include "constructor.h" | |||
34 | ||||
35 | bool gfc_seen_div0; | |||
36 | ||||
37 | /* MPFR does not have a direct replacement for mpz_set_f() from GMP. | |||
38 | It's easily implemented with a few calls though. */ | |||
39 | ||||
40 | void | |||
41 | gfc_mpfr_to_mpz (mpz_t z, mpfr_t x, locus *where) | |||
42 | { | |||
43 | mpfr_exp_t e; | |||
44 | ||||
45 | if (mpfr_inf_p (x)(((mpfr_srcptr) (0 ? (x) : (mpfr_srcptr) (x)))->_mpfr_exp == (2 - ((mpfr_exp_t) (((mpfr_uexp_t) -1) >> 1)))) || mpfr_nan_p (x)(((mpfr_srcptr) (0 ? (x) : (mpfr_srcptr) (x)))->_mpfr_exp == (1 - ((mpfr_exp_t) (((mpfr_uexp_t) -1) >> 1))))) | |||
46 | { | |||
47 | gfc_error ("Conversion of an Infinity or Not-a-Number at %L " | |||
48 | "to INTEGER", where); | |||
49 | mpz_set_ui__gmpz_set_ui (z, 0); | |||
50 | return; | |||
51 | } | |||
52 | ||||
53 | e = mpfr_get_z_expmpfr_get_z_2exp (z, x); | |||
54 | ||||
55 | if (e > 0) | |||
56 | mpz_mul_2exp__gmpz_mul_2exp (z, z, e); | |||
57 | else | |||
58 | mpz_tdiv_q_2exp__gmpz_tdiv_q_2exp (z, z, -e); | |||
59 | } | |||
60 | ||||
61 | ||||
62 | /* Set the model number precision by the requested KIND. */ | |||
63 | ||||
64 | void | |||
65 | gfc_set_model_kind (int kind) | |||
66 | { | |||
67 | int index = gfc_validate_kind (BT_REAL, kind, false); | |||
68 | int base2prec; | |||
69 | ||||
70 | base2prec = gfc_real_kinds[index].digits; | |||
71 | if (gfc_real_kinds[index].radix != 2) | |||
72 | base2prec *= gfc_real_kinds[index].radix / 2; | |||
73 | mpfr_set_default_prec (base2prec); | |||
74 | } | |||
75 | ||||
76 | ||||
77 | /* Set the model number precision from mpfr_t x. */ | |||
78 | ||||
79 | void | |||
80 | gfc_set_model (mpfr_t x) | |||
81 | { | |||
82 | mpfr_set_default_prec (mpfr_get_prec (x)(0 ? (((mpfr_srcptr) (0 ? (x) : (mpfr_srcptr) (x)))->_mpfr_prec ) : (((mpfr_srcptr) (0 ? (x) : (mpfr_srcptr) (x)))->_mpfr_prec ))); | |||
83 | } | |||
84 | ||||
85 | ||||
86 | /* Given an arithmetic error code, return a pointer to a string that | |||
87 | explains the error. */ | |||
88 | ||||
89 | static const char * | |||
90 | gfc_arith_error (arith code) | |||
91 | { | |||
92 | const char *p; | |||
93 | ||||
94 | switch (code) | |||
95 | { | |||
96 | case ARITH_OK: | |||
97 | p = G_("Arithmetic OK at %L")"Arithmetic OK at %L"; | |||
98 | break; | |||
99 | case ARITH_OVERFLOW: | |||
100 | p = G_("Arithmetic overflow at %L")"Arithmetic overflow at %L"; | |||
101 | break; | |||
102 | case ARITH_UNDERFLOW: | |||
103 | p = G_("Arithmetic underflow at %L")"Arithmetic underflow at %L"; | |||
104 | break; | |||
105 | case ARITH_NAN: | |||
106 | p = G_("Arithmetic NaN at %L")"Arithmetic NaN at %L"; | |||
107 | break; | |||
108 | case ARITH_DIV0: | |||
109 | p = G_("Division by zero at %L")"Division by zero at %L"; | |||
110 | break; | |||
111 | case ARITH_INCOMMENSURATE: | |||
112 | p = G_("Array operands are incommensurate at %L")"Array operands are incommensurate at %L"; | |||
113 | break; | |||
114 | case ARITH_ASYMMETRIC: | |||
115 | p = G_("Integer outside symmetric range implied by Standard Fortran""Integer outside symmetric range implied by Standard Fortran" " at %L" | |||
116 | " at %L")"Integer outside symmetric range implied by Standard Fortran" " at %L"; | |||
117 | break; | |||
118 | case ARITH_WRONGCONCAT: | |||
119 | p = G_("Illegal type in character concatenation at %L")"Illegal type in character concatenation at %L"; | |||
120 | break; | |||
121 | case ARITH_INVALID_TYPE: | |||
122 | p = G_("Invalid type in arithmetic operation at %L")"Invalid type in arithmetic operation at %L"; | |||
123 | break; | |||
124 | ||||
125 | default: | |||
126 | gfc_internal_error ("gfc_arith_error(): Bad error code"); | |||
127 | } | |||
128 | ||||
129 | return p; | |||
130 | } | |||
131 | ||||
132 | ||||
133 | /* Get things ready to do math. */ | |||
134 | ||||
135 | void | |||
136 | gfc_arith_init_1 (void) | |||
137 | { | |||
138 | gfc_integer_info *int_info; | |||
139 | gfc_real_info *real_info; | |||
140 | mpfr_t a, b; | |||
141 | int i; | |||
142 | ||||
143 | mpfr_set_default_prec (128); | |||
144 | mpfr_init (a); | |||
145 | ||||
146 | /* Convert the minimum and maximum values for each kind into their | |||
147 | GNU MP representation. */ | |||
148 | for (int_info = gfc_integer_kinds; int_info->kind != 0; int_info++) | |||
149 | { | |||
150 | /* Huge */ | |||
151 | mpz_init__gmpz_init (int_info->huge); | |||
152 | mpz_set_ui__gmpz_set_ui (int_info->huge, int_info->radix); | |||
153 | mpz_pow_ui__gmpz_pow_ui (int_info->huge, int_info->huge, int_info->digits); | |||
154 | mpz_sub_ui__gmpz_sub_ui (int_info->huge, int_info->huge, 1); | |||
155 | ||||
156 | /* These are the numbers that are actually representable by the | |||
157 | target. For bases other than two, this needs to be changed. */ | |||
158 | if (int_info->radix != 2) | |||
159 | gfc_internal_error ("Fix min_int calculation"); | |||
160 | ||||
161 | /* See PRs 13490 and 17912, related to integer ranges. | |||
162 | The pedantic_min_int exists for range checking when a program | |||
163 | is compiled with -pedantic, and reflects the belief that | |||
164 | Standard Fortran requires integers to be symmetrical, i.e. | |||
165 | every negative integer must have a representable positive | |||
166 | absolute value, and vice versa. */ | |||
167 | ||||
168 | mpz_init__gmpz_init (int_info->pedantic_min_int); | |||
169 | mpz_neg__gmpz_neg (int_info->pedantic_min_int, int_info->huge); | |||
170 | ||||
171 | mpz_init__gmpz_init (int_info->min_int); | |||
172 | mpz_sub_ui__gmpz_sub_ui (int_info->min_int, int_info->pedantic_min_int, 1); | |||
173 | ||||
174 | /* Range */ | |||
175 | mpfr_set_z (a, int_info->huge, GFC_RND_MODEMPFR_RNDN); | |||
176 | mpfr_log10 (a, a, GFC_RND_MODEMPFR_RNDN); | |||
177 | mpfr_trunc (a, a)mpfr_rint((a), (a), MPFR_RNDZ); | |||
178 | int_info->range = (int) mpfr_get_si (a, GFC_RND_MODEMPFR_RNDN); | |||
179 | } | |||
180 | ||||
181 | mpfr_clear (a); | |||
182 | ||||
183 | for (real_info = gfc_real_kinds; real_info->kind != 0; real_info++) | |||
184 | { | |||
185 | gfc_set_model_kind (real_info->kind); | |||
186 | ||||
187 | mpfr_init (a); | |||
188 | mpfr_init (b); | |||
189 | ||||
190 | /* huge(x) = (1 - b**(-p)) * b**(emax-1) * b */ | |||
191 | /* 1 - b**(-p) */ | |||
192 | mpfr_init (real_info->huge); | |||
193 | mpfr_set_ui (real_info->huge, 1, GFC_RND_MODEMPFR_RNDN); | |||
194 | mpfr_set_ui (a, real_info->radix, GFC_RND_MODEMPFR_RNDN); | |||
195 | mpfr_pow_si (a, a, -real_info->digits, GFC_RND_MODEMPFR_RNDN); | |||
196 | mpfr_sub (real_info->huge, real_info->huge, a, GFC_RND_MODEMPFR_RNDN); | |||
197 | ||||
198 | /* b**(emax-1) */ | |||
199 | mpfr_set_ui (a, real_info->radix, GFC_RND_MODEMPFR_RNDN); | |||
200 | mpfr_pow_ui (a, a, real_info->max_exponent - 1, GFC_RND_MODEMPFR_RNDN); | |||
201 | ||||
202 | /* (1 - b**(-p)) * b**(emax-1) */ | |||
203 | mpfr_mul (real_info->huge, real_info->huge, a, GFC_RND_MODEMPFR_RNDN); | |||
204 | ||||
205 | /* (1 - b**(-p)) * b**(emax-1) * b */ | |||
206 | mpfr_mul_ui (real_info->huge, real_info->huge, real_info->radix, | |||
207 | GFC_RND_MODEMPFR_RNDN); | |||
208 | ||||
209 | /* tiny(x) = b**(emin-1) */ | |||
210 | mpfr_init (real_info->tiny); | |||
211 | mpfr_set_ui (real_info->tiny, real_info->radix, GFC_RND_MODEMPFR_RNDN); | |||
212 | mpfr_pow_si (real_info->tiny, real_info->tiny, | |||
213 | real_info->min_exponent - 1, GFC_RND_MODEMPFR_RNDN); | |||
214 | ||||
215 | /* subnormal (x) = b**(emin - digit) */ | |||
216 | mpfr_init (real_info->subnormal); | |||
217 | mpfr_set_ui (real_info->subnormal, real_info->radix, GFC_RND_MODEMPFR_RNDN); | |||
218 | mpfr_pow_si (real_info->subnormal, real_info->subnormal, | |||
219 | real_info->min_exponent - real_info->digits, GFC_RND_MODEMPFR_RNDN); | |||
220 | ||||
221 | /* epsilon(x) = b**(1-p) */ | |||
222 | mpfr_init (real_info->epsilon); | |||
223 | mpfr_set_ui (real_info->epsilon, real_info->radix, GFC_RND_MODEMPFR_RNDN); | |||
224 | mpfr_pow_si (real_info->epsilon, real_info->epsilon, | |||
225 | 1 - real_info->digits, GFC_RND_MODEMPFR_RNDN); | |||
226 | ||||
227 | /* range(x) = int(min(log10(huge(x)), -log10(tiny)) */ | |||
228 | mpfr_log10 (a, real_info->huge, GFC_RND_MODEMPFR_RNDN); | |||
229 | mpfr_log10 (b, real_info->tiny, GFC_RND_MODEMPFR_RNDN); | |||
230 | mpfr_neg (b, b, GFC_RND_MODEMPFR_RNDN); | |||
231 | ||||
232 | /* a = min(a, b) */ | |||
233 | mpfr_min (a, a, b, GFC_RND_MODEMPFR_RNDN); | |||
234 | mpfr_trunc (a, a)mpfr_rint((a), (a), MPFR_RNDZ); | |||
235 | real_info->range = (int) mpfr_get_si (a, GFC_RND_MODEMPFR_RNDN); | |||
236 | ||||
237 | /* precision(x) = int((p - 1) * log10(b)) + k */ | |||
238 | mpfr_set_ui (a, real_info->radix, GFC_RND_MODEMPFR_RNDN); | |||
239 | mpfr_log10 (a, a, GFC_RND_MODEMPFR_RNDN); | |||
240 | mpfr_mul_ui (a, a, real_info->digits - 1, GFC_RND_MODEMPFR_RNDN); | |||
241 | mpfr_trunc (a, a)mpfr_rint((a), (a), MPFR_RNDZ); | |||
242 | real_info->precision = (int) mpfr_get_si (a, GFC_RND_MODEMPFR_RNDN); | |||
243 | ||||
244 | /* If the radix is an integral power of 10, add one to the precision. */ | |||
245 | for (i = 10; i <= real_info->radix; i *= 10) | |||
246 | if (i == real_info->radix) | |||
247 | real_info->precision++; | |||
248 | ||||
249 | mpfr_clears (a, b, NULL__null); | |||
250 | } | |||
251 | } | |||
252 | ||||
253 | ||||
254 | /* Clean up, get rid of numeric constants. */ | |||
255 | ||||
256 | void | |||
257 | gfc_arith_done_1 (void) | |||
258 | { | |||
259 | gfc_integer_info *ip; | |||
260 | gfc_real_info *rp; | |||
261 | ||||
262 | for (ip = gfc_integer_kinds; ip->kind; ip++) | |||
263 | { | |||
264 | mpz_clear__gmpz_clear (ip->min_int); | |||
265 | mpz_clear__gmpz_clear (ip->pedantic_min_int); | |||
266 | mpz_clear__gmpz_clear (ip->huge); | |||
267 | } | |||
268 | ||||
269 | for (rp = gfc_real_kinds; rp->kind; rp++) | |||
270 | mpfr_clears (rp->epsilon, rp->huge, rp->tiny, rp->subnormal, NULL__null); | |||
271 | ||||
272 | mpfr_free_cache (); | |||
273 | } | |||
274 | ||||
275 | ||||
276 | /* Given a wide character value and a character kind, determine whether | |||
277 | the character is representable for that kind. */ | |||
278 | bool | |||
279 | gfc_check_character_range (gfc_char_t c, int kind) | |||
280 | { | |||
281 | /* As wide characters are stored as 32-bit values, they're all | |||
282 | representable in UCS=4. */ | |||
283 | if (kind == 4) | |||
284 | return true; | |||
285 | ||||
286 | if (kind == 1) | |||
287 | return c <= 255 ? true : false; | |||
288 | ||||
289 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/arith.cc" , 289, __FUNCTION__)); | |||
290 | } | |||
291 | ||||
292 | ||||
293 | /* Given an integer and a kind, make sure that the integer lies within | |||
294 | the range of the kind. Returns ARITH_OK, ARITH_ASYMMETRIC or | |||
295 | ARITH_OVERFLOW. */ | |||
296 | ||||
297 | arith | |||
298 | gfc_check_integer_range (mpz_t p, int kind) | |||
299 | { | |||
300 | arith result; | |||
301 | int i; | |||
302 | ||||
303 | i = gfc_validate_kind (BT_INTEGER, kind, false); | |||
304 | result = ARITH_OK; | |||
305 | ||||
306 | if (pedanticglobal_options.x_pedantic) | |||
307 | { | |||
308 | if (mpz_cmp__gmpz_cmp (p, gfc_integer_kinds[i].pedantic_min_int) < 0) | |||
309 | result = ARITH_ASYMMETRIC; | |||
310 | } | |||
311 | ||||
312 | ||||
313 | if (flag_range_checkglobal_options.x_flag_range_check == 0) | |||
314 | return result; | |||
315 | ||||
316 | if (mpz_cmp__gmpz_cmp (p, gfc_integer_kinds[i].min_int) < 0 | |||
317 | || mpz_cmp__gmpz_cmp (p, gfc_integer_kinds[i].huge) > 0) | |||
318 | result = ARITH_OVERFLOW; | |||
319 | ||||
320 | return result; | |||
321 | } | |||
322 | ||||
323 | ||||
324 | /* Given a real and a kind, make sure that the real lies within the | |||
325 | range of the kind. Returns ARITH_OK, ARITH_OVERFLOW or | |||
326 | ARITH_UNDERFLOW. */ | |||
327 | ||||
328 | static arith | |||
329 | gfc_check_real_range (mpfr_t p, int kind) | |||
330 | { | |||
331 | arith retval; | |||
332 | mpfr_t q; | |||
333 | int i; | |||
334 | ||||
335 | i = gfc_validate_kind (BT_REAL, kind, false); | |||
336 | ||||
337 | gfc_set_model (p); | |||
338 | mpfr_init (q); | |||
339 | mpfr_abs (q, p, GFC_RND_MODE)mpfr_set4(q,p,MPFR_RNDN,1); | |||
340 | ||||
341 | retval = ARITH_OK; | |||
342 | ||||
343 | if (mpfr_inf_p (p)(((mpfr_srcptr) (0 ? (p) : (mpfr_srcptr) (p)))->_mpfr_exp == (2 - ((mpfr_exp_t) (((mpfr_uexp_t) -1) >> 1))))) | |||
344 | { | |||
345 | if (flag_range_checkglobal_options.x_flag_range_check != 0) | |||
346 | retval = ARITH_OVERFLOW; | |||
347 | } | |||
348 | else if (mpfr_nan_p (p)(((mpfr_srcptr) (0 ? (p) : (mpfr_srcptr) (p)))->_mpfr_exp == (1 - ((mpfr_exp_t) (((mpfr_uexp_t) -1) >> 1))))) | |||
349 | { | |||
350 | if (flag_range_checkglobal_options.x_flag_range_check != 0) | |||
351 | retval = ARITH_NAN; | |||
352 | } | |||
353 | else if (mpfr_sgn (q)((q)->_mpfr_exp < (2 - ((mpfr_exp_t) (((mpfr_uexp_t) -1 ) >> 1))) ? ((((mpfr_srcptr) (0 ? (q) : (mpfr_srcptr) ( q)))->_mpfr_exp == (1 - ((mpfr_exp_t) (((mpfr_uexp_t) -1) >> 1)))) ? mpfr_set_erangeflag () : (mpfr_void) 0), 0 : ((q)-> _mpfr_sign)) == 0) | |||
354 | { | |||
355 | mpfr_clear (q); | |||
356 | return retval; | |||
357 | } | |||
358 | else if (mpfr_cmp (q, gfc_real_kinds[i].huge)mpfr_cmp3(q, gfc_real_kinds[i].huge, 1) > 0) | |||
359 | { | |||
360 | if (flag_range_checkglobal_options.x_flag_range_check == 0) | |||
361 | mpfr_set_inf (p, mpfr_sgn (p)((p)->_mpfr_exp < (2 - ((mpfr_exp_t) (((mpfr_uexp_t) -1 ) >> 1))) ? ((((mpfr_srcptr) (0 ? (p) : (mpfr_srcptr) ( p)))->_mpfr_exp == (1 - ((mpfr_exp_t) (((mpfr_uexp_t) -1) >> 1)))) ? mpfr_set_erangeflag () : (mpfr_void) 0), 0 : ((p)-> _mpfr_sign))); | |||
362 | else | |||
363 | retval = ARITH_OVERFLOW; | |||
364 | } | |||
365 | else if (mpfr_cmp (q, gfc_real_kinds[i].subnormal)mpfr_cmp3(q, gfc_real_kinds[i].subnormal, 1) < 0) | |||
366 | { | |||
367 | if (flag_range_checkglobal_options.x_flag_range_check == 0) | |||
368 | { | |||
369 | if (mpfr_sgn (p)((p)->_mpfr_exp < (2 - ((mpfr_exp_t) (((mpfr_uexp_t) -1 ) >> 1))) ? ((((mpfr_srcptr) (0 ? (p) : (mpfr_srcptr) ( p)))->_mpfr_exp == (1 - ((mpfr_exp_t) (((mpfr_uexp_t) -1) >> 1)))) ? mpfr_set_erangeflag () : (mpfr_void) 0), 0 : ((p)-> _mpfr_sign)) < 0) | |||
370 | { | |||
371 | mpfr_set_ui (p, 0, GFC_RND_MODEMPFR_RNDN); | |||
372 | mpfr_set_si (q, -1, GFC_RND_MODEMPFR_RNDN); | |||
373 | mpfr_copysign (p, p, q, GFC_RND_MODE)mpfr_set4(p,p,MPFR_RNDN,(0 ? (((((mpfr_srcptr) (0 ? (q) : (mpfr_srcptr ) (q))))->_mpfr_sign)) : (((((mpfr_srcptr) (0 ? (q) : (mpfr_srcptr ) (q))))->_mpfr_sign)))); | |||
374 | } | |||
375 | else | |||
376 | mpfr_set_ui (p, 0, GFC_RND_MODEMPFR_RNDN); | |||
377 | } | |||
378 | else | |||
379 | retval = ARITH_UNDERFLOW; | |||
380 | } | |||
381 | else if (mpfr_cmp (q, gfc_real_kinds[i].tiny)mpfr_cmp3(q, gfc_real_kinds[i].tiny, 1) < 0) | |||
382 | { | |||
383 | mpfr_exp_t emin, emax; | |||
384 | int en; | |||
385 | ||||
386 | /* Save current values of emin and emax. */ | |||
387 | emin = mpfr_get_emin (); | |||
388 | emax = mpfr_get_emax (); | |||
389 | ||||
390 | /* Set emin and emax for the current model number. */ | |||
391 | en = gfc_real_kinds[i].min_exponent - gfc_real_kinds[i].digits + 1; | |||
392 | mpfr_set_emin ((mpfr_exp_t) en); | |||
393 | mpfr_set_emax ((mpfr_exp_t) gfc_real_kinds[i].max_exponent); | |||
394 | mpfr_check_range (q, 0, GFC_RND_MODEMPFR_RNDN); | |||
395 | mpfr_subnormalize (q, 0, GFC_RND_MODEMPFR_RNDN); | |||
396 | ||||
397 | /* Reset emin and emax. */ | |||
398 | mpfr_set_emin (emin); | |||
399 | mpfr_set_emax (emax); | |||
400 | ||||
401 | /* Copy sign if needed. */ | |||
402 | if (mpfr_sgn (p)((p)->_mpfr_exp < (2 - ((mpfr_exp_t) (((mpfr_uexp_t) -1 ) >> 1))) ? ((((mpfr_srcptr) (0 ? (p) : (mpfr_srcptr) ( p)))->_mpfr_exp == (1 - ((mpfr_exp_t) (((mpfr_uexp_t) -1) >> 1)))) ? mpfr_set_erangeflag () : (mpfr_void) 0), 0 : ((p)-> _mpfr_sign)) < 0) | |||
403 | mpfr_neg (p, q, MPFR_RNDN); | |||
404 | else | |||
405 | mpfr_set (p, q, MPFR_RNDN)__extension__ ({ mpfr_srcptr _p = (q); mpfr_set4(p,_p,MPFR_RNDN ,((_p)->_mpfr_sign)); }); | |||
406 | } | |||
407 | ||||
408 | mpfr_clear (q); | |||
409 | ||||
410 | return retval; | |||
411 | } | |||
412 | ||||
413 | ||||
414 | /* Low-level arithmetic functions. All of these subroutines assume | |||
415 | that all operands are of the same type and return an operand of the | |||
416 | same type. The other thing about these subroutines is that they | |||
417 | can fail in various ways -- overflow, underflow, division by zero, | |||
418 | zero raised to the zero, etc. */ | |||
419 | ||||
420 | static arith | |||
421 | gfc_arith_not (gfc_expr *op1, gfc_expr **resultp) | |||
422 | { | |||
423 | gfc_expr *result; | |||
424 | ||||
425 | if (op1->ts.type != BT_LOGICAL) | |||
426 | return ARITH_INVALID_TYPE; | |||
427 | ||||
428 | result = gfc_get_constant_expr (BT_LOGICAL, op1->ts.kind, &op1->where); | |||
429 | result->value.logical = !op1->value.logical; | |||
430 | *resultp = result; | |||
431 | ||||
432 | return ARITH_OK; | |||
433 | } | |||
434 | ||||
435 | ||||
436 | static arith | |||
437 | gfc_arith_and (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp) | |||
438 | { | |||
439 | gfc_expr *result; | |||
440 | ||||
441 | if (op1->ts.type != BT_LOGICAL || op2->ts.type != BT_LOGICAL) | |||
442 | return ARITH_INVALID_TYPE; | |||
443 | ||||
444 | result = gfc_get_constant_expr (BT_LOGICAL, gfc_kind_max (op1, op2), | |||
445 | &op1->where); | |||
446 | result->value.logical = op1->value.logical && op2->value.logical; | |||
447 | *resultp = result; | |||
448 | ||||
449 | return ARITH_OK; | |||
450 | } | |||
451 | ||||
452 | ||||
453 | static arith | |||
454 | gfc_arith_or (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp) | |||
455 | { | |||
456 | gfc_expr *result; | |||
457 | ||||
458 | if (op1->ts.type != BT_LOGICAL || op2->ts.type != BT_LOGICAL) | |||
459 | return ARITH_INVALID_TYPE; | |||
460 | ||||
461 | result = gfc_get_constant_expr (BT_LOGICAL, gfc_kind_max (op1, op2), | |||
462 | &op1->where); | |||
463 | result->value.logical = op1->value.logical || op2->value.logical; | |||
464 | *resultp = result; | |||
465 | ||||
466 | return ARITH_OK; | |||
467 | } | |||
468 | ||||
469 | ||||
470 | static arith | |||
471 | gfc_arith_eqv (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp) | |||
472 | { | |||
473 | gfc_expr *result; | |||
474 | ||||
475 | if (op1->ts.type != BT_LOGICAL || op2->ts.type != BT_LOGICAL) | |||
476 | return ARITH_INVALID_TYPE; | |||
477 | ||||
478 | result = gfc_get_constant_expr (BT_LOGICAL, gfc_kind_max (op1, op2), | |||
479 | &op1->where); | |||
480 | result->value.logical = op1->value.logical == op2->value.logical; | |||
481 | *resultp = result; | |||
482 | ||||
483 | return ARITH_OK; | |||
484 | } | |||
485 | ||||
486 | ||||
487 | static arith | |||
488 | gfc_arith_neqv (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp) | |||
489 | { | |||
490 | gfc_expr *result; | |||
491 | ||||
492 | if (op1->ts.type != BT_LOGICAL || op2->ts.type != BT_LOGICAL) | |||
493 | return ARITH_INVALID_TYPE; | |||
494 | ||||
495 | result = gfc_get_constant_expr (BT_LOGICAL, gfc_kind_max (op1, op2), | |||
496 | &op1->where); | |||
497 | result->value.logical = op1->value.logical != op2->value.logical; | |||
498 | *resultp = result; | |||
499 | ||||
500 | return ARITH_OK; | |||
501 | } | |||
502 | ||||
503 | ||||
504 | /* Make sure a constant numeric expression is within the range for | |||
505 | its type and kind. Note that there's also a gfc_check_range(), | |||
506 | but that one deals with the intrinsic RANGE function. */ | |||
507 | ||||
508 | arith | |||
509 | gfc_range_check (gfc_expr *e) | |||
510 | { | |||
511 | arith rc; | |||
512 | arith rc2; | |||
513 | ||||
514 | switch (e->ts.type) | |||
515 | { | |||
516 | case BT_INTEGER: | |||
517 | rc = gfc_check_integer_range (e->value.integer, e->ts.kind); | |||
518 | break; | |||
519 | ||||
520 | case BT_REAL: | |||
521 | rc = gfc_check_real_range (e->value.real, e->ts.kind); | |||
522 | if (rc == ARITH_UNDERFLOW) | |||
523 | mpfr_set_ui (e->value.real, 0, GFC_RND_MODEMPFR_RNDN); | |||
524 | if (rc == ARITH_OVERFLOW) | |||
525 | mpfr_set_inf (e->value.real, mpfr_sgn (e->value.real)((e->value.real)->_mpfr_exp < (2 - ((mpfr_exp_t) ((( mpfr_uexp_t) -1) >> 1))) ? ((((mpfr_srcptr) (0 ? (e-> value.real) : (mpfr_srcptr) (e->value.real)))->_mpfr_exp == (1 - ((mpfr_exp_t) (((mpfr_uexp_t) -1) >> 1)))) ? mpfr_set_erangeflag () : (mpfr_void) 0), 0 : ((e->value.real)->_mpfr_sign) )); | |||
526 | if (rc == ARITH_NAN) | |||
527 | mpfr_set_nan (e->value.real); | |||
528 | break; | |||
529 | ||||
530 | case BT_COMPLEX: | |||
531 | rc = gfc_check_real_range (mpc_realref (e->value.complex)((e->value.complex)->re), e->ts.kind); | |||
532 | if (rc == ARITH_UNDERFLOW) | |||
533 | mpfr_set_ui (mpc_realref (e->value.complex)((e->value.complex)->re), 0, GFC_RND_MODEMPFR_RNDN); | |||
534 | if (rc == ARITH_OVERFLOW) | |||
535 | mpfr_set_inf (mpc_realref (e->value.complex)((e->value.complex)->re), | |||
536 | mpfr_sgn (mpc_realref (e->value.complex))((((e->value.complex)->re))->_mpfr_exp < (2 - ((mpfr_exp_t ) (((mpfr_uexp_t) -1) >> 1))) ? ((((mpfr_srcptr) (0 ? ( ((e->value.complex)->re)) : (mpfr_srcptr) (((e->value .complex)->re))))->_mpfr_exp == (1 - ((mpfr_exp_t) (((mpfr_uexp_t ) -1) >> 1)))) ? mpfr_set_erangeflag () : (mpfr_void) 0 ), 0 : ((((e->value.complex)->re))->_mpfr_sign))); | |||
537 | if (rc == ARITH_NAN) | |||
538 | mpfr_set_nan (mpc_realref (e->value.complex)((e->value.complex)->re)); | |||
539 | ||||
540 | rc2 = gfc_check_real_range (mpc_imagref (e->value.complex)((e->value.complex)->im), e->ts.kind); | |||
541 | if (rc == ARITH_UNDERFLOW) | |||
542 | mpfr_set_ui (mpc_imagref (e->value.complex)((e->value.complex)->im), 0, GFC_RND_MODEMPFR_RNDN); | |||
543 | if (rc == ARITH_OVERFLOW) | |||
544 | mpfr_set_inf (mpc_imagref (e->value.complex)((e->value.complex)->im), | |||
545 | mpfr_sgn (mpc_imagref (e->value.complex))((((e->value.complex)->im))->_mpfr_exp < (2 - ((mpfr_exp_t ) (((mpfr_uexp_t) -1) >> 1))) ? ((((mpfr_srcptr) (0 ? ( ((e->value.complex)->im)) : (mpfr_srcptr) (((e->value .complex)->im))))->_mpfr_exp == (1 - ((mpfr_exp_t) (((mpfr_uexp_t ) -1) >> 1)))) ? mpfr_set_erangeflag () : (mpfr_void) 0 ), 0 : ((((e->value.complex)->im))->_mpfr_sign))); | |||
546 | if (rc == ARITH_NAN) | |||
547 | mpfr_set_nan (mpc_imagref (e->value.complex)((e->value.complex)->im)); | |||
548 | ||||
549 | if (rc == ARITH_OK) | |||
550 | rc = rc2; | |||
551 | break; | |||
552 | ||||
553 | default: | |||
554 | gfc_internal_error ("gfc_range_check(): Bad type"); | |||
555 | } | |||
556 | ||||
557 | return rc; | |||
558 | } | |||
559 | ||||
560 | ||||
561 | /* Several of the following routines use the same set of statements to | |||
562 | check the validity of the result. Encapsulate the checking here. */ | |||
563 | ||||
564 | static arith | |||
565 | check_result (arith rc, gfc_expr *x, gfc_expr *r, gfc_expr **rp) | |||
566 | { | |||
567 | arith val = rc; | |||
568 | ||||
569 | if (val == ARITH_UNDERFLOW) | |||
570 | { | |||
571 | if (warn_underflowglobal_options.x_warn_underflow) | |||
572 | gfc_warning (OPT_Wunderflow, gfc_arith_error (val), &x->where); | |||
573 | val = ARITH_OK; | |||
574 | } | |||
575 | ||||
576 | if (val == ARITH_ASYMMETRIC) | |||
577 | { | |||
578 | gfc_warning (0, gfc_arith_error (val), &x->where); | |||
579 | val = ARITH_OK; | |||
580 | } | |||
581 | ||||
582 | if (val == ARITH_OK || val == ARITH_OVERFLOW) | |||
583 | *rp = r; | |||
584 | else | |||
585 | gfc_free_expr (r); | |||
586 | ||||
587 | return val; | |||
588 | } | |||
589 | ||||
590 | ||||
591 | /* It may seem silly to have a subroutine that actually computes the | |||
592 | unary plus of a constant, but it prevents us from making exceptions | |||
593 | in the code elsewhere. Used for unary plus and parenthesized | |||
594 | expressions. */ | |||
595 | ||||
596 | static arith | |||
597 | gfc_arith_identity (gfc_expr *op1, gfc_expr **resultp) | |||
598 | { | |||
599 | *resultp = gfc_copy_expr (op1); | |||
600 | return ARITH_OK; | |||
601 | } | |||
602 | ||||
603 | ||||
604 | static arith | |||
605 | gfc_arith_uminus (gfc_expr *op1, gfc_expr **resultp) | |||
606 | { | |||
607 | gfc_expr *result; | |||
608 | arith rc; | |||
609 | ||||
610 | result = gfc_get_constant_expr (op1->ts.type, op1->ts.kind, &op1->where); | |||
611 | ||||
612 | switch (op1->ts.type) | |||
613 | { | |||
614 | case BT_INTEGER: | |||
615 | mpz_neg__gmpz_neg (result->value.integer, op1->value.integer); | |||
616 | break; | |||
617 | ||||
618 | case BT_REAL: | |||
619 | mpfr_neg (result->value.real, op1->value.real, GFC_RND_MODEMPFR_RNDN); | |||
620 | break; | |||
621 | ||||
622 | case BT_COMPLEX: | |||
623 | mpc_neg (result->value.complex, op1->value.complex, GFC_MPC_RND_MODE(((int)(MPFR_RNDN)) + ((int)(MPFR_RNDN) << 4))); | |||
624 | break; | |||
625 | ||||
626 | default: | |||
627 | gfc_internal_error ("gfc_arith_uminus(): Bad basic type"); | |||
628 | } | |||
629 | ||||
630 | rc = gfc_range_check (result); | |||
631 | ||||
632 | return check_result (rc, op1, result, resultp); | |||
633 | } | |||
634 | ||||
635 | ||||
636 | static arith | |||
637 | gfc_arith_plus (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp) | |||
638 | { | |||
639 | gfc_expr *result; | |||
640 | arith rc; | |||
641 | ||||
642 | if (op1->ts.type != op2->ts.type) | |||
643 | return ARITH_INVALID_TYPE; | |||
644 | ||||
645 | result = gfc_get_constant_expr (op1->ts.type, op1->ts.kind, &op1->where); | |||
646 | ||||
647 | switch (op1->ts.type) | |||
648 | { | |||
649 | case BT_INTEGER: | |||
650 | mpz_add__gmpz_add (result->value.integer, op1->value.integer, op2->value.integer); | |||
651 | break; | |||
652 | ||||
653 | case BT_REAL: | |||
654 | mpfr_add (result->value.real, op1->value.real, op2->value.real, | |||
655 | GFC_RND_MODEMPFR_RNDN); | |||
656 | break; | |||
657 | ||||
658 | case BT_COMPLEX: | |||
659 | mpc_add (result->value.complex, op1->value.complex, op2->value.complex, | |||
660 | GFC_MPC_RND_MODE(((int)(MPFR_RNDN)) + ((int)(MPFR_RNDN) << 4))); | |||
661 | break; | |||
662 | ||||
663 | default: | |||
664 | gfc_internal_error ("gfc_arith_plus(): Bad basic type"); | |||
665 | } | |||
666 | ||||
667 | rc = gfc_range_check (result); | |||
668 | ||||
669 | return check_result (rc, op1, result, resultp); | |||
670 | } | |||
671 | ||||
672 | ||||
673 | static arith | |||
674 | gfc_arith_minus (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp) | |||
675 | { | |||
676 | gfc_expr *result; | |||
677 | arith rc; | |||
678 | ||||
679 | if (op1->ts.type != op2->ts.type) | |||
680 | return ARITH_INVALID_TYPE; | |||
681 | ||||
682 | result = gfc_get_constant_expr (op1->ts.type, op1->ts.kind, &op1->where); | |||
683 | ||||
684 | switch (op1->ts.type) | |||
685 | { | |||
686 | case BT_INTEGER: | |||
687 | mpz_sub__gmpz_sub (result->value.integer, op1->value.integer, op2->value.integer); | |||
688 | break; | |||
689 | ||||
690 | case BT_REAL: | |||
691 | mpfr_sub (result->value.real, op1->value.real, op2->value.real, | |||
692 | GFC_RND_MODEMPFR_RNDN); | |||
693 | break; | |||
694 | ||||
695 | case BT_COMPLEX: | |||
696 | mpc_sub (result->value.complex, op1->value.complex, | |||
697 | op2->value.complex, GFC_MPC_RND_MODE(((int)(MPFR_RNDN)) + ((int)(MPFR_RNDN) << 4))); | |||
698 | break; | |||
699 | ||||
700 | default: | |||
701 | gfc_internal_error ("gfc_arith_minus(): Bad basic type"); | |||
702 | } | |||
703 | ||||
704 | rc = gfc_range_check (result); | |||
705 | ||||
706 | return check_result (rc, op1, result, resultp); | |||
707 | } | |||
708 | ||||
709 | ||||
710 | static arith | |||
711 | gfc_arith_times (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp) | |||
712 | { | |||
713 | gfc_expr *result; | |||
714 | arith rc; | |||
715 | ||||
716 | if (op1->ts.type != op2->ts.type) | |||
717 | return ARITH_INVALID_TYPE; | |||
718 | ||||
719 | result = gfc_get_constant_expr (op1->ts.type, op1->ts.kind, &op1->where); | |||
720 | ||||
721 | switch (op1->ts.type) | |||
722 | { | |||
723 | case BT_INTEGER: | |||
724 | mpz_mul__gmpz_mul (result->value.integer, op1->value.integer, op2->value.integer); | |||
725 | break; | |||
726 | ||||
727 | case BT_REAL: | |||
728 | mpfr_mul (result->value.real, op1->value.real, op2->value.real, | |||
729 | GFC_RND_MODEMPFR_RNDN); | |||
730 | break; | |||
731 | ||||
732 | case BT_COMPLEX: | |||
733 | gfc_set_model (mpc_realref (op1->value.complex)((op1->value.complex)->re)); | |||
734 | mpc_mul (result->value.complex, op1->value.complex, op2->value.complex, | |||
735 | GFC_MPC_RND_MODE(((int)(MPFR_RNDN)) + ((int)(MPFR_RNDN) << 4))); | |||
736 | break; | |||
737 | ||||
738 | default: | |||
739 | gfc_internal_error ("gfc_arith_times(): Bad basic type"); | |||
740 | } | |||
741 | ||||
742 | rc = gfc_range_check (result); | |||
743 | ||||
744 | return check_result (rc, op1, result, resultp); | |||
745 | } | |||
746 | ||||
747 | ||||
748 | static arith | |||
749 | gfc_arith_divide (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp) | |||
750 | { | |||
751 | gfc_expr *result; | |||
752 | arith rc; | |||
753 | ||||
754 | if (op1->ts.type != op2->ts.type) | |||
755 | return ARITH_INVALID_TYPE; | |||
756 | ||||
757 | rc = ARITH_OK; | |||
758 | ||||
759 | result = gfc_get_constant_expr (op1->ts.type, op1->ts.kind, &op1->where); | |||
760 | ||||
761 | switch (op1->ts.type) | |||
762 | { | |||
763 | case BT_INTEGER: | |||
764 | if (mpz_sgn (op2->value.integer)((op2->value.integer)->_mp_size < 0 ? -1 : (op2-> value.integer)->_mp_size > 0) == 0) | |||
765 | { | |||
766 | rc = ARITH_DIV0; | |||
767 | break; | |||
768 | } | |||
769 | ||||
770 | if (warn_integer_divisionglobal_options.x_warn_integer_division) | |||
771 | { | |||
772 | mpz_t r; | |||
773 | mpz_init__gmpz_init (r); | |||
774 | mpz_tdiv_qr__gmpz_tdiv_qr (result->value.integer, r, op1->value.integer, | |||
775 | op2->value.integer); | |||
776 | ||||
777 | if (mpz_cmp_si (r, 0)(__builtin_constant_p ((0) >= 0) && (0) >= 0 ? ( __builtin_constant_p ((static_cast<unsigned long> (0))) && ((static_cast<unsigned long> (0))) == 0 ? ( (r)->_mp_size < 0 ? -1 : (r)->_mp_size > 0) : __gmpz_cmp_ui (r,(static_cast<unsigned long> (0)))) : __gmpz_cmp_si ( r,0)) != 0) | |||
778 | { | |||
779 | char *p; | |||
780 | p = mpz_get_str__gmpz_get_str (NULL__null, 10, result->value.integer); | |||
781 | gfc_warning (OPT_Winteger_division, "Integer division " | |||
782 | "truncated to constant %qs at %L", p, | |||
783 | &op1->where); | |||
784 | free (p); | |||
785 | } | |||
786 | mpz_clear__gmpz_clear (r); | |||
787 | } | |||
788 | else | |||
789 | mpz_tdiv_q__gmpz_tdiv_q (result->value.integer, op1->value.integer, | |||
790 | op2->value.integer); | |||
791 | ||||
792 | break; | |||
793 | ||||
794 | case BT_REAL: | |||
795 | if (mpfr_sgn (op2->value.real)((op2->value.real)->_mpfr_exp < (2 - ((mpfr_exp_t) ( ((mpfr_uexp_t) -1) >> 1))) ? ((((mpfr_srcptr) (0 ? (op2 ->value.real) : (mpfr_srcptr) (op2->value.real)))->_mpfr_exp == (1 - ((mpfr_exp_t) (((mpfr_uexp_t) -1) >> 1)))) ? mpfr_set_erangeflag () : (mpfr_void) 0), 0 : ((op2->value.real)->_mpfr_sign )) == 0 && flag_range_checkglobal_options.x_flag_range_check == 1) | |||
796 | { | |||
797 | rc = ARITH_DIV0; | |||
798 | break; | |||
799 | } | |||
800 | ||||
801 | mpfr_div (result->value.real, op1->value.real, op2->value.real, | |||
802 | GFC_RND_MODEMPFR_RNDN); | |||
803 | break; | |||
804 | ||||
805 | case BT_COMPLEX: | |||
806 | if (mpc_cmp_si_si (op2->value.complex, 0, 0) == 0 | |||
807 | && flag_range_checkglobal_options.x_flag_range_check == 1) | |||
808 | { | |||
809 | rc = ARITH_DIV0; | |||
810 | break; | |||
811 | } | |||
812 | ||||
813 | gfc_set_model (mpc_realref (op1->value.complex)((op1->value.complex)->re)); | |||
814 | if (mpc_cmp_si_si (op2->value.complex, 0, 0) == 0) | |||
815 | { | |||
816 | /* In Fortran, return (NaN + NaN I) for any zero divisor. See | |||
817 | PR 40318. */ | |||
818 | mpfr_set_nan (mpc_realref (result->value.complex)((result->value.complex)->re)); | |||
819 | mpfr_set_nan (mpc_imagref (result->value.complex)((result->value.complex)->im)); | |||
820 | } | |||
821 | else | |||
822 | mpc_div (result->value.complex, op1->value.complex, op2->value.complex, | |||
823 | GFC_MPC_RND_MODE(((int)(MPFR_RNDN)) + ((int)(MPFR_RNDN) << 4))); | |||
824 | break; | |||
825 | ||||
826 | default: | |||
827 | gfc_internal_error ("gfc_arith_divide(): Bad basic type"); | |||
828 | } | |||
829 | ||||
830 | if (rc == ARITH_OK) | |||
831 | rc = gfc_range_check (result); | |||
832 | ||||
833 | return check_result (rc, op1, result, resultp); | |||
834 | } | |||
835 | ||||
836 | /* Raise a number to a power. */ | |||
837 | ||||
838 | static arith | |||
839 | arith_power (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp) | |||
840 | { | |||
841 | int power_sign; | |||
842 | gfc_expr *result; | |||
843 | arith rc; | |||
844 | ||||
845 | if (!gfc_numeric_ts (&op1->ts) || !gfc_numeric_ts (&op2->ts)) | |||
846 | return ARITH_INVALID_TYPE; | |||
847 | ||||
848 | /* The result type is derived from op1 and must be compatible with the | |||
849 | result of the simplification. Otherwise postpone simplification until | |||
850 | after operand conversions usually done by gfc_type_convert_binary. */ | |||
851 | if ((op1->ts.type == BT_INTEGER && op2->ts.type != BT_INTEGER) | |||
852 | || (op1->ts.type == BT_REAL && op2->ts.type == BT_COMPLEX)) | |||
853 | return ARITH_NOT_REDUCED; | |||
854 | ||||
855 | rc = ARITH_OK; | |||
856 | result = gfc_get_constant_expr (op1->ts.type, op1->ts.kind, &op1->where); | |||
857 | ||||
858 | switch (op2->ts.type) | |||
859 | { | |||
860 | case BT_INTEGER: | |||
861 | power_sign = mpz_sgn (op2->value.integer)((op2->value.integer)->_mp_size < 0 ? -1 : (op2-> value.integer)->_mp_size > 0); | |||
862 | ||||
863 | if (power_sign == 0) | |||
864 | { | |||
865 | /* Handle something to the zeroth power. Since we're dealing | |||
866 | with integral exponents, there is no ambiguity in the | |||
867 | limiting procedure used to determine the value of 0**0. */ | |||
868 | switch (op1->ts.type) | |||
869 | { | |||
870 | case BT_INTEGER: | |||
871 | mpz_set_ui__gmpz_set_ui (result->value.integer, 1); | |||
872 | break; | |||
873 | ||||
874 | case BT_REAL: | |||
875 | mpfr_set_ui (result->value.real, 1, GFC_RND_MODEMPFR_RNDN); | |||
876 | break; | |||
877 | ||||
878 | case BT_COMPLEX: | |||
879 | mpc_set_ui (result->value.complex, 1, GFC_MPC_RND_MODE(((int)(MPFR_RNDN)) + ((int)(MPFR_RNDN) << 4))); | |||
880 | break; | |||
881 | ||||
882 | default: | |||
883 | gfc_internal_error ("arith_power(): Bad base"); | |||
884 | } | |||
885 | } | |||
886 | else | |||
887 | { | |||
888 | switch (op1->ts.type) | |||
889 | { | |||
890 | case BT_INTEGER: | |||
891 | { | |||
892 | /* First, we simplify the cases of op1 == 1, 0 or -1. */ | |||
893 | if (mpz_cmp_si (op1->value.integer, 1)(__builtin_constant_p ((1) >= 0) && (1) >= 0 ? ( __builtin_constant_p ((static_cast<unsigned long> (1))) && ((static_cast<unsigned long> (1))) == 0 ? ( (op1->value.integer)->_mp_size < 0 ? -1 : (op1->value .integer)->_mp_size > 0) : __gmpz_cmp_ui (op1->value .integer,(static_cast<unsigned long> (1)))) : __gmpz_cmp_si (op1->value.integer,1)) == 0) | |||
894 | { | |||
895 | /* 1**op2 == 1 */ | |||
896 | mpz_set_si__gmpz_set_si (result->value.integer, 1); | |||
897 | } | |||
898 | else if (mpz_cmp_si (op1->value.integer, 0)(__builtin_constant_p ((0) >= 0) && (0) >= 0 ? ( __builtin_constant_p ((static_cast<unsigned long> (0))) && ((static_cast<unsigned long> (0))) == 0 ? ( (op1->value.integer)->_mp_size < 0 ? -1 : (op1->value .integer)->_mp_size > 0) : __gmpz_cmp_ui (op1->value .integer,(static_cast<unsigned long> (0)))) : __gmpz_cmp_si (op1->value.integer,0)) == 0) | |||
899 | { | |||
900 | /* 0**op2 == 0, if op2 > 0 | |||
901 | 0**op2 overflow, if op2 < 0 ; in that case, we | |||
902 | set the result to 0 and return ARITH_DIV0. */ | |||
903 | mpz_set_si__gmpz_set_si (result->value.integer, 0); | |||
904 | if (mpz_cmp_si (op2->value.integer, 0)(__builtin_constant_p ((0) >= 0) && (0) >= 0 ? ( __builtin_constant_p ((static_cast<unsigned long> (0))) && ((static_cast<unsigned long> (0))) == 0 ? ( (op2->value.integer)->_mp_size < 0 ? -1 : (op2->value .integer)->_mp_size > 0) : __gmpz_cmp_ui (op2->value .integer,(static_cast<unsigned long> (0)))) : __gmpz_cmp_si (op2->value.integer,0)) < 0) | |||
905 | rc = ARITH_DIV0; | |||
906 | } | |||
907 | else if (mpz_cmp_si (op1->value.integer, -1)(__builtin_constant_p ((-1) >= 0) && (-1) >= 0 ? (__builtin_constant_p ((static_cast<unsigned long> (-1 ))) && ((static_cast<unsigned long> (-1))) == 0 ? ((op1->value.integer)->_mp_size < 0 ? -1 : (op1-> value.integer)->_mp_size > 0) : __gmpz_cmp_ui (op1-> value.integer,(static_cast<unsigned long> (-1)))) : __gmpz_cmp_si (op1->value.integer,-1)) == 0) | |||
908 | { | |||
909 | /* (-1)**op2 == (-1)**(mod(op2,2)) */ | |||
910 | unsigned int odd = mpz_fdiv_ui__gmpz_fdiv_ui (op2->value.integer, 2); | |||
911 | if (odd) | |||
912 | mpz_set_si__gmpz_set_si (result->value.integer, -1); | |||
913 | else | |||
914 | mpz_set_si__gmpz_set_si (result->value.integer, 1); | |||
915 | } | |||
916 | /* Then, we take care of op2 < 0. */ | |||
917 | else if (mpz_cmp_si (op2->value.integer, 0)(__builtin_constant_p ((0) >= 0) && (0) >= 0 ? ( __builtin_constant_p ((static_cast<unsigned long> (0))) && ((static_cast<unsigned long> (0))) == 0 ? ( (op2->value.integer)->_mp_size < 0 ? -1 : (op2->value .integer)->_mp_size > 0) : __gmpz_cmp_ui (op2->value .integer,(static_cast<unsigned long> (0)))) : __gmpz_cmp_si (op2->value.integer,0)) < 0) | |||
918 | { | |||
919 | /* if op2 < 0, op1**op2 == 0 because abs(op1) > 1. */ | |||
920 | mpz_set_si__gmpz_set_si (result->value.integer, 0); | |||
921 | if (warn_integer_divisionglobal_options.x_warn_integer_division) | |||
922 | gfc_warning_now (OPT_Winteger_division, "Negative " | |||
923 | "exponent of integer has zero " | |||
924 | "result at %L", &result->where); | |||
925 | } | |||
926 | else | |||
927 | { | |||
928 | /* We have abs(op1) > 1 and op2 > 1. | |||
929 | If op2 > bit_size(op1), we'll have an out-of-range | |||
930 | result. */ | |||
931 | int k, power; | |||
932 | ||||
933 | k = gfc_validate_kind (BT_INTEGER, op1->ts.kind, false); | |||
934 | power = gfc_integer_kinds[k].bit_size; | |||
935 | if (mpz_cmp_si (op2->value.integer, power)(__builtin_constant_p ((power) >= 0) && (power) >= 0 ? (__builtin_constant_p ((static_cast<unsigned long> (power))) && ((static_cast<unsigned long> (power ))) == 0 ? ((op2->value.integer)->_mp_size < 0 ? -1 : (op2->value.integer)->_mp_size > 0) : __gmpz_cmp_ui (op2->value.integer,(static_cast<unsigned long> (power )))) : __gmpz_cmp_si (op2->value.integer,power)) < 0) | |||
936 | { | |||
937 | gfc_extract_int (op2, &power); | |||
938 | mpz_pow_ui__gmpz_pow_ui (result->value.integer, op1->value.integer, | |||
939 | power); | |||
940 | rc = gfc_range_check (result); | |||
941 | if (rc == ARITH_OVERFLOW) | |||
942 | gfc_error_now ("Result of exponentiation at %L " | |||
943 | "exceeds the range of %s", &op1->where, | |||
944 | gfc_typename (&(op1->ts))); | |||
945 | } | |||
946 | else | |||
947 | { | |||
948 | /* Provide a nonsense value to propagate up. */ | |||
949 | mpz_set__gmpz_set (result->value.integer, | |||
950 | gfc_integer_kinds[k].huge); | |||
951 | mpz_add_ui__gmpz_add_ui (result->value.integer, | |||
952 | result->value.integer, 1); | |||
953 | rc = ARITH_OVERFLOW; | |||
954 | } | |||
955 | } | |||
956 | } | |||
957 | break; | |||
958 | ||||
959 | case BT_REAL: | |||
960 | mpfr_pow_z (result->value.real, op1->value.real, | |||
961 | op2->value.integer, GFC_RND_MODEMPFR_RNDN); | |||
962 | break; | |||
963 | ||||
964 | case BT_COMPLEX: | |||
965 | mpc_pow_z (result->value.complex, op1->value.complex, | |||
966 | op2->value.integer, GFC_MPC_RND_MODE(((int)(MPFR_RNDN)) + ((int)(MPFR_RNDN) << 4))); | |||
967 | break; | |||
968 | ||||
969 | default: | |||
970 | break; | |||
971 | } | |||
972 | } | |||
973 | break; | |||
974 | ||||
975 | case BT_REAL: | |||
976 | ||||
977 | if (gfc_init_expr_flag) | |||
978 | { | |||
979 | if (!gfc_notify_std (GFC_STD_F2003(1<<4), "Noninteger " | |||
980 | "exponent in an initialization " | |||
981 | "expression at %L", &op2->where)) | |||
982 | { | |||
983 | gfc_free_expr (result); | |||
984 | return ARITH_PROHIBIT; | |||
985 | } | |||
986 | } | |||
987 | ||||
988 | if (mpfr_cmp_si (op1->value.real, 0)mpfr_cmp_si_2exp((op1->value.real),(0),0) < 0) | |||
989 | { | |||
990 | gfc_error ("Raising a negative REAL at %L to " | |||
991 | "a REAL power is prohibited", &op1->where); | |||
992 | gfc_free_expr (result); | |||
993 | return ARITH_PROHIBIT; | |||
994 | } | |||
995 | ||||
996 | mpfr_pow (result->value.real, op1->value.real, op2->value.real, | |||
997 | GFC_RND_MODEMPFR_RNDN); | |||
998 | break; | |||
999 | ||||
1000 | case BT_COMPLEX: | |||
1001 | { | |||
1002 | if (gfc_init_expr_flag) | |||
1003 | { | |||
1004 | if (!gfc_notify_std (GFC_STD_F2003(1<<4), "Noninteger " | |||
1005 | "exponent in an initialization " | |||
1006 | "expression at %L", &op2->where)) | |||
1007 | { | |||
1008 | gfc_free_expr (result); | |||
1009 | return ARITH_PROHIBIT; | |||
1010 | } | |||
1011 | } | |||
1012 | ||||
1013 | mpc_pow (result->value.complex, op1->value.complex, | |||
1014 | op2->value.complex, GFC_MPC_RND_MODE(((int)(MPFR_RNDN)) + ((int)(MPFR_RNDN) << 4))); | |||
1015 | } | |||
1016 | break; | |||
1017 | default: | |||
1018 | gfc_internal_error ("arith_power(): unknown type"); | |||
1019 | } | |||
1020 | ||||
1021 | if (rc == ARITH_OK) | |||
1022 | rc = gfc_range_check (result); | |||
1023 | ||||
1024 | return check_result (rc, op1, result, resultp); | |||
1025 | } | |||
1026 | ||||
1027 | ||||
1028 | /* Concatenate two string constants. */ | |||
1029 | ||||
1030 | static arith | |||
1031 | gfc_arith_concat (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp) | |||
1032 | { | |||
1033 | gfc_expr *result; | |||
1034 | size_t len; | |||
1035 | ||||
1036 | /* By cleverly playing around with constructors, it is possible | |||
1037 | to get mismaching types here. */ | |||
1038 | if (op1->ts.type != BT_CHARACTER || op2->ts.type != BT_CHARACTER | |||
1039 | || op1->ts.kind != op2->ts.kind) | |||
1040 | return ARITH_WRONGCONCAT; | |||
1041 | ||||
1042 | result = gfc_get_constant_expr (BT_CHARACTER, op1->ts.kind, | |||
1043 | &op1->where); | |||
1044 | ||||
1045 | len = op1->value.character.length + op2->value.character.length; | |||
1046 | ||||
1047 | result->value.character.string = gfc_get_wide_string (len + 1)((gfc_char_t *) xcalloc ((len + 1), sizeof (gfc_char_t))); | |||
1048 | result->value.character.length = len; | |||
1049 | ||||
1050 | memcpy (result->value.character.string, op1->value.character.string, | |||
1051 | op1->value.character.length * sizeof (gfc_char_t)); | |||
1052 | ||||
1053 | memcpy (&result->value.character.string[op1->value.character.length], | |||
1054 | op2->value.character.string, | |||
1055 | op2->value.character.length * sizeof (gfc_char_t)); | |||
1056 | ||||
1057 | result->value.character.string[len] = '\0'; | |||
1058 | ||||
1059 | *resultp = result; | |||
1060 | ||||
1061 | return ARITH_OK; | |||
1062 | } | |||
1063 | ||||
1064 | /* Comparison between real values; returns 0 if (op1 .op. op2) is true. | |||
1065 | This function mimics mpfr_cmp but takes NaN into account. */ | |||
1066 | ||||
1067 | static int | |||
1068 | compare_real (gfc_expr *op1, gfc_expr *op2, gfc_intrinsic_op op) | |||
1069 | { | |||
1070 | int rc; | |||
1071 | switch (op) | |||
1072 | { | |||
1073 | case INTRINSIC_EQ: | |||
1074 | rc = mpfr_equal_p (op1->value.real, op2->value.real) ? 0 : 1; | |||
1075 | break; | |||
1076 | case INTRINSIC_GT: | |||
1077 | rc = mpfr_greater_p (op1->value.real, op2->value.real) ? 1 : -1; | |||
1078 | break; | |||
1079 | case INTRINSIC_GE: | |||
1080 | rc = mpfr_greaterequal_p (op1->value.real, op2->value.real) ? 1 : -1; | |||
1081 | break; | |||
1082 | case INTRINSIC_LT: | |||
1083 | rc = mpfr_less_p (op1->value.real, op2->value.real) ? -1 : 1; | |||
1084 | break; | |||
1085 | case INTRINSIC_LE: | |||
1086 | rc = mpfr_lessequal_p (op1->value.real, op2->value.real) ? -1 : 1; | |||
1087 | break; | |||
1088 | default: | |||
1089 | gfc_internal_error ("compare_real(): Bad operator"); | |||
1090 | } | |||
1091 | ||||
1092 | return rc; | |||
1093 | } | |||
1094 | ||||
1095 | /* Comparison operators. Assumes that the two expression nodes | |||
1096 | contain two constants of the same type. The op argument is | |||
1097 | needed to handle NaN correctly. */ | |||
1098 | ||||
1099 | int | |||
1100 | gfc_compare_expr (gfc_expr *op1, gfc_expr *op2, gfc_intrinsic_op op) | |||
1101 | { | |||
1102 | int rc; | |||
1103 | ||||
1104 | switch (op1->ts.type) | |||
1105 | { | |||
1106 | case BT_INTEGER: | |||
1107 | rc = mpz_cmp__gmpz_cmp (op1->value.integer, op2->value.integer); | |||
1108 | break; | |||
1109 | ||||
1110 | case BT_REAL: | |||
1111 | rc = compare_real (op1, op2, op); | |||
1112 | break; | |||
1113 | ||||
1114 | case BT_CHARACTER: | |||
1115 | rc = gfc_compare_string (op1, op2); | |||
1116 | break; | |||
1117 | ||||
1118 | case BT_LOGICAL: | |||
1119 | rc = ((!op1->value.logical && op2->value.logical) | |||
1120 | || (op1->value.logical && !op2->value.logical)); | |||
1121 | break; | |||
1122 | ||||
1123 | default: | |||
1124 | gfc_internal_error ("gfc_compare_expr(): Bad basic type"); | |||
1125 | } | |||
1126 | ||||
1127 | return rc; | |||
1128 | } | |||
1129 | ||||
1130 | ||||
1131 | /* Compare a pair of complex numbers. Naturally, this is only for | |||
1132 | equality and inequality. */ | |||
1133 | ||||
1134 | static int | |||
1135 | compare_complex (gfc_expr *op1, gfc_expr *op2) | |||
1136 | { | |||
1137 | return mpc_cmp (op1->value.complex, op2->value.complex) == 0; | |||
1138 | } | |||
1139 | ||||
1140 | ||||
1141 | /* Given two constant strings and the inverse collating sequence, compare the | |||
1142 | strings. We return -1 for a < b, 0 for a == b and 1 for a > b. | |||
1143 | We use the processor's default collating sequence. */ | |||
1144 | ||||
1145 | int | |||
1146 | gfc_compare_string (gfc_expr *a, gfc_expr *b) | |||
1147 | { | |||
1148 | size_t len, alen, blen, i; | |||
1149 | gfc_char_t ac, bc; | |||
1150 | ||||
1151 | alen = a->value.character.length; | |||
1152 | blen = b->value.character.length; | |||
1153 | ||||
1154 | len = MAX(alen, blen)((alen) > (blen) ? (alen) : (blen)); | |||
1155 | ||||
1156 | for (i = 0; i < len; i++) | |||
1157 | { | |||
1158 | ac = ((i < alen) ? a->value.character.string[i] : ' '); | |||
1159 | bc = ((i < blen) ? b->value.character.string[i] : ' '); | |||
1160 | ||||
1161 | if (ac < bc) | |||
1162 | return -1; | |||
1163 | if (ac > bc) | |||
1164 | return 1; | |||
1165 | } | |||
1166 | ||||
1167 | /* Strings are equal */ | |||
1168 | return 0; | |||
1169 | } | |||
1170 | ||||
1171 | ||||
1172 | int | |||
1173 | gfc_compare_with_Cstring (gfc_expr *a, const char *b, bool case_sensitive) | |||
1174 | { | |||
1175 | size_t len, alen, blen, i; | |||
1176 | gfc_char_t ac, bc; | |||
1177 | ||||
1178 | alen = a->value.character.length; | |||
1179 | blen = strlen (b); | |||
1180 | ||||
1181 | len = MAX(alen, blen)((alen) > (blen) ? (alen) : (blen)); | |||
1182 | ||||
1183 | for (i = 0; i < len; i++) | |||
1184 | { | |||
1185 | ac = ((i < alen) ? a->value.character.string[i] : ' '); | |||
1186 | bc = ((i < blen) ? b[i] : ' '); | |||
1187 | ||||
1188 | if (!case_sensitive) | |||
1189 | { | |||
1190 | ac = TOLOWER (ac)_sch_tolower[(ac) & 0xff]; | |||
1191 | bc = TOLOWER (bc)_sch_tolower[(bc) & 0xff]; | |||
1192 | } | |||
1193 | ||||
1194 | if (ac < bc) | |||
1195 | return -1; | |||
1196 | if (ac > bc) | |||
1197 | return 1; | |||
1198 | } | |||
1199 | ||||
1200 | /* Strings are equal */ | |||
1201 | return 0; | |||
1202 | } | |||
1203 | ||||
1204 | ||||
1205 | /* Specific comparison subroutines. */ | |||
1206 | ||||
1207 | static arith | |||
1208 | gfc_arith_eq (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp) | |||
1209 | { | |||
1210 | gfc_expr *result; | |||
1211 | ||||
1212 | if (op1->ts.type != op2->ts.type) | |||
1213 | return ARITH_INVALID_TYPE; | |||
1214 | ||||
1215 | result = gfc_get_constant_expr (BT_LOGICAL, gfc_default_logical_kind, | |||
1216 | &op1->where); | |||
1217 | result->value.logical = (op1->ts.type == BT_COMPLEX) | |||
1218 | ? compare_complex (op1, op2) | |||
1219 | : (gfc_compare_expr (op1, op2, INTRINSIC_EQ) == 0); | |||
1220 | ||||
1221 | *resultp = result; | |||
1222 | return ARITH_OK; | |||
1223 | } | |||
1224 | ||||
1225 | ||||
1226 | static arith | |||
1227 | gfc_arith_ne (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp) | |||
1228 | { | |||
1229 | gfc_expr *result; | |||
1230 | ||||
1231 | if (op1->ts.type != op2->ts.type) | |||
1232 | return ARITH_INVALID_TYPE; | |||
1233 | ||||
1234 | result = gfc_get_constant_expr (BT_LOGICAL, gfc_default_logical_kind, | |||
1235 | &op1->where); | |||
1236 | result->value.logical = (op1->ts.type == BT_COMPLEX) | |||
1237 | ? !compare_complex (op1, op2) | |||
1238 | : (gfc_compare_expr (op1, op2, INTRINSIC_EQ) != 0); | |||
1239 | ||||
1240 | *resultp = result; | |||
1241 | return ARITH_OK; | |||
1242 | } | |||
1243 | ||||
1244 | ||||
1245 | static arith | |||
1246 | gfc_arith_gt (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp) | |||
1247 | { | |||
1248 | gfc_expr *result; | |||
1249 | ||||
1250 | if (op1->ts.type != op2->ts.type) | |||
1251 | return ARITH_INVALID_TYPE; | |||
1252 | ||||
1253 | result = gfc_get_constant_expr (BT_LOGICAL, gfc_default_logical_kind, | |||
1254 | &op1->where); | |||
1255 | result->value.logical = (gfc_compare_expr (op1, op2, INTRINSIC_GT) > 0); | |||
1256 | *resultp = result; | |||
1257 | ||||
1258 | return ARITH_OK; | |||
1259 | } | |||
1260 | ||||
1261 | ||||
1262 | static arith | |||
1263 | gfc_arith_ge (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp) | |||
1264 | { | |||
1265 | gfc_expr *result; | |||
1266 | ||||
1267 | if (op1->ts.type != op2->ts.type) | |||
1268 | return ARITH_INVALID_TYPE; | |||
1269 | ||||
1270 | result = gfc_get_constant_expr (BT_LOGICAL, gfc_default_logical_kind, | |||
1271 | &op1->where); | |||
1272 | result->value.logical = (gfc_compare_expr (op1, op2, INTRINSIC_GE) >= 0); | |||
1273 | *resultp = result; | |||
1274 | ||||
1275 | return ARITH_OK; | |||
1276 | } | |||
1277 | ||||
1278 | ||||
1279 | static arith | |||
1280 | gfc_arith_lt (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp) | |||
1281 | { | |||
1282 | gfc_expr *result; | |||
1283 | ||||
1284 | if (op1->ts.type != op2->ts.type) | |||
1285 | return ARITH_INVALID_TYPE; | |||
1286 | ||||
1287 | result = gfc_get_constant_expr (BT_LOGICAL, gfc_default_logical_kind, | |||
1288 | &op1->where); | |||
1289 | result->value.logical = (gfc_compare_expr (op1, op2, INTRINSIC_LT) < 0); | |||
1290 | *resultp = result; | |||
1291 | ||||
1292 | return ARITH_OK; | |||
1293 | } | |||
1294 | ||||
1295 | ||||
1296 | static arith | |||
1297 | gfc_arith_le (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp) | |||
1298 | { | |||
1299 | gfc_expr *result; | |||
1300 | ||||
1301 | if (op1->ts.type != op2->ts.type) | |||
1302 | return ARITH_INVALID_TYPE; | |||
1303 | ||||
1304 | result = gfc_get_constant_expr (BT_LOGICAL, gfc_default_logical_kind, | |||
1305 | &op1->where); | |||
1306 | result->value.logical = (gfc_compare_expr (op1, op2, INTRINSIC_LE) <= 0); | |||
1307 | *resultp = result; | |||
1308 | ||||
1309 | return ARITH_OK; | |||
1310 | } | |||
1311 | ||||
1312 | ||||
1313 | static arith | |||
1314 | reduce_unary (arith (*eval) (gfc_expr *, gfc_expr **), gfc_expr *op, | |||
1315 | gfc_expr **result) | |||
1316 | { | |||
1317 | gfc_constructor_base head; | |||
1318 | gfc_constructor *c; | |||
1319 | gfc_expr *r; | |||
1320 | arith rc; | |||
1321 | ||||
1322 | if (op->expr_type == EXPR_CONSTANT) | |||
1323 | return eval (op, result); | |||
1324 | ||||
1325 | if (op->expr_type != EXPR_ARRAY) | |||
1326 | return ARITH_NOT_REDUCED; | |||
1327 | ||||
1328 | rc = ARITH_OK; | |||
1329 | head = gfc_constructor_copy (op->value.constructor); | |||
1330 | for (c = gfc_constructor_first (head); c; c = gfc_constructor_next (c)) | |||
1331 | { | |||
1332 | rc = reduce_unary (eval, c->expr, &r); | |||
1333 | ||||
1334 | if (rc != ARITH_OK) | |||
1335 | break; | |||
1336 | ||||
1337 | gfc_replace_expr (c->expr, r); | |||
1338 | } | |||
1339 | ||||
1340 | if (rc
| |||
1341 | gfc_constructor_free (head); | |||
1342 | else | |||
1343 | { | |||
1344 | gfc_constructor *c = gfc_constructor_first (head); | |||
1345 | if (c == NULL__null) | |||
1346 | { | |||
1347 | /* Handle zero-sized arrays. */ | |||
1348 | r = gfc_get_array_expr (op->ts.type, op->ts.kind, &op->where); | |||
1349 | } | |||
1350 | else | |||
1351 | { | |||
1352 | r = gfc_get_array_expr (c->expr->ts.type, c->expr->ts.kind, | |||
1353 | &op->where); | |||
1354 | } | |||
1355 | r->shape = gfc_copy_shape (op->shape, op->rank); | |||
1356 | r->rank = op->rank; | |||
1357 | r->value.constructor = head; | |||
1358 | *result = r; | |||
1359 | } | |||
1360 | ||||
1361 | return rc; | |||
1362 | } | |||
1363 | ||||
1364 | ||||
1365 | static arith | |||
1366 | reduce_binary_ac (arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **), | |||
1367 | gfc_expr *op1, gfc_expr *op2, gfc_expr **result) | |||
1368 | { | |||
1369 | gfc_constructor_base head; | |||
1370 | gfc_constructor *c; | |||
1371 | gfc_expr *r; | |||
1372 | arith rc = ARITH_OK; | |||
1373 | ||||
1374 | head = gfc_constructor_copy (op1->value.constructor); | |||
1375 | for (c = gfc_constructor_first (head); c; c = gfc_constructor_next (c)) | |||
1376 | { | |||
1377 | gfc_simplify_expr (c->expr, 0); | |||
1378 | ||||
1379 | if (c->expr->expr_type == EXPR_CONSTANT) | |||
1380 | rc = eval (c->expr, op2, &r); | |||
1381 | else if (c->expr->expr_type != EXPR_ARRAY) | |||
1382 | rc = ARITH_NOT_REDUCED; | |||
1383 | else | |||
1384 | rc = reduce_binary_ac (eval, c->expr, op2, &r); | |||
1385 | ||||
1386 | if (rc != ARITH_OK) | |||
1387 | break; | |||
1388 | ||||
1389 | gfc_replace_expr (c->expr, r); | |||
1390 | } | |||
1391 | ||||
1392 | if (rc != ARITH_OK) | |||
1393 | gfc_constructor_free (head); | |||
1394 | else | |||
1395 | { | |||
1396 | gfc_constructor *c = gfc_constructor_first (head); | |||
1397 | if (c) | |||
1398 | { | |||
1399 | r = gfc_get_array_expr (c->expr->ts.type, c->expr->ts.kind, | |||
1400 | &op1->where); | |||
1401 | r->shape = gfc_copy_shape (op1->shape, op1->rank); | |||
1402 | } | |||
1403 | else | |||
1404 | { | |||
1405 | gcc_assert (op1->ts.type != BT_UNKNOWN)((void)(!(op1->ts.type != BT_UNKNOWN) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/arith.cc" , 1405, __FUNCTION__), 0 : 0)); | |||
1406 | r = gfc_get_array_expr (op1->ts.type, op1->ts.kind, | |||
1407 | &op1->where); | |||
1408 | r->shape = gfc_get_shape (op1->rank)(((mpz_t *) xcalloc (((op1->rank)), sizeof (mpz_t)))); | |||
1409 | } | |||
1410 | r->rank = op1->rank; | |||
1411 | r->value.constructor = head; | |||
1412 | *result = r; | |||
1413 | } | |||
1414 | ||||
1415 | return rc; | |||
1416 | } | |||
1417 | ||||
1418 | ||||
1419 | static arith | |||
1420 | reduce_binary_ca (arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **), | |||
1421 | gfc_expr *op1, gfc_expr *op2, gfc_expr **result) | |||
1422 | { | |||
1423 | gfc_constructor_base head; | |||
1424 | gfc_constructor *c; | |||
1425 | gfc_expr *r; | |||
1426 | arith rc = ARITH_OK; | |||
1427 | ||||
1428 | head = gfc_constructor_copy (op2->value.constructor); | |||
1429 | for (c = gfc_constructor_first (head); c; c = gfc_constructor_next (c)) | |||
1430 | { | |||
1431 | gfc_simplify_expr (c->expr, 0); | |||
1432 | ||||
1433 | if (c->expr->expr_type == EXPR_CONSTANT) | |||
1434 | rc = eval (op1, c->expr, &r); | |||
1435 | else if (c->expr->expr_type != EXPR_ARRAY) | |||
1436 | rc = ARITH_NOT_REDUCED; | |||
1437 | else | |||
1438 | rc = reduce_binary_ca (eval, op1, c->expr, &r); | |||
1439 | ||||
1440 | if (rc != ARITH_OK) | |||
1441 | break; | |||
1442 | ||||
1443 | gfc_replace_expr (c->expr, r); | |||
1444 | } | |||
1445 | ||||
1446 | if (rc != ARITH_OK) | |||
1447 | gfc_constructor_free (head); | |||
1448 | else | |||
1449 | { | |||
1450 | gfc_constructor *c = gfc_constructor_first (head); | |||
1451 | if (c) | |||
1452 | { | |||
1453 | r = gfc_get_array_expr (c->expr->ts.type, c->expr->ts.kind, | |||
1454 | &op2->where); | |||
1455 | r->shape = gfc_copy_shape (op2->shape, op2->rank); | |||
1456 | } | |||
1457 | else | |||
1458 | { | |||
1459 | gcc_assert (op2->ts.type != BT_UNKNOWN)((void)(!(op2->ts.type != BT_UNKNOWN) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/fortran/arith.cc" , 1459, __FUNCTION__), 0 : 0)); | |||
1460 | r = gfc_get_array_expr (op2->ts.type, op2->ts.kind, | |||
1461 | &op2->where); | |||
1462 | r->shape = gfc_get_shape (op2->rank)(((mpz_t *) xcalloc (((op2->rank)), sizeof (mpz_t)))); | |||
1463 | } | |||
1464 | r->rank = op2->rank; | |||
1465 | r->value.constructor = head; | |||
1466 | *result = r; | |||
1467 | } | |||
1468 | ||||
1469 | return rc; | |||
1470 | } | |||
1471 | ||||
1472 | ||||
1473 | /* We need a forward declaration of reduce_binary. */ | |||
1474 | static arith reduce_binary (arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **), | |||
1475 | gfc_expr *op1, gfc_expr *op2, gfc_expr **result); | |||
1476 | ||||
1477 | ||||
1478 | static arith | |||
1479 | reduce_binary_aa (arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **), | |||
1480 | gfc_expr *op1, gfc_expr *op2, gfc_expr **result) | |||
1481 | { | |||
1482 | gfc_constructor_base head; | |||
1483 | gfc_constructor *c, *d; | |||
1484 | gfc_expr *r; | |||
1485 | arith rc = ARITH_OK; | |||
1486 | ||||
1487 | if (!gfc_check_conformance (op1, op2, _("elemental binary operation")gettext ("elemental binary operation"))) | |||
1488 | return ARITH_INCOMMENSURATE; | |||
1489 | ||||
1490 | head = gfc_constructor_copy (op1->value.constructor); | |||
1491 | for (c = gfc_constructor_first (head), | |||
1492 | d = gfc_constructor_first (op2->value.constructor); | |||
1493 | c && d; | |||
1494 | c = gfc_constructor_next (c), d = gfc_constructor_next (d)) | |||
1495 | { | |||
1496 | rc = reduce_binary (eval, c->expr, d->expr, &r); | |||
1497 | ||||
1498 | if (rc != ARITH_OK) | |||
1499 | break; | |||
1500 | ||||
1501 | gfc_replace_expr (c->expr, r); | |||
1502 | } | |||
1503 | ||||
1504 | if (rc == ARITH_OK && (c || d)) | |||
1505 | rc = ARITH_INCOMMENSURATE; | |||
1506 | ||||
1507 | if (rc != ARITH_OK) | |||
1508 | gfc_constructor_free (head); | |||
1509 | else | |||
1510 | { | |||
1511 | gfc_constructor *c = gfc_constructor_first (head); | |||
1512 | if (c == NULL__null) | |||
1513 | { | |||
1514 | /* Handle zero-sized arrays. */ | |||
1515 | r = gfc_get_array_expr (op1->ts.type, op1->ts.kind, &op1->where); | |||
1516 | } | |||
1517 | else | |||
1518 | { | |||
1519 | r = gfc_get_array_expr (c->expr->ts.type, c->expr->ts.kind, | |||
1520 | &op1->where); | |||
1521 | } | |||
1522 | r->shape = gfc_copy_shape (op1->shape, op1->rank); | |||
1523 | r->rank = op1->rank; | |||
1524 | r->value.constructor = head; | |||
1525 | *result = r; | |||
1526 | } | |||
1527 | ||||
1528 | return rc; | |||
1529 | } | |||
1530 | ||||
1531 | ||||
1532 | static arith | |||
1533 | reduce_binary (arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **), | |||
1534 | gfc_expr *op1, gfc_expr *op2, gfc_expr **result) | |||
1535 | { | |||
1536 | if (op1->expr_type == EXPR_CONSTANT && op2->expr_type == EXPR_CONSTANT) | |||
1537 | return eval (op1, op2, result); | |||
1538 | ||||
1539 | if (op1->expr_type == EXPR_CONSTANT && op2->expr_type == EXPR_ARRAY) | |||
1540 | return reduce_binary_ca (eval, op1, op2, result); | |||
1541 | ||||
1542 | if (op1->expr_type == EXPR_ARRAY && op2->expr_type == EXPR_CONSTANT) | |||
1543 | return reduce_binary_ac (eval, op1, op2, result); | |||
1544 | ||||
1545 | if (op1->expr_type != EXPR_ARRAY || op2->expr_type != EXPR_ARRAY) | |||
1546 | return ARITH_NOT_REDUCED; | |||
1547 | ||||
1548 | return reduce_binary_aa (eval, op1, op2, result); | |||
1549 | } | |||
1550 | ||||
1551 | ||||
1552 | typedef union | |||
1553 | { | |||
1554 | arith (*f2)(gfc_expr *, gfc_expr **); | |||
1555 | arith (*f3)(gfc_expr *, gfc_expr *, gfc_expr **); | |||
1556 | } | |||
1557 | eval_f; | |||
1558 | ||||
1559 | /* High level arithmetic subroutines. These subroutines go into | |||
1560 | eval_intrinsic(), which can do one of several things to its | |||
1561 | operands. If the operands are incompatible with the intrinsic | |||
1562 | operation, we return a node pointing to the operands and hope that | |||
1563 | an operator interface is found during resolution. | |||
1564 | ||||
1565 | If the operands are compatible and are constants, then we try doing | |||
1566 | the arithmetic. We also handle the cases where either or both | |||
1567 | operands are array constructors. */ | |||
1568 | ||||
1569 | static gfc_expr * | |||
1570 | eval_intrinsic (gfc_intrinsic_op op, | |||
1571 | eval_f eval, gfc_expr *op1, gfc_expr *op2) | |||
1572 | { | |||
1573 | gfc_expr temp, *result; | |||
1574 | int unary; | |||
1575 | arith rc; | |||
1576 | ||||
1577 | if (!op1
| |||
1578 | return NULL__null; | |||
1579 | ||||
1580 | gfc_clear_ts (&temp.ts); | |||
1581 | ||||
1582 | switch (op) | |||
1583 | { | |||
1584 | /* Logical unary */ | |||
1585 | case INTRINSIC_NOT: | |||
1586 | if (op1->ts.type != BT_LOGICAL) | |||
1587 | goto runtime; | |||
1588 | ||||
1589 | temp.ts.type = BT_LOGICAL; | |||
1590 | temp.ts.kind = gfc_default_logical_kind; | |||
1591 | unary = 1; | |||
1592 | break; | |||
1593 | ||||
1594 | /* Logical binary operators */ | |||
1595 | case INTRINSIC_OR: | |||
1596 | case INTRINSIC_AND: | |||
1597 | case INTRINSIC_NEQV: | |||
1598 | case INTRINSIC_EQV: | |||
1599 | if (op1->ts.type != BT_LOGICAL || op2->ts.type != BT_LOGICAL) | |||
1600 | goto runtime; | |||
1601 | ||||
1602 | temp.ts.type = BT_LOGICAL; | |||
1603 | temp.ts.kind = gfc_default_logical_kind; | |||
1604 | unary = 0; | |||
1605 | break; | |||
1606 | ||||
1607 | /* Numeric unary */ | |||
1608 | case INTRINSIC_UPLUS: | |||
1609 | case INTRINSIC_UMINUS: | |||
1610 | if (!gfc_numeric_ts (&op1->ts)) | |||
1611 | goto runtime; | |||
1612 | ||||
1613 | temp.ts = op1->ts; | |||
1614 | unary = 1; | |||
1615 | break; | |||
1616 | ||||
1617 | case INTRINSIC_PARENTHESES: | |||
1618 | temp.ts = op1->ts; | |||
1619 | unary = 1; | |||
1620 | break; | |||
1621 | ||||
1622 | /* Additional restrictions for ordering relations. */ | |||
1623 | case INTRINSIC_GE: | |||
1624 | case INTRINSIC_GE_OS: | |||
1625 | case INTRINSIC_LT: | |||
1626 | case INTRINSIC_LT_OS: | |||
1627 | case INTRINSIC_LE: | |||
1628 | case INTRINSIC_LE_OS: | |||
1629 | case INTRINSIC_GT: | |||
1630 | case INTRINSIC_GT_OS: | |||
1631 | if (op1->ts.type == BT_COMPLEX || op2->ts.type == BT_COMPLEX) | |||
1632 | { | |||
1633 | temp.ts.type = BT_LOGICAL; | |||
1634 | temp.ts.kind = gfc_default_logical_kind; | |||
1635 | goto runtime; | |||
1636 | } | |||
1637 | ||||
1638 | /* Fall through */ | |||
1639 | case INTRINSIC_EQ: | |||
1640 | case INTRINSIC_EQ_OS: | |||
1641 | case INTRINSIC_NE: | |||
1642 | case INTRINSIC_NE_OS: | |||
1643 | if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER) | |||
1644 | { | |||
1645 | unary = 0; | |||
1646 | temp.ts.type = BT_LOGICAL; | |||
1647 | temp.ts.kind = gfc_default_logical_kind; | |||
1648 | ||||
1649 | /* If kind mismatch, exit and we'll error out later. */ | |||
1650 | if (op1->ts.kind != op2->ts.kind) | |||
1651 | goto runtime; | |||
1652 | ||||
1653 | break; | |||
1654 | } | |||
1655 | ||||
1656 | gcc_fallthrough (); | |||
1657 | /* Numeric binary */ | |||
1658 | case INTRINSIC_PLUS: | |||
1659 | case INTRINSIC_MINUS: | |||
1660 | case INTRINSIC_TIMES: | |||
1661 | case INTRINSIC_DIVIDE: | |||
1662 | case INTRINSIC_POWER: | |||
1663 | if (!gfc_numeric_ts (&op1->ts) || !gfc_numeric_ts (&op2->ts)) | |||
1664 | goto runtime; | |||
1665 | ||||
1666 | /* Insert any necessary type conversions to make the operands | |||
1667 | compatible. */ | |||
1668 | ||||
1669 | temp.expr_type = EXPR_OP; | |||
1670 | gfc_clear_ts (&temp.ts); | |||
1671 | temp.value.op.op = op; | |||
1672 | ||||
1673 | temp.value.op.op1 = op1; | |||
1674 | temp.value.op.op2 = op2; | |||
1675 | ||||
1676 | gfc_type_convert_binary (&temp, warn_conversionglobal_options.x_warn_conversion || warn_conversion_extraglobal_options.x_warn_conversion_extra); | |||
1677 | ||||
1678 | if (op == INTRINSIC_EQ || op == INTRINSIC_NE | |||
1679 | || op == INTRINSIC_GE || op == INTRINSIC_GT | |||
1680 | || op == INTRINSIC_LE || op == INTRINSIC_LT | |||
1681 | || op == INTRINSIC_EQ_OS || op == INTRINSIC_NE_OS | |||
1682 | || op == INTRINSIC_GE_OS || op == INTRINSIC_GT_OS | |||
1683 | || op == INTRINSIC_LE_OS || op == INTRINSIC_LT_OS) | |||
1684 | { | |||
1685 | temp.ts.type = BT_LOGICAL; | |||
1686 | temp.ts.kind = gfc_default_logical_kind; | |||
1687 | } | |||
1688 | ||||
1689 | unary = 0; | |||
1690 | break; | |||
1691 | ||||
1692 | /* Character binary */ | |||
1693 | case INTRINSIC_CONCAT: | |||
1694 | if (op1->ts.type != BT_CHARACTER || op2->ts.type != BT_CHARACTER | |||
1695 | || op1->ts.kind != op2->ts.kind) | |||
1696 | goto runtime; | |||
1697 | ||||
1698 | temp.ts.type = BT_CHARACTER; | |||
1699 | temp.ts.kind = op1->ts.kind; | |||
1700 | unary = 0; | |||
1701 | break; | |||
1702 | ||||
1703 | case INTRINSIC_USER: | |||
1704 | goto runtime; | |||
1705 | ||||
1706 | default: | |||
1707 | gfc_internal_error ("eval_intrinsic(): Bad operator"); | |||
1708 | } | |||
1709 | ||||
1710 | if (op1->expr_type
| |||
1711 | && (op1->expr_type
| |||
1712 | || !gfc_is_constant_expr (op1) || !gfc_expanded_ac (op1))) | |||
1713 | goto runtime; | |||
1714 | ||||
1715 | if (op2
| |||
1716 | && op2->expr_type
| |||
1717 | && (op2->expr_type
| |||
1718 | || !gfc_is_constant_expr (op2) || !gfc_expanded_ac (op2))) | |||
1719 | goto runtime; | |||
1720 | ||||
1721 | if (unary
| |||
1722 | rc = reduce_unary (eval.f2, op1, &result); | |||
1723 | else | |||
1724 | rc = reduce_binary (eval.f3, op1, op2, &result); | |||
1725 | ||||
1726 | if (rc == ARITH_INVALID_TYPE || rc == ARITH_NOT_REDUCED) | |||
1727 | goto runtime; | |||
1728 | ||||
1729 | /* Something went wrong. */ | |||
1730 | if (op
| |||
1731 | return NULL__null; | |||
1732 | ||||
1733 | if (rc
| |||
1734 | { | |||
1735 | gfc_error (gfc_arith_error (rc), &op1->where); | |||
1736 | if (rc
| |||
1737 | goto done; | |||
1738 | ||||
1739 | if (rc == ARITH_DIV0 && op2->ts.type == BT_INTEGER) | |||
1740 | gfc_seen_div0 = true; | |||
1741 | ||||
1742 | return NULL__null; | |||
1743 | } | |||
1744 | ||||
1745 | done: | |||
1746 | ||||
1747 | gfc_free_expr (op1); | |||
1748 | gfc_free_expr (op2); | |||
1749 | return result; | |||
| ||||
1750 | ||||
1751 | runtime: | |||
1752 | /* Create a run-time expression. */ | |||
1753 | result = gfc_get_operator_expr (&op1->where, op, op1, op2); | |||
1754 | result->ts = temp.ts; | |||
1755 | ||||
1756 | return result; | |||
1757 | } | |||
1758 | ||||
1759 | ||||
1760 | /* Modify type of expression for zero size array. */ | |||
1761 | ||||
1762 | static gfc_expr * | |||
1763 | eval_type_intrinsic0 (gfc_intrinsic_op iop, gfc_expr *op) | |||
1764 | { | |||
1765 | if (op == NULL__null) | |||
1766 | gfc_internal_error ("eval_type_intrinsic0(): op NULL"); | |||
1767 | ||||
1768 | switch (iop) | |||
1769 | { | |||
1770 | case INTRINSIC_GE: | |||
1771 | case INTRINSIC_GE_OS: | |||
1772 | case INTRINSIC_LT: | |||
1773 | case INTRINSIC_LT_OS: | |||
1774 | case INTRINSIC_LE: | |||
1775 | case INTRINSIC_LE_OS: | |||
1776 | case INTRINSIC_GT: | |||
1777 | case INTRINSIC_GT_OS: | |||
1778 | case INTRINSIC_EQ: | |||
1779 | case INTRINSIC_EQ_OS: | |||
1780 | case INTRINSIC_NE: | |||
1781 | case INTRINSIC_NE_OS: | |||
1782 | op->ts.type = BT_LOGICAL; | |||
1783 | op->ts.kind = gfc_default_logical_kind; | |||
1784 | break; | |||
1785 | ||||
1786 | default: | |||
1787 | break; | |||
1788 | } | |||
1789 | ||||
1790 | return op; | |||
1791 | } | |||
1792 | ||||
1793 | ||||
1794 | /* Return nonzero if the expression is a zero size array. */ | |||
1795 | ||||
1796 | static bool | |||
1797 | gfc_zero_size_array (gfc_expr *e) | |||
1798 | { | |||
1799 | if (e == NULL__null || e->expr_type != EXPR_ARRAY) | |||
1800 | return false; | |||
1801 | ||||
1802 | return e->value.constructor == NULL__null; | |||
1803 | } | |||
1804 | ||||
1805 | ||||
1806 | /* Reduce a binary expression where at least one of the operands | |||
1807 | involves a zero-length array. Returns NULL if neither of the | |||
1808 | operands is a zero-length array. */ | |||
1809 | ||||
1810 | static gfc_expr * | |||
1811 | reduce_binary0 (gfc_expr *op1, gfc_expr *op2) | |||
1812 | { | |||
1813 | if (gfc_zero_size_array (op1)) | |||
1814 | { | |||
1815 | gfc_free_expr (op2); | |||
1816 | return op1; | |||
1817 | } | |||
1818 | ||||
1819 | if (gfc_zero_size_array (op2)) | |||
1820 | { | |||
1821 | gfc_free_expr (op1); | |||
1822 | return op2; | |||
1823 | } | |||
1824 | ||||
1825 | return NULL__null; | |||
1826 | } | |||
1827 | ||||
1828 | ||||
1829 | static gfc_expr * | |||
1830 | eval_intrinsic_f2 (gfc_intrinsic_op op, | |||
1831 | arith (*eval) (gfc_expr *, gfc_expr **), | |||
1832 | gfc_expr *op1, gfc_expr *op2) | |||
1833 | { | |||
1834 | gfc_expr *result; | |||
1835 | eval_f f; | |||
1836 | ||||
1837 | if (op2 == NULL__null) | |||
1838 | { | |||
1839 | if (gfc_zero_size_array (op1)) | |||
1840 | return eval_type_intrinsic0 (op, op1); | |||
1841 | } | |||
1842 | else | |||
1843 | { | |||
1844 | result = reduce_binary0 (op1, op2); | |||
1845 | if (result != NULL__null) | |||
1846 | return eval_type_intrinsic0 (op, result); | |||
1847 | } | |||
1848 | ||||
1849 | f.f2 = eval; | |||
1850 | return eval_intrinsic (op, f, op1, op2); | |||
1851 | } | |||
1852 | ||||
1853 | ||||
1854 | static gfc_expr * | |||
1855 | eval_intrinsic_f3 (gfc_intrinsic_op op, | |||
1856 | arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **), | |||
1857 | gfc_expr *op1, gfc_expr *op2) | |||
1858 | { | |||
1859 | gfc_expr *result; | |||
1860 | eval_f f; | |||
1861 | ||||
1862 | if (!op1 && !op2) | |||
1863 | return NULL__null; | |||
1864 | ||||
1865 | result = reduce_binary0 (op1, op2); | |||
1866 | if (result
| |||
1867 | return eval_type_intrinsic0(op, result); | |||
1868 | ||||
1869 | f.f3 = eval; | |||
1870 | return eval_intrinsic (op, f, op1, op2); | |||
1871 | } | |||
1872 | ||||
1873 | ||||
1874 | gfc_expr * | |||
1875 | gfc_parentheses (gfc_expr *op) | |||
1876 | { | |||
1877 | if (gfc_is_constant_expr (op)) | |||
1878 | return op; | |||
1879 | ||||
1880 | return eval_intrinsic_f2 (INTRINSIC_PARENTHESES, gfc_arith_identity, | |||
1881 | op, NULL__null); | |||
1882 | } | |||
1883 | ||||
1884 | gfc_expr * | |||
1885 | gfc_uplus (gfc_expr *op) | |||
1886 | { | |||
1887 | return eval_intrinsic_f2 (INTRINSIC_UPLUS, gfc_arith_identity, op, NULL__null); | |||
1888 | } | |||
1889 | ||||
1890 | ||||
1891 | gfc_expr * | |||
1892 | gfc_uminus (gfc_expr *op) | |||
1893 | { | |||
1894 | return eval_intrinsic_f2 (INTRINSIC_UMINUS, gfc_arith_uminus, op, NULL__null); | |||
1895 | } | |||
1896 | ||||
1897 | ||||
1898 | gfc_expr * | |||
1899 | gfc_add (gfc_expr *op1, gfc_expr *op2) | |||
1900 | { | |||
1901 | return eval_intrinsic_f3 (INTRINSIC_PLUS, gfc_arith_plus, op1, op2); | |||
1902 | } | |||
1903 | ||||
1904 | ||||
1905 | gfc_expr * | |||
1906 | gfc_subtract (gfc_expr *op1, gfc_expr *op2) | |||
1907 | { | |||
1908 | return eval_intrinsic_f3 (INTRINSIC_MINUS, gfc_arith_minus, op1, op2); | |||
1909 | } | |||
1910 | ||||
1911 | ||||
1912 | gfc_expr * | |||
1913 | gfc_multiply (gfc_expr *op1, gfc_expr *op2) | |||
1914 | { | |||
1915 | return eval_intrinsic_f3 (INTRINSIC_TIMES, gfc_arith_times, op1, op2); | |||
1916 | } | |||
1917 | ||||
1918 | ||||
1919 | gfc_expr * | |||
1920 | gfc_divide (gfc_expr *op1, gfc_expr *op2) | |||
1921 | { | |||
1922 | return eval_intrinsic_f3 (INTRINSIC_DIVIDE, gfc_arith_divide, op1, op2); | |||
1923 | } | |||
1924 | ||||
1925 | ||||
1926 | gfc_expr * | |||
1927 | gfc_power (gfc_expr *op1, gfc_expr *op2) | |||
1928 | { | |||
1929 | return eval_intrinsic_f3 (INTRINSIC_POWER, arith_power, op1, op2); | |||
1930 | } | |||
1931 | ||||
1932 | ||||
1933 | gfc_expr * | |||
1934 | gfc_concat (gfc_expr *op1, gfc_expr *op2) | |||
1935 | { | |||
1936 | return eval_intrinsic_f3 (INTRINSIC_CONCAT, gfc_arith_concat, op1, op2); | |||
1937 | } | |||
1938 | ||||
1939 | ||||
1940 | gfc_expr * | |||
1941 | gfc_and (gfc_expr *op1, gfc_expr *op2) | |||
1942 | { | |||
1943 | return eval_intrinsic_f3 (INTRINSIC_AND, gfc_arith_and, op1, op2); | |||
1944 | } | |||
1945 | ||||
1946 | ||||
1947 | gfc_expr * | |||
1948 | gfc_or (gfc_expr *op1, gfc_expr *op2) | |||
1949 | { | |||
1950 | return eval_intrinsic_f3 (INTRINSIC_OR, gfc_arith_or, op1, op2); | |||
1951 | } | |||
1952 | ||||
1953 | ||||
1954 | gfc_expr * | |||
1955 | gfc_not (gfc_expr *op1) | |||
1956 | { | |||
1957 | return eval_intrinsic_f2 (INTRINSIC_NOT, gfc_arith_not, op1, NULL__null); | |||
1958 | } | |||
1959 | ||||
1960 | ||||
1961 | gfc_expr * | |||
1962 | gfc_eqv (gfc_expr *op1, gfc_expr *op2) | |||
1963 | { | |||
1964 | return eval_intrinsic_f3 (INTRINSIC_EQV, gfc_arith_eqv, op1, op2); | |||
1965 | } | |||
1966 | ||||
1967 | ||||
1968 | gfc_expr * | |||
1969 | gfc_neqv (gfc_expr *op1, gfc_expr *op2) | |||
1970 | { | |||
1971 | return eval_intrinsic_f3 (INTRINSIC_NEQV, gfc_arith_neqv, op1, op2); | |||
1972 | } | |||
1973 | ||||
1974 | ||||
1975 | gfc_expr * | |||
1976 | gfc_eq (gfc_expr *op1, gfc_expr *op2, gfc_intrinsic_op op) | |||
1977 | { | |||
1978 | return eval_intrinsic_f3 (op, gfc_arith_eq, op1, op2); | |||
1979 | } | |||
1980 | ||||
1981 | ||||
1982 | gfc_expr * | |||
1983 | gfc_ne (gfc_expr *op1, gfc_expr *op2, gfc_intrinsic_op op) | |||
1984 | { | |||
1985 | return eval_intrinsic_f3 (op, gfc_arith_ne, op1, op2); | |||
1986 | } | |||
1987 | ||||
1988 | ||||
1989 | gfc_expr * | |||
1990 | gfc_gt (gfc_expr *op1, gfc_expr *op2, gfc_intrinsic_op op) | |||
1991 | { | |||
1992 | return eval_intrinsic_f3 (op, gfc_arith_gt, op1, op2); | |||
1993 | } | |||
1994 | ||||
1995 | ||||
1996 | gfc_expr * | |||
1997 | gfc_ge (gfc_expr *op1, gfc_expr *op2, gfc_intrinsic_op op) | |||
1998 | { | |||
1999 | return eval_intrinsic_f3 (op, gfc_arith_ge, op1, op2); | |||
2000 | } | |||
2001 | ||||
2002 | ||||
2003 | gfc_expr * | |||
2004 | gfc_lt (gfc_expr *op1, gfc_expr *op2, gfc_intrinsic_op op) | |||
2005 | { | |||
2006 | return eval_intrinsic_f3 (op, gfc_arith_lt, op1, op2); | |||
2007 | } | |||
2008 | ||||
2009 | ||||
2010 | gfc_expr * | |||
2011 | gfc_le (gfc_expr *op1, gfc_expr *op2, gfc_intrinsic_op op) | |||
2012 | { | |||
2013 | return eval_intrinsic_f3 (op, gfc_arith_le, op1, op2); | |||
| ||||
2014 | } | |||
2015 | ||||
2016 | ||||
2017 | /******* Simplification of intrinsic functions with constant arguments *****/ | |||
2018 | ||||
2019 | ||||
2020 | /* Deal with an arithmetic error. */ | |||
2021 | ||||
2022 | static void | |||
2023 | arith_error (arith rc, gfc_typespec *from, gfc_typespec *to, locus *where) | |||
2024 | { | |||
2025 | switch (rc) | |||
2026 | { | |||
2027 | case ARITH_OK: | |||
2028 | gfc_error ("Arithmetic OK converting %s to %s at %L", | |||
2029 | gfc_typename (from), gfc_typename (to), where); | |||
2030 | break; | |||
2031 | case ARITH_OVERFLOW: | |||
2032 | gfc_error ("Arithmetic overflow converting %s to %s at %L. This check " | |||
2033 | "can be disabled with the option %<-fno-range-check%>", | |||
2034 | gfc_typename (from), gfc_typename (to), where); | |||
2035 | break; | |||
2036 | case ARITH_UNDERFLOW: | |||
2037 | gfc_error ("Arithmetic underflow converting %s to %s at %L. This check " | |||
2038 | "can be disabled with the option %<-fno-range-check%>", | |||
2039 | gfc_typename (from), gfc_typename (to), where); | |||
2040 | break; | |||
2041 | case ARITH_NAN: | |||
2042 | gfc_error ("Arithmetic NaN converting %s to %s at %L. This check " | |||
2043 | "can be disabled with the option %<-fno-range-check%>", | |||
2044 | gfc_typename (from), gfc_typename (to), where); | |||
2045 | break; | |||
2046 | case ARITH_DIV0: | |||
2047 | gfc_error ("Division by zero converting %s to %s at %L", | |||
2048 | gfc_typename (from), gfc_typename (to), where); | |||
2049 | break; | |||
2050 | case ARITH_INCOMMENSURATE: | |||
2051 | gfc_error ("Array operands are incommensurate converting %s to %s at %L", | |||
2052 | gfc_typename (from), gfc_typename (to), where); | |||
2053 | break; | |||
2054 | case ARITH_ASYMMETRIC: | |||
2055 | gfc_error ("Integer outside symmetric range implied by Standard Fortran" | |||
2056 | " converting %s to %s at %L", | |||
2057 | gfc_typename (from), gfc_typename (to), where); | |||
2058 | break; | |||
2059 | default: | |||
2060 | gfc_internal_error ("gfc_arith_error(): Bad error code"); | |||
2061 | } | |||
2062 | ||||
2063 | /* TODO: Do something about the error, i.e., throw exception, return | |||
2064 | NaN, etc. */ | |||
2065 | } | |||
2066 | ||||
2067 | /* Returns true if significant bits were lost when converting real | |||
2068 | constant r from from_kind to to_kind. */ | |||
2069 | ||||
2070 | static bool | |||
2071 | wprecision_real_real (mpfr_t r, int from_kind, int to_kind) | |||
2072 | { | |||
2073 | mpfr_t rv, diff; | |||
2074 | bool ret; | |||
2075 | ||||
2076 | gfc_set_model_kind (to_kind); | |||
2077 | mpfr_init (rv); | |||
2078 | gfc_set_model_kind (from_kind); | |||
2079 | mpfr_init (diff); | |||
2080 | ||||
2081 | mpfr_set (rv, r, GFC_RND_MODE)__extension__ ({ mpfr_srcptr _p = (r); mpfr_set4(rv,_p,MPFR_RNDN ,((_p)->_mpfr_sign)); }); | |||
2082 | mpfr_sub (diff, rv, r, GFC_RND_MODEMPFR_RNDN); | |||
2083 | ||||
2084 | ret = ! mpfr_zero_p (diff)(((mpfr_srcptr) (0 ? (diff) : (mpfr_srcptr) (diff)))->_mpfr_exp == (0 - ((mpfr_exp_t) (((mpfr_uexp_t) -1) >> 1)))); | |||
2085 | mpfr_clear (rv); | |||
2086 | mpfr_clear (diff); | |||
2087 | return ret; | |||
2088 | } | |||
2089 | ||||
2090 | /* Return true if conversion from an integer to a real loses precision. */ | |||
2091 | ||||
2092 | static bool | |||
2093 | wprecision_int_real (mpz_t n, mpfr_t r) | |||
2094 | { | |||
2095 | bool ret; | |||
2096 | mpz_t i; | |||
2097 | mpz_init__gmpz_init (i); | |||
2098 | mpfr_get_z (i, r, GFC_RND_MODEMPFR_RNDN); | |||
2099 | mpz_sub__gmpz_sub (i, i, n); | |||
2100 | ret = mpz_cmp_si (i, 0)(__builtin_constant_p ((0) >= 0) && (0) >= 0 ? ( __builtin_constant_p ((static_cast<unsigned long> (0))) && ((static_cast<unsigned long> (0))) == 0 ? ( (i)->_mp_size < 0 ? -1 : (i)->_mp_size > 0) : __gmpz_cmp_ui (i,(static_cast<unsigned long> (0)))) : __gmpz_cmp_si ( i,0)) != 0; | |||
2101 | mpz_clear__gmpz_clear (i); | |||
2102 | return ret; | |||
2103 | } | |||
2104 | ||||
2105 | /* Convert integers to integers. */ | |||
2106 | ||||
2107 | gfc_expr * | |||
2108 | gfc_int2int (gfc_expr *src, int kind) | |||
2109 | { | |||
2110 | gfc_expr *result; | |||
2111 | arith rc; | |||
2112 | ||||
2113 | if (src->ts.type != BT_INTEGER) | |||
2114 | return NULL__null; | |||
2115 | ||||
2116 | result = gfc_get_constant_expr (BT_INTEGER, kind, &src->where); | |||
2117 | ||||
2118 | mpz_set__gmpz_set (result->value.integer, src->value.integer); | |||
2119 | ||||
2120 | if ((rc = gfc_check_integer_range (result->value.integer, kind)) != ARITH_OK) | |||
2121 | { | |||
2122 | if (rc == ARITH_ASYMMETRIC) | |||
2123 | { | |||
2124 | gfc_warning (0, gfc_arith_error (rc), &src->where); | |||
2125 | } | |||
2126 | else | |||
2127 | { | |||
2128 | arith_error (rc, &src->ts, &result->ts, &src->where); | |||
2129 | gfc_free_expr (result); | |||
2130 | return NULL__null; | |||
2131 | } | |||
2132 | } | |||
2133 | ||||
2134 | /* If we do not trap numeric overflow, we need to convert the number to | |||
2135 | signed, throwing away high-order bits if necessary. */ | |||
2136 | if (flag_range_checkglobal_options.x_flag_range_check == 0) | |||
2137 | { | |||
2138 | int k; | |||
2139 | ||||
2140 | k = gfc_validate_kind (BT_INTEGER, kind, false); | |||
2141 | gfc_convert_mpz_to_signed (result->value.integer, | |||
2142 | gfc_integer_kinds[k].bit_size); | |||
2143 | ||||
2144 | if (warn_conversionglobal_options.x_warn_conversion && !src->do_not_warn && kind < src->ts.kind) | |||
2145 | gfc_warning_now (OPT_Wconversion, "Conversion from %qs to %qs at %L", | |||
2146 | gfc_typename (&src->ts), gfc_typename (&result->ts), | |||
2147 | &src->where); | |||
2148 | } | |||
2149 | return result; | |||
2150 | } | |||
2151 | ||||
2152 | ||||
2153 | /* Convert integers to reals. */ | |||
2154 | ||||
2155 | gfc_expr * | |||
2156 | gfc_int2real (gfc_expr *src, int kind) | |||
2157 | { | |||
2158 | gfc_expr *result; | |||
2159 | arith rc; | |||
2160 | ||||
2161 | if (src->ts.type != BT_INTEGER) | |||
2162 | return NULL__null; | |||
2163 | ||||
2164 | result = gfc_get_constant_expr (BT_REAL, kind, &src->where); | |||
2165 | ||||
2166 | mpfr_set_z (result->value.real, src->value.integer, GFC_RND_MODEMPFR_RNDN); | |||
2167 | ||||
2168 | if ((rc = gfc_check_real_range (result->value.real, kind)) != ARITH_OK) | |||
2169 | { | |||
2170 | arith_error (rc, &src->ts, &result->ts, &src->where); | |||
2171 | gfc_free_expr (result); | |||
2172 | return NULL__null; | |||
2173 | } | |||
2174 | ||||
2175 | if (warn_conversionglobal_options.x_warn_conversion | |||
2176 | && wprecision_int_real (src->value.integer, result->value.real)) | |||
2177 | gfc_warning (OPT_Wconversion, "Change of value in conversion " | |||
2178 | "from %qs to %qs at %L", | |||
2179 | gfc_typename (&src->ts), | |||
2180 | gfc_typename (&result->ts), | |||
2181 | &src->where); | |||
2182 | ||||
2183 | return result; | |||
2184 | } | |||
2185 | ||||
2186 | ||||
2187 | /* Convert default integer to default complex. */ | |||
2188 | ||||
2189 | gfc_expr * | |||
2190 | gfc_int2complex (gfc_expr *src, int kind) | |||
2191 | { | |||
2192 | gfc_expr *result; | |||
2193 | arith rc; | |||
2194 | ||||
2195 | if (src->ts.type != BT_INTEGER) | |||
2196 | return NULL__null; | |||
2197 | ||||
2198 | result = gfc_get_constant_expr (BT_COMPLEX, kind, &src->where); | |||
2199 | ||||
2200 | mpc_set_z (result->value.complex, src->value.integer, GFC_MPC_RND_MODE(((int)(MPFR_RNDN)) + ((int)(MPFR_RNDN) << 4))); | |||
2201 | ||||
2202 | if ((rc = gfc_check_real_range (mpc_realref (result->value.complex)((result->value.complex)->re), kind)) | |||
2203 | != ARITH_OK) | |||
2204 | { | |||
2205 | arith_error (rc, &src->ts, &result->ts, &src->where); | |||
2206 | gfc_free_expr (result); | |||
2207 | return NULL__null; | |||
2208 | } | |||
2209 | ||||
2210 | if (warn_conversionglobal_options.x_warn_conversion | |||
2211 | && wprecision_int_real (src->value.integer, | |||
2212 | mpc_realref (result->value.complex)((result->value.complex)->re))) | |||
2213 | gfc_warning_now (OPT_Wconversion, "Change of value in conversion " | |||
2214 | "from %qs to %qs at %L", | |||
2215 | gfc_typename (&src->ts), | |||
2216 | gfc_typename (&result->ts), | |||
2217 | &src->where); | |||
2218 | ||||
2219 | return result; | |||
2220 | } | |||
2221 | ||||
2222 | ||||
2223 | /* Convert default real to default integer. */ | |||
2224 | ||||
2225 | gfc_expr * | |||
2226 | gfc_real2int (gfc_expr *src, int kind) | |||
2227 | { | |||
2228 | gfc_expr *result; | |||
2229 | arith rc; | |||
2230 | bool did_warn = false; | |||
2231 | ||||
2232 | if (src->ts.type != BT_REAL) | |||
2233 | return NULL__null; | |||
2234 | ||||
2235 | result = gfc_get_constant_expr (BT_INTEGER, kind, &src->where); | |||
2236 | ||||
2237 | gfc_mpfr_to_mpz (result->value.integer, src->value.real, &src->where); | |||
2238 | ||||
2239 | if ((rc = gfc_check_integer_range (result->value.integer, kind)) != ARITH_OK) | |||
2240 | { | |||
2241 | arith_error (rc, &src->ts, &result->ts, &src->where); | |||
2242 | gfc_free_expr (result); | |||
2243 | return NULL__null; | |||
2244 | } | |||
2245 | ||||
2246 | /* If there was a fractional part, warn about this. */ | |||
2247 | ||||
2248 | if (warn_conversionglobal_options.x_warn_conversion) | |||
2249 | { | |||
2250 | mpfr_t f; | |||
2251 | mpfr_init (f); | |||
2252 | mpfr_frac (f, src->value.real, GFC_RND_MODEMPFR_RNDN); | |||
2253 | if (mpfr_cmp_si (f, 0)mpfr_cmp_si_2exp((f),(0),0) != 0) | |||
2254 | { | |||
2255 | gfc_warning_now (OPT_Wconversion, "Change of value in conversion " | |||
2256 | "from %qs to %qs at %L", gfc_typename (&src->ts), | |||
2257 | gfc_typename (&result->ts), &src->where); | |||
2258 | did_warn = true; | |||
2259 | } | |||
2260 | mpfr_clear (f); | |||
2261 | } | |||
2262 | if (!did_warn && warn_conversion_extraglobal_options.x_warn_conversion_extra) | |||
2263 | { | |||
2264 | gfc_warning_now (OPT_Wconversion_extra, "Conversion from %qs to %qs " | |||
2265 | "at %L", gfc_typename (&src->ts), | |||
2266 | gfc_typename (&result->ts), &src->where); | |||
2267 | } | |||
2268 | ||||
2269 | return result; | |||
2270 | } | |||
2271 | ||||
2272 | ||||
2273 | /* Convert real to real. */ | |||
2274 | ||||
2275 | gfc_expr * | |||
2276 | gfc_real2real (gfc_expr *src, int kind) | |||
2277 | { | |||
2278 | gfc_expr *result; | |||
2279 | arith rc; | |||
2280 | bool did_warn = false; | |||
2281 | ||||
2282 | if (src->ts.type != BT_REAL) | |||
2283 | return NULL__null; | |||
2284 | ||||
2285 | result = gfc_get_constant_expr (BT_REAL, kind, &src->where); | |||
2286 | ||||
2287 | mpfr_set (result->value.real, src->value.real, GFC_RND_MODE)__extension__ ({ mpfr_srcptr _p = (src->value.real); mpfr_set4 (result->value.real,_p,MPFR_RNDN,((_p)->_mpfr_sign)); } ); | |||
2288 | ||||
2289 | rc = gfc_check_real_range (result->value.real, kind); | |||
2290 | ||||
2291 | if (rc == ARITH_UNDERFLOW) | |||
2292 | { | |||
2293 | if (warn_underflowglobal_options.x_warn_underflow) | |||
2294 | gfc_warning (OPT_Woverflow, gfc_arith_error (rc), &src->where); | |||
2295 | mpfr_set_ui (result->value.real, 0, GFC_RND_MODEMPFR_RNDN); | |||
2296 | } | |||
2297 | else if (rc != ARITH_OK) | |||
2298 | { | |||
2299 | arith_error (rc, &src->ts, &result->ts, &src->where); | |||
2300 | gfc_free_expr (result); | |||
2301 | return NULL__null; | |||
2302 | } | |||
2303 | ||||
2304 | /* As a special bonus, don't warn about REAL values which are not changed by | |||
2305 | the conversion if -Wconversion is specified and -Wconversion-extra is | |||
2306 | not. */ | |||
2307 | ||||
2308 | if ((warn_conversionglobal_options.x_warn_conversion || warn_conversion_extraglobal_options.x_warn_conversion_extra) && src->ts.kind > kind) | |||
2309 | { | |||
2310 | int w = warn_conversionglobal_options.x_warn_conversion ? OPT_Wconversion : OPT_Wconversion_extra; | |||
2311 | ||||
2312 | /* Calculate the difference between the constant and the rounded | |||
2313 | value and check it against zero. */ | |||
2314 | ||||
2315 | if (wprecision_real_real (src->value.real, src->ts.kind, kind)) | |||
2316 | { | |||
2317 | gfc_warning_now (w, "Change of value in conversion from " | |||
2318 | "%qs to %qs at %L", | |||
2319 | gfc_typename (&src->ts), gfc_typename (&result->ts), | |||
2320 | &src->where); | |||
2321 | /* Make sure the conversion warning is not emitted again. */ | |||
2322 | did_warn = true; | |||
2323 | } | |||
2324 | } | |||
2325 | ||||
2326 | if (!did_warn && warn_conversion_extraglobal_options.x_warn_conversion_extra) | |||
2327 | gfc_warning_now (OPT_Wconversion_extra, "Conversion from %qs to %qs " | |||
2328 | "at %L", gfc_typename(&src->ts), | |||
2329 | gfc_typename(&result->ts), &src->where); | |||
2330 | ||||
2331 | return result; | |||
2332 | } | |||
2333 | ||||
2334 | ||||
2335 | /* Convert real to complex. */ | |||
2336 | ||||
2337 | gfc_expr * | |||
2338 | gfc_real2complex (gfc_expr *src, int kind) | |||
2339 | { | |||
2340 | gfc_expr *result; | |||
2341 | arith rc; | |||
2342 | bool did_warn = false; | |||
2343 | ||||
2344 | if (src->ts.type != BT_REAL) | |||
2345 | return NULL__null; | |||
2346 | ||||
2347 | result = gfc_get_constant_expr (BT_COMPLEX, kind, &src->where); | |||
2348 | ||||
2349 | mpc_set_fr (result->value.complex, src->value.real, GFC_MPC_RND_MODE(((int)(MPFR_RNDN)) + ((int)(MPFR_RNDN) << 4))); | |||
2350 | ||||
2351 | rc = gfc_check_real_range (mpc_realref (result->value.complex)((result->value.complex)->re), kind); | |||
2352 | ||||
2353 | if (rc == ARITH_UNDERFLOW) | |||
2354 | { | |||
2355 | if (warn_underflowglobal_options.x_warn_underflow) | |||
2356 | gfc_warning (OPT_Woverflow, gfc_arith_error (rc), &src->where); | |||
2357 | mpfr_set_ui (mpc_realref (result->value.complex)((result->value.complex)->re), 0, GFC_RND_MODEMPFR_RNDN); | |||
2358 | } | |||
2359 | else if (rc != ARITH_OK) | |||
2360 | { | |||
2361 | arith_error (rc, &src->ts, &result->ts, &src->where); | |||
2362 | gfc_free_expr (result); | |||
2363 | return NULL__null; | |||
2364 | } | |||
2365 | ||||
2366 | if ((warn_conversionglobal_options.x_warn_conversion || warn_conversion_extraglobal_options.x_warn_conversion_extra) && src->ts.kind > kind) | |||
2367 | { | |||
2368 | int w = warn_conversionglobal_options.x_warn_conversion ? OPT_Wconversion : OPT_Wconversion_extra; | |||
2369 | ||||
2370 | if (wprecision_real_real (src->value.real, src->ts.kind, kind)) | |||
2371 | { | |||
2372 | gfc_warning_now (w, "Change of value in conversion from " | |||
2373 | "%qs to %qs at %L", | |||
2374 | gfc_typename (&src->ts), gfc_typename (&result->ts), | |||
2375 | &src->where); | |||
2376 | /* Make sure the conversion warning is not emitted again. */ | |||
2377 | did_warn = true; | |||
2378 | } | |||
2379 | } | |||
2380 | ||||
2381 | if (!did_warn && warn_conversion_extraglobal_options.x_warn_conversion_extra) | |||
2382 | gfc_warning_now (OPT_Wconversion_extra, "Conversion from %qs to %qs " | |||
2383 | "at %L", gfc_typename(&src->ts), | |||
2384 | gfc_typename(&result->ts), &src->where); | |||
2385 | ||||
2386 | return result; | |||
2387 | } | |||
2388 | ||||
2389 | ||||
2390 | /* Convert complex to integer. */ | |||
2391 | ||||
2392 | gfc_expr * | |||
2393 | gfc_complex2int (gfc_expr *src, int kind) | |||
2394 | { | |||
2395 | gfc_expr *result; | |||
2396 | arith rc; | |||
2397 | bool did_warn = false; | |||
2398 | ||||
2399 | if (src->ts.type != BT_COMPLEX) | |||
2400 | return NULL__null; | |||
2401 | ||||
2402 | result = gfc_get_constant_expr (BT_INTEGER, kind, &src->where); | |||
2403 | ||||
2404 | gfc_mpfr_to_mpz (result->value.integer, mpc_realref (src->value.complex)((src->value.complex)->re), | |||
2405 | &src->where); | |||
2406 | ||||
2407 | if ((rc = gfc_check_integer_range (result->value.integer, kind)) != ARITH_OK) | |||
2408 | { | |||
2409 | arith_error (rc, &src->ts, &result->ts, &src->where); | |||
2410 | gfc_free_expr (result); | |||
2411 | return NULL__null; | |||
2412 | } | |||
2413 | ||||
2414 | if (warn_conversionglobal_options.x_warn_conversion || warn_conversion_extraglobal_options.x_warn_conversion_extra) | |||
2415 | { | |||
2416 | int w = warn_conversionglobal_options.x_warn_conversion ? OPT_Wconversion : OPT_Wconversion_extra; | |||
2417 | ||||
2418 | /* See if we discarded an imaginary part. */ | |||
2419 | if (mpfr_cmp_si (mpc_imagref (src->value.complex), 0)mpfr_cmp_si_2exp((((src->value.complex)->im)),(0),0) != 0) | |||
2420 | { | |||
2421 | gfc_warning_now (w, "Non-zero imaginary part discarded " | |||
2422 | "in conversion from %qs to %qs at %L", | |||
2423 | gfc_typename(&src->ts), gfc_typename (&result->ts), | |||
2424 | &src->where); | |||
2425 | did_warn = true; | |||
2426 | } | |||
2427 | ||||
2428 | else { | |||
2429 | mpfr_t f; | |||
2430 | ||||
2431 | mpfr_init (f); | |||
2432 | mpfr_frac (f, src->value.real, GFC_RND_MODEMPFR_RNDN); | |||
2433 | if (mpfr_cmp_si (f, 0)mpfr_cmp_si_2exp((f),(0),0) != 0) | |||
2434 | { | |||
2435 | gfc_warning_now (w, "Change of value in conversion from " | |||
2436 | "%qs to %qs at %L", gfc_typename (&src->ts), | |||
2437 | gfc_typename (&result->ts), &src->where); | |||
2438 | did_warn = true; | |||
2439 | } | |||
2440 | mpfr_clear (f); | |||
2441 | } | |||
2442 | ||||
2443 | if (!did_warn && warn_conversion_extraglobal_options.x_warn_conversion_extra) | |||
2444 | { | |||
2445 | gfc_warning_now (OPT_Wconversion_extra, "Conversion from %qs to %qs " | |||
2446 | "at %L", gfc_typename (&src->ts), | |||
2447 | gfc_typename (&result->ts), &src->where); | |||
2448 | } | |||
2449 | } | |||
2450 | ||||
2451 | return result; | |||
2452 | } | |||
2453 | ||||
2454 | ||||
2455 | /* Convert complex to real. */ | |||
2456 | ||||
2457 | gfc_expr * | |||
2458 | gfc_complex2real (gfc_expr *src, int kind) | |||
2459 | { | |||
2460 | gfc_expr *result; | |||
2461 | arith rc; | |||
2462 | bool did_warn = false; | |||
2463 | ||||
2464 | if (src->ts.type != BT_COMPLEX) | |||
2465 | return NULL__null; | |||
2466 | ||||
2467 | result = gfc_get_constant_expr (BT_REAL, kind, &src->where); | |||
2468 | ||||
2469 | mpc_real (result->value.real, src->value.complex, GFC_RND_MODEMPFR_RNDN); | |||
2470 | ||||
2471 | rc = gfc_check_real_range (result->value.real, kind); | |||
2472 | ||||
2473 | if (rc == ARITH_UNDERFLOW) | |||
2474 | { | |||
2475 | if (warn_underflowglobal_options.x_warn_underflow) | |||
2476 | gfc_warning (OPT_Woverflow, gfc_arith_error (rc), &src->where); | |||
2477 | mpfr_set_ui (result->value.real, 0, GFC_RND_MODEMPFR_RNDN); | |||
2478 | } | |||
2479 | if (rc != ARITH_OK) | |||
2480 | { | |||
2481 | arith_error (rc, &src->ts, &result->ts, &src->where); | |||
2482 | gfc_free_expr (result); | |||
2483 | return NULL__null; | |||
2484 | } | |||
2485 | ||||
2486 | if (warn_conversionglobal_options.x_warn_conversion || warn_conversion_extraglobal_options.x_warn_conversion_extra) | |||
2487 | { | |||
2488 | int w = warn_conversionglobal_options.x_warn_conversion ? OPT_Wconversion : OPT_Wconversion_extra; | |||
2489 | ||||
2490 | /* See if we discarded an imaginary part. */ | |||
2491 | if (mpfr_cmp_si (mpc_imagref (src->value.complex), 0)mpfr_cmp_si_2exp((((src->value.complex)->im)),(0),0) != 0) | |||
2492 | { | |||
2493 | gfc_warning (w, "Non-zero imaginary part discarded " | |||
2494 | "in conversion from %qs to %qs at %L", | |||
2495 | gfc_typename(&src->ts), gfc_typename (&result->ts), | |||
2496 | &src->where); | |||
2497 | did_warn = true; | |||
2498 | } | |||
2499 | ||||
2500 | /* Calculate the difference between the real constant and the rounded | |||
2501 | value and check it against zero. */ | |||
2502 | ||||
2503 | if (kind > src->ts.kind | |||
2504 | && wprecision_real_real (mpc_realref (src->value.complex)((src->value.complex)->re), | |||
2505 | src->ts.kind, kind)) | |||
2506 | { | |||
2507 | gfc_warning_now (w, "Change of value in conversion from " | |||
2508 | "%qs to %qs at %L", | |||
2509 | gfc_typename (&src->ts), gfc_typename (&result->ts), | |||
2510 | &src->where); | |||
2511 | /* Make sure the conversion warning is not emitted again. */ | |||
2512 | did_warn = true; | |||
2513 | } | |||
2514 | } | |||
2515 | ||||
2516 | if (!did_warn && warn_conversion_extraglobal_options.x_warn_conversion_extra) | |||
2517 | gfc_warning_now (OPT_Wconversion, "Conversion from %qs to %qs at %L", | |||
2518 | gfc_typename(&src->ts), gfc_typename (&result->ts), | |||
2519 | &src->where); | |||
2520 | ||||
2521 | return result; | |||
2522 | } | |||
2523 | ||||
2524 | ||||
2525 | /* Convert complex to complex. */ | |||
2526 | ||||
2527 | gfc_expr * | |||
2528 | gfc_complex2complex (gfc_expr *src, int kind) | |||
2529 | { | |||
2530 | gfc_expr *result; | |||
2531 | arith rc; | |||
2532 | bool did_warn = false; | |||
2533 | ||||
2534 | if (src->ts.type != BT_COMPLEX) | |||
2535 | return NULL__null; | |||
2536 | ||||
2537 | result = gfc_get_constant_expr (BT_COMPLEX, kind, &src->where); | |||
2538 | ||||
2539 | mpc_set (result->value.complex, src->value.complex, GFC_MPC_RND_MODE(((int)(MPFR_RNDN)) + ((int)(MPFR_RNDN) << 4))); | |||
2540 | ||||
2541 | rc = gfc_check_real_range (mpc_realref (result->value.complex)((result->value.complex)->re), kind); | |||
2542 | ||||
2543 | if (rc == ARITH_UNDERFLOW) | |||
2544 | { | |||
2545 | if (warn_underflowglobal_options.x_warn_underflow) | |||
2546 | gfc_warning (OPT_Woverflow, gfc_arith_error (rc), &src->where); | |||
2547 | mpfr_set_ui (mpc_realref (result->value.complex)((result->value.complex)->re), 0, GFC_RND_MODEMPFR_RNDN); | |||
2548 | } | |||
2549 | else if (rc != ARITH_OK) | |||
2550 | { | |||
2551 | arith_error (rc, &src->ts, &result->ts, &src->where); | |||
2552 | gfc_free_expr (result); | |||
2553 | return NULL__null; | |||
2554 | } | |||
2555 | ||||
2556 | rc = gfc_check_real_range (mpc_imagref (result->value.complex)((result->value.complex)->im), kind); | |||
2557 | ||||
2558 | if (rc == ARITH_UNDERFLOW) | |||
2559 | { | |||
2560 | if (warn_underflowglobal_options.x_warn_underflow) | |||
2561 | gfc_warning (OPT_Woverflow, gfc_arith_error (rc), &src->where); | |||
2562 | mpfr_set_ui (mpc_imagref (result->value.complex)((result->value.complex)->im), 0, GFC_RND_MODEMPFR_RNDN); | |||
2563 | } | |||
2564 | else if (rc != ARITH_OK) | |||
2565 | { | |||
2566 | arith_error (rc, &src->ts, &result->ts, &src->where); | |||
2567 | gfc_free_expr (result); | |||
2568 | return NULL__null; | |||
2569 | } | |||
2570 | ||||
2571 | if ((warn_conversionglobal_options.x_warn_conversion || warn_conversion_extraglobal_options.x_warn_conversion_extra) && src->ts.kind > kind | |||
2572 | && (wprecision_real_real (mpc_realref (src->value.complex)((src->value.complex)->re), | |||
2573 | src->ts.kind, kind) | |||
2574 | || wprecision_real_real (mpc_imagref (src->value.complex)((src->value.complex)->im), | |||
2575 | src->ts.kind, kind))) | |||
2576 | { | |||
2577 | int w = warn_conversionglobal_options.x_warn_conversion ? OPT_Wconversion : OPT_Wconversion_extra; | |||
2578 | ||||
2579 | gfc_warning_now (w, "Change of value in conversion from " | |||
2580 | "%qs to %qs at %L", | |||
2581 | gfc_typename (&src->ts), gfc_typename (&result->ts), | |||
2582 | &src->where); | |||
2583 | did_warn = true; | |||
2584 | } | |||
2585 | ||||
2586 | if (!did_warn && warn_conversion_extraglobal_options.x_warn_conversion_extra && src->ts.kind != kind) | |||
2587 | gfc_warning_now (OPT_Wconversion_extra, "Conversion from %qs to %qs " | |||
2588 | "at %L", gfc_typename(&src->ts), | |||
2589 | gfc_typename (&result->ts), &src->where); | |||
2590 | ||||
2591 | return result; | |||
2592 | } | |||
2593 | ||||
2594 | ||||
2595 | /* Logical kind conversion. */ | |||
2596 | ||||
2597 | gfc_expr * | |||
2598 | gfc_log2log (gfc_expr *src, int kind) | |||
2599 | { | |||
2600 | gfc_expr *result; | |||
2601 | ||||
2602 | if (src->ts.type != BT_LOGICAL) | |||
2603 | return NULL__null; | |||
2604 | ||||
2605 | result = gfc_get_constant_expr (BT_LOGICAL, kind, &src->where); | |||
2606 | result->value.logical = src->value.logical; | |||
2607 | ||||
2608 | return result; | |||
2609 | } | |||
2610 | ||||
2611 | ||||
2612 | /* Convert logical to integer. */ | |||
2613 | ||||
2614 | gfc_expr * | |||
2615 | gfc_log2int (gfc_expr *src, int kind) | |||
2616 | { | |||
2617 | gfc_expr *result; | |||
2618 | ||||
2619 | if (src->ts.type != BT_LOGICAL) | |||
2620 | return NULL__null; | |||
2621 | ||||
2622 | result = gfc_get_constant_expr (BT_INTEGER, kind, &src->where); | |||
2623 | mpz_set_si__gmpz_set_si (result->value.integer, src->value.logical); | |||
2624 | ||||
2625 | return result; | |||
2626 | } | |||
2627 | ||||
2628 | ||||
2629 | /* Convert integer to logical. */ | |||
2630 | ||||
2631 | gfc_expr * | |||
2632 | gfc_int2log (gfc_expr *src, int kind) | |||
2633 | { | |||
2634 | gfc_expr *result; | |||
2635 | ||||
2636 | if (src->ts.type != BT_INTEGER) | |||
2637 | return NULL__null; | |||
2638 | ||||
2639 | result = gfc_get_constant_expr (BT_LOGICAL, kind, &src->where); | |||
2640 | result->value.logical = (mpz_cmp_si (src->value.integer, 0)(__builtin_constant_p ((0) >= 0) && (0) >= 0 ? ( __builtin_constant_p ((static_cast<unsigned long> (0))) && ((static_cast<unsigned long> (0))) == 0 ? ( (src->value.integer)->_mp_size < 0 ? -1 : (src->value .integer)->_mp_size > 0) : __gmpz_cmp_ui (src->value .integer,(static_cast<unsigned long> (0)))) : __gmpz_cmp_si (src->value.integer,0)) != 0); | |||
2641 | ||||
2642 | return result; | |||
2643 | } | |||
2644 | ||||
2645 | /* Convert character to character. We only use wide strings internally, | |||
2646 | so we only set the kind. */ | |||
2647 | ||||
2648 | gfc_expr * | |||
2649 | gfc_character2character (gfc_expr *src, int kind) | |||
2650 | { | |||
2651 | gfc_expr *result; | |||
2652 | result = gfc_copy_expr (src); | |||
2653 | result->ts.kind = kind; | |||
2654 | ||||
2655 | return result; | |||
2656 | } | |||
2657 | ||||
2658 | /* Helper function to set the representation in a Hollerith conversion. | |||
2659 | This assumes that the ts.type and ts.kind of the result have already | |||
2660 | been set. */ | |||
2661 | ||||
2662 | static void | |||
2663 | hollerith2representation (gfc_expr *result, gfc_expr *src) | |||
2664 | { | |||
2665 | size_t src_len, result_len; | |||
2666 | ||||
2667 | src_len = src->representation.length - src->ts.u.pad; | |||
2668 | gfc_target_expr_size (result, &result_len); | |||
2669 | ||||
2670 | if (src_len > result_len) | |||
2671 | { | |||
2672 | gfc_warning (OPT_Wcharacter_truncation, "The Hollerith constant at %L " | |||
2673 | "is truncated in conversion to %qs", &src->where, | |||
2674 | gfc_typename(&result->ts)); | |||
2675 | } | |||
2676 | ||||
2677 | result->representation.string = XCNEWVEC (char, result_len + 1)((char *) xcalloc ((result_len + 1), sizeof (char))); | |||
2678 | memcpy (result->representation.string, src->representation.string, | |||
2679 | MIN (result_len, src_len)((result_len) < (src_len) ? (result_len) : (src_len))); | |||
2680 | ||||
2681 | if (src_len < result_len) | |||
2682 | memset (&result->representation.string[src_len], ' ', result_len - src_len); | |||
2683 | ||||
2684 | result->representation.string[result_len] = '\0'; /* For debugger */ | |||
2685 | result->representation.length = result_len; | |||
2686 | } | |||
2687 | ||||
2688 | ||||
2689 | /* Helper function to set the representation in a character conversion. | |||
2690 | This assumes that the ts.type and ts.kind of the result have already | |||
2691 | been set. */ | |||
2692 | ||||
2693 | static void | |||
2694 | character2representation (gfc_expr *result, gfc_expr *src) | |||
2695 | { | |||
2696 | size_t src_len, result_len, i; | |||
2697 | src_len = src->value.character.length; | |||
2698 | gfc_target_expr_size (result, &result_len); | |||
2699 | ||||
2700 | if (src_len > result_len) | |||
2701 | gfc_warning (OPT_Wcharacter_truncation, "The character constant at %L is " | |||
2702 | "truncated in conversion to %s", &src->where, | |||
2703 | gfc_typename(&result->ts)); | |||
2704 | ||||
2705 | result->representation.string = XCNEWVEC (char, result_len + 1)((char *) xcalloc ((result_len + 1), sizeof (char))); | |||
2706 | ||||
2707 | for (i = 0; i < MIN (result_len, src_len)((result_len) < (src_len) ? (result_len) : (src_len)); i++) | |||
2708 | result->representation.string[i] = (char) src->value.character.string[i]; | |||
2709 | ||||
2710 | if (src_len < result_len) | |||
2711 | memset (&result->representation.string[src_len], ' ', | |||
2712 | result_len - src_len); | |||
2713 | ||||
2714 | result->representation.string[result_len] = '\0'; /* For debugger. */ | |||
2715 | result->representation.length = result_len; | |||
2716 | } | |||
2717 | ||||
2718 | /* Convert Hollerith to integer. The constant will be padded or truncated. */ | |||
2719 | ||||
2720 | gfc_expr * | |||
2721 | gfc_hollerith2int (gfc_expr *src, int kind) | |||
2722 | { | |||
2723 | gfc_expr *result; | |||
2724 | result = gfc_get_constant_expr (BT_INTEGER, kind, &src->where); | |||
2725 | ||||
2726 | hollerith2representation (result, src); | |||
2727 | gfc_interpret_integer (kind, (unsigned char *) result->representation.string, | |||
2728 | result->representation.length, result->value.integer); | |||
2729 | ||||
2730 | return result; | |||
2731 | } | |||
2732 | ||||
2733 | /* Convert character to integer. The constant will be padded or truncated. */ | |||
2734 | ||||
2735 | gfc_expr * | |||
2736 | gfc_character2int (gfc_expr *src, int kind) | |||
2737 | { | |||
2738 | gfc_expr *result; | |||
2739 | result = gfc_get_constant_expr (BT_INTEGER, kind, &src->where); | |||
2740 | ||||
2741 | character2representation (result, src); | |||
2742 | gfc_interpret_integer (kind, (unsigned char *) result->representation.string, | |||
2743 | result->representation.length, result->value.integer); | |||
2744 | return result; | |||
2745 | } | |||
2746 | ||||
2747 | /* Convert Hollerith to real. The constant will be padded or truncated. */ | |||
2748 | ||||
2749 | gfc_expr * | |||
2750 | gfc_hollerith2real (gfc_expr *src, int kind) | |||
2751 | { | |||
2752 | gfc_expr *result; | |||
2753 | result = gfc_get_constant_expr (BT_REAL, kind, &src->where); | |||
2754 | ||||
2755 | hollerith2representation (result, src); | |||
2756 | if (gfc_interpret_float (kind, | |||
2757 | (unsigned char *) result->representation.string, | |||
2758 | result->representation.length, result->value.real)) | |||
2759 | return result; | |||
2760 | else | |||
2761 | return NULL__null; | |||
2762 | } | |||
2763 | ||||
2764 | /* Convert character to real. The constant will be padded or truncated. */ | |||
2765 | ||||
2766 | gfc_expr * | |||
2767 | gfc_character2real (gfc_expr *src, int kind) | |||
2768 | { | |||
2769 | gfc_expr *result; | |||
2770 | result = gfc_get_constant_expr (BT_REAL, kind, &src->where); | |||
2771 | ||||
2772 | character2representation (result, src); | |||
2773 | gfc_interpret_float (kind, (unsigned char *) result->representation.string, | |||
2774 | result->representation.length, result->value.real); | |||
2775 | ||||
2776 | return result; | |||
2777 | } | |||
2778 | ||||
2779 | ||||
2780 | /* Convert Hollerith to complex. The constant will be padded or truncated. */ | |||
2781 | ||||
2782 | gfc_expr * | |||
2783 | gfc_hollerith2complex (gfc_expr *src, int kind) | |||
2784 | { | |||
2785 | gfc_expr *result; | |||
2786 | result = gfc_get_constant_expr (BT_COMPLEX, kind, &src->where); | |||
2787 | ||||
2788 | hollerith2representation (result, src); | |||
2789 | gfc_interpret_complex (kind, (unsigned char *) result->representation.string, | |||
2790 | result->representation.length, result->value.complex); | |||
2791 | ||||
2792 | return result; | |||
2793 | } | |||
2794 | ||||
2795 | /* Convert character to complex. The constant will be padded or truncated. */ | |||
2796 | ||||
2797 | gfc_expr * | |||
2798 | gfc_character2complex (gfc_expr *src, int kind) | |||
2799 | { | |||
2800 | gfc_expr *result; | |||
2801 | result = gfc_get_constant_expr (BT_COMPLEX, kind, &src->where); | |||
2802 | ||||
2803 | character2representation (result, src); | |||
2804 | gfc_interpret_complex (kind, (unsigned char *) result->representation.string, | |||
2805 | result->representation.length, result->value.complex); | |||
2806 | ||||
2807 | return result; | |||
2808 | } | |||
2809 | ||||
2810 | ||||
2811 | /* Convert Hollerith to character. */ | |||
2812 | ||||
2813 | gfc_expr * | |||
2814 | gfc_hollerith2character (gfc_expr *src, int kind) | |||
2815 | { | |||
2816 | gfc_expr *result; | |||
2817 | ||||
2818 | result = gfc_copy_expr (src); | |||
2819 | result->ts.type = BT_CHARACTER; | |||
2820 | result->ts.kind = kind; | |||
2821 | result->ts.u.pad = 0; | |||
2822 | ||||
2823 | result->value.character.length = result->representation.length; | |||
2824 | result->value.character.string | |||
2825 | = gfc_char_to_widechar (result->representation.string); | |||
2826 | ||||
2827 | return result; | |||
2828 | } | |||
2829 | ||||
2830 | ||||
2831 | /* Convert Hollerith to logical. The constant will be padded or truncated. */ | |||
2832 | ||||
2833 | gfc_expr * | |||
2834 | gfc_hollerith2logical (gfc_expr *src, int kind) | |||
2835 | { | |||
2836 | gfc_expr *result; | |||
2837 | result = gfc_get_constant_expr (BT_LOGICAL, kind, &src->where); | |||
2838 | ||||
2839 | hollerith2representation (result, src); | |||
2840 | gfc_interpret_logical (kind, (unsigned char *) result->representation.string, | |||
2841 | result->representation.length, &result->value.logical); | |||
2842 | ||||
2843 | return result; | |||
2844 | } | |||
2845 | ||||
2846 | /* Convert character to logical. The constant will be padded or truncated. */ | |||
2847 | ||||
2848 | gfc_expr * | |||
2849 | gfc_character2logical (gfc_expr *src, int kind) | |||
2850 | { | |||
2851 | gfc_expr *result; | |||
2852 | result = gfc_get_constant_expr (BT_LOGICAL, kind, &src->where); | |||
2853 | ||||
2854 | character2representation (result, src); | |||
2855 | gfc_interpret_logical (kind, (unsigned char *) result->representation.string, | |||
2856 | result->representation.length, &result->value.logical); | |||
2857 | ||||
2858 | return result; | |||
2859 | } |