]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fortran/simplify.c
PR fortran/95090 - ICE: identifier overflow
[thirdparty/gcc.git] / gcc / fortran / simplify.c
CommitLineData
6de9cd9a 1/* Simplify intrinsic functions at compile-time.
8d9254fc 2 Copyright (C) 2000-2020 Free Software Foundation, Inc.
6de9cd9a
DN
3 Contributed by Andy Vaught & Katherine Holcomb
4
9fc4d79b 5This file is part of GCC.
6de9cd9a 6
9fc4d79b
TS
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
d234d788 9Software Foundation; either version 3, or (at your option) any later
9fc4d79b 10version.
6de9cd9a 11
9fc4d79b
TS
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
6de9cd9a
DN
16
17You should have received a copy of the GNU General Public License
d234d788
NC
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
6de9cd9a
DN
20
21#include "config.h"
22#include "system.h"
953bee7c 23#include "coretypes.h"
2adfab87 24#include "tm.h" /* For BITS_PER_UNIT. */
6de9cd9a
DN
25#include "gfortran.h"
26#include "arith.h"
27#include "intrinsic.h"
a900a060 28#include "match.h"
7433458d 29#include "target-memory.h"
b7e75771 30#include "constructor.h"
1a8c1e35 31#include "version.h" /* For version_string. */
6de9cd9a 32
317fa064
TK
33/* Prototypes. */
34
b573f931 35static int min_max_choose (gfc_expr *, gfc_expr *, int, bool back_val = false);
7ba8c18c 36
6de9cd9a
DN
37gfc_expr gfc_bad_expr;
38
1634e53f
TB
39static gfc_expr *simplify_size (gfc_expr *, gfc_expr *, int);
40
6de9cd9a
DN
41
42/* Note that 'simplification' is not just transforming expressions.
43 For functions that are not simplified at compile time, range
44 checking is done if possible.
45
46 The return convention is that each simplification function returns:
47
48 A new expression node corresponding to the simplified arguments.
49 The original arguments are destroyed by the caller, and must not
50 be a part of the new expression.
51
52 NULL pointer indicating that no simplification was possible and
b7e75771 53 the original expression should remain intact.
6de9cd9a
DN
54
55 An expression pointer to gfc_bad_expr (a static placeholder)
b7e75771
JD
56 indicating that some error has prevented simplification. The
57 error is generated within the function and should be propagated
58 upwards
6de9cd9a
DN
59
60 By the time a simplification function gets control, it has been
61 decided that the function call is really supposed to be the
62 intrinsic. No type checking is strictly necessary, since only
63 valid types will be passed on. On the other hand, a simplification
64 subroutine may have to look at the type of an argument as part of
65 its processing.
66
b7e75771
JD
67 Array arguments are only passed to these subroutines that implement
68 the simplification of transformational intrinsics.
6de9cd9a
DN
69
70 The functions in this file don't have much comment with them, but
71 everything is reasonably straight-forward. The Standard, chapter 13
72 is the best comment you'll find for this file anyway. */
73
6de9cd9a
DN
74/* Range checks an expression node. If all goes well, returns the
75 node, otherwise returns &gfc_bad_expr and frees the node. */
76
77static gfc_expr *
edf1eac2 78range_check (gfc_expr *result, const char *name)
6de9cd9a 79{
e0f6835d
JD
80 if (result == NULL)
81 return &gfc_bad_expr;
82
69dcd06a
DK
83 if (result->expr_type != EXPR_CONSTANT)
84 return result;
85
54554825
JD
86 switch (gfc_range_check (result))
87 {
88 case ARITH_OK:
89 return result;
8b704316 90
54554825 91 case ARITH_OVERFLOW:
edf1eac2
SK
92 gfc_error ("Result of %s overflows its kind at %L", name,
93 &result->where);
54554825
JD
94 break;
95
96 case ARITH_UNDERFLOW:
edf1eac2
SK
97 gfc_error ("Result of %s underflows its kind at %L", name,
98 &result->where);
54554825
JD
99 break;
100
101 case ARITH_NAN:
102 gfc_error ("Result of %s is NaN at %L", name, &result->where);
103 break;
104
105 default:
edf1eac2
SK
106 gfc_error ("Result of %s gives range error for its kind at %L", name,
107 &result->where);
54554825
JD
108 break;
109 }
110
6de9cd9a
DN
111 gfc_free_expr (result);
112 return &gfc_bad_expr;
113}
114
115
116/* A helper function that gets an optional and possibly missing
117 kind parameter. Returns the kind, -1 if something went wrong. */
118
119static int
edf1eac2 120get_kind (bt type, gfc_expr *k, const char *name, int default_kind)
6de9cd9a
DN
121{
122 int kind;
123
124 if (k == NULL)
125 return default_kind;
126
127 if (k->expr_type != EXPR_CONSTANT)
128 {
129 gfc_error ("KIND parameter of %s at %L must be an initialization "
130 "expression", name, &k->where);
6de9cd9a
DN
131 return -1;
132 }
133
51f03c6b 134 if (gfc_extract_int (k, &kind)
e7a2d5fb 135 || gfc_validate_kind (type, kind, true) < 0)
6de9cd9a 136 {
6de9cd9a
DN
137 gfc_error ("Invalid KIND parameter of %s at %L", name, &k->where);
138 return -1;
139 }
140
141 return kind;
142}
143
144
f1dcb9bf
BM
145/* Converts an mpz_t signed variable into an unsigned one, assuming
146 two's complement representations and a binary width of bitsize.
147 The conversion is a no-op unless x is negative; otherwise, it can
148 be accomplished by masking out the high bits. */
5d24a977
TS
149
150static void
f1dcb9bf 151convert_mpz_to_unsigned (mpz_t x, int bitsize)
5d24a977
TS
152{
153 mpz_t mask;
5d24a977 154
f1dcb9bf
BM
155 if (mpz_sgn (x) < 0)
156 {
d01b2c21
TK
157 /* Confirm that no bits above the signed range are unset if we
158 are doing range checking. */
c61819ff 159 if (flag_range_check != 0)
d01b2c21 160 gcc_assert (mpz_scan0 (x, bitsize-1) == ULONG_MAX);
f1dcb9bf
BM
161
162 mpz_init_set_ui (mask, 1);
163 mpz_mul_2exp (mask, mask, bitsize);
164 mpz_sub_ui (mask, mask, 1);
165
166 mpz_and (x, x, mask);
167
168 mpz_clear (mask);
169 }
170 else
171 {
c5144966
HA
172 /* Confirm that no bits above the signed range are set if we
173 are doing range checking. */
174 if (flag_range_check != 0)
175 gcc_assert (mpz_scan1 (x, bitsize-1) == ULONG_MAX);
f1dcb9bf
BM
176 }
177}
178
179
180/* Converts an mpz_t unsigned variable into a signed one, assuming
181 two's complement representations and a binary width of bitsize.
182 If the bitsize-1 bit is set, this is taken as a sign bit and
183 the number is converted to the corresponding negative number. */
184
d01b2c21
TK
185void
186gfc_convert_mpz_to_signed (mpz_t x, int bitsize)
f1dcb9bf
BM
187{
188 mpz_t mask;
189
d01b2c21
TK
190 /* Confirm that no bits above the unsigned range are set if we are
191 doing range checking. */
c61819ff 192 if (flag_range_check != 0)
d01b2c21 193 gcc_assert (mpz_scan1 (x, bitsize) == ULONG_MAX);
f1dcb9bf 194
5d24a977
TS
195 if (mpz_tstbit (x, bitsize - 1) == 1)
196 {
f1dcb9bf
BM
197 mpz_init_set_ui (mask, 1);
198 mpz_mul_2exp (mask, mask, bitsize);
199 mpz_sub_ui (mask, mask, 1);
b7398e72
TS
200
201 /* We negate the number by hand, zeroing the high bits, that is
edf1eac2
SK
202 make it the corresponding positive number, and then have it
203 negated by GMP, giving the correct representation of the
204 negative number. */
5d24a977
TS
205 mpz_com (x, x);
206 mpz_add_ui (x, x, 1);
207 mpz_and (x, x, mask);
208
209 mpz_neg (x, x);
210
211 mpz_clear (mask);
212 }
213}
214
b7e75771 215
a1d6c052 216/* Test that the expression is a constant array, simplifying if
6c6bde30 217 we are dealing with a parameter array. */
7ba8c18c
DF
218
219static bool
220is_constant_array_expr (gfc_expr *e)
221{
222 gfc_constructor *c;
223
224 if (e == NULL)
225 return true;
226
6c6bde30
TK
227 if (e->expr_type == EXPR_VARIABLE && e->rank > 0
228 && e->symtree->n.sym->attr.flavor == FL_PARAMETER)
229 gfc_simplify_expr (e, 1);
230
7ba8c18c
DF
231 if (e->expr_type != EXPR_ARRAY || !gfc_is_constant_expr (e))
232 return false;
233
b7e75771
JD
234 for (c = gfc_constructor_first (e->value.constructor);
235 c; c = gfc_constructor_next (c))
15c2ef5a
PT
236 if (c->expr->expr_type != EXPR_CONSTANT
237 && c->expr->expr_type != EXPR_STRUCTURE)
7ba8c18c
DF
238 return false;
239
240 return true;
241}
242
94e6b5e5 243/* Test for a size zero array. */
5867bb9a
TK
244bool
245gfc_is_size_zero_array (gfc_expr *array)
94e6b5e5 246{
94e6b5e5 247
5867bb9a
TK
248 if (array->rank == 0)
249 return false;
94e6b5e5 250
5867bb9a
TK
251 if (array->expr_type == EXPR_VARIABLE && array->rank > 0
252 && array->symtree->n.sym->attr.flavor == FL_PARAMETER
253 && array->shape != NULL)
254 {
255 for (int i = 0; i < array->rank; i++)
256 if (mpz_cmp_si (array->shape[i], 0) <= 0)
257 return true;
94e6b5e5 258
5867bb9a
TK
259 return false;
260 }
94e6b5e5 261
5867bb9a
TK
262 if (array->expr_type == EXPR_ARRAY)
263 return array->value.constructor == NULL;
264
265 return false;
94e6b5e5
SK
266}
267
7ba8c18c 268
8ec259c1
DF
269/* Initialize a transformational result expression with a given value. */
270
271static void
272init_result_expr (gfc_expr *e, int init, gfc_expr *array)
273{
274 if (e && e->expr_type == EXPR_ARRAY)
275 {
b7e75771 276 gfc_constructor *ctor = gfc_constructor_first (e->value.constructor);
8ec259c1
DF
277 while (ctor)
278 {
279 init_result_expr (ctor->expr, init, array);
b7e75771 280 ctor = gfc_constructor_next (ctor);
8ec259c1
DF
281 }
282 }
283 else if (e && e->expr_type == EXPR_CONSTANT)
284 {
285 int i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
6b271a2e 286 HOST_WIDE_INT length;
8ec259c1
DF
287 gfc_char_t *string;
288
289 switch (e->ts.type)
290 {
291 case BT_LOGICAL:
292 e->value.logical = (init ? 1 : 0);
293 break;
294
295 case BT_INTEGER:
296 if (init == INT_MIN)
297 mpz_set (e->value.integer, gfc_integer_kinds[i].min_int);
298 else if (init == INT_MAX)
299 mpz_set (e->value.integer, gfc_integer_kinds[i].huge);
300 else
301 mpz_set_si (e->value.integer, init);
302 break;
303
304 case BT_REAL:
305 if (init == INT_MIN)
306 {
307 mpfr_set (e->value.real, gfc_real_kinds[i].huge, GFC_RND_MODE);
308 mpfr_neg (e->value.real, e->value.real, GFC_RND_MODE);
309 }
310 else if (init == INT_MAX)
311 mpfr_set (e->value.real, gfc_real_kinds[i].huge, GFC_RND_MODE);
312 else
313 mpfr_set_si (e->value.real, init, GFC_RND_MODE);
314 break;
315
316 case BT_COMPLEX:
eb6f9a86 317 mpc_set_si (e->value.complex, init, GFC_MPC_RND_MODE);
8ec259c1
DF
318 break;
319
320 case BT_CHARACTER:
321 if (init == INT_MIN)
322 {
323 gfc_expr *len = gfc_simplify_len (array, NULL);
6b271a2e 324 gfc_extract_hwi (len, &length);
8ec259c1
DF
325 string = gfc_get_wide_string (length + 1);
326 gfc_wide_memset (string, 0, length);
327 }
328 else if (init == INT_MAX)
329 {
330 gfc_expr *len = gfc_simplify_len (array, NULL);
6b271a2e 331 gfc_extract_hwi (len, &length);
8ec259c1
DF
332 string = gfc_get_wide_string (length + 1);
333 gfc_wide_memset (string, 255, length);
334 }
335 else
336 {
337 length = 0;
338 string = gfc_get_wide_string (1);
339 }
340
341 string[length] = '\0';
342 e->value.character.length = length;
343 e->value.character.string = string;
344 break;
345
346 default:
347 gcc_unreachable();
348 }
349 }
350 else
351 gcc_unreachable();
352}
353
354
eebb98a5
TB
355/* Helper function for gfc_simplify_dot_product() and gfc_simplify_matmul;
356 if conj_a is true, the matrix_a is complex conjugated. */
8ec259c1
DF
357
358static gfc_expr *
b7e75771 359compute_dot_product (gfc_expr *matrix_a, int stride_a, int offset_a,
eebb98a5
TB
360 gfc_expr *matrix_b, int stride_b, int offset_b,
361 bool conj_a)
8ec259c1 362{
eebb98a5 363 gfc_expr *result, *a, *b, *c;
8ec259c1 364
0ada0dc0 365 /* Set result to an INTEGER(1) 0 for numeric types and .false. for
deece1aa
SK
366 LOGICAL. Mixed-mode math in the loop will promote result to the
367 correct type and kind. */
368 if (matrix_a->ts.type == BT_LOGICAL)
369 result = gfc_get_logical_expr (gfc_default_logical_kind, NULL, false);
370 else
371 result = gfc_get_int_expr (1, NULL, 0);
372 result->where = matrix_a->where;
8ec259c1 373
b7e75771
JD
374 a = gfc_constructor_lookup_expr (matrix_a->value.constructor, offset_a);
375 b = gfc_constructor_lookup_expr (matrix_b->value.constructor, offset_b);
376 while (a && b)
8ec259c1
DF
377 {
378 /* Copying of expressions is required as operands are free'd
379 by the gfc_arith routines. */
380 switch (result->ts.type)
381 {
382 case BT_LOGICAL:
383 result = gfc_or (result,
b7e75771
JD
384 gfc_and (gfc_copy_expr (a),
385 gfc_copy_expr (b)));
8ec259c1
DF
386 break;
387
388 case BT_INTEGER:
389 case BT_REAL:
390 case BT_COMPLEX:
eebb98a5
TB
391 if (conj_a && a->ts.type == BT_COMPLEX)
392 c = gfc_simplify_conjg (a);
393 else
394 c = gfc_copy_expr (a);
395 result = gfc_add (result, gfc_multiply (c, gfc_copy_expr (b)));
8ec259c1
DF
396 break;
397
398 default:
399 gcc_unreachable();
400 }
401
b7e75771
JD
402 offset_a += stride_a;
403 a = gfc_constructor_lookup_expr (matrix_a->value.constructor, offset_a);
404
405 offset_b += stride_b;
406 b = gfc_constructor_lookup_expr (matrix_b->value.constructor, offset_b);
8ec259c1
DF
407 }
408
409 return result;
410}
411
a16d978f 412
8b704316 413/* Build a result expression for transformational intrinsics,
1cc0e193 414 depending on DIM. */
a16d978f
DF
415
416static gfc_expr *
417transformational_result (gfc_expr *array, gfc_expr *dim, bt type,
418 int kind, locus* where)
419{
420 gfc_expr *result;
421 int i, nelem;
422
423 if (!dim || array->rank == 1)
b7e75771 424 return gfc_get_constant_expr (type, kind, where);
a16d978f 425
b7e75771 426 result = gfc_get_array_expr (type, kind, where);
a16d978f
DF
427 result->shape = gfc_copy_shape_excluding (array->shape, array->rank, dim);
428 result->rank = array->rank - 1;
429
430 /* gfc_array_size() would count the number of elements in the constructor,
431 we have not built those yet. */
432 nelem = 1;
433 for (i = 0; i < result->rank; ++i)
434 nelem *= mpz_get_ui (result->shape[i]);
435
436 for (i = 0; i < nelem; ++i)
437 {
b7e75771
JD
438 gfc_constructor_append_expr (&result->value.constructor,
439 gfc_get_constant_expr (type, kind, where),
440 NULL);
a16d978f
DF
441 }
442
443 return result;
444}
445
446
447typedef gfc_expr* (*transformational_op)(gfc_expr*, gfc_expr*);
448
449/* Wrapper function, implements 'op1 += 1'. Only called if MASK
450 of COUNT intrinsic is .TRUE..
451
62732c30 452 Interface and implementation mimics arith functions as
a16d978f
DF
453 gfc_add, gfc_multiply, etc. */
454
317fa064
TK
455static gfc_expr *
456gfc_count (gfc_expr *op1, gfc_expr *op2)
a16d978f
DF
457{
458 gfc_expr *result;
459
460 gcc_assert (op1->ts.type == BT_INTEGER);
461 gcc_assert (op2->ts.type == BT_LOGICAL);
462 gcc_assert (op2->value.logical);
463
464 result = gfc_copy_expr (op1);
465 mpz_add_ui (result->value.integer, result->value.integer, 1);
466
467 gfc_free_expr (op1);
468 gfc_free_expr (op2);
469 return result;
470}
471
472
473/* Transforms an ARRAY with operation OP, according to MASK, to a
474 scalar RESULT. E.g. called if
475
476 REAL, PARAMETER :: array(n, m) = ...
477 REAL, PARAMETER :: s = SUM(array)
478
479 where OP == gfc_add(). */
480
481static gfc_expr *
482simplify_transformation_to_scalar (gfc_expr *result, gfc_expr *array, gfc_expr *mask,
483 transformational_op op)
484{
485 gfc_expr *a, *m;
486 gfc_constructor *array_ctor, *mask_ctor;
487
488 /* Shortcut for constant .FALSE. MASK. */
489 if (mask
490 && mask->expr_type == EXPR_CONSTANT
491 && !mask->value.logical)
492 return result;
493
b7e75771 494 array_ctor = gfc_constructor_first (array->value.constructor);
a16d978f
DF
495 mask_ctor = NULL;
496 if (mask && mask->expr_type == EXPR_ARRAY)
b7e75771 497 mask_ctor = gfc_constructor_first (mask->value.constructor);
a16d978f
DF
498
499 while (array_ctor)
500 {
501 a = array_ctor->expr;
b7e75771 502 array_ctor = gfc_constructor_next (array_ctor);
a16d978f
DF
503
504 /* A constant MASK equals .TRUE. here and can be ignored. */
505 if (mask_ctor)
506 {
507 m = mask_ctor->expr;
b7e75771 508 mask_ctor = gfc_constructor_next (mask_ctor);
a16d978f
DF
509 if (!m->value.logical)
510 continue;
511 }
512
513 result = op (result, gfc_copy_expr (a));
e85921ee
SK
514 if (!result)
515 return result;
a16d978f
DF
516 }
517
518 return result;
519}
520
521/* Transforms an ARRAY with operation OP, according to MASK, to an
522 array RESULT. E.g. called if
523
524 REAL, PARAMETER :: array(n, m) = ...
525 REAL, PARAMETER :: s(n) = PROD(array, DIM=1)
526
1cc0e193
JV
527 where OP == gfc_multiply().
528 The result might be post processed using post_op. */
a16d978f
DF
529
530static gfc_expr *
531simplify_transformation_to_array (gfc_expr *result, gfc_expr *array, gfc_expr *dim,
0cd0559e
TB
532 gfc_expr *mask, transformational_op op,
533 transformational_op post_op)
a16d978f
DF
534{
535 mpz_t size;
536 int done, i, n, arraysize, resultsize, dim_index, dim_extent, dim_stride;
537 gfc_expr **arrayvec, **resultvec, **base, **src, **dest;
538 gfc_constructor *array_ctor, *mask_ctor, *result_ctor;
539
540 int count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS],
541 sstride[GFC_MAX_DIMENSIONS], dstride[GFC_MAX_DIMENSIONS],
542 tmpstride[GFC_MAX_DIMENSIONS];
543
544 /* Shortcut for constant .FALSE. MASK. */
545 if (mask
546 && mask->expr_type == EXPR_CONSTANT
547 && !mask->value.logical)
548 return result;
549
550 /* Build an indexed table for array element expressions to minimize
551 linked-list traversal. Masked elements are set to NULL. */
552 gfc_array_size (array, &size);
553 arraysize = mpz_get_ui (size);
9c85d38b 554 mpz_clear (size);
a16d978f 555
93acb62c 556 arrayvec = XCNEWVEC (gfc_expr*, arraysize);
a16d978f 557
b7e75771 558 array_ctor = gfc_constructor_first (array->value.constructor);
a16d978f
DF
559 mask_ctor = NULL;
560 if (mask && mask->expr_type == EXPR_ARRAY)
b7e75771 561 mask_ctor = gfc_constructor_first (mask->value.constructor);
a16d978f
DF
562
563 for (i = 0; i < arraysize; ++i)
564 {
565 arrayvec[i] = array_ctor->expr;
b7e75771 566 array_ctor = gfc_constructor_next (array_ctor);
a16d978f
DF
567
568 if (mask_ctor)
569 {
570 if (!mask_ctor->expr->value.logical)
571 arrayvec[i] = NULL;
572
b7e75771 573 mask_ctor = gfc_constructor_next (mask_ctor);
a16d978f
DF
574 }
575 }
576
577 /* Same for the result expression. */
578 gfc_array_size (result, &size);
579 resultsize = mpz_get_ui (size);
580 mpz_clear (size);
581
93acb62c 582 resultvec = XCNEWVEC (gfc_expr*, resultsize);
b7e75771 583 result_ctor = gfc_constructor_first (result->value.constructor);
a16d978f
DF
584 for (i = 0; i < resultsize; ++i)
585 {
586 resultvec[i] = result_ctor->expr;
b7e75771 587 result_ctor = gfc_constructor_next (result_ctor);
a16d978f
DF
588 }
589
590 gfc_extract_int (dim, &dim_index);
591 dim_index -= 1; /* zero-base index */
592 dim_extent = 0;
593 dim_stride = 0;
594
595 for (i = 0, n = 0; i < array->rank; ++i)
596 {
597 count[i] = 0;
598 tmpstride[i] = (i == 0) ? 1 : tmpstride[i-1] * mpz_get_si (array->shape[i-1]);
599 if (i == dim_index)
600 {
601 dim_extent = mpz_get_si (array->shape[i]);
602 dim_stride = tmpstride[i];
603 continue;
604 }
605
606 extent[n] = mpz_get_si (array->shape[i]);
607 sstride[n] = tmpstride[i];
608 dstride[n] = (n == 0) ? 1 : dstride[n-1] * extent[n-1];
609 n += 1;
610 }
611
1832cbf8 612 done = resultsize <= 0;
a16d978f
DF
613 base = arrayvec;
614 dest = resultvec;
615 while (!done)
616 {
617 for (src = base, n = 0; n < dim_extent; src += dim_stride, ++n)
618 if (*src)
619 *dest = op (*dest, gfc_copy_expr (*src));
620
843192c0
JJ
621 if (post_op)
622 *dest = post_op (*dest, *dest);
623
a16d978f
DF
624 count[0]++;
625 base += sstride[0];
626 dest += dstride[0];
627
628 n = 0;
629 while (!done && count[n] == extent[n])
630 {
631 count[n] = 0;
632 base -= sstride[n] * extent[n];
633 dest -= dstride[n] * extent[n];
634
635 n++;
636 if (n < result->rank)
637 {
e1d070a4
AO
638 /* If the nested loop is unrolled GFC_MAX_DIMENSIONS
639 times, we'd warn for the last iteration, because the
640 array index will have already been incremented to the
641 array sizes, and we can't tell that this must make
642 the test against result->rank false, because ranks
643 must not exceed GFC_MAX_DIMENSIONS. */
75213cc0 644 GCC_DIAGNOSTIC_PUSH_IGNORED (-Warray-bounds)
e1d070a4 645 count[n]++;
a16d978f
DF
646 base += sstride[n];
647 dest += dstride[n];
75213cc0 648 GCC_DIAGNOSTIC_POP
a16d978f
DF
649 }
650 else
651 done = true;
652 }
653 }
654
655 /* Place updated expression in result constructor. */
b7e75771 656 result_ctor = gfc_constructor_first (result->value.constructor);
a16d978f
DF
657 for (i = 0; i < resultsize; ++i)
658 {
843192c0 659 result_ctor->expr = resultvec[i];
b7e75771 660 result_ctor = gfc_constructor_next (result_ctor);
a16d978f
DF
661 }
662
cede9502
JM
663 free (arrayvec);
664 free (resultvec);
a16d978f
DF
665 return result;
666}
667
668
195a95c4
TB
669static gfc_expr *
670simplify_transformation (gfc_expr *array, gfc_expr *dim, gfc_expr *mask,
671 int init_val, transformational_op op)
672{
673 gfc_expr *result;
6f76317a 674 bool size_zero;
195a95c4 675
6f76317a
TK
676 size_zero = gfc_is_size_zero_array (array);
677
678 if (!(is_constant_array_expr (array) || size_zero)
195a95c4
TB
679 || !gfc_is_constant_expr (dim))
680 return NULL;
681
682 if (mask
683 && !is_constant_array_expr (mask)
684 && mask->expr_type != EXPR_CONSTANT)
685 return NULL;
686
687 result = transformational_result (array, dim, array->ts.type,
688 array->ts.kind, &array->where);
317fa064 689 init_result_expr (result, init_val, array);
195a95c4 690
6f76317a
TK
691 if (size_zero)
692 return result;
693
195a95c4
TB
694 return !dim || array->rank == 1 ?
695 simplify_transformation_to_scalar (result, array, mask, op) :
696 simplify_transformation_to_array (result, array, dim, mask, op, NULL);
697}
698
a16d978f 699
6de9cd9a
DN
700/********************** Simplification functions *****************************/
701
702gfc_expr *
edf1eac2 703gfc_simplify_abs (gfc_expr *e)
6de9cd9a
DN
704{
705 gfc_expr *result;
6de9cd9a
DN
706
707 if (e->expr_type != EXPR_CONSTANT)
708 return NULL;
709
710 switch (e->ts.type)
711 {
b7e75771
JD
712 case BT_INTEGER:
713 result = gfc_get_constant_expr (BT_INTEGER, e->ts.kind, &e->where);
714 mpz_abs (result->value.integer, e->value.integer);
715 return range_check (result, "IABS");
6de9cd9a 716
b7e75771
JD
717 case BT_REAL:
718 result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
719 mpfr_abs (result->value.real, e->value.real, GFC_RND_MODE);
720 return range_check (result, "ABS");
6de9cd9a 721
b7e75771
JD
722 case BT_COMPLEX:
723 gfc_set_model_kind (e->ts.kind);
724 result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
725 mpc_abs (result->value.real, e->value.complex, GFC_RND_MODE);
726 return range_check (result, "CABS");
6de9cd9a 727
b7e75771
JD
728 default:
729 gfc_internal_error ("gfc_simplify_abs(): Bad type");
6de9cd9a 730 }
6de9cd9a
DN
731}
732
733
d393bbd7
FXC
734static gfc_expr *
735simplify_achar_char (gfc_expr *e, gfc_expr *k, const char *name, bool ascii)
6de9cd9a
DN
736{
737 gfc_expr *result;
d393bbd7
FXC
738 int kind;
739 bool too_large = false;
6de9cd9a
DN
740
741 if (e->expr_type != EXPR_CONSTANT)
742 return NULL;
743
d393bbd7 744 kind = get_kind (BT_CHARACTER, k, name, gfc_default_character_kind);
719e72fb
FXC
745 if (kind == -1)
746 return &gfc_bad_expr;
747
d393bbd7
FXC
748 if (mpz_cmp_si (e->value.integer, 0) < 0)
749 {
750 gfc_error ("Argument of %s function at %L is negative", name,
751 &e->where);
752 return &gfc_bad_expr;
753 }
34462c28 754
73e42eef 755 if (ascii && warn_surprising && mpz_cmp_si (e->value.integer, 127) > 0)
48749dbc
MLI
756 gfc_warning (OPT_Wsurprising,
757 "Argument of %s function at %L outside of range [0,127]",
d393bbd7 758 name, &e->where);
34462c28 759
d393bbd7
FXC
760 if (kind == 1 && mpz_cmp_si (e->value.integer, 255) > 0)
761 too_large = true;
762 else if (kind == 4)
763 {
764 mpz_t t;
765 mpz_init_set_ui (t, 2);
766 mpz_pow_ui (t, t, 32);
767 mpz_sub_ui (t, t, 1);
768 if (mpz_cmp (e->value.integer, t) > 0)
769 too_large = true;
770 mpz_clear (t);
771 }
6de9cd9a 772
d393bbd7
FXC
773 if (too_large)
774 {
775 gfc_error ("Argument of %s function at %L is too large for the "
776 "collating sequence of kind %d", name, &e->where, kind);
777 return &gfc_bad_expr;
778 }
6de9cd9a 779
b7e75771 780 result = gfc_get_character_expr (kind, &e->where, NULL, 1);
d393bbd7 781 result->value.character.string[0] = mpz_get_ui (e->value.integer);
b7e75771 782
6de9cd9a
DN
783 return result;
784}
785
786
d393bbd7
FXC
787
788/* We use the processor's collating sequence, because all
789 systems that gfortran currently works on are ASCII. */
790
791gfc_expr *
792gfc_simplify_achar (gfc_expr *e, gfc_expr *k)
793{
794 return simplify_achar_char (e, k, "ACHAR", true);
795}
796
797
6de9cd9a 798gfc_expr *
edf1eac2 799gfc_simplify_acos (gfc_expr *x)
6de9cd9a
DN
800{
801 gfc_expr *result;
6de9cd9a
DN
802
803 if (x->expr_type != EXPR_CONSTANT)
804 return NULL;
805
504ed63a 806 switch (x->ts.type)
6de9cd9a 807 {
504ed63a
TB
808 case BT_REAL:
809 if (mpfr_cmp_si (x->value.real, 1) > 0
810 || mpfr_cmp_si (x->value.real, -1) < 0)
811 {
812 gfc_error ("Argument of ACOS at %L must be between -1 and 1",
813 &x->where);
814 return &gfc_bad_expr;
815 }
b7e75771 816 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
8e70c271 817 mpfr_acos (result->value.real, x->value.real, GFC_RND_MODE);
504ed63a 818 break;
b7e75771 819
504ed63a 820 case BT_COMPLEX:
b7e75771 821 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
8e70c271
KG
822 mpc_acos (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
823 break;
b7e75771 824
504ed63a 825 default:
67749498 826 gfc_internal_error ("in gfc_simplify_acos(): Bad type");
6de9cd9a
DN
827 }
828
6de9cd9a
DN
829 return range_check (result, "ACOS");
830}
831
1e399e23 832gfc_expr *
edf1eac2 833gfc_simplify_acosh (gfc_expr *x)
1e399e23
JD
834{
835 gfc_expr *result;
836
837 if (x->expr_type != EXPR_CONSTANT)
838 return NULL;
839
504ed63a 840 switch (x->ts.type)
1e399e23 841 {
504ed63a
TB
842 case BT_REAL:
843 if (mpfr_cmp_si (x->value.real, 1) < 0)
844 {
845 gfc_error ("Argument of ACOSH at %L must not be less than 1",
846 &x->where);
847 return &gfc_bad_expr;
848 }
1e399e23 849
b7e75771 850 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
504ed63a
TB
851 mpfr_acosh (result->value.real, x->value.real, GFC_RND_MODE);
852 break;
b7e75771 853
504ed63a 854 case BT_COMPLEX:
b7e75771 855 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
8e70c271
KG
856 mpc_acosh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
857 break;
b7e75771 858
504ed63a 859 default:
67749498 860 gfc_internal_error ("in gfc_simplify_acosh(): Bad type");
504ed63a 861 }
1e399e23
JD
862
863 return range_check (result, "ACOSH");
864}
6de9cd9a
DN
865
866gfc_expr *
edf1eac2 867gfc_simplify_adjustl (gfc_expr *e)
6de9cd9a
DN
868{
869 gfc_expr *result;
870 int count, i, len;
00660189 871 gfc_char_t ch;
6de9cd9a
DN
872
873 if (e->expr_type != EXPR_CONSTANT)
874 return NULL;
875
876 len = e->value.character.length;
877
6de9cd9a
DN
878 for (count = 0, i = 0; i < len; ++i)
879 {
880 ch = e->value.character.string[i];
881 if (ch != ' ')
882 break;
883 ++count;
884 }
885
b7e75771 886 result = gfc_get_character_expr (e->ts.kind, &e->where, NULL, len);
6de9cd9a 887 for (i = 0; i < len - count; ++i)
edf1eac2 888 result->value.character.string[i] = e->value.character.string[count + i];
6de9cd9a 889
6de9cd9a
DN
890 return result;
891}
892
893
894gfc_expr *
edf1eac2 895gfc_simplify_adjustr (gfc_expr *e)
6de9cd9a
DN
896{
897 gfc_expr *result;
898 int count, i, len;
00660189 899 gfc_char_t ch;
6de9cd9a
DN
900
901 if (e->expr_type != EXPR_CONSTANT)
902 return NULL;
903
904 len = e->value.character.length;
905
6de9cd9a
DN
906 for (count = 0, i = len - 1; i >= 0; --i)
907 {
908 ch = e->value.character.string[i];
909 if (ch != ' ')
910 break;
911 ++count;
912 }
913
b7e75771 914 result = gfc_get_character_expr (e->ts.kind, &e->where, NULL, len);
6de9cd9a 915 for (i = 0; i < count; ++i)
edf1eac2 916 result->value.character.string[i] = ' ';
6de9cd9a
DN
917
918 for (i = count; i < len; ++i)
edf1eac2 919 result->value.character.string[i] = e->value.character.string[i - count];
6de9cd9a 920
6de9cd9a
DN
921 return result;
922}
923
924
925gfc_expr *
edf1eac2 926gfc_simplify_aimag (gfc_expr *e)
6de9cd9a
DN
927{
928 gfc_expr *result;
929
930 if (e->expr_type != EXPR_CONSTANT)
931 return NULL;
932
b7e75771 933 result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
eb6f9a86 934 mpfr_set (result->value.real, mpc_imagref (e->value.complex), GFC_RND_MODE);
6de9cd9a
DN
935
936 return range_check (result, "AIMAG");
937}
938
939
940gfc_expr *
edf1eac2 941gfc_simplify_aint (gfc_expr *e, gfc_expr *k)
6de9cd9a
DN
942{
943 gfc_expr *rtrunc, *result;
944 int kind;
945
946 kind = get_kind (BT_REAL, k, "AINT", e->ts.kind);
947 if (kind == -1)
948 return &gfc_bad_expr;
949
950 if (e->expr_type != EXPR_CONSTANT)
951 return NULL;
952
953 rtrunc = gfc_copy_expr (e);
f8e566e5 954 mpfr_trunc (rtrunc->value.real, e->value.real);
6de9cd9a
DN
955
956 result = gfc_real2real (rtrunc, kind);
b7e75771 957
6de9cd9a
DN
958 gfc_free_expr (rtrunc);
959
960 return range_check (result, "AINT");
961}
962
963
a16d978f
DF
964gfc_expr *
965gfc_simplify_all (gfc_expr *mask, gfc_expr *dim)
966{
195a95c4 967 return simplify_transformation (mask, dim, NULL, true, gfc_and);
a16d978f
DF
968}
969
970
6de9cd9a 971gfc_expr *
edf1eac2 972gfc_simplify_dint (gfc_expr *e)
6de9cd9a
DN
973{
974 gfc_expr *rtrunc, *result;
975
976 if (e->expr_type != EXPR_CONSTANT)
977 return NULL;
978
979 rtrunc = gfc_copy_expr (e);
f8e566e5 980 mpfr_trunc (rtrunc->value.real, e->value.real);
6de9cd9a 981
9d64df18 982 result = gfc_real2real (rtrunc, gfc_default_double_kind);
b7e75771 983
6de9cd9a
DN
984 gfc_free_expr (rtrunc);
985
986 return range_check (result, "DINT");
6de9cd9a
DN
987}
988
989
02c74373
FXC
990gfc_expr *
991gfc_simplify_dreal (gfc_expr *e)
992{
993 gfc_expr *result = NULL;
994
995 if (e->expr_type != EXPR_CONSTANT)
996 return NULL;
997
998 result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
999 mpc_real (result->value.real, e->value.complex, GFC_RND_MODE);
1000
1001 return range_check (result, "DREAL");
1002}
1003
1004
6de9cd9a 1005gfc_expr *
edf1eac2 1006gfc_simplify_anint (gfc_expr *e, gfc_expr *k)
6de9cd9a 1007{
8e1fa5d6
SK
1008 gfc_expr *result;
1009 int kind;
6de9cd9a
DN
1010
1011 kind = get_kind (BT_REAL, k, "ANINT", e->ts.kind);
1012 if (kind == -1)
1013 return &gfc_bad_expr;
1014
1015 if (e->expr_type != EXPR_CONSTANT)
1016 return NULL;
1017
b7e75771 1018 result = gfc_get_constant_expr (e->ts.type, kind, &e->where);
8e1fa5d6 1019 mpfr_round (result->value.real, e->value.real);
6de9cd9a
DN
1020
1021 return range_check (result, "ANINT");
1022}
1023
1024
5d723e54 1025gfc_expr *
edf1eac2 1026gfc_simplify_and (gfc_expr *x, gfc_expr *y)
5d723e54
FXC
1027{
1028 gfc_expr *result;
1029 int kind;
1030
1031 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
1032 return NULL;
1033
1034 kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;
b7e75771
JD
1035
1036 switch (x->ts.type)
5d723e54 1037 {
b7e75771
JD
1038 case BT_INTEGER:
1039 result = gfc_get_constant_expr (BT_INTEGER, kind, &x->where);
1040 mpz_and (result->value.integer, x->value.integer, y->value.integer);
1041 return range_check (result, "AND");
1042
1043 case BT_LOGICAL:
1044 return gfc_get_logical_expr (kind, &x->where,
1045 x->value.logical && y->value.logical);
1046
1047 default:
1048 gcc_unreachable ();
5d723e54 1049 }
5d723e54
FXC
1050}
1051
1052
a16d978f
DF
1053gfc_expr *
1054gfc_simplify_any (gfc_expr *mask, gfc_expr *dim)
1055{
195a95c4 1056 return simplify_transformation (mask, dim, NULL, false, gfc_or);
a16d978f
DF
1057}
1058
1059
6de9cd9a 1060gfc_expr *
edf1eac2 1061gfc_simplify_dnint (gfc_expr *e)
6de9cd9a 1062{
8e1fa5d6 1063 gfc_expr *result;
6de9cd9a
DN
1064
1065 if (e->expr_type != EXPR_CONSTANT)
1066 return NULL;
1067
b7e75771 1068 result = gfc_get_constant_expr (BT_REAL, gfc_default_double_kind, &e->where);
8e1fa5d6 1069 mpfr_round (result->value.real, e->value.real);
6de9cd9a
DN
1070
1071 return range_check (result, "DNINT");
1072}
1073
1074
1075gfc_expr *
edf1eac2 1076gfc_simplify_asin (gfc_expr *x)
6de9cd9a
DN
1077{
1078 gfc_expr *result;
6de9cd9a
DN
1079
1080 if (x->expr_type != EXPR_CONSTANT)
1081 return NULL;
1082
504ed63a 1083 switch (x->ts.type)
6de9cd9a 1084 {
504ed63a
TB
1085 case BT_REAL:
1086 if (mpfr_cmp_si (x->value.real, 1) > 0
1087 || mpfr_cmp_si (x->value.real, -1) < 0)
1088 {
1089 gfc_error ("Argument of ASIN at %L must be between -1 and 1",
1090 &x->where);
1091 return &gfc_bad_expr;
1092 }
b7e75771 1093 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
504ed63a
TB
1094 mpfr_asin (result->value.real, x->value.real, GFC_RND_MODE);
1095 break;
b7e75771 1096
504ed63a 1097 case BT_COMPLEX:
b7e75771 1098 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
8e70c271
KG
1099 mpc_asin (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
1100 break;
b7e75771 1101
504ed63a 1102 default:
67749498 1103 gfc_internal_error ("in gfc_simplify_asin(): Bad type");
6de9cd9a
DN
1104 }
1105
6de9cd9a
DN
1106 return range_check (result, "ASIN");
1107}
1108
1109
57391dda
FR
1110/* Convert radians to degrees, i.e., x * 180 / pi. */
1111
1112static void
1113rad2deg (mpfr_t x)
1114{
1115 mpfr_t tmp;
1116
1117 mpfr_init (tmp);
1118 mpfr_const_pi (tmp, GFC_RND_MODE);
1119 mpfr_mul_ui (x, x, 180, GFC_RND_MODE);
1120 mpfr_div (x, x, tmp, GFC_RND_MODE);
1121 mpfr_clear (tmp);
1122}
1123
1124
1125/* Simplify ACOSD(X) where the returned value has units of degree. */
1126
1127gfc_expr *
1128gfc_simplify_acosd (gfc_expr *x)
1129{
1130 gfc_expr *result;
1131
1132 if (x->expr_type != EXPR_CONSTANT)
1133 return NULL;
1134
1135 if (mpfr_cmp_si (x->value.real, 1) > 0
1136 || mpfr_cmp_si (x->value.real, -1) < 0)
1137 {
1138 gfc_error ("Argument of ACOSD at %L must be between -1 and 1",
1139 &x->where);
1140 return &gfc_bad_expr;
1141 }
1142
1143 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
1144 mpfr_acos (result->value.real, x->value.real, GFC_RND_MODE);
1145 rad2deg (result->value.real);
1146
1147 return range_check (result, "ACOSD");
1148}
1149
1150
1151/* Simplify asind (x) where the returned value has units of degree. */
1152
1153gfc_expr *
1154gfc_simplify_asind (gfc_expr *x)
1155{
1156 gfc_expr *result;
1157
1158 if (x->expr_type != EXPR_CONSTANT)
1159 return NULL;
1160
1161 if (mpfr_cmp_si (x->value.real, 1) > 0
1162 || mpfr_cmp_si (x->value.real, -1) < 0)
1163 {
1164 gfc_error ("Argument of ASIND at %L must be between -1 and 1",
1165 &x->where);
1166 return &gfc_bad_expr;
1167 }
1168
1169 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
1170 mpfr_asin (result->value.real, x->value.real, GFC_RND_MODE);
1171 rad2deg (result->value.real);
1172
1173 return range_check (result, "ASIND");
1174}
1175
1176
1177/* Simplify atand (x) where the returned value has units of degree. */
1178
1179gfc_expr *
1180gfc_simplify_atand (gfc_expr *x)
1181{
1182 gfc_expr *result;
1183
1184 if (x->expr_type != EXPR_CONSTANT)
1185 return NULL;
1186
1187 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
1188 mpfr_atan (result->value.real, x->value.real, GFC_RND_MODE);
1189 rad2deg (result->value.real);
1190
1191 return range_check (result, "ATAND");
1192}
1193
1194
6de9cd9a 1195gfc_expr *
edf1eac2 1196gfc_simplify_asinh (gfc_expr *x)
6de9cd9a
DN
1197{
1198 gfc_expr *result;
1199
1200 if (x->expr_type != EXPR_CONSTANT)
1201 return NULL;
1202
b7e75771
JD
1203 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
1204
504ed63a
TB
1205 switch (x->ts.type)
1206 {
1207 case BT_REAL:
504ed63a
TB
1208 mpfr_asinh (result->value.real, x->value.real, GFC_RND_MODE);
1209 break;
b7e75771 1210
504ed63a 1211 case BT_COMPLEX:
8e70c271
KG
1212 mpc_asinh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
1213 break;
b7e75771 1214
504ed63a 1215 default:
67749498 1216 gfc_internal_error ("in gfc_simplify_asinh(): Bad type");
504ed63a 1217 }
1e399e23
JD
1218
1219 return range_check (result, "ASINH");
1220}
1221
1222
1223gfc_expr *
edf1eac2 1224gfc_simplify_atan (gfc_expr *x)
1e399e23
JD
1225{
1226 gfc_expr *result;
1227
1228 if (x->expr_type != EXPR_CONSTANT)
1229 return NULL;
b7e75771
JD
1230
1231 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
1232
504ed63a
TB
1233 switch (x->ts.type)
1234 {
1235 case BT_REAL:
504ed63a
TB
1236 mpfr_atan (result->value.real, x->value.real, GFC_RND_MODE);
1237 break;
b7e75771 1238
504ed63a 1239 case BT_COMPLEX:
8e70c271
KG
1240 mpc_atan (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
1241 break;
b7e75771 1242
504ed63a 1243 default:
67749498 1244 gfc_internal_error ("in gfc_simplify_atan(): Bad type");
504ed63a 1245 }
6de9cd9a
DN
1246
1247 return range_check (result, "ATAN");
1e399e23
JD
1248}
1249
1250
1251gfc_expr *
edf1eac2 1252gfc_simplify_atanh (gfc_expr *x)
1e399e23
JD
1253{
1254 gfc_expr *result;
6de9cd9a 1255
1e399e23
JD
1256 if (x->expr_type != EXPR_CONSTANT)
1257 return NULL;
1258
504ed63a 1259 switch (x->ts.type)
1e399e23 1260 {
504ed63a
TB
1261 case BT_REAL:
1262 if (mpfr_cmp_si (x->value.real, 1) >= 0
1263 || mpfr_cmp_si (x->value.real, -1) <= 0)
1264 {
1265 gfc_error ("Argument of ATANH at %L must be inside the range -1 "
1266 "to 1", &x->where);
1267 return &gfc_bad_expr;
1268 }
b7e75771 1269 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
504ed63a
TB
1270 mpfr_atanh (result->value.real, x->value.real, GFC_RND_MODE);
1271 break;
b7e75771 1272
504ed63a 1273 case BT_COMPLEX:
b7e75771 1274 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
8e70c271
KG
1275 mpc_atanh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
1276 break;
b7e75771 1277
504ed63a 1278 default:
67749498 1279 gfc_internal_error ("in gfc_simplify_atanh(): Bad type");
504ed63a 1280 }
1e399e23
JD
1281
1282 return range_check (result, "ATANH");
6de9cd9a
DN
1283}
1284
1285
1286gfc_expr *
edf1eac2 1287gfc_simplify_atan2 (gfc_expr *y, gfc_expr *x)
6de9cd9a
DN
1288{
1289 gfc_expr *result;
1290
1291 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
1292 return NULL;
1293
d2af8cc6 1294 if (mpfr_zero_p (y->value.real) && mpfr_zero_p (x->value.real))
6de9cd9a 1295 {
57391dda
FR
1296 gfc_error ("If first argument of ATAN2 at %L is zero, then the "
1297 "second argument must not be zero", &y->where);
6de9cd9a
DN
1298 return &gfc_bad_expr;
1299 }
1300
b7e75771 1301 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
e48d66a9 1302 mpfr_atan2 (result->value.real, y->value.real, x->value.real, GFC_RND_MODE);
6de9cd9a
DN
1303
1304 return range_check (result, "ATAN2");
6de9cd9a
DN
1305}
1306
1307
3c3f4265 1308gfc_expr *
b7e75771 1309gfc_simplify_bessel_j0 (gfc_expr *x)
3c3f4265 1310{
3c3f4265
TB
1311 gfc_expr *result;
1312
1313 if (x->expr_type != EXPR_CONSTANT)
1314 return NULL;
1315
b7e75771 1316 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
3c3f4265
TB
1317 mpfr_j0 (result->value.real, x->value.real, GFC_RND_MODE);
1318
1319 return range_check (result, "BESSEL_J0");
3c3f4265
TB
1320}
1321
1322
1323gfc_expr *
b7e75771 1324gfc_simplify_bessel_j1 (gfc_expr *x)
3c3f4265 1325{
3c3f4265
TB
1326 gfc_expr *result;
1327
1328 if (x->expr_type != EXPR_CONSTANT)
1329 return NULL;
1330
b7e75771 1331 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
3c3f4265
TB
1332 mpfr_j1 (result->value.real, x->value.real, GFC_RND_MODE);
1333
1334 return range_check (result, "BESSEL_J1");
3c3f4265
TB
1335}
1336
1337
1338gfc_expr *
b7e75771 1339gfc_simplify_bessel_jn (gfc_expr *order, gfc_expr *x)
3c3f4265 1340{
3c3f4265
TB
1341 gfc_expr *result;
1342 long n;
1343
1344 if (x->expr_type != EXPR_CONSTANT || order->expr_type != EXPR_CONSTANT)
1345 return NULL;
1346
1347 n = mpz_get_si (order->value.integer);
b7e75771 1348 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
3c3f4265
TB
1349 mpfr_jn (result->value.real, n, x->value.real, GFC_RND_MODE);
1350
1351 return range_check (result, "BESSEL_JN");
3c3f4265
TB
1352}
1353
1354
29698e0f
TB
1355/* Simplify transformational form of JN and YN. */
1356
1357static gfc_expr *
1358gfc_simplify_bessel_n2 (gfc_expr *order1, gfc_expr *order2, gfc_expr *x,
1359 bool jn)
1360{
1361 gfc_expr *result;
1362 gfc_expr *e;
1363 long n1, n2;
1364 int i;
1365 mpfr_t x2rev, last1, last2;
1366
1367 if (x->expr_type != EXPR_CONSTANT || order1->expr_type != EXPR_CONSTANT
1368 || order2->expr_type != EXPR_CONSTANT)
47b99694 1369 return NULL;
29698e0f
TB
1370
1371 n1 = mpz_get_si (order1->value.integer);
1372 n2 = mpz_get_si (order2->value.integer);
1373 result = gfc_get_array_expr (x->ts.type, x->ts.kind, &x->where);
1374 result->rank = 1;
1375 result->shape = gfc_get_shape (1);
1376 mpz_init_set_ui (result->shape[0], MAX (n2-n1+1, 0));
1377
1378 if (n2 < n1)
1379 return result;
1380
1381 /* Special case: x == 0; it is J0(0.0) == 1, JN(N > 0, 0.0) == 0; and
1382 YN(N, 0.0) = -Inf. */
1383
1384 if (mpfr_cmp_ui (x->value.real, 0.0) == 0)
1385 {
c61819ff 1386 if (!jn && flag_range_check)
29698e0f
TB
1387 {
1388 gfc_error ("Result of BESSEL_YN is -INF at %L", &result->where);
1389 gfc_free_expr (result);
1390 return &gfc_bad_expr;
1391 }
1392
1393 if (jn && n1 == 0)
1394 {
1395 e = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
4c6e913c 1396 mpfr_set_ui (e->value.real, 1, GFC_RND_MODE);
29698e0f
TB
1397 gfc_constructor_append_expr (&result->value.constructor, e,
1398 &x->where);
1399 n1++;
1400 }
1401
1402 for (i = n1; i <= n2; i++)
1403 {
1404 e = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
1405 if (jn)
4c6e913c 1406 mpfr_set_ui (e->value.real, 0, GFC_RND_MODE);
29698e0f 1407 else
47b99694 1408 mpfr_set_inf (e->value.real, -1);
29698e0f
TB
1409 gfc_constructor_append_expr (&result->value.constructor, e,
1410 &x->where);
1411 }
1412
1413 return result;
1414 }
1415
d76799c7 1416 /* Use the faster but more verbose recurrence algorithm. Bessel functions
29698e0f
TB
1417 are stable for downward recursion and Neumann functions are stable
1418 for upward recursion. It is
1419 x2rev = 2.0/x,
1420 J(N-1, x) = x2rev * N * J(N, x) - J(N+1, x),
1421 Y(N+1, x) = x2rev * N * Y(N, x) - Y(N-1, x).
1422 Cf. http://dlmf.nist.gov/10.74#iv and http://dlmf.nist.gov/10.6#E1 */
1423
1424 gfc_set_model_kind (x->ts.kind);
1425
1426 /* Get first recursion anchor. */
1427
1428 mpfr_init (last1);
1429 if (jn)
1430 mpfr_jn (last1, n2, x->value.real, GFC_RND_MODE);
1431 else
1432 mpfr_yn (last1, n1, x->value.real, GFC_RND_MODE);
1433
1434 e = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
1435 mpfr_set (e->value.real, last1, GFC_RND_MODE);
1436 if (range_check (e, jn ? "BESSEL_JN" : "BESSEL_YN") == &gfc_bad_expr)
1437 {
1438 mpfr_clear (last1);
1439 gfc_free_expr (e);
1440 gfc_free_expr (result);
1441 return &gfc_bad_expr;
1442 }
1443 gfc_constructor_append_expr (&result->value.constructor, e, &x->where);
1444
1445 if (n1 == n2)
1446 {
1447 mpfr_clear (last1);
1448 return result;
1449 }
8b704316 1450
29698e0f
TB
1451 /* Get second recursion anchor. */
1452
1453 mpfr_init (last2);
1454 if (jn)
1455 mpfr_jn (last2, n2-1, x->value.real, GFC_RND_MODE);
1456 else
1457 mpfr_yn (last2, n1+1, x->value.real, GFC_RND_MODE);
1458
1459 e = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
1460 mpfr_set (e->value.real, last2, GFC_RND_MODE);
1461 if (range_check (e, jn ? "BESSEL_JN" : "BESSEL_YN") == &gfc_bad_expr)
1462 {
1463 mpfr_clear (last1);
1464 mpfr_clear (last2);
1465 gfc_free_expr (e);
1466 gfc_free_expr (result);
1467 return &gfc_bad_expr;
1468 }
1469 if (jn)
4c6e913c 1470 gfc_constructor_insert_expr (&result->value.constructor, e, &x->where, -2);
8b704316 1471 else
29698e0f
TB
1472 gfc_constructor_append_expr (&result->value.constructor, e, &x->where);
1473
1474 if (n1 + 1 == n2)
1475 {
1476 mpfr_clear (last1);
1477 mpfr_clear (last2);
1478 return result;
1479 }
1480
1481 /* Start actual recursion. */
1482
1483 mpfr_init (x2rev);
1484 mpfr_ui_div (x2rev, 2, x->value.real, GFC_RND_MODE);
8b704316 1485
29698e0f
TB
1486 for (i = 2; i <= n2-n1; i++)
1487 {
1488 e = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
47b99694
TB
1489
1490 /* Special case: For YN, if the previous N gave -INF, set
1491 also N+1 to -INF. */
c61819ff 1492 if (!jn && !flag_range_check && mpfr_inf_p (last2))
47b99694
TB
1493 {
1494 mpfr_set_inf (e->value.real, -1);
1495 gfc_constructor_append_expr (&result->value.constructor, e,
1496 &x->where);
1497 continue;
1498 }
1499
29698e0f
TB
1500 mpfr_mul_si (e->value.real, x2rev, jn ? (n2-i+1) : (n1+i-1),
1501 GFC_RND_MODE);
1502 mpfr_mul (e->value.real, e->value.real, last2, GFC_RND_MODE);
1503 mpfr_sub (e->value.real, e->value.real, last1, GFC_RND_MODE);
1504
1505 if (range_check (e, jn ? "BESSEL_JN" : "BESSEL_YN") == &gfc_bad_expr)
fd2805e1
TB
1506 {
1507 /* Range_check frees "e" in that case. */
1508 e = NULL;
1509 goto error;
1510 }
29698e0f
TB
1511
1512 if (jn)
1513 gfc_constructor_insert_expr (&result->value.constructor, e, &x->where,
1514 -i-1);
1515 else
1516 gfc_constructor_append_expr (&result->value.constructor, e, &x->where);
1517
1518 mpfr_set (last1, last2, GFC_RND_MODE);
1519 mpfr_set (last2, e->value.real, GFC_RND_MODE);
1520 }
1521
1522 mpfr_clear (last1);
1523 mpfr_clear (last2);
1524 mpfr_clear (x2rev);
1525 return result;
1526
1527error:
1528 mpfr_clear (last1);
1529 mpfr_clear (last2);
1530 mpfr_clear (x2rev);
1531 gfc_free_expr (e);
1532 gfc_free_expr (result);
1533 return &gfc_bad_expr;
1534}
1535
1536
1537gfc_expr *
1538gfc_simplify_bessel_jn2 (gfc_expr *order1, gfc_expr *order2, gfc_expr *x)
1539{
1540 return gfc_simplify_bessel_n2 (order1, order2, x, true);
1541}
1542
1543
3c3f4265 1544gfc_expr *
b7e75771 1545gfc_simplify_bessel_y0 (gfc_expr *x)
3c3f4265 1546{
3c3f4265
TB
1547 gfc_expr *result;
1548
1549 if (x->expr_type != EXPR_CONSTANT)
1550 return NULL;
1551
b7e75771 1552 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
3c3f4265
TB
1553 mpfr_y0 (result->value.real, x->value.real, GFC_RND_MODE);
1554
1555 return range_check (result, "BESSEL_Y0");
3c3f4265
TB
1556}
1557
1558
1559gfc_expr *
b7e75771 1560gfc_simplify_bessel_y1 (gfc_expr *x)
3c3f4265 1561{
3c3f4265
TB
1562 gfc_expr *result;
1563
1564 if (x->expr_type != EXPR_CONSTANT)
1565 return NULL;
1566
b7e75771 1567 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
3c3f4265
TB
1568 mpfr_y1 (result->value.real, x->value.real, GFC_RND_MODE);
1569
1570 return range_check (result, "BESSEL_Y1");
3c3f4265
TB
1571}
1572
1573
1574gfc_expr *
b7e75771 1575gfc_simplify_bessel_yn (gfc_expr *order, gfc_expr *x)
3c3f4265 1576{
3c3f4265
TB
1577 gfc_expr *result;
1578 long n;
1579
1580 if (x->expr_type != EXPR_CONSTANT || order->expr_type != EXPR_CONSTANT)
1581 return NULL;
1582
1583 n = mpz_get_si (order->value.integer);
b7e75771 1584 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
3c3f4265
TB
1585 mpfr_yn (result->value.real, n, x->value.real, GFC_RND_MODE);
1586
1587 return range_check (result, "BESSEL_YN");
3c3f4265
TB
1588}
1589
1590
29698e0f
TB
1591gfc_expr *
1592gfc_simplify_bessel_yn2 (gfc_expr *order1, gfc_expr *order2, gfc_expr *x)
1593{
1594 return gfc_simplify_bessel_n2 (order1, order2, x, false);
1595}
1596
1597
6de9cd9a 1598gfc_expr *
edf1eac2 1599gfc_simplify_bit_size (gfc_expr *e)
6de9cd9a 1600{
b7e75771
JD
1601 int i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
1602 return gfc_get_int_expr (e->ts.kind, &e->where,
1603 gfc_integer_kinds[i].bit_size);
6de9cd9a
DN
1604}
1605
1606
1607gfc_expr *
edf1eac2 1608gfc_simplify_btest (gfc_expr *e, gfc_expr *bit)
6de9cd9a
DN
1609{
1610 int b;
1611
1612 if (e->expr_type != EXPR_CONSTANT || bit->expr_type != EXPR_CONSTANT)
1613 return NULL;
1614
51f03c6b 1615 if (gfc_extract_int (bit, &b) || b < 0)
b7e75771 1616 return gfc_get_logical_expr (gfc_default_logical_kind, &e->where, false);
6de9cd9a 1617
b7e75771
JD
1618 return gfc_get_logical_expr (gfc_default_logical_kind, &e->where,
1619 mpz_tstbit (e->value.integer, b));
6de9cd9a
DN
1620}
1621
1622
88a95a11
FXC
1623static int
1624compare_bitwise (gfc_expr *i, gfc_expr *j)
1625{
1626 mpz_t x, y;
1627 int k, res;
1628
1629 gcc_assert (i->ts.type == BT_INTEGER);
1630 gcc_assert (j->ts.type == BT_INTEGER);
1631
1632 mpz_init_set (x, i->value.integer);
1633 k = gfc_validate_kind (i->ts.type, i->ts.kind, false);
1634 convert_mpz_to_unsigned (x, gfc_integer_kinds[k].bit_size);
1635
1636 mpz_init_set (y, j->value.integer);
1637 k = gfc_validate_kind (j->ts.type, j->ts.kind, false);
1638 convert_mpz_to_unsigned (y, gfc_integer_kinds[k].bit_size);
1639
1640 res = mpz_cmp (x, y);
1641 mpz_clear (x);
1642 mpz_clear (y);
1643 return res;
1644}
1645
1646
1647gfc_expr *
1648gfc_simplify_bge (gfc_expr *i, gfc_expr *j)
1649{
1650 if (i->expr_type != EXPR_CONSTANT || j->expr_type != EXPR_CONSTANT)
1651 return NULL;
1652
1653 return gfc_get_logical_expr (gfc_default_logical_kind, &i->where,
1654 compare_bitwise (i, j) >= 0);
1655}
1656
1657
1658gfc_expr *
1659gfc_simplify_bgt (gfc_expr *i, gfc_expr *j)
1660{
1661 if (i->expr_type != EXPR_CONSTANT || j->expr_type != EXPR_CONSTANT)
1662 return NULL;
1663
1664 return gfc_get_logical_expr (gfc_default_logical_kind, &i->where,
1665 compare_bitwise (i, j) > 0);
1666}
1667
1668
1669gfc_expr *
1670gfc_simplify_ble (gfc_expr *i, gfc_expr *j)
1671{
1672 if (i->expr_type != EXPR_CONSTANT || j->expr_type != EXPR_CONSTANT)
1673 return NULL;
1674
1675 return gfc_get_logical_expr (gfc_default_logical_kind, &i->where,
1676 compare_bitwise (i, j) <= 0);
1677}
1678
1679
1680gfc_expr *
1681gfc_simplify_blt (gfc_expr *i, gfc_expr *j)
1682{
1683 if (i->expr_type != EXPR_CONSTANT || j->expr_type != EXPR_CONSTANT)
1684 return NULL;
1685
1686 return gfc_get_logical_expr (gfc_default_logical_kind, &i->where,
1687 compare_bitwise (i, j) < 0);
1688}
1689
1690
6de9cd9a 1691gfc_expr *
edf1eac2 1692gfc_simplify_ceiling (gfc_expr *e, gfc_expr *k)
6de9cd9a
DN
1693{
1694 gfc_expr *ceil, *result;
1695 int kind;
1696
145cf79b 1697 kind = get_kind (BT_INTEGER, k, "CEILING", gfc_default_integer_kind);
6de9cd9a
DN
1698 if (kind == -1)
1699 return &gfc_bad_expr;
1700
1701 if (e->expr_type != EXPR_CONSTANT)
1702 return NULL;
1703
6de9cd9a 1704 ceil = gfc_copy_expr (e);
f8e566e5 1705 mpfr_ceil (ceil->value.real, e->value.real);
b7e75771
JD
1706
1707 result = gfc_get_constant_expr (BT_INTEGER, kind, &e->where);
7278e4dc 1708 gfc_mpfr_to_mpz (result->value.integer, ceil->value.real, &e->where);
6de9cd9a
DN
1709
1710 gfc_free_expr (ceil);
1711
1712 return range_check (result, "CEILING");
1713}
1714
1715
1716gfc_expr *
edf1eac2 1717gfc_simplify_char (gfc_expr *e, gfc_expr *k)
6de9cd9a 1718{
d393bbd7 1719 return simplify_achar_char (e, k, "CHAR", false);
6de9cd9a
DN
1720}
1721
1722
b7e75771 1723/* Common subroutine for simplifying CMPLX, COMPLEX and DCMPLX. */
6de9cd9a
DN
1724
1725static gfc_expr *
edf1eac2 1726simplify_cmplx (const char *name, gfc_expr *x, gfc_expr *y, int kind)
6de9cd9a
DN
1727{
1728 gfc_expr *result;
1729
b7e75771
JD
1730 if (x->expr_type != EXPR_CONSTANT
1731 || (y != NULL && y->expr_type != EXPR_CONSTANT))
1732 return NULL;
1733
1734 result = gfc_get_constant_expr (BT_COMPLEX, kind, &x->where);
6de9cd9a 1735
6de9cd9a
DN
1736 switch (x->ts.type)
1737 {
b7e75771 1738 case BT_INTEGER:
eb6f9a86 1739 mpc_set_z (result->value.complex, x->value.integer, GFC_MPC_RND_MODE);
b7e75771 1740 break;
6de9cd9a 1741
b7e75771
JD
1742 case BT_REAL:
1743 mpc_set_fr (result->value.complex, x->value.real, GFC_RND_MODE);
1744 break;
6de9cd9a 1745
b7e75771
JD
1746 case BT_COMPLEX:
1747 mpc_set (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
1748 break;
6de9cd9a 1749
b7e75771
JD
1750 default:
1751 gfc_internal_error ("gfc_simplify_dcmplx(): Bad type (x)");
6de9cd9a
DN
1752 }
1753
b7e75771
JD
1754 if (!y)
1755 return range_check (result, name);
6de9cd9a 1756
b7e75771 1757 switch (y->ts.type)
00a4618b 1758 {
b7e75771
JD
1759 case BT_INTEGER:
1760 mpfr_set_z (mpc_imagref (result->value.complex),
1761 y->value.integer, GFC_RND_MODE);
1762 break;
00a4618b 1763
b7e75771
JD
1764 case BT_REAL:
1765 mpfr_set (mpc_imagref (result->value.complex),
1766 y->value.real, GFC_RND_MODE);
1767 break;
1768
1769 default:
1770 gfc_internal_error ("gfc_simplify_dcmplx(): Bad type (y)");
00a4618b
TB
1771 }
1772
6de9cd9a
DN
1773 return range_check (result, name);
1774}
1775
1776
1777gfc_expr *
edf1eac2 1778gfc_simplify_cmplx (gfc_expr *x, gfc_expr *y, gfc_expr *k)
6de9cd9a
DN
1779{
1780 int kind;
1781
b7e75771 1782 kind = get_kind (BT_REAL, k, "CMPLX", gfc_default_complex_kind);
6de9cd9a
DN
1783 if (kind == -1)
1784 return &gfc_bad_expr;
1785
1786 return simplify_cmplx ("CMPLX", x, y, kind);
1787}
1788
1789
5d723e54 1790gfc_expr *
edf1eac2 1791gfc_simplify_complex (gfc_expr *x, gfc_expr *y)
5d723e54
FXC
1792{
1793 int kind;
1794
b7e75771
JD
1795 if (x->ts.type == BT_INTEGER && y->ts.type == BT_INTEGER)
1796 kind = gfc_default_complex_kind;
1797 else if (x->ts.type == BT_REAL || y->ts.type == BT_INTEGER)
1798 kind = x->ts.kind;
1799 else if (x->ts.type == BT_INTEGER || y->ts.type == BT_REAL)
1800 kind = y->ts.kind;
1801 else if (x->ts.type == BT_REAL && y->ts.type == BT_REAL)
1802 kind = (x->ts.kind > y->ts.kind) ? x->ts.kind : y->ts.kind;
5d723e54 1803 else
b7e75771 1804 gcc_unreachable ();
6401bf9c 1805
5d723e54
FXC
1806 return simplify_cmplx ("COMPLEX", x, y, kind);
1807}
1808
1809
6de9cd9a 1810gfc_expr *
edf1eac2 1811gfc_simplify_conjg (gfc_expr *e)
6de9cd9a
DN
1812{
1813 gfc_expr *result;
1814
1815 if (e->expr_type != EXPR_CONSTANT)
1816 return NULL;
1817
1818 result = gfc_copy_expr (e);
eb6f9a86 1819 mpc_conj (result->value.complex, result->value.complex, GFC_MPC_RND_MODE);
b7e75771 1820
6de9cd9a
DN
1821 return range_check (result, "CONJG");
1822}
1823
8e8c2744 1824
57391dda
FR
1825/* Simplify atan2d (x) where the unit is degree. */
1826
1827gfc_expr *
1828gfc_simplify_atan2d (gfc_expr *y, gfc_expr *x)
1829{
1830 gfc_expr *result;
1831
1832 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
1833 return NULL;
1834
1835 if (mpfr_zero_p (y->value.real) && mpfr_zero_p (x->value.real))
1836 {
1837 gfc_error ("If first argument of ATAN2D at %L is zero, then the "
1838 "second argument must not be zero", &y->where);
1839 return &gfc_bad_expr;
0a4613f0 1840 }
57391dda
FR
1841
1842 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
1843 mpfr_atan2 (result->value.real, y->value.real, x->value.real, GFC_RND_MODE);
1844 rad2deg (result->value.real);
1845
1846 return range_check (result, "ATAN2D");
8e8c2744
FR
1847}
1848
8e8c2744 1849
57391dda
FR
1850gfc_expr *
1851gfc_simplify_cos (gfc_expr *x)
8e8c2744 1852{
57391dda 1853 gfc_expr *result;
8e8c2744 1854
57391dda
FR
1855 if (x->expr_type != EXPR_CONSTANT)
1856 return NULL;
8e8c2744 1857
57391dda 1858 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
8e8c2744 1859
57391dda
FR
1860 switch (x->ts.type)
1861 {
1862 case BT_REAL:
1863 mpfr_cos (result->value.real, x->value.real, GFC_RND_MODE);
1864 break;
1865
1866 case BT_COMPLEX:
1867 gfc_set_model_kind (x->ts.kind);
1868 mpc_cos (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
1869 break;
1870
1871 default:
1872 gfc_internal_error ("in gfc_simplify_cos(): Bad type");
1873 }
1874
1875 return range_check (result, "COS");
8e8c2744
FR
1876}
1877
8e8c2744
FR
1878
1879static void
57391dda 1880deg2rad (mpfr_t x)
8e8c2744 1881{
57391dda 1882 mpfr_t d2r;
8e8c2744 1883
57391dda
FR
1884 mpfr_init (d2r);
1885 mpfr_const_pi (d2r, GFC_RND_MODE);
1886 mpfr_div_ui (d2r, d2r, 180, GFC_RND_MODE);
1887 mpfr_mul (x, x, d2r, GFC_RND_MODE);
1888 mpfr_clear (d2r);
1889}
8e8c2744 1890
8e8c2744 1891
57391dda
FR
1892/* Simplification routines for SIND, COSD, TAND. */
1893#include "trigd_fe.inc"
8e8c2744
FR
1894
1895
57391dda 1896/* Simplify COSD(X) where X has the unit of degree. */
8e8c2744
FR
1897
1898gfc_expr *
57391dda 1899gfc_simplify_cosd (gfc_expr *x)
8e8c2744 1900{
57391dda 1901 gfc_expr *result;
8e8c2744 1902
57391dda
FR
1903 if (x->expr_type != EXPR_CONSTANT)
1904 return NULL;
8e8c2744 1905
57391dda
FR
1906 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
1907 mpfr_set (result->value.real, x->value.real, GFC_RND_MODE);
1908 simplify_cosd (result->value.real);
8e8c2744 1909
57391dda 1910 return range_check (result, "COSD");
8e8c2744
FR
1911}
1912
57391dda
FR
1913
1914/* Simplify SIND(X) where X has the unit of degree. */
8e8c2744
FR
1915
1916gfc_expr *
57391dda 1917gfc_simplify_sind (gfc_expr *x)
8e8c2744
FR
1918{
1919 gfc_expr *result;
1920
57391dda
FR
1921 if (x->expr_type != EXPR_CONSTANT)
1922 return NULL;
8e8c2744 1923
57391dda
FR
1924 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
1925 mpfr_set (result->value.real, x->value.real, GFC_RND_MODE);
1926 simplify_sind (result->value.real);
8e8c2744 1927
57391dda 1928 return range_check (result, "SIND");
8e8c2744
FR
1929}
1930
57391dda
FR
1931
1932/* Simplify TAND(X) where X has the unit of degree. */
8e8c2744
FR
1933
1934gfc_expr *
57391dda 1935gfc_simplify_tand (gfc_expr *x)
8e8c2744
FR
1936{
1937 gfc_expr *result;
1938
57391dda
FR
1939 if (x->expr_type != EXPR_CONSTANT)
1940 return NULL;
8e8c2744 1941
57391dda
FR
1942 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
1943 mpfr_set (result->value.real, x->value.real, GFC_RND_MODE);
1944 simplify_tand (result->value.real);
8e8c2744 1945
57391dda 1946 return range_check (result, "TAND");
8e8c2744 1947}
6de9cd9a 1948
57391dda
FR
1949
1950/* Simplify COTAND(X) where X has the unit of degree. */
1951
6de9cd9a 1952gfc_expr *
57391dda 1953gfc_simplify_cotand (gfc_expr *x)
6de9cd9a
DN
1954{
1955 gfc_expr *result;
6de9cd9a
DN
1956
1957 if (x->expr_type != EXPR_CONSTANT)
1958 return NULL;
1959
57391dda
FR
1960 /* Implement COTAND = -TAND(x+90).
1961 TAND offers correct exact values for multiples of 30 degrees.
1962 This implementation is also compatible with the behavior of some legacy
1963 compilers. Keep this consistent with gfc_conv_intrinsic_cotand. */
b7e75771 1964 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
57391dda
FR
1965 mpfr_set (result->value.real, x->value.real, GFC_RND_MODE);
1966 mpfr_add_ui (result->value.real, result->value.real, 90, GFC_RND_MODE);
1967 simplify_tand (result->value.real);
1968 mpfr_neg (result->value.real, result->value.real, GFC_RND_MODE);
6de9cd9a 1969
57391dda 1970 return range_check (result, "COTAND");
6de9cd9a
DN
1971}
1972
1973
1974gfc_expr *
edf1eac2 1975gfc_simplify_cosh (gfc_expr *x)
6de9cd9a
DN
1976{
1977 gfc_expr *result;
1978
1979 if (x->expr_type != EXPR_CONSTANT)
1980 return NULL;
1981
b7e75771 1982 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
6de9cd9a 1983
b7e75771
JD
1984 switch (x->ts.type)
1985 {
1986 case BT_REAL:
1987 mpfr_cosh (result->value.real, x->value.real, GFC_RND_MODE);
1988 break;
1989
1990 case BT_COMPLEX:
1991 mpc_cosh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
1992 break;
8b704316 1993
b7e75771
JD
1994 default:
1995 gcc_unreachable ();
1996 }
6de9cd9a
DN
1997
1998 return range_check (result, "COSH");
1999}
2000
2001
a16d978f
DF
2002gfc_expr *
2003gfc_simplify_count (gfc_expr *mask, gfc_expr *dim, gfc_expr *kind)
2004{
2005 gfc_expr *result;
6f76317a 2006 bool size_zero;
a16d978f 2007
6f76317a 2008 size_zero = gfc_is_size_zero_array (mask);
94e6b5e5 2009
6f76317a 2010 if (!(is_constant_array_expr (mask) || size_zero)
a16d978f
DF
2011 || !gfc_is_constant_expr (dim)
2012 || !gfc_is_constant_expr (kind))
2013 return NULL;
2014
2015 result = transformational_result (mask, dim,
2016 BT_INTEGER,
2017 get_kind (BT_INTEGER, kind, "COUNT",
2018 gfc_default_integer_kind),
2019 &mask->where);
2020
2021 init_result_expr (result, 0, NULL);
2022
6f76317a
TK
2023 if (size_zero)
2024 return result;
2025
a16d978f
DF
2026 /* Passing MASK twice, once as data array, once as mask.
2027 Whenever gfc_count is called, '1' is added to the result. */
2028 return !dim || mask->rank == 1 ?
2029 simplify_transformation_to_scalar (result, mask, mask, gfc_count) :
0cd0559e 2030 simplify_transformation_to_array (result, mask, dim, mask, gfc_count, NULL);
a16d978f
DF
2031}
2032
a9ec0cfc
TK
2033/* Simplification routine for cshift. This works by copying the array
2034 expressions into a one-dimensional array, shuffling the values into another
2035 one-dimensional array and creating the new array expression from this. The
2036 shuffling part is basically taken from the library routine. */
a16d978f 2037
b1c1d761
SK
2038gfc_expr *
2039gfc_simplify_cshift (gfc_expr *array, gfc_expr *shift, gfc_expr *dim)
2040{
a9ec0cfc
TK
2041 gfc_expr *result;
2042 int which;
2043 gfc_expr **arrayvec, **resultvec;
2044 gfc_expr **rptr, **sptr;
2045 mpz_t size;
2046 size_t arraysize, shiftsize, i;
2047 gfc_constructor *array_ctor, *shift_ctor;
2048 ssize_t *shiftvec, *hptr;
2049 ssize_t shift_val, len;
2050 ssize_t count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS],
f64b9ed9 2051 hs_ex[GFC_MAX_DIMENSIONS + 1],
a9ec0cfc
TK
2052 hstride[GFC_MAX_DIMENSIONS], sstride[GFC_MAX_DIMENSIONS],
2053 a_extent[GFC_MAX_DIMENSIONS], a_stride[GFC_MAX_DIMENSIONS],
2054 h_extent[GFC_MAX_DIMENSIONS],
f64b9ed9 2055 ss_ex[GFC_MAX_DIMENSIONS + 1];
a9ec0cfc
TK
2056 ssize_t rsoffset;
2057 int d, n;
2058 bool continue_loop;
2059 gfc_expr **src, **dest;
2060
2061 if (!is_constant_array_expr (array))
2062 return NULL;
b1c1d761 2063
a9ec0cfc
TK
2064 if (shift->rank > 0)
2065 gfc_simplify_expr (shift, 1);
2066
2067 if (!gfc_is_constant_expr (shift))
2068 return NULL;
2069
2070 /* Make dim zero-based. */
b1c1d761
SK
2071 if (dim)
2072 {
2073 if (!gfc_is_constant_expr (dim))
2074 return NULL;
a9ec0cfc 2075 which = mpz_get_si (dim->value.integer) - 1;
b1c1d761
SK
2076 }
2077 else
a9ec0cfc 2078 which = 0;
b1c1d761 2079
a9ec0cfc
TK
2080 gfc_array_size (array, &size);
2081 arraysize = mpz_get_ui (size);
2082 mpz_clear (size);
b1c1d761 2083
a9ec0cfc
TK
2084 result = gfc_get_array_expr (array->ts.type, array->ts.kind, &array->where);
2085 result->shape = gfc_copy_shape (array->shape, array->rank);
2086 result->rank = array->rank;
2087 result->ts.u.derived = array->ts.u.derived;
b1c1d761 2088
a9ec0cfc
TK
2089 if (arraysize == 0)
2090 return result;
b1c1d761 2091
a9ec0cfc
TK
2092 arrayvec = XCNEWVEC (gfc_expr *, arraysize);
2093 array_ctor = gfc_constructor_first (array->value.constructor);
2094 for (i = 0; i < arraysize; i++)
2095 {
2096 arrayvec[i] = array_ctor->expr;
2097 array_ctor = gfc_constructor_next (array_ctor);
2098 }
b1c1d761 2099
a9ec0cfc 2100 resultvec = XCNEWVEC (gfc_expr *, arraysize);
b1c1d761 2101
a9ec0cfc
TK
2102 extent[0] = 1;
2103 count[0] = 0;
b1c1d761 2104
a9ec0cfc
TK
2105 for (d=0; d < array->rank; d++)
2106 {
2107 a_extent[d] = mpz_get_si (array->shape[d]);
2108 a_stride[d] = d == 0 ? 1 : a_stride[d-1] * a_extent[d-1];
2109 }
b1c1d761 2110
a9ec0cfc
TK
2111 if (shift->rank > 0)
2112 {
2113 gfc_array_size (shift, &size);
2114 shiftsize = mpz_get_ui (size);
2115 mpz_clear (size);
2116 shiftvec = XCNEWVEC (ssize_t, shiftsize);
2117 shift_ctor = gfc_constructor_first (shift->value.constructor);
2118 for (d = 0; d < shift->rank; d++)
b1c1d761 2119 {
a9ec0cfc
TK
2120 h_extent[d] = mpz_get_si (shift->shape[d]);
2121 hstride[d] = d == 0 ? 1 : hstride[d-1] * h_extent[d-1];
b1c1d761 2122 }
a9ec0cfc
TK
2123 }
2124 else
2125 shiftvec = NULL;
0ada0dc0 2126
a9ec0cfc
TK
2127 /* Shut up compiler */
2128 len = 1;
2129 rsoffset = 1;
2130
2131 n = 0;
2132 for (d=0; d < array->rank; d++)
2133 {
2134 if (d == which)
2135 {
2136 rsoffset = a_stride[d];
2137 len = a_extent[d];
2138 }
2139 else
2140 {
2141 count[n] = 0;
2142 extent[n] = a_extent[d];
2143 sstride[n] = a_stride[d];
2144 ss_ex[n] = sstride[n] * extent[n];
2145 if (shiftvec)
2146 hs_ex[n] = hstride[n] * extent[n];
2147 n++;
2148 }
2149 }
f64b9ed9
TK
2150 ss_ex[n] = 0;
2151 hs_ex[n] = 0;
b1c1d761 2152
a9ec0cfc
TK
2153 if (shiftvec)
2154 {
2155 for (i = 0; i < shiftsize; i++)
2156 {
2157 ssize_t val;
2158 val = mpz_get_si (shift_ctor->expr->value.integer);
2159 val = val % len;
2160 if (val < 0)
2161 val += len;
2162 shiftvec[i] = val;
2163 shift_ctor = gfc_constructor_next (shift_ctor);
2164 }
2165 shift_val = 0;
b1c1d761
SK
2166 }
2167 else
2168 {
a9ec0cfc
TK
2169 shift_val = mpz_get_si (shift->value.integer);
2170 shift_val = shift_val % len;
2171 if (shift_val < 0)
2172 shift_val += len;
2173 }
2174
2175 continue_loop = true;
2176 d = array->rank;
2177 rptr = resultvec;
2178 sptr = arrayvec;
2179 hptr = shiftvec;
fcae71a3 2180
a9ec0cfc
TK
2181 while (continue_loop)
2182 {
2183 ssize_t sh;
2184 if (shiftvec)
2185 sh = *hptr;
2186 else
2187 sh = shift_val;
2188
2189 src = &sptr[sh * rsoffset];
2190 dest = rptr;
2191 for (n = 0; n < len - sh; n++)
2192 {
2193 *dest = *src;
2194 dest += rsoffset;
2195 src += rsoffset;
2196 }
2197 src = sptr;
2198 for ( n = 0; n < sh; n++)
2199 {
2200 *dest = *src;
2201 dest += rsoffset;
2202 src += rsoffset;
2203 }
2204 rptr += sstride[0];
2205 sptr += sstride[0];
2206 if (shiftvec)
2207 hptr += hstride[0];
2208 count[0]++;
2209 n = 0;
2210 while (count[n] == extent[n])
2211 {
2212 count[n] = 0;
2213 rptr -= ss_ex[n];
2214 sptr -= ss_ex[n];
2215 if (shiftvec)
2216 hptr -= hs_ex[n];
2217 n++;
2218 if (n >= d - 1)
2219 {
2220 continue_loop = false;
2221 break;
2222 }
2223 else
2224 {
2225 count[n]++;
2226 rptr += sstride[n];
2227 sptr += sstride[n];
2228 if (shiftvec)
2229 hptr += hstride[n];
2230 }
2231 }
b1c1d761
SK
2232 }
2233
a9ec0cfc
TK
2234 for (i = 0; i < arraysize; i++)
2235 {
2236 gfc_constructor_append_expr (&result->value.constructor,
2237 gfc_copy_expr (resultvec[i]),
2238 NULL);
2239 }
2240 return result;
b1c1d761
SK
2241}
2242
2243
6de9cd9a 2244gfc_expr *
edf1eac2 2245gfc_simplify_dcmplx (gfc_expr *x, gfc_expr *y)
6de9cd9a 2246{
9d64df18 2247 return simplify_cmplx ("DCMPLX", x, y, gfc_default_double_kind);
6de9cd9a
DN
2248}
2249
2250
2251gfc_expr *
edf1eac2 2252gfc_simplify_dble (gfc_expr *e)
6de9cd9a 2253{
9e23c1aa 2254 gfc_expr *result = NULL;
e23390d2 2255 int tmp1, tmp2;
6de9cd9a
DN
2256
2257 if (e->expr_type != EXPR_CONSTANT)
2258 return NULL;
2259
e23390d2
SK
2260 /* For explicit conversion, turn off -Wconversion and -Wconversion-extra
2261 warnings. */
2262 tmp1 = warn_conversion;
2263 tmp2 = warn_conversion_extra;
2264 warn_conversion = warn_conversion_extra = 0;
2265
b7e75771 2266 result = gfc_convert_constant (e, BT_REAL, gfc_default_double_kind);
e23390d2
SK
2267
2268 warn_conversion = tmp1;
2269 warn_conversion_extra = tmp2;
2270
b7e75771
JD
2271 if (result == &gfc_bad_expr)
2272 return &gfc_bad_expr;
00a4618b 2273
6de9cd9a
DN
2274 return range_check (result, "DBLE");
2275}
2276
2277
2278gfc_expr *
edf1eac2 2279gfc_simplify_digits (gfc_expr *x)
6de9cd9a
DN
2280{
2281 int i, digits;
2282
e7a2d5fb 2283 i = gfc_validate_kind (x->ts.type, x->ts.kind, false);
b7e75771 2284
6de9cd9a
DN
2285 switch (x->ts.type)
2286 {
b7e75771
JD
2287 case BT_INTEGER:
2288 digits = gfc_integer_kinds[i].digits;
2289 break;
6de9cd9a 2290
b7e75771
JD
2291 case BT_REAL:
2292 case BT_COMPLEX:
2293 digits = gfc_real_kinds[i].digits;
2294 break;
6de9cd9a 2295
b7e75771
JD
2296 default:
2297 gcc_unreachable ();
6de9cd9a
DN
2298 }
2299
b7e75771 2300 return gfc_get_int_expr (gfc_default_integer_kind, NULL, digits);
6de9cd9a
DN
2301}
2302
2303
2304gfc_expr *
edf1eac2 2305gfc_simplify_dim (gfc_expr *x, gfc_expr *y)
6de9cd9a
DN
2306{
2307 gfc_expr *result;
991bb832 2308 int kind;
6de9cd9a
DN
2309
2310 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
2311 return NULL;
2312
991bb832 2313 kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;
b7e75771 2314 result = gfc_get_constant_expr (x->ts.type, kind, &x->where);
6de9cd9a
DN
2315
2316 switch (x->ts.type)
2317 {
b7e75771
JD
2318 case BT_INTEGER:
2319 if (mpz_cmp (x->value.integer, y->value.integer) > 0)
2320 mpz_sub (result->value.integer, x->value.integer, y->value.integer);
2321 else
2322 mpz_set_ui (result->value.integer, 0);
6de9cd9a 2323
b7e75771 2324 break;
6de9cd9a 2325
b7e75771
JD
2326 case BT_REAL:
2327 if (mpfr_cmp (x->value.real, y->value.real) > 0)
2328 mpfr_sub (result->value.real, x->value.real, y->value.real,
2329 GFC_RND_MODE);
2330 else
2331 mpfr_set_ui (result->value.real, 0, GFC_RND_MODE);
6de9cd9a 2332
b7e75771 2333 break;
6de9cd9a 2334
b7e75771
JD
2335 default:
2336 gfc_internal_error ("gfc_simplify_dim(): Bad type");
6de9cd9a
DN
2337 }
2338
2339 return range_check (result, "DIM");
2340}
2341
2342
8ec259c1
DF
2343gfc_expr*
2344gfc_simplify_dot_product (gfc_expr *vector_a, gfc_expr *vector_b)
2345{
0ada0dc0 2346 /* If vector_a is a zero-sized array, the result is 0 for INTEGER,
deece1aa
SK
2347 REAL, and COMPLEX types and .false. for LOGICAL. */
2348 if (vector_a->shape && mpz_get_si (vector_a->shape[0]) == 0)
2349 {
2350 if (vector_a->ts.type == BT_LOGICAL)
2351 return gfc_get_logical_expr (gfc_default_logical_kind, NULL, false);
2352 else
2353 return gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
2354 }
4d051340 2355
8ec259c1
DF
2356 if (!is_constant_array_expr (vector_a)
2357 || !is_constant_array_expr (vector_b))
2358 return NULL;
2359
eebb98a5 2360 return compute_dot_product (vector_a, 1, 0, vector_b, 1, 0, true);
8ec259c1
DF
2361}
2362
2363
6de9cd9a 2364gfc_expr *
edf1eac2 2365gfc_simplify_dprod (gfc_expr *x, gfc_expr *y)
6de9cd9a 2366{
f8e566e5 2367 gfc_expr *a1, *a2, *result;
6de9cd9a
DN
2368
2369 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
2370 return NULL;
2371
9d64df18
TS
2372 a1 = gfc_real2real (x, gfc_default_double_kind);
2373 a2 = gfc_real2real (y, gfc_default_double_kind);
6de9cd9a 2374
b7e75771 2375 result = gfc_get_constant_expr (BT_REAL, gfc_default_double_kind, &x->where);
f8e566e5 2376 mpfr_mul (result->value.real, a1->value.real, a2->value.real, GFC_RND_MODE);
6de9cd9a 2377
f8e566e5 2378 gfc_free_expr (a2);
b7e75771 2379 gfc_free_expr (a1);
6de9cd9a
DN
2380
2381 return range_check (result, "DPROD");
2382}
2383
2384
88a95a11
FXC
2385static gfc_expr *
2386simplify_dshift (gfc_expr *arg1, gfc_expr *arg2, gfc_expr *shiftarg,
2387 bool right)
2388{
2389 gfc_expr *result;
2390 int i, k, size, shift;
2391
2392 if (arg1->expr_type != EXPR_CONSTANT || arg2->expr_type != EXPR_CONSTANT
2393 || shiftarg->expr_type != EXPR_CONSTANT)
2394 return NULL;
2395
2396 k = gfc_validate_kind (BT_INTEGER, arg1->ts.kind, false);
2397 size = gfc_integer_kinds[k].bit_size;
2398
58a9e3c4 2399 gfc_extract_int (shiftarg, &shift);
88a95a11
FXC
2400
2401 /* DSHIFTR(I,J,SHIFT) = DSHIFTL(I,J,SIZE-SHIFT). */
2402 if (right)
2403 shift = size - shift;
2404
2405 result = gfc_get_constant_expr (BT_INTEGER, arg1->ts.kind, &arg1->where);
2406 mpz_set_ui (result->value.integer, 0);
2407
2408 for (i = 0; i < shift; i++)
2409 if (mpz_tstbit (arg2->value.integer, size - shift + i))
2410 mpz_setbit (result->value.integer, i);
2411
2412 for (i = 0; i < size - shift; i++)
2413 if (mpz_tstbit (arg1->value.integer, i))
2414 mpz_setbit (result->value.integer, shift + i);
2415
2416 /* Convert to a signed value. */
d01b2c21 2417 gfc_convert_mpz_to_signed (result->value.integer, size);
88a95a11
FXC
2418
2419 return result;
2420}
2421
2422
2423gfc_expr *
2424gfc_simplify_dshiftr (gfc_expr *arg1, gfc_expr *arg2, gfc_expr *shiftarg)
2425{
2426 return simplify_dshift (arg1, arg2, shiftarg, true);
2427}
2428
2429
2430gfc_expr *
2431gfc_simplify_dshiftl (gfc_expr *arg1, gfc_expr *arg2, gfc_expr *shiftarg)
2432{
2433 return simplify_dshift (arg1, arg2, shiftarg, false);
2434}
2435
2436
fbd35ba1
TK
2437gfc_expr *
2438gfc_simplify_eoshift (gfc_expr *array, gfc_expr *shift, gfc_expr *boundary,
2439 gfc_expr *dim)
2440{
2441 bool temp_boundary;
2442 gfc_expr *bnd;
2443 gfc_expr *result;
2444 int which;
2445 gfc_expr **arrayvec, **resultvec;
2446 gfc_expr **rptr, **sptr;
2447 mpz_t size;
2448 size_t arraysize, i;
2449 gfc_constructor *array_ctor, *shift_ctor, *bnd_ctor;
2450 ssize_t shift_val, len;
2451 ssize_t count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS],
2452 sstride[GFC_MAX_DIMENSIONS], a_extent[GFC_MAX_DIMENSIONS],
f64b9ed9 2453 a_stride[GFC_MAX_DIMENSIONS], ss_ex[GFC_MAX_DIMENSIONS + 1];
fbd35ba1
TK
2454 ssize_t rsoffset;
2455 int d, n;
2456 bool continue_loop;
2457 gfc_expr **src, **dest;
2458 size_t s_len;
2459
2460 if (!is_constant_array_expr (array))
2461 return NULL;
2462
2463 if (shift->rank > 0)
2464 gfc_simplify_expr (shift, 1);
2465
2466 if (!gfc_is_constant_expr (shift))
2467 return NULL;
2468
2469 if (boundary)
2470 {
2471 if (boundary->rank > 0)
2472 gfc_simplify_expr (boundary, 1);
0ada0dc0 2473
fbd35ba1
TK
2474 if (!gfc_is_constant_expr (boundary))
2475 return NULL;
2476 }
2477
2478 if (dim)
2479 {
2480 if (!gfc_is_constant_expr (dim))
2481 return NULL;
2482 which = mpz_get_si (dim->value.integer) - 1;
2483 }
2484 else
2485 which = 0;
2486
2487 s_len = 0;
2488 if (boundary == NULL)
2489 {
2490 temp_boundary = true;
2491 switch (array->ts.type)
2492 {
0ada0dc0 2493
fbd35ba1
TK
2494 case BT_INTEGER:
2495 bnd = gfc_get_int_expr (array->ts.kind, NULL, 0);
2496 break;
2497
2498 case BT_LOGICAL:
2499 bnd = gfc_get_logical_expr (array->ts.kind, NULL, 0);
2500 break;
2501
2502 case BT_REAL:
2503 bnd = gfc_get_constant_expr (array->ts.type, array->ts.kind, &gfc_current_locus);
2504 mpfr_set_ui (bnd->value.real, 0, GFC_RND_MODE);
2505 break;
2506
2507 case BT_COMPLEX:
2508 bnd = gfc_get_constant_expr (array->ts.type, array->ts.kind, &gfc_current_locus);
2509 mpc_set_ui (bnd->value.complex, 0, GFC_RND_MODE);
2510 break;
2511
2512 case BT_CHARACTER:
2513 s_len = mpz_get_ui (array->ts.u.cl->length->value.integer);
2514 bnd = gfc_get_character_expr (array->ts.kind, &gfc_current_locus, NULL, s_len);
2515 break;
2516
2517 default:
2518 gcc_unreachable();
2519
2520 }
2521 }
2522 else
2523 {
2524 temp_boundary = false;
2525 bnd = boundary;
2526 }
0ada0dc0 2527
fbd35ba1
TK
2528 gfc_array_size (array, &size);
2529 arraysize = mpz_get_ui (size);
2530 mpz_clear (size);
2531
2532 result = gfc_get_array_expr (array->ts.type, array->ts.kind, &array->where);
2533 result->shape = gfc_copy_shape (array->shape, array->rank);
2534 result->rank = array->rank;
2535 result->ts = array->ts;
2536
2537 if (arraysize == 0)
2538 goto final;
2539
2540 arrayvec = XCNEWVEC (gfc_expr *, arraysize);
2541 array_ctor = gfc_constructor_first (array->value.constructor);
2542 for (i = 0; i < arraysize; i++)
2543 {
2544 arrayvec[i] = array_ctor->expr;
2545 array_ctor = gfc_constructor_next (array_ctor);
2546 }
2547
2548 resultvec = XCNEWVEC (gfc_expr *, arraysize);
2549
2550 extent[0] = 1;
2551 count[0] = 0;
2552
2553 for (d=0; d < array->rank; d++)
2554 {
2555 a_extent[d] = mpz_get_si (array->shape[d]);
2556 a_stride[d] = d == 0 ? 1 : a_stride[d-1] * a_extent[d-1];
2557 }
2558
2559 if (shift->rank > 0)
2560 {
2561 shift_ctor = gfc_constructor_first (shift->value.constructor);
2562 shift_val = 0;
2563 }
2564 else
2565 {
2566 shift_ctor = NULL;
2567 shift_val = mpz_get_si (shift->value.integer);
2568 }
2569
2570 if (bnd->rank > 0)
2571 bnd_ctor = gfc_constructor_first (bnd->value.constructor);
2572 else
2573 bnd_ctor = NULL;
2574
2575 /* Shut up compiler */
2576 len = 1;
2577 rsoffset = 1;
2578
2579 n = 0;
2580 for (d=0; d < array->rank; d++)
2581 {
2582 if (d == which)
2583 {
2584 rsoffset = a_stride[d];
2585 len = a_extent[d];
2586 }
2587 else
2588 {
2589 count[n] = 0;
2590 extent[n] = a_extent[d];
2591 sstride[n] = a_stride[d];
2592 ss_ex[n] = sstride[n] * extent[n];
2593 n++;
2594 }
2595 }
f64b9ed9 2596 ss_ex[n] = 0;
fbd35ba1
TK
2597
2598 continue_loop = true;
2599 d = array->rank;
2600 rptr = resultvec;
2601 sptr = arrayvec;
2602
2603 while (continue_loop)
2604 {
2605 ssize_t sh, delta;
2606
2607 if (shift_ctor)
2608 sh = mpz_get_si (shift_ctor->expr->value.integer);
2609 else
2610 sh = shift_val;
2611
2612 if (( sh >= 0 ? sh : -sh ) > len)
2613 {
2614 delta = len;
2615 sh = len;
2616 }
2617 else
2618 delta = (sh >= 0) ? sh: -sh;
2619
2620 if (sh > 0)
2621 {
2622 src = &sptr[delta * rsoffset];
2623 dest = rptr;
2624 }
2625 else
2626 {
2627 src = sptr;
2628 dest = &rptr[delta * rsoffset];
2629 }
2630
2631 for (n = 0; n < len - delta; n++)
2632 {
2633 *dest = *src;
2634 dest += rsoffset;
2635 src += rsoffset;
2636 }
2637
2638 if (sh < 0)
2639 dest = rptr;
2640
2641 n = delta;
2642
2643 if (bnd_ctor)
2644 {
2645 while (n--)
2646 {
2647 *dest = gfc_copy_expr (bnd_ctor->expr);
2648 dest += rsoffset;
2649 }
2650 }
2651 else
2652 {
2653 while (n--)
2654 {
2655 *dest = gfc_copy_expr (bnd);
2656 dest += rsoffset;
2657 }
2658 }
2659 rptr += sstride[0];
2660 sptr += sstride[0];
2661 if (shift_ctor)
2662 shift_ctor = gfc_constructor_next (shift_ctor);
2663
2664 if (bnd_ctor)
2665 bnd_ctor = gfc_constructor_next (bnd_ctor);
0ada0dc0 2666
fbd35ba1
TK
2667 count[0]++;
2668 n = 0;
2669 while (count[n] == extent[n])
2670 {
2671 count[n] = 0;
2672 rptr -= ss_ex[n];
2673 sptr -= ss_ex[n];
2674 n++;
2675 if (n >= d - 1)
2676 {
2677 continue_loop = false;
2678 break;
2679 }
2680 else
2681 {
2682 count[n]++;
2683 rptr += sstride[n];
2684 sptr += sstride[n];
2685 }
2686 }
2687 }
2688
2689 for (i = 0; i < arraysize; i++)
2690 {
2691 gfc_constructor_append_expr (&result->value.constructor,
2692 gfc_copy_expr (resultvec[i]),
2693 NULL);
2694 }
2695
2696 final:
2697 if (temp_boundary)
2698 gfc_free_expr (bnd);
2699
2700 return result;
2701}
2702
fdc54e88
FXC
2703gfc_expr *
2704gfc_simplify_erf (gfc_expr *x)
2705{
2706 gfc_expr *result;
2707
2708 if (x->expr_type != EXPR_CONSTANT)
2709 return NULL;
2710
b7e75771 2711 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
fdc54e88
FXC
2712 mpfr_erf (result->value.real, x->value.real, GFC_RND_MODE);
2713
2714 return range_check (result, "ERF");
2715}
2716
2717
2718gfc_expr *
2719gfc_simplify_erfc (gfc_expr *x)
2720{
2721 gfc_expr *result;
2722
2723 if (x->expr_type != EXPR_CONSTANT)
2724 return NULL;
2725
b7e75771 2726 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
fdc54e88
FXC
2727 mpfr_erfc (result->value.real, x->value.real, GFC_RND_MODE);
2728
2729 return range_check (result, "ERFC");
2730}
2731
2732
9b33a6a1
FXC
2733/* Helper functions to simplify ERFC_SCALED(x) = ERFC(x) * EXP(X**2). */
2734
2735#define MAX_ITER 200
2736#define ARG_LIMIT 12
2737
2738/* Calculate ERFC_SCALED directly by its definition:
2739
2740 ERFC_SCALED(x) = ERFC(x) * EXP(X**2)
2741
2742 using a large precision for intermediate results. This is used for all
2743 but large values of the argument. */
2744static void
2745fullprec_erfc_scaled (mpfr_t res, mpfr_t arg)
2746{
c9d4cc5d 2747 mpfr_prec_t prec;
9b33a6a1
FXC
2748 mpfr_t a, b;
2749
2750 prec = mpfr_get_default_prec ();
2751 mpfr_set_default_prec (10 * prec);
2752
2753 mpfr_init (a);
2754 mpfr_init (b);
2755
2756 mpfr_set (a, arg, GFC_RND_MODE);
2757 mpfr_sqr (b, a, GFC_RND_MODE);
2758 mpfr_exp (b, b, GFC_RND_MODE);
2759 mpfr_erfc (a, a, GFC_RND_MODE);
2760 mpfr_mul (a, a, b, GFC_RND_MODE);
2761
2762 mpfr_set (res, a, GFC_RND_MODE);
2763 mpfr_set_default_prec (prec);
2764
2765 mpfr_clear (a);
2766 mpfr_clear (b);
2767}
2768
2769/* Calculate ERFC_SCALED using a power series expansion in 1/arg:
2770
2771 ERFC_SCALED(x) = 1 / (x * sqrt(pi))
2772 * (1 + Sum_n (-1)**n * (1 * 3 * 5 * ... * (2n-1))
2773 / (2 * x**2)**n)
2774
2775 This is used for large values of the argument. Intermediate calculations
2776 are performed with twice the precision. We don't do a fixed number of
2777 iterations of the sum, but stop when it has converged to the required
2778 precision. */
2779static void
2780asympt_erfc_scaled (mpfr_t res, mpfr_t arg)
2781{
2782 mpfr_t sum, x, u, v, w, oldsum, sumtrunc;
2783 mpz_t num;
c9d4cc5d 2784 mpfr_prec_t prec;
9b33a6a1
FXC
2785 unsigned i;
2786
2787 prec = mpfr_get_default_prec ();
2788 mpfr_set_default_prec (2 * prec);
2789
2790 mpfr_init (sum);
2791 mpfr_init (x);
2792 mpfr_init (u);
2793 mpfr_init (v);
2794 mpfr_init (w);
2795 mpz_init (num);
2796
2797 mpfr_init (oldsum);
2798 mpfr_init (sumtrunc);
2799 mpfr_set_prec (oldsum, prec);
2800 mpfr_set_prec (sumtrunc, prec);
2801
2802 mpfr_set (x, arg, GFC_RND_MODE);
2803 mpfr_set_ui (sum, 1, GFC_RND_MODE);
2804 mpz_set_ui (num, 1);
2805
2806 mpfr_set (u, x, GFC_RND_MODE);
2807 mpfr_sqr (u, u, GFC_RND_MODE);
2808 mpfr_mul_ui (u, u, 2, GFC_RND_MODE);
2809 mpfr_pow_si (u, u, -1, GFC_RND_MODE);
2810
2811 for (i = 1; i < MAX_ITER; i++)
2812 {
2813 mpfr_set (oldsum, sum, GFC_RND_MODE);
2814
2815 mpz_mul_ui (num, num, 2 * i - 1);
2816 mpz_neg (num, num);
2817
2818 mpfr_set (w, u, GFC_RND_MODE);
2819 mpfr_pow_ui (w, w, i, GFC_RND_MODE);
2820
2821 mpfr_set_z (v, num, GFC_RND_MODE);
2822 mpfr_mul (v, v, w, GFC_RND_MODE);
2823
2824 mpfr_add (sum, sum, v, GFC_RND_MODE);
2825
2826 mpfr_set (sumtrunc, sum, GFC_RND_MODE);
2827 if (mpfr_cmp (sumtrunc, oldsum) == 0)
2828 break;
2829 }
2830
2831 /* We should have converged by now; otherwise, ARG_LIMIT is probably
2832 set too low. */
2833 gcc_assert (i < MAX_ITER);
2834
2835 /* Divide by x * sqrt(Pi). */
2836 mpfr_const_pi (u, GFC_RND_MODE);
2837 mpfr_sqrt (u, u, GFC_RND_MODE);
2838 mpfr_mul (u, u, x, GFC_RND_MODE);
2839 mpfr_div (sum, sum, u, GFC_RND_MODE);
2840
2841 mpfr_set (res, sum, GFC_RND_MODE);
2842 mpfr_set_default_prec (prec);
2843
2844 mpfr_clears (sum, x, u, v, w, oldsum, sumtrunc, NULL);
2845 mpz_clear (num);
2846}
2847
2848
2849gfc_expr *
2850gfc_simplify_erfc_scaled (gfc_expr *x)
2851{
2852 gfc_expr *result;
2853
2854 if (x->expr_type != EXPR_CONSTANT)
2855 return NULL;
2856
b7e75771 2857 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
9b33a6a1
FXC
2858 if (mpfr_cmp_d (x->value.real, ARG_LIMIT) >= 0)
2859 asympt_erfc_scaled (result->value.real, x->value.real);
2860 else
2861 fullprec_erfc_scaled (result->value.real, x->value.real);
2862
2863 return range_check (result, "ERFC_SCALED");
2864}
2865
2866#undef MAX_ITER
2867#undef ARG_LIMIT
2868
2869
6de9cd9a 2870gfc_expr *
edf1eac2 2871gfc_simplify_epsilon (gfc_expr *e)
6de9cd9a
DN
2872{
2873 gfc_expr *result;
2874 int i;
2875
e7a2d5fb 2876 i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
6de9cd9a 2877
b7e75771 2878 result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
f8e566e5 2879 mpfr_set (result->value.real, gfc_real_kinds[i].epsilon, GFC_RND_MODE);
6de9cd9a
DN
2880
2881 return range_check (result, "EPSILON");
2882}
2883
2884
2885gfc_expr *
edf1eac2 2886gfc_simplify_exp (gfc_expr *x)
6de9cd9a
DN
2887{
2888 gfc_expr *result;
6de9cd9a
DN
2889
2890 if (x->expr_type != EXPR_CONSTANT)
2891 return NULL;
2892
b7e75771 2893 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
6de9cd9a 2894
6de9cd9a
DN
2895 switch (x->ts.type)
2896 {
b7e75771
JD
2897 case BT_REAL:
2898 mpfr_exp (result->value.real, x->value.real, GFC_RND_MODE);
2899 break;
6de9cd9a 2900
b7e75771
JD
2901 case BT_COMPLEX:
2902 gfc_set_model_kind (x->ts.kind);
2903 mpc_exp (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
2904 break;
6de9cd9a 2905
b7e75771
JD
2906 default:
2907 gfc_internal_error ("in gfc_simplify_exp(): Bad type");
6de9cd9a
DN
2908 }
2909
2910 return range_check (result, "EXP");
2911}
2912
d0a4a61c 2913
6de9cd9a 2914gfc_expr *
edf1eac2 2915gfc_simplify_exponent (gfc_expr *x)
6de9cd9a 2916{
d2af8cc6 2917 long int val;
6de9cd9a
DN
2918 gfc_expr *result;
2919
2920 if (x->expr_type != EXPR_CONSTANT)
2921 return NULL;
2922
b7e75771
JD
2923 result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
2924 &x->where);
6de9cd9a 2925
d2af8cc6
FXC
2926 /* EXPONENT(inf) = EXPONENT(nan) = HUGE(0) */
2927 if (mpfr_inf_p (x->value.real) || mpfr_nan_p (x->value.real))
2928 {
2929 int i = gfc_validate_kind (BT_INTEGER, gfc_default_integer_kind, false);
2930 mpz_set (result->value.integer, gfc_integer_kinds[i].huge);
2931 return result;
2932 }
f8e566e5 2933
d2af8cc6
FXC
2934 /* EXPONENT(+/- 0.0) = 0 */
2935 if (mpfr_zero_p (x->value.real))
6de9cd9a
DN
2936 {
2937 mpz_set_ui (result->value.integer, 0);
2938 return result;
2939 }
2940
d2af8cc6
FXC
2941 gfc_set_model (x->value.real);
2942
2943 val = (long int) mpfr_get_exp (x->value.real);
2944 mpz_set_si (result->value.integer, val);
6de9cd9a
DN
2945
2946 return range_check (result, "EXPONENT");
2947}
2948
2949
ef78bc3c
AV
2950gfc_expr *
2951gfc_simplify_failed_or_stopped_images (gfc_expr *team ATTRIBUTE_UNUSED,
2952 gfc_expr *kind)
2953{
2954 if (flag_coarray == GFC_FCOARRAY_NONE)
2955 {
2956 gfc_current_locus = *gfc_current_intrinsic_where;
2957 gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
2958 return &gfc_bad_expr;
2959 }
2960
2961 if (flag_coarray == GFC_FCOARRAY_SINGLE)
2962 {
2963 gfc_expr *result;
2964 int actual_kind;
2965 if (kind)
2966 gfc_extract_int (kind, &actual_kind);
2967 else
2968 actual_kind = gfc_default_integer_kind;
2969
2970 result = gfc_get_array_expr (BT_INTEGER, actual_kind, &gfc_current_locus);
2971 result->rank = 1;
2972 return result;
2973 }
2974
2975 /* For fcoarray = lib no simplification is possible, because it is not known
2976 what images failed or are stopped at compile time. */
2977 return NULL;
2978}
2979
2980
f8862a1b
DR
2981gfc_expr *
2982gfc_simplify_get_team (gfc_expr *level ATTRIBUTE_UNUSED)
2983{
2984 if (flag_coarray == GFC_FCOARRAY_NONE)
2985 {
2986 gfc_current_locus = *gfc_current_intrinsic_where;
2987 gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
2988 return &gfc_bad_expr;
2989 }
2990
2991 if (flag_coarray == GFC_FCOARRAY_SINGLE)
2992 {
2993 gfc_expr *result;
2994 result = gfc_get_array_expr (BT_INTEGER, gfc_default_integer_kind, &gfc_current_locus);
2995 result->rank = 0;
2996 return result;
2997 }
2998
2999 /* For fcoarray = lib no simplification is possible, because it is not known
3000 what images failed or are stopped at compile time. */
3001 return NULL;
3002}
3003
3004
6de9cd9a 3005gfc_expr *
edf1eac2 3006gfc_simplify_float (gfc_expr *a)
6de9cd9a
DN
3007{
3008 gfc_expr *result;
3009
3010 if (a->expr_type != EXPR_CONSTANT)
3011 return NULL;
3012
8dc63166 3013 result = gfc_int2real (a, gfc_default_real_kind);
b7e75771 3014
6de9cd9a
DN
3015 return range_check (result, "FLOAT");
3016}
3017
3018
eaf31d82
TB
3019static bool
3020is_last_ref_vtab (gfc_expr *e)
3021{
3022 gfc_ref *ref;
3023 gfc_component *comp = NULL;
3024
3025 if (e->expr_type != EXPR_VARIABLE)
3026 return false;
3027
3028 for (ref = e->ref; ref; ref = ref->next)
3029 if (ref->type == REF_COMPONENT)
3030 comp = ref->u.c.component;
3031
3032 if (!e->ref || !comp)
3033 return e->symtree->n.sym->attr.vtab;
3034
3035 if (comp->name[0] == '_' && strcmp (comp->name, "_vptr") == 0)
3036 return true;
3037
3038 return false;
3039}
3040
3041
3042gfc_expr *
3043gfc_simplify_extends_type_of (gfc_expr *a, gfc_expr *mold)
3044{
3045 /* Avoid simplification of resolved symbols. */
3046 if (is_last_ref_vtab (a) || is_last_ref_vtab (mold))
3047 return NULL;
3048
3049 if (a->ts.type == BT_DERIVED && mold->ts.type == BT_DERIVED)
3050 return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
3051 gfc_type_is_extension_of (mold->ts.u.derived,
3052 a->ts.u.derived));
8b704316
PT
3053
3054 if (UNLIMITED_POLY (a) || UNLIMITED_POLY (mold))
3055 return NULL;
3056
04f1c830 3057 /* Return .false. if the dynamic type can never be an extension. */
eaf31d82
TB
3058 if ((a->ts.type == BT_CLASS && mold->ts.type == BT_CLASS
3059 && !gfc_type_is_extension_of
3060 (mold->ts.u.derived->components->ts.u.derived,
3061 a->ts.u.derived->components->ts.u.derived)
3062 && !gfc_type_is_extension_of
3063 (a->ts.u.derived->components->ts.u.derived,
3064 mold->ts.u.derived->components->ts.u.derived))
3065 || (a->ts.type == BT_DERIVED && mold->ts.type == BT_CLASS
eaf31d82
TB
3066 && !gfc_type_is_extension_of
3067 (mold->ts.u.derived->components->ts.u.derived,
3068 a->ts.u.derived))
3069 || (a->ts.type == BT_CLASS && mold->ts.type == BT_DERIVED
3070 && !gfc_type_is_extension_of
3071 (mold->ts.u.derived,
04f1c830
JW
3072 a->ts.u.derived->components->ts.u.derived)
3073 && !gfc_type_is_extension_of
3074 (a->ts.u.derived->components->ts.u.derived,
3075 mold->ts.u.derived)))
eaf31d82
TB
3076 return gfc_get_logical_expr (gfc_default_logical_kind, &a->where, false);
3077
04f1c830
JW
3078 /* Return .true. if the dynamic type is guaranteed to be an extension. */
3079 if (a->ts.type == BT_CLASS && mold->ts.type == BT_DERIVED
eaf31d82
TB
3080 && gfc_type_is_extension_of (mold->ts.u.derived,
3081 a->ts.u.derived->components->ts.u.derived))
3082 return gfc_get_logical_expr (gfc_default_logical_kind, &a->where, true);
3083
3084 return NULL;
3085}
3086
3087
3088gfc_expr *
3089gfc_simplify_same_type_as (gfc_expr *a, gfc_expr *b)
3090{
3091 /* Avoid simplification of resolved symbols. */
3092 if (is_last_ref_vtab (a) || is_last_ref_vtab (b))
3093 return NULL;
3094
3095 /* Return .false. if the dynamic type can never be the
3096 same. */
67b1d004
JW
3097 if (((a->ts.type == BT_CLASS && gfc_expr_attr (a).class_ok)
3098 || (b->ts.type == BT_CLASS && gfc_expr_attr (b).class_ok))
eaf31d82
TB
3099 && !gfc_type_compatible (&a->ts, &b->ts)
3100 && !gfc_type_compatible (&b->ts, &a->ts))
3101 return gfc_get_logical_expr (gfc_default_logical_kind, &a->where, false);
3102
3103 if (a->ts.type != BT_DERIVED || b->ts.type != BT_DERIVED)
3104 return NULL;
3105
3106 return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
3107 gfc_compare_derived_types (a->ts.u.derived,
3108 b->ts.u.derived));
3109}
3110
3111
6de9cd9a 3112gfc_expr *
edf1eac2 3113gfc_simplify_floor (gfc_expr *e, gfc_expr *k)
6de9cd9a
DN
3114{
3115 gfc_expr *result;
f8e566e5 3116 mpfr_t floor;
6de9cd9a
DN
3117 int kind;
3118
145cf79b 3119 kind = get_kind (BT_INTEGER, k, "FLOOR", gfc_default_integer_kind);
6de9cd9a
DN
3120 if (kind == -1)
3121 gfc_internal_error ("gfc_simplify_floor(): Bad kind");
3122
3123 if (e->expr_type != EXPR_CONSTANT)
3124 return NULL;
3125
ff7097f2 3126 mpfr_init2 (floor, mpfr_get_prec (e->value.real));
f8e566e5
SK
3127 mpfr_floor (floor, e->value.real);
3128
b7e75771 3129 result = gfc_get_constant_expr (BT_INTEGER, kind, &e->where);
7278e4dc 3130 gfc_mpfr_to_mpz (result->value.integer, floor, &e->where);
f8e566e5
SK
3131
3132 mpfr_clear (floor);
6de9cd9a
DN
3133
3134 return range_check (result, "FLOOR");
3135}
3136
3137
3138gfc_expr *
edf1eac2 3139gfc_simplify_fraction (gfc_expr *x)
6de9cd9a
DN
3140{
3141 gfc_expr *result;
03a8a2d5 3142 mpfr_exp_t e;
6de9cd9a
DN
3143
3144 if (x->expr_type != EXPR_CONSTANT)
3145 return NULL;
3146
b7e75771 3147 result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where);
6de9cd9a 3148
d2af8cc6
FXC
3149 /* FRACTION(inf) = NaN. */
3150 if (mpfr_inf_p (x->value.real))
3151 {
3152 mpfr_set_nan (result->value.real);
3153 return result;
3154 }
3155
d2af8cc6 3156 /* mpfr_frexp() correctly handles zeros and NaNs. */
03a8a2d5
TB
3157 mpfr_frexp (&e, result->value.real, x->value.real, GFC_RND_MODE);
3158
6de9cd9a
DN
3159 return range_check (result, "FRACTION");
3160}
3161
3162
75be5dc0
TB
3163gfc_expr *
3164gfc_simplify_gamma (gfc_expr *x)
3165{
3166 gfc_expr *result;
3167
3168 if (x->expr_type != EXPR_CONSTANT)
3169 return NULL;
3170
b7e75771 3171 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
75be5dc0
TB
3172 mpfr_gamma (result->value.real, x->value.real, GFC_RND_MODE);
3173
3174 return range_check (result, "GAMMA");
3175}
3176
3177
6de9cd9a 3178gfc_expr *
edf1eac2 3179gfc_simplify_huge (gfc_expr *e)
6de9cd9a
DN
3180{
3181 gfc_expr *result;
3182 int i;
3183
e7a2d5fb 3184 i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
b7e75771 3185 result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
6de9cd9a
DN
3186
3187 switch (e->ts.type)
3188 {
b7e75771
JD
3189 case BT_INTEGER:
3190 mpz_set (result->value.integer, gfc_integer_kinds[i].huge);
3191 break;
6de9cd9a 3192
b7e75771
JD
3193 case BT_REAL:
3194 mpfr_set (result->value.real, gfc_real_kinds[i].huge, GFC_RND_MODE);
3195 break;
6de9cd9a 3196
b7e75771
JD
3197 default:
3198 gcc_unreachable ();
6de9cd9a
DN
3199 }
3200
3201 return result;
3202}
3203
f489fba1
FXC
3204
3205gfc_expr *
3206gfc_simplify_hypot (gfc_expr *x, gfc_expr *y)
3207{
3208 gfc_expr *result;
3209
3210 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
3211 return NULL;
3212
b7e75771 3213 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
f489fba1
FXC
3214 mpfr_hypot (result->value.real, x->value.real, y->value.real, GFC_RND_MODE);
3215 return range_check (result, "HYPOT");
3216}
3217
3218
34462c28 3219/* We use the processor's collating sequence, because all
65de695f 3220 systems that gfortran currently works on are ASCII. */
6de9cd9a
DN
3221
3222gfc_expr *
5cda5098 3223gfc_simplify_iachar (gfc_expr *e, gfc_expr *kind)
6de9cd9a
DN
3224{
3225 gfc_expr *result;
00660189 3226 gfc_char_t index;
b7e75771 3227 int k;
6de9cd9a
DN
3228
3229 if (e->expr_type != EXPR_CONSTANT)
3230 return NULL;
3231
3232 if (e->value.character.length != 1)
3233 {
3234 gfc_error ("Argument of IACHAR at %L must be of length one", &e->where);
3235 return &gfc_bad_expr;
3236 }
3237
00660189 3238 index = e->value.character.string[0];
34462c28 3239
73e42eef 3240 if (warn_surprising && index > 127)
48749dbc
MLI
3241 gfc_warning (OPT_Wsurprising,
3242 "Argument of IACHAR function at %L outside of range 0..127",
34462c28 3243 &e->where);
6de9cd9a 3244
b7e75771
JD
3245 k = get_kind (BT_INTEGER, kind, "IACHAR", gfc_default_integer_kind);
3246 if (k == -1)
5cda5098
FXC
3247 return &gfc_bad_expr;
3248
b7e75771 3249 result = gfc_get_int_expr (k, &e->where, index);
6de9cd9a
DN
3250
3251 return range_check (result, "IACHAR");
3252}
3253
3254
195a95c4
TB
3255static gfc_expr *
3256do_bit_and (gfc_expr *result, gfc_expr *e)
3257{
3258 gcc_assert (e->ts.type == BT_INTEGER && e->expr_type == EXPR_CONSTANT);
3259 gcc_assert (result->ts.type == BT_INTEGER
3260 && result->expr_type == EXPR_CONSTANT);
3261
3262 mpz_and (result->value.integer, result->value.integer, e->value.integer);
3263 return result;
3264}
3265
3266
3267gfc_expr *
3268gfc_simplify_iall (gfc_expr *array, gfc_expr *dim, gfc_expr *mask)
3269{
3270 return simplify_transformation (array, dim, mask, -1, do_bit_and);
3271}
3272
3273
3274static gfc_expr *
3275do_bit_ior (gfc_expr *result, gfc_expr *e)
3276{
3277 gcc_assert (e->ts.type == BT_INTEGER && e->expr_type == EXPR_CONSTANT);
3278 gcc_assert (result->ts.type == BT_INTEGER
3279 && result->expr_type == EXPR_CONSTANT);
3280
3281 mpz_ior (result->value.integer, result->value.integer, e->value.integer);
3282 return result;
3283}
3284
3285
3286gfc_expr *
3287gfc_simplify_iany (gfc_expr *array, gfc_expr *dim, gfc_expr *mask)
3288{
3289 return simplify_transformation (array, dim, mask, 0, do_bit_ior);
3290}
3291
3292
6de9cd9a 3293gfc_expr *
edf1eac2 3294gfc_simplify_iand (gfc_expr *x, gfc_expr *y)
6de9cd9a
DN
3295{
3296 gfc_expr *result;
3297
3298 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
3299 return NULL;
3300
b7e75771 3301 result = gfc_get_constant_expr (BT_INTEGER, x->ts.kind, &x->where);
6de9cd9a
DN
3302 mpz_and (result->value.integer, x->value.integer, y->value.integer);
3303
3304 return range_check (result, "IAND");
3305}
3306
3307
3308gfc_expr *
edf1eac2 3309gfc_simplify_ibclr (gfc_expr *x, gfc_expr *y)
6de9cd9a
DN
3310{
3311 gfc_expr *result;
3312 int k, pos;
3313
3314 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
3315 return NULL;
3316
58a9e3c4 3317 gfc_extract_int (y, &pos);
6de9cd9a 3318
e7a2d5fb 3319 k = gfc_validate_kind (x->ts.type, x->ts.kind, false);
6de9cd9a 3320
6de9cd9a
DN
3321 result = gfc_copy_expr (x);
3322
f1dcb9bf
BM
3323 convert_mpz_to_unsigned (result->value.integer,
3324 gfc_integer_kinds[k].bit_size);
3325
6de9cd9a 3326 mpz_clrbit (result->value.integer, pos);
f1dcb9bf 3327
d01b2c21 3328 gfc_convert_mpz_to_signed (result->value.integer,
f1dcb9bf
BM
3329 gfc_integer_kinds[k].bit_size);
3330
c05800b6 3331 return result;
6de9cd9a
DN
3332}
3333
3334
3335gfc_expr *
edf1eac2 3336gfc_simplify_ibits (gfc_expr *x, gfc_expr *y, gfc_expr *z)
6de9cd9a
DN
3337{
3338 gfc_expr *result;
3339 int pos, len;
3340 int i, k, bitsize;
3341 int *bits;
3342
3343 if (x->expr_type != EXPR_CONSTANT
3344 || y->expr_type != EXPR_CONSTANT
3345 || z->expr_type != EXPR_CONSTANT)
3346 return NULL;
3347
58a9e3c4
SK
3348 gfc_extract_int (y, &pos);
3349 gfc_extract_int (z, &len);
6de9cd9a 3350
e7a2d5fb 3351 k = gfc_validate_kind (BT_INTEGER, x->ts.kind, false);
6de9cd9a
DN
3352
3353 bitsize = gfc_integer_kinds[k].bit_size;
3354
3355 if (pos + len > bitsize)
3356 {
f1dcb9bf
BM
3357 gfc_error ("Sum of second and third arguments of IBITS exceeds "
3358 "bit size at %L", &y->where);
6de9cd9a
DN
3359 return &gfc_bad_expr;
3360 }
3361
b7e75771 3362 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
c05800b6
JD
3363 convert_mpz_to_unsigned (result->value.integer,
3364 gfc_integer_kinds[k].bit_size);
6de9cd9a 3365
ece3f663 3366 bits = XCNEWVEC (int, bitsize);
6de9cd9a
DN
3367
3368 for (i = 0; i < bitsize; i++)
3369 bits[i] = 0;
3370
3371 for (i = 0; i < len; i++)
3372 bits[i] = mpz_tstbit (x->value.integer, i + pos);
3373
3374 for (i = 0; i < bitsize; i++)
3375 {
3376 if (bits[i] == 0)
edf1eac2 3377 mpz_clrbit (result->value.integer, i);
6de9cd9a 3378 else if (bits[i] == 1)
edf1eac2 3379 mpz_setbit (result->value.integer, i);
6de9cd9a 3380 else
edf1eac2 3381 gfc_internal_error ("IBITS: Bad bit");
6de9cd9a
DN
3382 }
3383
cede9502 3384 free (bits);
6de9cd9a 3385
d01b2c21 3386 gfc_convert_mpz_to_signed (result->value.integer,
c05800b6
JD
3387 gfc_integer_kinds[k].bit_size);
3388
3389 return result;
6de9cd9a
DN
3390}
3391
3392
3393gfc_expr *
edf1eac2 3394gfc_simplify_ibset (gfc_expr *x, gfc_expr *y)
6de9cd9a
DN
3395{
3396 gfc_expr *result;
3397 int k, pos;
3398
3399 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
3400 return NULL;
3401
58a9e3c4 3402 gfc_extract_int (y, &pos);
6de9cd9a 3403
e7a2d5fb 3404 k = gfc_validate_kind (x->ts.type, x->ts.kind, false);
6de9cd9a 3405
6de9cd9a
DN
3406 result = gfc_copy_expr (x);
3407
f1dcb9bf
BM
3408 convert_mpz_to_unsigned (result->value.integer,
3409 gfc_integer_kinds[k].bit_size);
3410
6de9cd9a 3411 mpz_setbit (result->value.integer, pos);
ef98c52a 3412
d01b2c21 3413 gfc_convert_mpz_to_signed (result->value.integer,
f1dcb9bf 3414 gfc_integer_kinds[k].bit_size);
ef98c52a 3415
c05800b6 3416 return result;
6de9cd9a
DN
3417}
3418
3419
3420gfc_expr *
5cda5098 3421gfc_simplify_ichar (gfc_expr *e, gfc_expr *kind)
6de9cd9a
DN
3422{
3423 gfc_expr *result;
00660189 3424 gfc_char_t index;
b7e75771 3425 int k;
6de9cd9a
DN
3426
3427 if (e->expr_type != EXPR_CONSTANT)
3428 return NULL;
3429
3430 if (e->value.character.length != 1)
3431 {
3432 gfc_error ("Argument of ICHAR at %L must be of length one", &e->where);
3433 return &gfc_bad_expr;
3434 }
3435
00660189 3436 index = e->value.character.string[0];
6de9cd9a 3437
b7e75771
JD
3438 k = get_kind (BT_INTEGER, kind, "ICHAR", gfc_default_integer_kind);
3439 if (k == -1)
5cda5098
FXC
3440 return &gfc_bad_expr;
3441
b7e75771
JD
3442 result = gfc_get_int_expr (k, &e->where, index);
3443
6de9cd9a
DN
3444 return range_check (result, "ICHAR");
3445}
3446
3447
3448gfc_expr *
edf1eac2 3449gfc_simplify_ieor (gfc_expr *x, gfc_expr *y)
6de9cd9a
DN
3450{
3451 gfc_expr *result;
3452
3453 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
3454 return NULL;
3455
b7e75771 3456 result = gfc_get_constant_expr (BT_INTEGER, x->ts.kind, &x->where);
6de9cd9a
DN
3457 mpz_xor (result->value.integer, x->value.integer, y->value.integer);
3458
3459 return range_check (result, "IEOR");
3460}
3461
3462
3463gfc_expr *
5cda5098 3464gfc_simplify_index (gfc_expr *x, gfc_expr *y, gfc_expr *b, gfc_expr *kind)
6de9cd9a
DN
3465{
3466 gfc_expr *result;
3467 int back, len, lensub;
3468 int i, j, k, count, index = 0, start;
3469
8b704316 3470 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT
00113de8 3471 || ( b != NULL && b->expr_type != EXPR_CONSTANT))
6de9cd9a
DN
3472 return NULL;
3473
3474 if (b != NULL && b->value.logical != 0)
3475 back = 1;
3476 else
3477 back = 0;
3478
8b704316 3479 k = get_kind (BT_INTEGER, kind, "INDEX", gfc_default_integer_kind);
5cda5098
FXC
3480 if (k == -1)
3481 return &gfc_bad_expr;
3482
b7e75771 3483 result = gfc_get_constant_expr (BT_INTEGER, k, &x->where);
6de9cd9a
DN
3484
3485 len = x->value.character.length;
3486 lensub = y->value.character.length;
3487
3488 if (len < lensub)
3489 {
3490 mpz_set_si (result->value.integer, 0);
3491 return result;
3492 }
3493
3494 if (back == 0)
3495 {
6de9cd9a
DN
3496 if (lensub == 0)
3497 {
3498 mpz_set_si (result->value.integer, 1);
3499 return result;
3500 }
3501 else if (lensub == 1)
3502 {
3503 for (i = 0; i < len; i++)
3504 {
3505 for (j = 0; j < lensub; j++)
3506 {
edf1eac2
SK
3507 if (y->value.character.string[j]
3508 == x->value.character.string[i])
6de9cd9a
DN
3509 {
3510 index = i + 1;
3511 goto done;
3512 }
3513 }
3514 }
3515 }
3516 else
3517 {
3518 for (i = 0; i < len; i++)
3519 {
3520 for (j = 0; j < lensub; j++)
3521 {
edf1eac2
SK
3522 if (y->value.character.string[j]
3523 == x->value.character.string[i])
6de9cd9a
DN
3524 {
3525 start = i;
3526 count = 0;
3527
3528 for (k = 0; k < lensub; k++)
3529 {
edf1eac2
SK
3530 if (y->value.character.string[k]
3531 == x->value.character.string[k + start])
6de9cd9a
DN
3532 count++;
3533 }
3534
3535 if (count == lensub)
3536 {
3537 index = start + 1;
3538 goto done;
3539 }
3540 }
3541 }
3542 }
3543 }
3544
3545 }
3546 else
3547 {
6de9cd9a
DN
3548 if (lensub == 0)
3549 {
3550 mpz_set_si (result->value.integer, len + 1);
3551 return result;
3552 }
3553 else if (lensub == 1)
3554 {
3555 for (i = 0; i < len; i++)
3556 {
3557 for (j = 0; j < lensub; j++)
3558 {
edf1eac2
SK
3559 if (y->value.character.string[j]
3560 == x->value.character.string[len - i])
6de9cd9a
DN
3561 {
3562 index = len - i + 1;
3563 goto done;
3564 }
3565 }
3566 }
3567 }
3568 else
3569 {
3570 for (i = 0; i < len; i++)
3571 {
3572 for (j = 0; j < lensub; j++)
3573 {
edf1eac2
SK
3574 if (y->value.character.string[j]
3575 == x->value.character.string[len - i])
6de9cd9a
DN
3576 {
3577 start = len - i;
3578 if (start <= len - lensub)
3579 {
3580 count = 0;
3581 for (k = 0; k < lensub; k++)
edf1eac2
SK
3582 if (y->value.character.string[k]
3583 == x->value.character.string[k + start])
6de9cd9a
DN
3584 count++;
3585
3586 if (count == lensub)
3587 {
3588 index = start + 1;
3589 goto done;
3590 }
3591 }
3592 else
3593 {
3594 continue;
3595 }
3596 }
3597 }
3598 }
3599 }
3600 }
3601
3602done:
3603 mpz_set_si (result->value.integer, index);
3604 return range_check (result, "INDEX");
3605}
3606
3607
b7e75771
JD
3608static gfc_expr *
3609simplify_intconv (gfc_expr *e, int kind, const char *name)
6de9cd9a 3610{
d93712d9 3611 gfc_expr *result = NULL;
e23390d2 3612 int tmp1, tmp2;
6de9cd9a 3613
8dc63166
SK
3614 /* Convert BOZ to integer, and return without range checking. */
3615 if (e->ts.type == BT_BOZ)
3616 {
3617 if (!gfc_boz2int (e, kind))
3618 return NULL;
3619 result = gfc_copy_expr (e);
3620 return result;
3621 }
3622
6de9cd9a
DN
3623 if (e->expr_type != EXPR_CONSTANT)
3624 return NULL;
3625
e23390d2
SK
3626 /* For explicit conversion, turn off -Wconversion and -Wconversion-extra
3627 warnings. */
3628 tmp1 = warn_conversion;
3629 tmp2 = warn_conversion_extra;
3630 warn_conversion = warn_conversion_extra = 0;
3631
b7e75771 3632 result = gfc_convert_constant (e, BT_INTEGER, kind);
e23390d2
SK
3633
3634 warn_conversion = tmp1;
3635 warn_conversion_extra = tmp2;
3636
b7e75771
JD
3637 if (result == &gfc_bad_expr)
3638 return &gfc_bad_expr;
6de9cd9a 3639
b7e75771 3640 return range_check (result, name);
6de9cd9a
DN
3641}
3642
3643
b7e75771
JD
3644gfc_expr *
3645gfc_simplify_int (gfc_expr *e, gfc_expr *k)
bf3fb7e4 3646{
b7e75771 3647 int kind;
bf3fb7e4 3648
b7e75771
JD
3649 kind = get_kind (BT_INTEGER, k, "INT", gfc_default_integer_kind);
3650 if (kind == -1)
3651 return &gfc_bad_expr;
bf3fb7e4 3652
b7e75771 3653 return simplify_intconv (e, kind, "INT");
bf3fb7e4
FXC
3654}
3655
3656gfc_expr *
edf1eac2 3657gfc_simplify_int2 (gfc_expr *e)
bf3fb7e4 3658{
d93712d9 3659 return simplify_intconv (e, 2, "INT2");
bf3fb7e4
FXC
3660}
3661
edf1eac2 3662
bf3fb7e4 3663gfc_expr *
edf1eac2 3664gfc_simplify_int8 (gfc_expr *e)
bf3fb7e4 3665{
d93712d9 3666 return simplify_intconv (e, 8, "INT8");
bf3fb7e4
FXC
3667}
3668
edf1eac2 3669
bf3fb7e4 3670gfc_expr *
edf1eac2 3671gfc_simplify_long (gfc_expr *e)
bf3fb7e4 3672{
d93712d9 3673 return simplify_intconv (e, 4, "LONG");
bf3fb7e4
FXC
3674}
3675
3676
6de9cd9a 3677gfc_expr *
edf1eac2 3678gfc_simplify_ifix (gfc_expr *e)
6de9cd9a
DN
3679{
3680 gfc_expr *rtrunc, *result;
3681
3682 if (e->expr_type != EXPR_CONSTANT)
3683 return NULL;
3684
6de9cd9a 3685 rtrunc = gfc_copy_expr (e);
f8e566e5 3686 mpfr_trunc (rtrunc->value.real, e->value.real);
b7e75771
JD
3687
3688 result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
3689 &e->where);
7278e4dc 3690 gfc_mpfr_to_mpz (result->value.integer, rtrunc->value.real, &e->where);
6de9cd9a
DN
3691
3692 gfc_free_expr (rtrunc);
b7e75771 3693
6de9cd9a
DN
3694 return range_check (result, "IFIX");
3695}
3696
3697
3698gfc_expr *
edf1eac2 3699gfc_simplify_idint (gfc_expr *e)
6de9cd9a
DN
3700{
3701 gfc_expr *rtrunc, *result;
3702
3703 if (e->expr_type != EXPR_CONSTANT)
3704 return NULL;
3705
6de9cd9a 3706 rtrunc = gfc_copy_expr (e);
f8e566e5 3707 mpfr_trunc (rtrunc->value.real, e->value.real);
b7e75771
JD
3708
3709 result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
3710 &e->where);
7278e4dc 3711 gfc_mpfr_to_mpz (result->value.integer, rtrunc->value.real, &e->where);
6de9cd9a
DN
3712
3713 gfc_free_expr (rtrunc);
b7e75771 3714
6de9cd9a
DN
3715 return range_check (result, "IDINT");
3716}
3717
3718
3719gfc_expr *
edf1eac2 3720gfc_simplify_ior (gfc_expr *x, gfc_expr *y)
6de9cd9a
DN
3721{
3722 gfc_expr *result;
3723
3724 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
3725 return NULL;
3726
b7e75771 3727 result = gfc_get_constant_expr (BT_INTEGER, x->ts.kind, &x->where);
6de9cd9a 3728 mpz_ior (result->value.integer, x->value.integer, y->value.integer);
b7e75771 3729
6de9cd9a
DN
3730 return range_check (result, "IOR");
3731}
3732
3733
195a95c4
TB
3734static gfc_expr *
3735do_bit_xor (gfc_expr *result, gfc_expr *e)
3736{
3737 gcc_assert (e->ts.type == BT_INTEGER && e->expr_type == EXPR_CONSTANT);
3738 gcc_assert (result->ts.type == BT_INTEGER
3739 && result->expr_type == EXPR_CONSTANT);
3740
3741 mpz_xor (result->value.integer, result->value.integer, e->value.integer);
3742 return result;
3743}
3744
3745
3746gfc_expr *
3747gfc_simplify_iparity (gfc_expr *array, gfc_expr *dim, gfc_expr *mask)
3748{
3749 return simplify_transformation (array, dim, mask, 0, do_bit_xor);
3750}
3751
3752
4ec80803
FXC
3753gfc_expr *
3754gfc_simplify_is_iostat_end (gfc_expr *x)
3755{
4ec80803
FXC
3756 if (x->expr_type != EXPR_CONSTANT)
3757 return NULL;
3758
b7e75771
JD
3759 return gfc_get_logical_expr (gfc_default_logical_kind, &x->where,
3760 mpz_cmp_si (x->value.integer,
3761 LIBERROR_END) == 0);
4ec80803
FXC
3762}
3763
3764
3765gfc_expr *
3766gfc_simplify_is_iostat_eor (gfc_expr *x)
3767{
4ec80803
FXC
3768 if (x->expr_type != EXPR_CONSTANT)
3769 return NULL;
3770
b7e75771
JD
3771 return gfc_get_logical_expr (gfc_default_logical_kind, &x->where,
3772 mpz_cmp_si (x->value.integer,
3773 LIBERROR_EOR) == 0);
4ec80803
FXC
3774}
3775
3776
3777gfc_expr *
3778gfc_simplify_isnan (gfc_expr *x)
3779{
4ec80803
FXC
3780 if (x->expr_type != EXPR_CONSTANT)
3781 return NULL;
3782
b7e75771
JD
3783 return gfc_get_logical_expr (gfc_default_logical_kind, &x->where,
3784 mpfr_nan_p (x->value.real));
4ec80803
FXC
3785}
3786
3787
88a95a11
FXC
3788/* Performs a shift on its first argument. Depending on the last
3789 argument, the shift can be arithmetic, i.e. with filling from the
3790 left like in the SHIFTA intrinsic. */
3791static gfc_expr *
3792simplify_shift (gfc_expr *e, gfc_expr *s, const char *name,
3793 bool arithmetic, int direction)
6de9cd9a
DN
3794{
3795 gfc_expr *result;
88a95a11 3796 int ashift, *bits, i, k, bitsize, shift;
6de9cd9a
DN
3797
3798 if (e->expr_type != EXPR_CONSTANT || s->expr_type != EXPR_CONSTANT)
3799 return NULL;
58a9e3c4
SK
3800
3801 gfc_extract_int (s, &shift);
6de9cd9a 3802
e7a2d5fb 3803 k = gfc_validate_kind (BT_INTEGER, e->ts.kind, false);
88a95a11 3804 bitsize = gfc_integer_kinds[k].bit_size;
6de9cd9a 3805
88a95a11 3806 result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
6de9cd9a 3807
88a95a11
FXC
3808 if (shift == 0)
3809 {
3810 mpz_set (result->value.integer, e->value.integer);
3811 return result;
3812 }
6de9cd9a 3813
88a95a11 3814 if (direction > 0 && shift < 0)
6de9cd9a 3815 {
88a95a11
FXC
3816 /* Left shift, as in SHIFTL. */
3817 gfc_error ("Second argument of %s is negative at %L", name, &e->where);
6de9cd9a
DN
3818 return &gfc_bad_expr;
3819 }
88a95a11
FXC
3820 else if (direction < 0)
3821 {
3822 /* Right shift, as in SHIFTR or SHIFTA. */
3823 if (shift < 0)
3824 {
3825 gfc_error ("Second argument of %s is negative at %L",
3826 name, &e->where);
3827 return &gfc_bad_expr;
3828 }
6de9cd9a 3829
88a95a11
FXC
3830 shift = -shift;
3831 }
6de9cd9a 3832
88a95a11
FXC
3833 ashift = (shift >= 0 ? shift : -shift);
3834
3835 if (ashift > bitsize)
6de9cd9a 3836 {
88a95a11
FXC
3837 gfc_error ("Magnitude of second argument of %s exceeds bit size "
3838 "at %L", name, &e->where);
3839 return &gfc_bad_expr;
6de9cd9a 3840 }
5d24a977 3841
88a95a11
FXC
3842 bits = XCNEWVEC (int, bitsize);
3843
3844 for (i = 0; i < bitsize; i++)
5d24a977 3845 bits[i] = mpz_tstbit (e->value.integer, i);
6de9cd9a
DN
3846
3847 if (shift > 0)
5d24a977 3848 {
88a95a11 3849 /* Left shift. */
5d24a977
TS
3850 for (i = 0; i < shift; i++)
3851 mpz_clrbit (result->value.integer, i);
3852
88a95a11 3853 for (i = 0; i < bitsize - shift; i++)
5d24a977
TS
3854 {
3855 if (bits[i] == 0)
3856 mpz_clrbit (result->value.integer, i + shift);
3857 else
3858 mpz_setbit (result->value.integer, i + shift);
3859 }
3860 }
6de9cd9a 3861 else
5d24a977 3862 {
88a95a11
FXC
3863 /* Right shift. */
3864 if (arithmetic && bits[bitsize - 1])
3865 for (i = bitsize - 1; i >= bitsize - ashift; i--)
3866 mpz_setbit (result->value.integer, i);
3867 else
3868 for (i = bitsize - 1; i >= bitsize - ashift; i--)
3869 mpz_clrbit (result->value.integer, i);
5d24a977 3870
88a95a11 3871 for (i = bitsize - 1; i >= ashift; i--)
5d24a977
TS
3872 {
3873 if (bits[i] == 0)
3874 mpz_clrbit (result->value.integer, i - ashift);
3875 else
3876 mpz_setbit (result->value.integer, i - ashift);
3877 }
3878 }
6de9cd9a 3879
d01b2c21 3880 gfc_convert_mpz_to_signed (result->value.integer, bitsize);
cede9502 3881 free (bits);
88a95a11 3882
5d24a977 3883 return result;
6de9cd9a
DN
3884}
3885
3886
88a95a11
FXC
3887gfc_expr *
3888gfc_simplify_ishft (gfc_expr *e, gfc_expr *s)
3889{
3890 return simplify_shift (e, s, "ISHFT", false, 0);
3891}
3892
3893
3894gfc_expr *
3895gfc_simplify_lshift (gfc_expr *e, gfc_expr *s)
3896{
3897 return simplify_shift (e, s, "LSHIFT", false, 1);
3898}
3899
3900
3901gfc_expr *
3902gfc_simplify_rshift (gfc_expr *e, gfc_expr *s)
3903{
3904 return simplify_shift (e, s, "RSHIFT", true, -1);
3905}
3906
3907
3908gfc_expr *
3909gfc_simplify_shifta (gfc_expr *e, gfc_expr *s)
3910{
3911 return simplify_shift (e, s, "SHIFTA", true, -1);
3912}
3913
3914
3915gfc_expr *
3916gfc_simplify_shiftl (gfc_expr *e, gfc_expr *s)
3917{
3918 return simplify_shift (e, s, "SHIFTL", false, 1);
3919}
3920
3921
3922gfc_expr *
3923gfc_simplify_shiftr (gfc_expr *e, gfc_expr *s)
3924{
3925 return simplify_shift (e, s, "SHIFTR", false, -1);
3926}
3927
3928
6de9cd9a 3929gfc_expr *
edf1eac2 3930gfc_simplify_ishftc (gfc_expr *e, gfc_expr *s, gfc_expr *sz)
6de9cd9a
DN
3931{
3932 gfc_expr *result;
f1dcb9bf 3933 int shift, ashift, isize, ssize, delta, k;
6de9cd9a
DN
3934 int i, *bits;
3935
3936 if (e->expr_type != EXPR_CONSTANT || s->expr_type != EXPR_CONSTANT)
3937 return NULL;
3938
58a9e3c4 3939 gfc_extract_int (s, &shift);
6de9cd9a 3940
e7a2d5fb 3941 k = gfc_validate_kind (e->ts.type, e->ts.kind, false);
f1dcb9bf 3942 isize = gfc_integer_kinds[k].bit_size;
6de9cd9a
DN
3943
3944 if (sz != NULL)
3945 {
f1dcb9bf 3946 if (sz->expr_type != EXPR_CONSTANT)
edf1eac2 3947 return NULL;
f1dcb9bf 3948
58a9e3c4 3949 gfc_extract_int (sz, &ssize);
6de9cd9a
DN
3950 }
3951 else
f1dcb9bf 3952 ssize = isize;
6de9cd9a
DN
3953
3954 if (shift >= 0)
3955 ashift = shift;
3956 else
3957 ashift = -shift;
3958
f1dcb9bf 3959 if (ashift > ssize)
6de9cd9a 3960 {
58a9e3c4 3961 if (sz == NULL)
f1dcb9bf 3962 gfc_error ("Magnitude of second argument of ISHFTC exceeds "
c20f6223
JD
3963 "BIT_SIZE of first argument at %C");
3964 else
3965 gfc_error ("Absolute value of SHIFT shall be less than or equal "
3966 "to SIZE at %C");
6de9cd9a
DN
3967 return &gfc_bad_expr;
3968 }
3969
b7e75771 3970 result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
6de9cd9a 3971
f1dcb9bf
BM
3972 mpz_set (result->value.integer, e->value.integer);
3973
5d24a977 3974 if (shift == 0)
f1dcb9bf 3975 return result;
5d24a977 3976
f1dcb9bf 3977 convert_mpz_to_unsigned (result->value.integer, isize);
6de9cd9a 3978
ece3f663 3979 bits = XCNEWVEC (int, ssize);
f1dcb9bf
BM
3980
3981 for (i = 0; i < ssize; i++)
6de9cd9a
DN
3982 bits[i] = mpz_tstbit (e->value.integer, i);
3983
f1dcb9bf 3984 delta = ssize - ashift;
6de9cd9a 3985
5d24a977 3986 if (shift > 0)
6de9cd9a
DN
3987 {
3988 for (i = 0; i < delta; i++)
3989 {
3990 if (bits[i] == 0)
3991 mpz_clrbit (result->value.integer, i + shift);
5d24a977 3992 else
6de9cd9a
DN
3993 mpz_setbit (result->value.integer, i + shift);
3994 }
3995
f1dcb9bf 3996 for (i = delta; i < ssize; i++)
6de9cd9a
DN
3997 {
3998 if (bits[i] == 0)
3999 mpz_clrbit (result->value.integer, i - delta);
5d24a977 4000 else
6de9cd9a
DN
4001 mpz_setbit (result->value.integer, i - delta);
4002 }
6de9cd9a
DN
4003 }
4004 else
4005 {
4006 for (i = 0; i < ashift; i++)
4007 {
4008 if (bits[i] == 0)
4009 mpz_clrbit (result->value.integer, i + delta);
5d24a977 4010 else
6de9cd9a
DN
4011 mpz_setbit (result->value.integer, i + delta);
4012 }
4013
f1dcb9bf 4014 for (i = ashift; i < ssize; i++)
6de9cd9a
DN
4015 {
4016 if (bits[i] == 0)
4017 mpz_clrbit (result->value.integer, i + shift);
5d24a977 4018 else
6de9cd9a
DN
4019 mpz_setbit (result->value.integer, i + shift);
4020 }
6de9cd9a 4021 }
5d24a977 4022
d01b2c21 4023 gfc_convert_mpz_to_signed (result->value.integer, isize);
5d24a977 4024
cede9502 4025 free (bits);
5d24a977 4026 return result;
6de9cd9a
DN
4027}
4028
4029
4030gfc_expr *
edf1eac2 4031gfc_simplify_kind (gfc_expr *e)
6de9cd9a 4032{
b7e75771 4033 return gfc_get_int_expr (gfc_default_integer_kind, NULL, e->ts.kind);
6de9cd9a
DN
4034}
4035
4036
4037static gfc_expr *
5cda5098 4038simplify_bound_dim (gfc_expr *array, gfc_expr *kind, int d, int upper,
64f002ed 4039 gfc_array_spec *as, gfc_ref *ref, bool coarray)
6de9cd9a 4040{
9f1dce56 4041 gfc_expr *l, *u, *result;
5cda5098 4042 int k;
6de9cd9a 4043
69dcd06a 4044 k = get_kind (BT_INTEGER, kind, upper ? "UBOUND" : "LBOUND",
8b704316 4045 gfc_default_integer_kind);
69dcd06a
DK
4046 if (k == -1)
4047 return &gfc_bad_expr;
4048
4049 result = gfc_get_constant_expr (BT_INTEGER, k, &array->where);
4050
4051 /* For non-variables, LBOUND(expr, DIM=n) = 1 and
4052 UBOUND(expr, DIM=n) = SIZE(expr, DIM=n). */
4053 if (!coarray && array->expr_type != EXPR_VARIABLE)
4054 {
4055 if (upper)
4056 {
4057 gfc_expr* dim = result;
4058 mpz_set_si (dim->value.integer, d);
4059
1634e53f 4060 result = simplify_size (array, dim, k);
69dcd06a
DK
4061 gfc_free_expr (dim);
4062 if (!result)
4063 goto returnNull;
4064 }
4065 else
4066 mpz_set_si (result->value.integer, 1);
4067
4068 goto done;
4069 }
4070
4071 /* Otherwise, we have a variable expression. */
4072 gcc_assert (array->expr_type == EXPR_VARIABLE);
4073 gcc_assert (as);
4074
524af0d6 4075 if (!gfc_resolve_array_spec (as, 0))
0423b64a
MM
4076 return NULL;
4077
fc9f54d5 4078 /* The last dimension of an assumed-size array is special. */
64f002ed 4079 if ((!coarray && d == as->rank && as->type == AS_ASSUMED_SIZE && !upper)
155e5d5f 4080 || (coarray && d == as->rank + as->corank
f19626cf 4081 && (!upper || flag_coarray == GFC_FCOARRAY_SINGLE)))
fc9f54d5
FXC
4082 {
4083 if (as->lower[d-1]->expr_type == EXPR_CONSTANT)
69dcd06a
DK
4084 {
4085 gfc_free_expr (result);
4086 return gfc_copy_expr (as->lower[d-1]);
4087 }
6de9cd9a 4088
69dcd06a
DK
4089 goto returnNull;
4090 }
5cda5098 4091
b7e75771 4092 result = gfc_get_constant_expr (BT_INTEGER, k, &array->where);
fc9f54d5 4093
543af7ab 4094 /* Then, we need to know the extent of the given dimension. */
11642de8 4095 if (coarray || (ref->u.ar.type == AR_FULL && !ref->next))
fc9f54d5 4096 {
22fa926f
MM
4097 gfc_expr *declared_bound;
4098 int empty_bound;
4099 bool constant_lbound, constant_ubound;
4100
543af7ab
TK
4101 l = as->lower[d-1];
4102 u = as->upper[d-1];
4103
22fa926f
MM
4104 gcc_assert (l != NULL);
4105
4106 constant_lbound = l->expr_type == EXPR_CONSTANT;
4107 constant_ubound = u && u->expr_type == EXPR_CONSTANT;
4108
4109 empty_bound = upper ? 0 : 1;
4110 declared_bound = upper ? u : l;
4111
4112 if ((!upper && !constant_lbound)
4113 || (upper && !constant_ubound))
69dcd06a 4114 goto returnNull;
543af7ab 4115
22fa926f 4116 if (!coarray)
543af7ab 4117 {
22fa926f
MM
4118 /* For {L,U}BOUND, the value depends on whether the array
4119 is empty. We can nevertheless simplify if the declared bound
4120 has the same value as that of an empty array, in which case
4121 the result isn't dependent on the array emptyness. */
4122 if (mpz_cmp_si (declared_bound->value.integer, empty_bound) == 0)
4123 mpz_set_si (result->value.integer, empty_bound);
4124 else if (!constant_lbound || !constant_ubound)
4125 /* Array emptyness can't be determined, we can't simplify. */
4126 goto returnNull;
4127 else if (mpz_cmp (l->value.integer, u->value.integer) > 0)
4128 mpz_set_si (result->value.integer, empty_bound);
543af7ab 4129 else
22fa926f 4130 mpz_set (result->value.integer, declared_bound->value.integer);
543af7ab 4131 }
fc9f54d5 4132 else
22fa926f 4133 mpz_set (result->value.integer, declared_bound->value.integer);
fc9f54d5
FXC
4134 }
4135 else
4136 {
fc9f54d5 4137 if (upper)
543af7ab 4138 {
524af0d6 4139 if (!gfc_ref_dimen_size (&ref->u.ar, d - 1, &result->value.integer, NULL))
69dcd06a 4140 goto returnNull;
543af7ab 4141 }
fc9f54d5 4142 else
543af7ab 4143 mpz_set_si (result->value.integer, (long int) 1);
fc9f54d5
FXC
4144 }
4145
69dcd06a 4146done:
fc9f54d5 4147 return range_check (result, upper ? "UBOUND" : "LBOUND");
69dcd06a
DK
4148
4149returnNull:
4150 gfc_free_expr (result);
4151 return NULL;
fc9f54d5
FXC
4152}
4153
4154
4155static gfc_expr *
5cda5098 4156simplify_bound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind, int upper)
fc9f54d5
FXC
4157{
4158 gfc_ref *ref;
4159 gfc_array_spec *as;
808a6ead 4160 ar_type type = AR_UNKNOWN;
fc9f54d5
FXC
4161 int d;
4162
c49ea23d
PT
4163 if (array->ts.type == BT_CLASS)
4164 return NULL;
4165
9f1dce56 4166 if (array->expr_type != EXPR_VARIABLE)
69dcd06a
DK
4167 {
4168 as = NULL;
4169 ref = NULL;
4170 goto done;
4171 }
9f1dce56 4172
49795733
FR
4173 /* Do not attempt to resolve if error has already been issued. */
4174 if (array->symtree->n.sym->error)
4175 return NULL;
4176
6de9cd9a
DN
4177 /* Follow any component references. */
4178 as = array->symtree->n.sym->as;
2a4a7830
TS
4179 for (ref = array->ref; ref; ref = ref->next)
4180 {
4181 switch (ref->type)
4182 {
4183 case REF_ARRAY:
808a6ead 4184 type = ref->u.ar.type;
2a4a7830
TS
4185 switch (ref->u.ar.type)
4186 {
4187 case AR_ELEMENT:
4188 as = NULL;
4189 continue;
4190
4191 case AR_FULL:
4192 /* We're done because 'as' has already been set in the
4193 previous iteration. */
11642de8 4194 goto done;
2a4a7830 4195
2a4a7830
TS
4196 case AR_UNKNOWN:
4197 return NULL;
543af7ab
TK
4198
4199 case AR_SECTION:
4200 as = ref->u.ar.as;
4201 goto done;
2a4a7830
TS
4202 }
4203
4204 gcc_unreachable ();
4205
4206 case REF_COMPONENT:
4207 as = ref->u.c.component->as;
4208 continue;
4209
4210 case REF_SUBSTRING:
a5fbc2f3 4211 case REF_INQUIRY:
2a4a7830
TS
4212 continue;
4213 }
4214 }
4215
4216 gcc_unreachable ();
4217
4218 done:
fc9f54d5 4219
22fa926f
MM
4220 if (as && (as->type == AS_DEFERRED || as->type == AS_ASSUMED_RANK
4221 || (as->type == AS_ASSUMED_SHAPE && upper)))
2a4a7830
TS
4222 return NULL;
4223
22fa926f
MM
4224 gcc_assert (!as
4225 || (as->type != AS_DEFERRED
4226 && array->expr_type == EXPR_VARIABLE
21cd397e
MM
4227 && !gfc_expr_attr (array).allocatable
4228 && !gfc_expr_attr (array).pointer));
22fa926f 4229
fc9f54d5 4230 if (dim == NULL)
6de9cd9a 4231 {
fc9f54d5
FXC
4232 /* Multi-dimensional bounds. */
4233 gfc_expr *bounds[GFC_MAX_DIMENSIONS];
4234 gfc_expr *e;
5cda5098 4235 int k;
6de9cd9a 4236
fc9f54d5 4237 /* UBOUND(ARRAY) is not valid for an assumed-size array. */
808a6ead 4238 if (upper && type == AR_FULL && as && as->type == AS_ASSUMED_SIZE)
fc9f54d5
FXC
4239 {
4240 /* An error message will be emitted in
4241 check_assumed_size_reference (resolve.c). */
4242 return &gfc_bad_expr;
4243 }
2a4a7830 4244
fc9f54d5
FXC
4245 /* Simplify the bounds for each dimension. */
4246 for (d = 0; d < array->rank; d++)
4247 {
64f002ed
TB
4248 bounds[d] = simplify_bound_dim (array, kind, d + 1, upper, as, ref,
4249 false);
fc9f54d5
FXC
4250 if (bounds[d] == NULL || bounds[d] == &gfc_bad_expr)
4251 {
4252 int j;
9f1dce56 4253
fc9f54d5
FXC
4254 for (j = 0; j < d; j++)
4255 gfc_free_expr (bounds[j]);
4dc64371
TK
4256
4257 if (gfc_seen_div0)
4258 return &gfc_bad_expr;
4259 else
4260 return bounds[d];
fc9f54d5
FXC
4261 }
4262 }
2a4a7830 4263
fc9f54d5 4264 /* Allocate the result expression. */
5cda5098 4265 k = get_kind (BT_INTEGER, kind, upper ? "UBOUND" : "LBOUND",
b7e75771 4266 gfc_default_integer_kind);
5cda5098 4267 if (k == -1)
b7e75771
JD
4268 return &gfc_bad_expr;
4269
4270 e = gfc_get_array_expr (BT_INTEGER, k, &array->where);
fc9f54d5
FXC
4271
4272 /* The result is a rank 1 array; its size is the rank of the first
4273 argument to {L,U}BOUND. */
4274 e->rank = 1;
4275 e->shape = gfc_get_shape (1);
4276 mpz_init_set_ui (e->shape[0], array->rank);
4277
4278 /* Create the constructor for this array. */
fc9f54d5 4279 for (d = 0; d < array->rank; d++)
b7e75771
JD
4280 gfc_constructor_append_expr (&e->value.constructor,
4281 bounds[d], &e->where);
fc9f54d5
FXC
4282
4283 return e;
9f1dce56
FXC
4284 }
4285 else
4286 {
fc9f54d5
FXC
4287 /* A DIM argument is specified. */
4288 if (dim->expr_type != EXPR_CONSTANT)
4289 return NULL;
9f1dce56 4290
fc9f54d5
FXC
4291 d = mpz_get_si (dim->value.integer);
4292
c62c6622 4293 if ((d < 1 || d > array->rank)
69dcd06a 4294 || (d == array->rank && as && as->type == AS_ASSUMED_SIZE && upper))
fc9f54d5
FXC
4295 {
4296 gfc_error ("DIM argument at %L is out of bounds", &dim->where);
4297 return &gfc_bad_expr;
4298 }
4299
c62c6622
TB
4300 if (as && as->type == AS_ASSUMED_RANK)
4301 return NULL;
4302
64f002ed
TB
4303 return simplify_bound_dim (array, kind, d, upper, as, ref, false);
4304 }
4305}
4306
4307
4308static gfc_expr *
4309simplify_cobound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind, int upper)
4310{
4311 gfc_ref *ref;
4312 gfc_array_spec *as;
4313 int d;
4314
4315 if (array->expr_type != EXPR_VARIABLE)
4316 return NULL;
4317
4318 /* Follow any component references. */
c49ea23d
PT
4319 as = (array->ts.type == BT_CLASS && array->ts.u.derived->components)
4320 ? array->ts.u.derived->components->as
4321 : array->symtree->n.sym->as;
64f002ed
TB
4322 for (ref = array->ref; ref; ref = ref->next)
4323 {
4324 switch (ref->type)
4325 {
4326 case REF_ARRAY:
4327 switch (ref->u.ar.type)
4328 {
4329 case AR_ELEMENT:
dbeebc56 4330 if (ref->u.ar.as->corank > 0)
a10da381 4331 {
dbeebc56 4332 gcc_assert (as == ref->u.ar.as);
a10da381
TB
4333 goto done;
4334 }
64f002ed
TB
4335 as = NULL;
4336 continue;
4337
4338 case AR_FULL:
4339 /* We're done because 'as' has already been set in the
4340 previous iteration. */
11642de8 4341 goto done;
64f002ed
TB
4342
4343 case AR_UNKNOWN:
4344 return NULL;
4345
4346 case AR_SECTION:
4347 as = ref->u.ar.as;
4348 goto done;
4349 }
4350
4351 gcc_unreachable ();
4352
4353 case REF_COMPONENT:
4354 as = ref->u.c.component->as;
4355 continue;
4356
4357 case REF_SUBSTRING:
a5fbc2f3 4358 case REF_INQUIRY:
64f002ed
TB
4359 continue;
4360 }
4361 }
4362
c49ea23d
PT
4363 if (!as)
4364 gcc_unreachable ();
64f002ed
TB
4365
4366 done:
4367
c49ea23d 4368 if (as->cotype == AS_DEFERRED || as->cotype == AS_ASSUMED_SHAPE)
64f002ed
TB
4369 return NULL;
4370
4371 if (dim == NULL)
4372 {
4373 /* Multi-dimensional cobounds. */
4374 gfc_expr *bounds[GFC_MAX_DIMENSIONS];
4375 gfc_expr *e;
4376 int k;
4377
4378 /* Simplify the cobounds for each dimension. */
4379 for (d = 0; d < as->corank; d++)
4380 {
c49ea23d 4381 bounds[d] = simplify_bound_dim (array, kind, d + 1 + as->rank,
64f002ed
TB
4382 upper, as, ref, true);
4383 if (bounds[d] == NULL || bounds[d] == &gfc_bad_expr)
4384 {
4385 int j;
4386
4387 for (j = 0; j < d; j++)
4388 gfc_free_expr (bounds[j]);
4389 return bounds[d];
4390 }
4391 }
4392
4393 /* Allocate the result expression. */
4394 e = gfc_get_expr ();
4395 e->where = array->where;
4396 e->expr_type = EXPR_ARRAY;
4397 e->ts.type = BT_INTEGER;
4398 k = get_kind (BT_INTEGER, kind, upper ? "UCOBOUND" : "LCOBOUND",
8b704316 4399 gfc_default_integer_kind);
64f002ed
TB
4400 if (k == -1)
4401 {
4402 gfc_free_expr (e);
4403 return &gfc_bad_expr;
4404 }
4405 e->ts.kind = k;
4406
4407 /* The result is a rank 1 array; its size is the rank of the first
4408 argument to {L,U}COBOUND. */
4409 e->rank = 1;
4410 e->shape = gfc_get_shape (1);
4411 mpz_init_set_ui (e->shape[0], as->corank);
4412
4413 /* Create the constructor for this array. */
4414 for (d = 0; d < as->corank; d++)
4415 gfc_constructor_append_expr (&e->value.constructor,
4416 bounds[d], &e->where);
4417 return e;
4418 }
4419 else
4420 {
4421 /* A DIM argument is specified. */
4422 if (dim->expr_type != EXPR_CONSTANT)
4423 return NULL;
4424
4425 d = mpz_get_si (dim->value.integer);
4426
4427 if (d < 1 || d > as->corank)
4428 {
4429 gfc_error ("DIM argument at %L is out of bounds", &dim->where);
4430 return &gfc_bad_expr;
4431 }
4432
c49ea23d 4433 return simplify_bound_dim (array, kind, d+as->rank, upper, as, ref, true);
fc9f54d5 4434 }
6de9cd9a
DN
4435}
4436
4437
4438gfc_expr *
5cda5098 4439gfc_simplify_lbound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
6de9cd9a 4440{
5cda5098 4441 return simplify_bound (array, dim, kind, 0);
6de9cd9a
DN
4442}
4443
4444
64f002ed
TB
4445gfc_expr *
4446gfc_simplify_lcobound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
4447{
a3935ffc 4448 return simplify_cobound (array, dim, kind, 0);
64f002ed
TB
4449}
4450
414f00e9
SB
4451gfc_expr *
4452gfc_simplify_leadz (gfc_expr *e)
4453{
414f00e9
SB
4454 unsigned long lz, bs;
4455 int i;
4456
4457 if (e->expr_type != EXPR_CONSTANT)
4458 return NULL;
4459
4460 i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
4461 bs = gfc_integer_kinds[i].bit_size;
4462 if (mpz_cmp_si (e->value.integer, 0) == 0)
4463 lz = bs;
0a05c536
FXC
4464 else if (mpz_cmp_si (e->value.integer, 0) < 0)
4465 lz = 0;
414f00e9
SB
4466 else
4467 lz = bs - mpz_sizeinbase (e->value.integer, 2);
4468
b7e75771 4469 return gfc_get_int_expr (gfc_default_integer_kind, &e->where, lz);
414f00e9
SB
4470}
4471
4472
6de9cd9a 4473gfc_expr *
5cda5098 4474gfc_simplify_len (gfc_expr *e, gfc_expr *kind)
6de9cd9a
DN
4475{
4476 gfc_expr *result;
5cda5098
FXC
4477 int k = get_kind (BT_INTEGER, kind, "LEN", gfc_default_integer_kind);
4478
4479 if (k == -1)
4480 return &gfc_bad_expr;
6de9cd9a 4481
49914d03
FXC
4482 if (e->expr_type == EXPR_CONSTANT)
4483 {
b7e75771 4484 result = gfc_get_constant_expr (BT_INTEGER, k, &e->where);
49914d03 4485 mpz_set_si (result->value.integer, e->value.character.length);
b7e75771 4486 return range_check (result, "LEN");
49914d03 4487 }
b7e75771
JD
4488 else if (e->ts.u.cl != NULL && e->ts.u.cl->length != NULL
4489 && e->ts.u.cl->length->expr_type == EXPR_CONSTANT
4490 && e->ts.u.cl->length->ts.type == BT_INTEGER)
49914d03 4491 {
b7e75771 4492 result = gfc_get_constant_expr (BT_INTEGER, k, &e->where);
bc21d315 4493 mpz_set (result->value.integer, e->ts.u.cl->length->value.integer);
b7e75771 4494 return range_check (result, "LEN");
49914d03 4495 }
5b384b3d
PT
4496 else if (e->expr_type == EXPR_VARIABLE && e->ts.type == BT_CHARACTER
4497 && e->symtree->n.sym
1f8dd420 4498 && e->symtree->n.sym->ts.type != BT_DERIVED
5b384b3d 4499 && e->symtree->n.sym->assoc && e->symtree->n.sym->assoc->target
1f8dd420
AV
4500 && e->symtree->n.sym->assoc->target->ts.type == BT_DERIVED
4501 && e->symtree->n.sym->assoc->target->symtree->n.sym
4502 && UNLIMITED_POLY (e->symtree->n.sym->assoc->target->symtree->n.sym))
4503
5b384b3d
PT
4504 /* The expression in assoc->target points to a ref to the _data component
4505 of the unlimited polymorphic entity. To get the _len component the last
4506 _data ref needs to be stripped and a ref to the _len component added. */
9e6644c6 4507 return gfc_get_len_component (e->symtree->n.sym->assoc->target, k);
b7e75771
JD
4508 else
4509 return NULL;
6de9cd9a
DN
4510}
4511
4512
4513gfc_expr *
5cda5098 4514gfc_simplify_len_trim (gfc_expr *e, gfc_expr *kind)
6de9cd9a
DN
4515{
4516 gfc_expr *result;
6b271a2e 4517 size_t count, len, i;
5cda5098
FXC
4518 int k = get_kind (BT_INTEGER, kind, "LEN_TRIM", gfc_default_integer_kind);
4519
4520 if (k == -1)
4521 return &gfc_bad_expr;
6de9cd9a
DN
4522
4523 if (e->expr_type != EXPR_CONSTANT)
4524 return NULL;
4525
6de9cd9a 4526 len = e->value.character.length;
6de9cd9a
DN
4527 for (count = 0, i = 1; i <= len; i++)
4528 if (e->value.character.string[len - i] == ' ')
4529 count++;
4530 else
4531 break;
4532
b7e75771 4533 result = gfc_get_int_expr (k, &e->where, len - count);
6de9cd9a
DN
4534 return range_check (result, "LEN_TRIM");
4535}
4536
75be5dc0 4537gfc_expr *
b7e75771 4538gfc_simplify_lgamma (gfc_expr *x)
75be5dc0 4539{
75be5dc0 4540 gfc_expr *result;
5b550abd 4541 int sg;
75be5dc0
TB
4542
4543 if (x->expr_type != EXPR_CONSTANT)
4544 return NULL;
4545
b7e75771 4546 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
5b550abd 4547 mpfr_lgamma (result->value.real, &sg, x->value.real, GFC_RND_MODE);
75be5dc0
TB
4548
4549 return range_check (result, "LGAMMA");
75be5dc0
TB
4550}
4551
6de9cd9a
DN
4552
4553gfc_expr *
edf1eac2 4554gfc_simplify_lge (gfc_expr *a, gfc_expr *b)
6de9cd9a 4555{
6de9cd9a
DN
4556 if (a->expr_type != EXPR_CONSTANT || b->expr_type != EXPR_CONSTANT)
4557 return NULL;
4558
b7e75771
JD
4559 return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
4560 gfc_compare_string (a, b) >= 0);
6de9cd9a
DN
4561}
4562
4563
4564gfc_expr *
edf1eac2 4565gfc_simplify_lgt (gfc_expr *a, gfc_expr *b)
6de9cd9a 4566{
6de9cd9a
DN
4567 if (a->expr_type != EXPR_CONSTANT || b->expr_type != EXPR_CONSTANT)
4568 return NULL;
4569
b7e75771
JD
4570 return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
4571 gfc_compare_string (a, b) > 0);
6de9cd9a
DN
4572}
4573
4574
4575gfc_expr *
edf1eac2 4576gfc_simplify_lle (gfc_expr *a, gfc_expr *b)
6de9cd9a 4577{
6de9cd9a
DN
4578 if (a->expr_type != EXPR_CONSTANT || b->expr_type != EXPR_CONSTANT)
4579 return NULL;
4580
b7e75771
JD
4581 return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
4582 gfc_compare_string (a, b) <= 0);
6de9cd9a
DN
4583}
4584
4585
4586gfc_expr *
edf1eac2 4587gfc_simplify_llt (gfc_expr *a, gfc_expr *b)
6de9cd9a 4588{
6de9cd9a
DN
4589 if (a->expr_type != EXPR_CONSTANT || b->expr_type != EXPR_CONSTANT)
4590 return NULL;
4591
b7e75771
JD
4592 return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
4593 gfc_compare_string (a, b) < 0);
6de9cd9a
DN
4594}
4595
4596
4597gfc_expr *
edf1eac2 4598gfc_simplify_log (gfc_expr *x)
6de9cd9a
DN
4599{
4600 gfc_expr *result;
6de9cd9a
DN
4601
4602 if (x->expr_type != EXPR_CONSTANT)
4603 return NULL;
4604
b7e75771 4605 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
f8e566e5 4606
6de9cd9a
DN
4607 switch (x->ts.type)
4608 {
4609 case BT_REAL:
03ddaf35 4610 if (mpfr_sgn (x->value.real) <= 0)
6de9cd9a 4611 {
edf1eac2
SK
4612 gfc_error ("Argument of LOG at %L cannot be less than or equal "
4613 "to zero", &x->where);
6de9cd9a
DN
4614 gfc_free_expr (result);
4615 return &gfc_bad_expr;
4616 }
4617
edf1eac2 4618 mpfr_log (result->value.real, x->value.real, GFC_RND_MODE);
6de9cd9a
DN
4619 break;
4620
4621 case BT_COMPLEX:
d2af8cc6
FXC
4622 if (mpfr_zero_p (mpc_realref (x->value.complex))
4623 && mpfr_zero_p (mpc_imagref (x->value.complex)))
6de9cd9a
DN
4624 {
4625 gfc_error ("Complex argument of LOG at %L cannot be zero",
4626 &x->where);
4627 gfc_free_expr (result);
4628 return &gfc_bad_expr;
4629 }
4630
7306494a 4631 gfc_set_model_kind (x->ts.kind);
eb6f9a86 4632 mpc_log (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
6de9cd9a
DN
4633 break;
4634
4635 default:
4636 gfc_internal_error ("gfc_simplify_log: bad type");
4637 }
4638
4639 return range_check (result, "LOG");
4640}
4641
4642
4643gfc_expr *
edf1eac2 4644gfc_simplify_log10 (gfc_expr *x)
6de9cd9a
DN
4645{
4646 gfc_expr *result;
4647
4648 if (x->expr_type != EXPR_CONSTANT)
4649 return NULL;
4650
03ddaf35 4651 if (mpfr_sgn (x->value.real) <= 0)
6de9cd9a 4652 {
edf1eac2
SK
4653 gfc_error ("Argument of LOG10 at %L cannot be less than or equal "
4654 "to zero", &x->where);
6de9cd9a
DN
4655 return &gfc_bad_expr;
4656 }
4657
b7e75771 4658 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
f8e566e5 4659 mpfr_log10 (result->value.real, x->value.real, GFC_RND_MODE);
6de9cd9a
DN
4660
4661 return range_check (result, "LOG10");
4662}
4663
4664
4665gfc_expr *
edf1eac2 4666gfc_simplify_logical (gfc_expr *e, gfc_expr *k)
6de9cd9a 4667{
6de9cd9a
DN
4668 int kind;
4669
9d64df18 4670 kind = get_kind (BT_LOGICAL, k, "LOGICAL", gfc_default_logical_kind);
6de9cd9a
DN
4671 if (kind < 0)
4672 return &gfc_bad_expr;
4673
4674 if (e->expr_type != EXPR_CONSTANT)
4675 return NULL;
4676
b7e75771 4677 return gfc_get_logical_expr (kind, &e->where, e->value.logical);
6de9cd9a
DN
4678}
4679
4680
8ec259c1
DF
4681gfc_expr*
4682gfc_simplify_matmul (gfc_expr *matrix_a, gfc_expr *matrix_b)
4683{
4684 gfc_expr *result;
b7e75771
JD
4685 int row, result_rows, col, result_columns;
4686 int stride_a, offset_a, stride_b, offset_b;
8ec259c1
DF
4687
4688 if (!is_constant_array_expr (matrix_a)
4689 || !is_constant_array_expr (matrix_b))
4690 return NULL;
4691
f5240750
SK
4692 /* MATMUL should do mixed-mode arithmetic. Set the result type. */
4693 if (matrix_a->ts.type != matrix_b->ts.type)
4694 {
4695 gfc_expr e;
4696 e.expr_type = EXPR_OP;
4697 gfc_clear_ts (&e.ts);
4698 e.value.op.op = INTRINSIC_NONE;
4699 e.value.op.op1 = matrix_a;
4700 e.value.op.op2 = matrix_b;
4701 gfc_type_convert_binary (&e, 1);
4702 result = gfc_get_array_expr (e.ts.type, e.ts.kind, &matrix_a->where);
4703 }
4704 else
4705 {
4706 result = gfc_get_array_expr (matrix_a->ts.type, matrix_a->ts.kind,
4707 &matrix_a->where);
4708 }
8ec259c1
DF
4709
4710 if (matrix_a->rank == 1 && matrix_b->rank == 2)
4711 {
4712 result_rows = 1;
711db0a6 4713 result_columns = mpz_get_si (matrix_b->shape[1]);
8ec259c1
DF
4714 stride_a = 1;
4715 stride_b = mpz_get_si (matrix_b->shape[0]);
4716
4717 result->rank = 1;
4718 result->shape = gfc_get_shape (result->rank);
4719 mpz_init_set_si (result->shape[0], result_columns);
4720 }
4721 else if (matrix_a->rank == 2 && matrix_b->rank == 1)
4722 {
711db0a6 4723 result_rows = mpz_get_si (matrix_a->shape[0]);
8ec259c1
DF
4724 result_columns = 1;
4725 stride_a = mpz_get_si (matrix_a->shape[0]);
4726 stride_b = 1;
4727
4728 result->rank = 1;
4729 result->shape = gfc_get_shape (result->rank);
4730 mpz_init_set_si (result->shape[0], result_rows);
4731 }
4732 else if (matrix_a->rank == 2 && matrix_b->rank == 2)
4733 {
4734 result_rows = mpz_get_si (matrix_a->shape[0]);
4735 result_columns = mpz_get_si (matrix_b->shape[1]);
711db0a6 4736 stride_a = mpz_get_si (matrix_a->shape[0]);
8ec259c1
DF
4737 stride_b = mpz_get_si (matrix_b->shape[0]);
4738
4739 result->rank = 2;
4740 result->shape = gfc_get_shape (result->rank);
4741 mpz_init_set_si (result->shape[0], result_rows);
4742 mpz_init_set_si (result->shape[1], result_columns);
4743 }
4744 else
4745 gcc_unreachable();
4746
8ba6ea87 4747 offset_b = 0;
8ec259c1
DF
4748 for (col = 0; col < result_columns; ++col)
4749 {
b7e75771 4750 offset_a = 0;
8ec259c1
DF
4751
4752 for (row = 0; row < result_rows; ++row)
4753 {
b7e75771 4754 gfc_expr *e = compute_dot_product (matrix_a, stride_a, offset_a,
eebb98a5 4755 matrix_b, 1, offset_b, false);
b7e75771
JD
4756 gfc_constructor_append_expr (&result->value.constructor,
4757 e, NULL);
8ec259c1 4758
b7e75771
JD
4759 offset_a += 1;
4760 }
8ec259c1 4761
b7e75771 4762 offset_b += stride_b;
8ec259c1
DF
4763 }
4764
4765 return result;
4766}
4767
4768
88a95a11
FXC
4769gfc_expr *
4770gfc_simplify_maskr (gfc_expr *i, gfc_expr *kind_arg)
4771{
4772 gfc_expr *result;
4773 int kind, arg, k;
88a95a11
FXC
4774
4775 if (i->expr_type != EXPR_CONSTANT)
4776 return NULL;
8b704316 4777
88a95a11
FXC
4778 kind = get_kind (BT_INTEGER, kind_arg, "MASKR", gfc_default_integer_kind);
4779 if (kind == -1)
4780 return &gfc_bad_expr;
4781 k = gfc_validate_kind (BT_INTEGER, kind, false);
4782
51f03c6b
JJ
4783 bool fail = gfc_extract_int (i, &arg);
4784 gcc_assert (!fail);
88a95a11
FXC
4785
4786 result = gfc_get_constant_expr (BT_INTEGER, kind, &i->where);
4787
4788 /* MASKR(n) = 2^n - 1 */
4789 mpz_set_ui (result->value.integer, 1);
4790 mpz_mul_2exp (result->value.integer, result->value.integer, arg);
4791 mpz_sub_ui (result->value.integer, result->value.integer, 1);
4792
d01b2c21 4793 gfc_convert_mpz_to_signed (result->value.integer, gfc_integer_kinds[k].bit_size);
88a95a11
FXC
4794
4795 return result;
4796}
4797
4798
4799gfc_expr *
4800gfc_simplify_maskl (gfc_expr *i, gfc_expr *kind_arg)
4801{
4802 gfc_expr *result;
4803 int kind, arg, k;
88a95a11
FXC
4804 mpz_t z;
4805
4806 if (i->expr_type != EXPR_CONSTANT)
4807 return NULL;
8b704316 4808
88a95a11
FXC
4809 kind = get_kind (BT_INTEGER, kind_arg, "MASKL", gfc_default_integer_kind);
4810 if (kind == -1)
4811 return &gfc_bad_expr;
4812 k = gfc_validate_kind (BT_INTEGER, kind, false);
4813
51f03c6b
JJ
4814 bool fail = gfc_extract_int (i, &arg);
4815 gcc_assert (!fail);
88a95a11
FXC
4816
4817 result = gfc_get_constant_expr (BT_INTEGER, kind, &i->where);
4818
4819 /* MASKL(n) = 2^bit_size - 2^(bit_size - n) */
4820 mpz_init_set_ui (z, 1);
4821 mpz_mul_2exp (z, z, gfc_integer_kinds[k].bit_size);
4822 mpz_set_ui (result->value.integer, 1);
4823 mpz_mul_2exp (result->value.integer, result->value.integer,
4824 gfc_integer_kinds[k].bit_size - arg);
4825 mpz_sub (result->value.integer, z, result->value.integer);
4826 mpz_clear (z);
4827
d01b2c21 4828 gfc_convert_mpz_to_signed (result->value.integer, gfc_integer_kinds[k].bit_size);
88a95a11
FXC
4829
4830 return result;
4831}
4832
4833
8f2b565d
DF
4834gfc_expr *
4835gfc_simplify_merge (gfc_expr *tsource, gfc_expr *fsource, gfc_expr *mask)
4836{
03580130
TB
4837 gfc_expr * result;
4838 gfc_constructor *tsource_ctor, *fsource_ctor, *mask_ctor;
4839
4840 if (mask->expr_type == EXPR_CONSTANT)
81e87db4
SK
4841 {
4842 result = gfc_copy_expr (mask->value.logical ? tsource : fsource);
4843 /* Parenthesis is needed to get lower bounds of 1. */
4844 result = gfc_get_parentheses (result);
4845 gfc_simplify_expr (result, 1);
4846 return result;
4847 }
03580130
TB
4848
4849 if (!mask->rank || !is_constant_array_expr (mask)
4850 || !is_constant_array_expr (tsource) || !is_constant_array_expr (fsource))
8f2b565d
DF
4851 return NULL;
4852
03580130
TB
4853 result = gfc_get_array_expr (tsource->ts.type, tsource->ts.kind,
4854 &tsource->where);
4855 if (tsource->ts.type == BT_DERIVED)
4856 result->ts.u.derived = tsource->ts.u.derived;
4857 else if (tsource->ts.type == BT_CHARACTER)
4858 result->ts.u.cl = tsource->ts.u.cl;
4859
4860 tsource_ctor = gfc_constructor_first (tsource->value.constructor);
4861 fsource_ctor = gfc_constructor_first (fsource->value.constructor);
4862 mask_ctor = gfc_constructor_first (mask->value.constructor);
4863
4864 while (mask_ctor)
4865 {
4866 if (mask_ctor->expr->value.logical)
4867 gfc_constructor_append_expr (&result->value.constructor,
4868 gfc_copy_expr (tsource_ctor->expr),
4869 NULL);
4870 else
4871 gfc_constructor_append_expr (&result->value.constructor,
4872 gfc_copy_expr (fsource_ctor->expr),
4873 NULL);
4874 tsource_ctor = gfc_constructor_next (tsource_ctor);
4875 fsource_ctor = gfc_constructor_next (fsource_ctor);
4876 mask_ctor = gfc_constructor_next (mask_ctor);
4877 }
4878
4879 result->shape = gfc_get_shape (1);
4880 gfc_array_size (result, &result->shape[0]);
4881
4882 return result;
8f2b565d
DF
4883}
4884
4885
88a95a11
FXC
4886gfc_expr *
4887gfc_simplify_merge_bits (gfc_expr *i, gfc_expr *j, gfc_expr *mask_expr)
4888{
4889 mpz_t arg1, arg2, mask;
4890 gfc_expr *result;
4891
4892 if (i->expr_type != EXPR_CONSTANT || j->expr_type != EXPR_CONSTANT
4893 || mask_expr->expr_type != EXPR_CONSTANT)
4894 return NULL;
4895
4896 result = gfc_get_constant_expr (BT_INTEGER, i->ts.kind, &i->where);
4897
4898 /* Convert all argument to unsigned. */
4899 mpz_init_set (arg1, i->value.integer);
4900 mpz_init_set (arg2, j->value.integer);
4901 mpz_init_set (mask, mask_expr->value.integer);
4902
4903 /* MERGE_BITS(I,J,MASK) = IOR (IAND (I, MASK), IAND (J, NOT (MASK))). */
4904 mpz_and (arg1, arg1, mask);
4905 mpz_com (mask, mask);
4906 mpz_and (arg2, arg2, mask);
4907 mpz_ior (result->value.integer, arg1, arg2);
4908
4909 mpz_clear (arg1);
4910 mpz_clear (arg2);
4911 mpz_clear (mask);
4912
4913 return result;
4914}
4915
4916
4917/* Selects between current value and extremum for simplify_min_max
5a0193ee 4918 and simplify_minval_maxval. */
a1d6c052 4919static int
b573f931 4920min_max_choose (gfc_expr *arg, gfc_expr *extremum, int sign, bool back_val)
5a0193ee 4921{
a1d6c052
TK
4922 int ret;
4923
5a0193ee
PT
4924 switch (arg->ts.type)
4925 {
4926 case BT_INTEGER:
a1d6c052
TK
4927 ret = mpz_cmp (arg->value.integer,
4928 extremum->value.integer) * sign;
4929 if (ret > 0)
4930 mpz_set (extremum->value.integer, arg->value.integer);
5a0193ee
PT
4931 break;
4932
4933 case BT_REAL:
a1d6c052
TK
4934 if (mpfr_nan_p (extremum->value.real))
4935 {
4936 ret = 1;
4937 mpfr_set (extremum->value.real, arg->value.real, GFC_RND_MODE);
4938 }
4939 else if (mpfr_nan_p (arg->value.real))
4940 ret = -1;
5a0193ee 4941 else
a1d6c052
TK
4942 {
4943 ret = mpfr_cmp (arg->value.real, extremum->value.real) * sign;
4944 if (ret > 0)
4945 mpfr_set (extremum->value.real, arg->value.real, GFC_RND_MODE);
4946 }
5a0193ee
PT
4947 break;
4948
4949 case BT_CHARACTER:
4950#define LENGTH(x) ((x)->value.character.length)
4951#define STRING(x) ((x)->value.character.string)
524af0d6 4952 if (LENGTH (extremum) < LENGTH(arg))
5a0193ee
PT
4953 {
4954 gfc_char_t *tmp = STRING(extremum);
4955
4956 STRING(extremum) = gfc_get_wide_string (LENGTH(arg) + 1);
4957 memcpy (STRING(extremum), tmp,
4958 LENGTH(extremum) * sizeof (gfc_char_t));
4959 gfc_wide_memset (&STRING(extremum)[LENGTH(extremum)], ' ',
4960 LENGTH(arg) - LENGTH(extremum));
4961 STRING(extremum)[LENGTH(arg)] = '\0'; /* For debugger */
4962 LENGTH(extremum) = LENGTH(arg);
cede9502 4963 free (tmp);
5a0193ee 4964 }
a1d6c052
TK
4965 ret = gfc_compare_string (arg, extremum) * sign;
4966 if (ret > 0)
5a0193ee 4967 {
cede9502 4968 free (STRING(extremum));
5a0193ee
PT
4969 STRING(extremum) = gfc_get_wide_string (LENGTH(extremum) + 1);
4970 memcpy (STRING(extremum), STRING(arg),
4971 LENGTH(arg) * sizeof (gfc_char_t));
4972 gfc_wide_memset (&STRING(extremum)[LENGTH(arg)], ' ',
4973 LENGTH(extremum) - LENGTH(arg));
4974 STRING(extremum)[LENGTH(extremum)] = '\0'; /* For debugger */
4975 }
4976#undef LENGTH
4977#undef STRING
4978 break;
8b704316 4979
5a0193ee
PT
4980 default:
4981 gfc_internal_error ("simplify_min_max(): Bad type in arglist");
4982 }
b573f931
TK
4983 if (back_val && ret == 0)
4984 ret = 1;
4985
a1d6c052 4986 return ret;
5a0193ee
PT
4987}
4988
4989
6de9cd9a
DN
4990/* This function is special since MAX() can take any number of
4991 arguments. The simplified expression is a rewritten version of the
4992 argument list containing at most one constant element. Other
4993 constant elements are deleted. Because the argument list has
4994 already been checked, this function always succeeds. sign is 1 for
4995 MAX(), -1 for MIN(). */
4996
4997static gfc_expr *
edf1eac2 4998simplify_min_max (gfc_expr *expr, int sign)
6de9cd9a
DN
4999{
5000 gfc_actual_arglist *arg, *last, *extremum;
13b1afe4
TK
5001 gfc_expr *tmp, *ret;
5002 const char *fname;
6de9cd9a
DN
5003
5004 last = NULL;
5005 extremum = NULL;
6de9cd9a
DN
5006
5007 arg = expr->value.function.actual;
5008
5009 for (; arg; last = arg, arg = arg->next)
5010 {
5011 if (arg->expr->expr_type != EXPR_CONSTANT)
5012 continue;
5013
5014 if (extremum == NULL)
5015 {
5016 extremum = arg;
5017 continue;
5018 }
5019
5a0193ee 5020 min_max_choose (arg->expr, extremum->expr, sign);
6de9cd9a
DN
5021
5022 /* Delete the extra constant argument. */
99c25a87 5023 last->next = arg->next;
6de9cd9a
DN
5024
5025 arg->next = NULL;
5026 gfc_free_actual_arglist (arg);
5027 arg = last;
5028 }
5029
5030 /* If there is one value left, replace the function call with the
5031 expression. */
5032 if (expr->value.function.actual->next != NULL)
5033 return NULL;
5034
13b1afe4
TK
5035 /* Handle special cases of specific functions (min|max)1 and
5036 a(min|max)0. */
5037
5038 tmp = expr->value.function.actual->expr;
5039 fname = expr->value.function.isym->name;
5040
5041 if ((tmp->ts.type != BT_INTEGER || tmp->ts.kind != gfc_integer_4_kind)
5042 && (strcmp (fname, "min1") == 0 || strcmp (fname, "max1") == 0))
5043 {
5044 ret = gfc_convert_constant (tmp, BT_INTEGER, gfc_integer_4_kind);
5045 }
5046 else if ((tmp->ts.type != BT_REAL || tmp->ts.kind != gfc_real_4_kind)
5047 && (strcmp (fname, "amin0") == 0 || strcmp (fname, "amax0") == 0))
5048 {
5049 ret = gfc_convert_constant (tmp, BT_REAL, gfc_real_4_kind);
5050 }
5051 else
5052 ret = gfc_copy_expr (tmp);
5053
5054 return ret;
5055
6de9cd9a
DN
5056}
5057
5058
5059gfc_expr *
edf1eac2 5060gfc_simplify_min (gfc_expr *e)
6de9cd9a 5061{
6de9cd9a
DN
5062 return simplify_min_max (e, -1);
5063}
5064
5065
5066gfc_expr *
edf1eac2 5067gfc_simplify_max (gfc_expr *e)
6de9cd9a 5068{
6de9cd9a
DN
5069 return simplify_min_max (e, 1);
5070}
5071
317fa064 5072/* Helper function for gfc_simplify_minval. */
5a0193ee
PT
5073
5074static gfc_expr *
317fa064 5075gfc_min (gfc_expr *op1, gfc_expr *op2)
5a0193ee 5076{
317fa064
TK
5077 min_max_choose (op1, op2, -1);
5078 gfc_free_expr (op1);
5079 return op2;
5a0193ee
PT
5080}
5081
317fa064 5082/* Simplify minval for constant arrays. */
5a0193ee
PT
5083
5084gfc_expr *
5085gfc_simplify_minval (gfc_expr *array, gfc_expr* dim, gfc_expr *mask)
5086{
317fa064
TK
5087 return simplify_transformation (array, dim, mask, INT_MAX, gfc_min);
5088}
5089
5090/* Helper function for gfc_simplify_maxval. */
b7e75771 5091
317fa064
TK
5092static gfc_expr *
5093gfc_max (gfc_expr *op1, gfc_expr *op2)
5094{
5095 min_max_choose (op1, op2, 1);
5096 gfc_free_expr (op1);
5097 return op2;
5a0193ee
PT
5098}
5099
5100
317fa064
TK
5101/* Simplify maxval for constant arrays. */
5102
5a0193ee
PT
5103gfc_expr *
5104gfc_simplify_maxval (gfc_expr *array, gfc_expr* dim, gfc_expr *mask)
5105{
317fa064 5106 return simplify_transformation (array, dim, mask, INT_MIN, gfc_max);
5a0193ee
PT
5107}
5108
5109
a1d6c052
TK
5110/* Transform minloc or maxloc of an array, according to MASK,
5111 to the scalar result. This code is mostly identical to
5112 simplify_transformation_to_scalar. */
5113
5114static gfc_expr *
5115simplify_minmaxloc_to_scalar (gfc_expr *result, gfc_expr *array, gfc_expr *mask,
b573f931 5116 gfc_expr *extremum, int sign, bool back_val)
a1d6c052
TK
5117{
5118 gfc_expr *a, *m;
5119 gfc_constructor *array_ctor, *mask_ctor;
5120 mpz_t count;
5121
5122 mpz_set_si (result->value.integer, 0);
5123
5124
5125 /* Shortcut for constant .FALSE. MASK. */
5126 if (mask
5127 && mask->expr_type == EXPR_CONSTANT
5128 && !mask->value.logical)
5129 return result;
5130
5131 array_ctor = gfc_constructor_first (array->value.constructor);
5132 if (mask && mask->expr_type == EXPR_ARRAY)
5133 mask_ctor = gfc_constructor_first (mask->value.constructor);
5134 else
5135 mask_ctor = NULL;
5136
5137 mpz_init_set_si (count, 0);
5138 while (array_ctor)
5139 {
5140 mpz_add_ui (count, count, 1);
5141 a = array_ctor->expr;
5142 array_ctor = gfc_constructor_next (array_ctor);
5143 /* A constant MASK equals .TRUE. here and can be ignored. */
5144 if (mask_ctor)
5145 {
5146 m = mask_ctor->expr;
5147 mask_ctor = gfc_constructor_next (mask_ctor);
5148 if (!m->value.logical)
5149 continue;
5150 }
b573f931 5151 if (min_max_choose (a, extremum, sign, back_val) > 0)
a1d6c052
TK
5152 mpz_set (result->value.integer, count);
5153 }
5154 mpz_clear (count);
5155 gfc_free_expr (extremum);
5156 return result;
5157}
5158
5159/* Simplify minloc / maxloc in the absence of a dim argument. */
5160
5161static gfc_expr *
5162simplify_minmaxloc_nodim (gfc_expr *result, gfc_expr *extremum,
b573f931
TK
5163 gfc_expr *array, gfc_expr *mask, int sign,
5164 bool back_val)
a1d6c052
TK
5165{
5166 ssize_t res[GFC_MAX_DIMENSIONS];
5167 int i, n;
5168 gfc_constructor *result_ctor, *array_ctor, *mask_ctor;
5169 ssize_t count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS],
5170 sstride[GFC_MAX_DIMENSIONS];
5171 gfc_expr *a, *m;
5172 bool continue_loop;
5173 bool ma;
5174
5175 for (i = 0; i<array->rank; i++)
5176 res[i] = -1;
5177
5178 /* Shortcut for constant .FALSE. MASK. */
5179 if (mask
5180 && mask->expr_type == EXPR_CONSTANT
5181 && !mask->value.logical)
5182 goto finish;
5183
5184 for (i = 0; i < array->rank; i++)
5185 {
5186 count[i] = 0;
5187 sstride[i] = (i == 0) ? 1 : sstride[i-1] * mpz_get_si (array->shape[i-1]);
5188 extent[i] = mpz_get_si (array->shape[i]);
5189 if (extent[i] <= 0)
5190 goto finish;
5191 }
5192
5193 continue_loop = true;
5194 array_ctor = gfc_constructor_first (array->value.constructor);
5195 if (mask && mask->rank > 0)
5196 mask_ctor = gfc_constructor_first (mask->value.constructor);
5197 else
5198 mask_ctor = NULL;
5199
5200 /* Loop over the array elements (and mask), keeping track of
5201 the indices to return. */
5202 while (continue_loop)
5203 {
5204 do
5205 {
5206 a = array_ctor->expr;
5207 if (mask_ctor)
5208 {
5209 m = mask_ctor->expr;
5210 ma = m->value.logical;
5211 mask_ctor = gfc_constructor_next (mask_ctor);
5212 }
5213 else
5214 ma = true;
5215
b573f931 5216 if (ma && min_max_choose (a, extremum, sign, back_val) > 0)
a1d6c052
TK
5217 {
5218 for (i = 0; i<array->rank; i++)
5219 res[i] = count[i];
5220 }
5221 array_ctor = gfc_constructor_next (array_ctor);
5222 count[0] ++;
5223 } while (count[0] != extent[0]);
5224 n = 0;
5225 do
5226 {
5227 /* When we get to the end of a dimension, reset it and increment
5228 the next dimension. */
5229 count[n] = 0;
5230 n++;
5231 if (n >= array->rank)
5232 {
5233 continue_loop = false;
5234 break;
5235 }
5236 else
5237 count[n] ++;
5238 } while (count[n] == extent[n]);
5239 }
5240
5241 finish:
5242 gfc_free_expr (extremum);
5243 result_ctor = gfc_constructor_first (result->value.constructor);
5244 for (i = 0; i<array->rank; i++)
5245 {
5246 gfc_expr *r_expr;
5247 r_expr = result_ctor->expr;
5248 mpz_set_si (r_expr->value.integer, res[i] + 1);
5249 result_ctor = gfc_constructor_next (result_ctor);
5250 }
5251 return result;
5252}
5253
5254/* Helper function for gfc_simplify_minmaxloc - build an array
5255 expression with n elements. */
5256
5257static gfc_expr *
5258new_array (bt type, int kind, int n, locus *where)
5259{
5260 gfc_expr *result;
5261 int i;
5262
5263 result = gfc_get_array_expr (type, kind, where);
5264 result->rank = 1;
5265 result->shape = gfc_get_shape(1);
5266 mpz_init_set_si (result->shape[0], n);
5267 for (i = 0; i < n; i++)
5268 {
5269 gfc_constructor_append_expr (&result->value.constructor,
5270 gfc_get_constant_expr (type, kind, where),
5271 NULL);
5272 }
5273
5274 return result;
5275}
5276
5277/* Simplify minloc and maxloc. This code is mostly identical to
5278 simplify_transformation_to_array. */
5279
5280static gfc_expr *
5281simplify_minmaxloc_to_array (gfc_expr *result, gfc_expr *array,
5282 gfc_expr *dim, gfc_expr *mask,
b573f931 5283 gfc_expr *extremum, int sign, bool back_val)
a1d6c052
TK
5284{
5285 mpz_t size;
5286 int done, i, n, arraysize, resultsize, dim_index, dim_extent, dim_stride;
5287 gfc_expr **arrayvec, **resultvec, **base, **src, **dest;
5288 gfc_constructor *array_ctor, *mask_ctor, *result_ctor;
5289
5290 int count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS],
5291 sstride[GFC_MAX_DIMENSIONS], dstride[GFC_MAX_DIMENSIONS],
5292 tmpstride[GFC_MAX_DIMENSIONS];
5293
5294 /* Shortcut for constant .FALSE. MASK. */
5295 if (mask
5296 && mask->expr_type == EXPR_CONSTANT
5297 && !mask->value.logical)
5298 return result;
5299
5300 /* Build an indexed table for array element expressions to minimize
5301 linked-list traversal. Masked elements are set to NULL. */
5302 gfc_array_size (array, &size);
5303 arraysize = mpz_get_ui (size);
5304 mpz_clear (size);
5305
5306 arrayvec = XCNEWVEC (gfc_expr*, arraysize);
5307
5308 array_ctor = gfc_constructor_first (array->value.constructor);
5309 mask_ctor = NULL;
5310 if (mask && mask->expr_type == EXPR_ARRAY)
5311 mask_ctor = gfc_constructor_first (mask->value.constructor);
5312
5313 for (i = 0; i < arraysize; ++i)
5314 {
5315 arrayvec[i] = array_ctor->expr;
5316 array_ctor = gfc_constructor_next (array_ctor);
5317
5318 if (mask_ctor)
5319 {
5320 if (!mask_ctor->expr->value.logical)
5321 arrayvec[i] = NULL;
5322
5323 mask_ctor = gfc_constructor_next (mask_ctor);
5324 }
5325 }
5326
5327 /* Same for the result expression. */
5328 gfc_array_size (result, &size);
5329 resultsize = mpz_get_ui (size);
5330 mpz_clear (size);
5331
5332 resultvec = XCNEWVEC (gfc_expr*, resultsize);
5333 result_ctor = gfc_constructor_first (result->value.constructor);
5334 for (i = 0; i < resultsize; ++i)
5335 {
5336 resultvec[i] = result_ctor->expr;
5337 result_ctor = gfc_constructor_next (result_ctor);
5338 }
5339
5340 gfc_extract_int (dim, &dim_index);
5341 dim_index -= 1; /* zero-base index */
5342 dim_extent = 0;
5343 dim_stride = 0;
5344
5345 for (i = 0, n = 0; i < array->rank; ++i)
5346 {
5347 count[i] = 0;
5348 tmpstride[i] = (i == 0) ? 1 : tmpstride[i-1] * mpz_get_si (array->shape[i-1]);
5349 if (i == dim_index)
5350 {
5351 dim_extent = mpz_get_si (array->shape[i]);
5352 dim_stride = tmpstride[i];
5353 continue;
5354 }
5355
5356 extent[n] = mpz_get_si (array->shape[i]);
5357 sstride[n] = tmpstride[i];
5358 dstride[n] = (n == 0) ? 1 : dstride[n-1] * extent[n-1];
5359 n += 1;
5360 }
5361
1832cbf8 5362 done = resultsize <= 0;
a1d6c052
TK
5363 base = arrayvec;
5364 dest = resultvec;
5365 while (!done)
5366 {
5367 gfc_expr *ex;
5368 ex = gfc_copy_expr (extremum);
5369 for (src = base, n = 0; n < dim_extent; src += dim_stride, ++n)
5370 {
b573f931 5371 if (*src && min_max_choose (*src, ex, sign, back_val) > 0)
a1d6c052
TK
5372 mpz_set_si ((*dest)->value.integer, n + 1);
5373 }
0ada0dc0 5374
a1d6c052
TK
5375 count[0]++;
5376 base += sstride[0];
5377 dest += dstride[0];
5378 gfc_free_expr (ex);
5379
5380 n = 0;
5381 while (!done && count[n] == extent[n])
5382 {
5383 count[n] = 0;
5384 base -= sstride[n] * extent[n];
5385 dest -= dstride[n] * extent[n];
5386
5387 n++;
5388 if (n < result->rank)
5389 {
5390 /* If the nested loop is unrolled GFC_MAX_DIMENSIONS
5391 times, we'd warn for the last iteration, because the
5392 array index will have already been incremented to the
5393 array sizes, and we can't tell that this must make
5394 the test against result->rank false, because ranks
5395 must not exceed GFC_MAX_DIMENSIONS. */
5396 GCC_DIAGNOSTIC_PUSH_IGNORED (-Warray-bounds)
5397 count[n]++;
5398 base += sstride[n];
5399 dest += dstride[n];
5400 GCC_DIAGNOSTIC_POP
5401 }
5402 else
5403 done = true;
5404 }
5405 }
5406
5407 /* Place updated expression in result constructor. */
5408 result_ctor = gfc_constructor_first (result->value.constructor);
5409 for (i = 0; i < resultsize; ++i)
5410 {
5411 result_ctor->expr = resultvec[i];
5412 result_ctor = gfc_constructor_next (result_ctor);
5413 }
5414
5415 free (arrayvec);
5416 free (resultvec);
5417 free (extremum);
5418 return result;
5419}
5420
5421/* Simplify minloc and maxloc for constant arrays. */
5422
01ce9e31 5423static gfc_expr *
a1d6c052 5424gfc_simplify_minmaxloc (gfc_expr *array, gfc_expr *dim, gfc_expr *mask,
b573f931 5425 gfc_expr *kind, gfc_expr *back, int sign)
a1d6c052
TK
5426{
5427 gfc_expr *result;
5428 gfc_expr *extremum;
5429 int ikind;
5430 int init_val;
b573f931 5431 bool back_val = false;
0ada0dc0 5432
a1d6c052
TK
5433 if (!is_constant_array_expr (array)
5434 || !gfc_is_constant_expr (dim))
5435 return NULL;
5436
5437 if (mask
5438 && !is_constant_array_expr (mask)
5439 && mask->expr_type != EXPR_CONSTANT)
5440 return NULL;
5441
5442 if (kind)
5443 {
5444 if (gfc_extract_int (kind, &ikind, -1))
5445 return NULL;
5446 }
5447 else
5448 ikind = gfc_default_integer_kind;
5449
b573f931
TK
5450 if (back)
5451 {
5452 if (back->expr_type != EXPR_CONSTANT)
5453 return NULL;
5454
5455 back_val = back->value.logical;
5456 }
a5fbc2f3 5457
a1d6c052
TK
5458 if (sign < 0)
5459 init_val = INT_MAX;
5460 else if (sign > 0)
5461 init_val = INT_MIN;
5462 else
5463 gcc_unreachable();
5464
5465 extremum = gfc_get_constant_expr (array->ts.type, array->ts.kind, &array->where);
5466 init_result_expr (extremum, init_val, array);
5467
5468 if (dim)
5469 {
5470 result = transformational_result (array, dim, BT_INTEGER,
5471 ikind, &array->where);
5472 init_result_expr (result, 0, array);
5473
5474 if (array->rank == 1)
b573f931
TK
5475 return simplify_minmaxloc_to_scalar (result, array, mask, extremum,
5476 sign, back_val);
a1d6c052 5477 else
b573f931
TK
5478 return simplify_minmaxloc_to_array (result, array, dim, mask, extremum,
5479 sign, back_val);
a1d6c052
TK
5480 }
5481 else
5482 {
5483 result = new_array (BT_INTEGER, ikind, array->rank, &array->where);
b573f931
TK
5484 return simplify_minmaxloc_nodim (result, extremum, array, mask,
5485 sign, back_val);
a1d6c052
TK
5486 }
5487}
5488
5489gfc_expr *
64b1806b 5490gfc_simplify_minloc (gfc_expr *array, gfc_expr *dim, gfc_expr *mask, gfc_expr *kind,
b573f931 5491 gfc_expr *back)
a1d6c052 5492{
b573f931 5493 return gfc_simplify_minmaxloc (array, dim, mask, kind, back, -1);
a1d6c052
TK
5494}
5495
5496gfc_expr *
64b1806b 5497gfc_simplify_maxloc (gfc_expr *array, gfc_expr *dim, gfc_expr *mask, gfc_expr *kind,
b573f931 5498 gfc_expr *back)
a1d6c052 5499{
b573f931 5500 return gfc_simplify_minmaxloc (array, dim, mask, kind, back, 1);
a1d6c052
TK
5501}
5502
01ce9e31
TK
5503/* Simplify findloc to scalar. Similar to
5504 simplify_minmaxloc_to_scalar. */
5505
5506static gfc_expr *
5507simplify_findloc_to_scalar (gfc_expr *result, gfc_expr *array, gfc_expr *value,
5508 gfc_expr *mask, int back_val)
5509{
5510 gfc_expr *a, *m;
5511 gfc_constructor *array_ctor, *mask_ctor;
5512 mpz_t count;
5513
5514 mpz_set_si (result->value.integer, 0);
5515
5516 /* Shortcut for constant .FALSE. MASK. */
5517 if (mask
5518 && mask->expr_type == EXPR_CONSTANT
5519 && !mask->value.logical)
5520 return result;
5521
5522 array_ctor = gfc_constructor_first (array->value.constructor);
5523 if (mask && mask->expr_type == EXPR_ARRAY)
5524 mask_ctor = gfc_constructor_first (mask->value.constructor);
5525 else
5526 mask_ctor = NULL;
5527
5528 mpz_init_set_si (count, 0);
5529 while (array_ctor)
5530 {
5531 mpz_add_ui (count, count, 1);
5532 a = array_ctor->expr;
5533 array_ctor = gfc_constructor_next (array_ctor);
5534 /* A constant MASK equals .TRUE. here and can be ignored. */
5535 if (mask_ctor)
5536 {
5537 m = mask_ctor->expr;
5538 mask_ctor = gfc_constructor_next (mask_ctor);
5539 if (!m->value.logical)
5540 continue;
5541 }
5542 if (gfc_compare_expr (a, value, INTRINSIC_EQ) == 0)
5543 {
5544 /* We have a match. If BACK is true, continue so we find
5545 the last one. */
5546 mpz_set (result->value.integer, count);
5547 if (!back_val)
5548 break;
5549 }
5550 }
5551 mpz_clear (count);
5552 return result;
5553}
5554
5555/* Simplify findloc in the absence of a dim argument. Similar to
5556 simplify_minmaxloc_nodim. */
5557
5558static gfc_expr *
5559simplify_findloc_nodim (gfc_expr *result, gfc_expr *value, gfc_expr *array,
5560 gfc_expr *mask, bool back_val)
5561{
5562 ssize_t res[GFC_MAX_DIMENSIONS];
5563 int i, n;
5564 gfc_constructor *result_ctor, *array_ctor, *mask_ctor;
5565 ssize_t count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS],
5566 sstride[GFC_MAX_DIMENSIONS];
5567 gfc_expr *a, *m;
5568 bool continue_loop;
5569 bool ma;
5570
27bf39a8 5571 for (i = 0; i < array->rank; i++)
01ce9e31
TK
5572 res[i] = -1;
5573
5574 /* Shortcut for constant .FALSE. MASK. */
5575 if (mask
5576 && mask->expr_type == EXPR_CONSTANT
5577 && !mask->value.logical)
5578 goto finish;
5579
5580 for (i = 0; i < array->rank; i++)
5581 {
5582 count[i] = 0;
5583 sstride[i] = (i == 0) ? 1 : sstride[i-1] * mpz_get_si (array->shape[i-1]);
5584 extent[i] = mpz_get_si (array->shape[i]);
5585 if (extent[i] <= 0)
5586 goto finish;
5587 }
5588
5589 continue_loop = true;
5590 array_ctor = gfc_constructor_first (array->value.constructor);
5591 if (mask && mask->rank > 0)
5592 mask_ctor = gfc_constructor_first (mask->value.constructor);
5593 else
5594 mask_ctor = NULL;
5595
5596 /* Loop over the array elements (and mask), keeping track of
5597 the indices to return. */
5598 while (continue_loop)
5599 {
5600 do
5601 {
5602 a = array_ctor->expr;
5603 if (mask_ctor)
5604 {
5605 m = mask_ctor->expr;
5606 ma = m->value.logical;
5607 mask_ctor = gfc_constructor_next (mask_ctor);
5608 }
5609 else
5610 ma = true;
5611
5612 if (ma && gfc_compare_expr (a, value, INTRINSIC_EQ) == 0)
5613 {
27bf39a8 5614 for (i = 0; i < array->rank; i++)
01ce9e31
TK
5615 res[i] = count[i];
5616 if (!back_val)
5617 goto finish;
5618 }
5619 array_ctor = gfc_constructor_next (array_ctor);
5620 count[0] ++;
5621 } while (count[0] != extent[0]);
5622 n = 0;
5623 do
5624 {
5625 /* When we get to the end of a dimension, reset it and increment
5626 the next dimension. */
5627 count[n] = 0;
5628 n++;
5629 if (n >= array->rank)
5630 {
5631 continue_loop = false;
5632 break;
5633 }
5634 else
5635 count[n] ++;
5636 } while (count[n] == extent[n]);
5637 }
5638
27bf39a8 5639finish:
01ce9e31 5640 result_ctor = gfc_constructor_first (result->value.constructor);
27bf39a8 5641 for (i = 0; i < array->rank; i++)
01ce9e31
TK
5642 {
5643 gfc_expr *r_expr;
5644 r_expr = result_ctor->expr;
5645 mpz_set_si (r_expr->value.integer, res[i] + 1);
5646 result_ctor = gfc_constructor_next (result_ctor);
5647 }
5648 return result;
5649}
5650
5651
5652/* Simplify findloc to an array. Similar to
5653 simplify_minmaxloc_to_array. */
5654
5655static gfc_expr *
5656simplify_findloc_to_array (gfc_expr *result, gfc_expr *array, gfc_expr *value,
5657 gfc_expr *dim, gfc_expr *mask, bool back_val)
5658{
5659 mpz_t size;
5660 int done, i, n, arraysize, resultsize, dim_index, dim_extent, dim_stride;
5661 gfc_expr **arrayvec, **resultvec, **base, **src, **dest;
5662 gfc_constructor *array_ctor, *mask_ctor, *result_ctor;
5663
5664 int count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS],
5665 sstride[GFC_MAX_DIMENSIONS], dstride[GFC_MAX_DIMENSIONS],
5666 tmpstride[GFC_MAX_DIMENSIONS];
5667
5668 /* Shortcut for constant .FALSE. MASK. */
5669 if (mask
5670 && mask->expr_type == EXPR_CONSTANT
5671 && !mask->value.logical)
5672 return result;
5673
5674 /* Build an indexed table for array element expressions to minimize
5675 linked-list traversal. Masked elements are set to NULL. */
5676 gfc_array_size (array, &size);
5677 arraysize = mpz_get_ui (size);
5678 mpz_clear (size);
5679
5680 arrayvec = XCNEWVEC (gfc_expr*, arraysize);
5681
5682 array_ctor = gfc_constructor_first (array->value.constructor);
5683 mask_ctor = NULL;
5684 if (mask && mask->expr_type == EXPR_ARRAY)
5685 mask_ctor = gfc_constructor_first (mask->value.constructor);
5686
5687 for (i = 0; i < arraysize; ++i)
5688 {
5689 arrayvec[i] = array_ctor->expr;
5690 array_ctor = gfc_constructor_next (array_ctor);
5691
5692 if (mask_ctor)
5693 {
5694 if (!mask_ctor->expr->value.logical)
5695 arrayvec[i] = NULL;
5696
5697 mask_ctor = gfc_constructor_next (mask_ctor);
5698 }
5699 }
5700
5701 /* Same for the result expression. */
5702 gfc_array_size (result, &size);
5703 resultsize = mpz_get_ui (size);
5704 mpz_clear (size);
5705
5706 resultvec = XCNEWVEC (gfc_expr*, resultsize);
5707 result_ctor = gfc_constructor_first (result->value.constructor);
5708 for (i = 0; i < resultsize; ++i)
5709 {
5710 resultvec[i] = result_ctor->expr;
5711 result_ctor = gfc_constructor_next (result_ctor);
5712 }
5713
5714 gfc_extract_int (dim, &dim_index);
5715
5716 dim_index -= 1; /* Zero-base index. */
5717 dim_extent = 0;
5718 dim_stride = 0;
5719
5720 for (i = 0, n = 0; i < array->rank; ++i)
5721 {
5722 count[i] = 0;
5723 tmpstride[i] = (i == 0) ? 1 : tmpstride[i-1] * mpz_get_si (array->shape[i-1]);
5724 if (i == dim_index)
5725 {
5726 dim_extent = mpz_get_si (array->shape[i]);
5727 dim_stride = tmpstride[i];
5728 continue;
5729 }
5730
5731 extent[n] = mpz_get_si (array->shape[i]);
5732 sstride[n] = tmpstride[i];
5733 dstride[n] = (n == 0) ? 1 : dstride[n-1] * extent[n-1];
5734 n += 1;
5735 }
5736
5737 done = resultsize <= 0;
5738 base = arrayvec;
5739 dest = resultvec;
5740 while (!done)
5741 {
5742 for (src = base, n = 0; n < dim_extent; src += dim_stride, ++n)
5743 {
5744 if (*src && gfc_compare_expr (*src, value, INTRINSIC_EQ) == 0)
5745 {
5746 mpz_set_si ((*dest)->value.integer, n + 1);
5747 if (!back_val)
5748 break;
5749 }
5750 }
5751
5752 count[0]++;
5753 base += sstride[0];
5754 dest += dstride[0];
5755
5756 n = 0;
5757 while (!done && count[n] == extent[n])
5758 {
5759 count[n] = 0;
5760 base -= sstride[n] * extent[n];
5761 dest -= dstride[n] * extent[n];
5762
5763 n++;
5764 if (n < result->rank)
5765 {
5766 /* If the nested loop is unrolled GFC_MAX_DIMENSIONS
5767 times, we'd warn for the last iteration, because the
5768 array index will have already been incremented to the
5769 array sizes, and we can't tell that this must make
5770 the test against result->rank false, because ranks
5771 must not exceed GFC_MAX_DIMENSIONS. */
5772 GCC_DIAGNOSTIC_PUSH_IGNORED (-Warray-bounds)
5773 count[n]++;
5774 base += sstride[n];
5775 dest += dstride[n];
5776 GCC_DIAGNOSTIC_POP
5777 }
5778 else
5779 done = true;
5780 }
5781 }
5782
5783 /* Place updated expression in result constructor. */
5784 result_ctor = gfc_constructor_first (result->value.constructor);
5785 for (i = 0; i < resultsize; ++i)
5786 {
5787 result_ctor->expr = resultvec[i];
5788 result_ctor = gfc_constructor_next (result_ctor);
5789 }
5790
5791 free (arrayvec);
5792 free (resultvec);
5793 return result;
5794}
5795
5796/* Simplify findloc. */
5797
5798gfc_expr *
5799gfc_simplify_findloc (gfc_expr *array, gfc_expr *value, gfc_expr *dim,
5800 gfc_expr *mask, gfc_expr *kind, gfc_expr *back)
5801{
5802 gfc_expr *result;
5803 int ikind;
5804 bool back_val = false;
5805
5806 if (!is_constant_array_expr (array)
5807 || !gfc_is_constant_expr (dim))
5808 return NULL;
5809
5810 if (! gfc_is_constant_expr (value))
5811 return 0;
5812
5813 if (mask
5814 && !is_constant_array_expr (mask)
5815 && mask->expr_type != EXPR_CONSTANT)
5816 return NULL;
5817
5818 if (kind)
5819 {
5820 if (gfc_extract_int (kind, &ikind, -1))
5821 return NULL;
5822 }
5823 else
5824 ikind = gfc_default_integer_kind;
5825
5826 if (back)
5827 {
5828 if (back->expr_type != EXPR_CONSTANT)
5829 return NULL;
5830
5831 back_val = back->value.logical;
5832 }
5833
5834 if (dim)
5835 {
5836 result = transformational_result (array, dim, BT_INTEGER,
5837 ikind, &array->where);
5838 init_result_expr (result, 0, array);
5839
5840 if (array->rank == 1)
5841 return simplify_findloc_to_scalar (result, array, value, mask,
5842 back_val);
5843 else
5844 return simplify_findloc_to_array (result, array, value, dim, mask,
5845 back_val);
5846 }
5847 else
5848 {
5849 result = new_array (BT_INTEGER, ikind, array->rank, &array->where);
5850 return simplify_findloc_nodim (result, value, array, mask, back_val);
5851 }
5852 return NULL;
5853}
5854
6de9cd9a 5855gfc_expr *
edf1eac2 5856gfc_simplify_maxexponent (gfc_expr *x)
6de9cd9a 5857{
b7e75771
JD
5858 int i = gfc_validate_kind (BT_REAL, x->ts.kind, false);
5859 return gfc_get_int_expr (gfc_default_integer_kind, &x->where,
5860 gfc_real_kinds[i].max_exponent);
6de9cd9a
DN
5861}
5862
5863
5864gfc_expr *
edf1eac2 5865gfc_simplify_minexponent (gfc_expr *x)
6de9cd9a 5866{
b7e75771
JD
5867 int i = gfc_validate_kind (BT_REAL, x->ts.kind, false);
5868 return gfc_get_int_expr (gfc_default_integer_kind, &x->where,
5869 gfc_real_kinds[i].min_exponent);
6de9cd9a
DN
5870}
5871
5872
5873gfc_expr *
edf1eac2 5874gfc_simplify_mod (gfc_expr *a, gfc_expr *p)
6de9cd9a
DN
5875{
5876 gfc_expr *result;
991bb832 5877 int kind;
6de9cd9a 5878
75d1c004
SK
5879 /* First check p. */
5880 if (p->expr_type != EXPR_CONSTANT)
6de9cd9a
DN
5881 return NULL;
5882
75d1c004
SK
5883 /* p shall not be 0. */
5884 switch (p->ts.type)
6de9cd9a 5885 {
b7e75771
JD
5886 case BT_INTEGER:
5887 if (mpz_cmp_ui (p->value.integer, 0) == 0)
5888 {
75d1c004
SK
5889 gfc_error ("Argument %qs of MOD at %L shall not be zero",
5890 "P", &p->where);
b7e75771
JD
5891 return &gfc_bad_expr;
5892 }
b7e75771 5893 break;
b7e75771
JD
5894 case BT_REAL:
5895 if (mpfr_cmp_ui (p->value.real, 0) == 0)
5896 {
75d1c004
SK
5897 gfc_error ("Argument %qs of MOD at %L shall not be zero",
5898 "P", &p->where);
b7e75771
JD
5899 return &gfc_bad_expr;
5900 }
b7e75771 5901 break;
b7e75771
JD
5902 default:
5903 gfc_internal_error ("gfc_simplify_mod(): Bad arguments");
6de9cd9a
DN
5904 }
5905
75d1c004
SK
5906 if (a->expr_type != EXPR_CONSTANT)
5907 return NULL;
5908
5909 kind = a->ts.kind > p->ts.kind ? a->ts.kind : p->ts.kind;
5910 result = gfc_get_constant_expr (a->ts.type, kind, &a->where);
5911
5912 if (a->ts.type == BT_INTEGER)
5913 mpz_tdiv_r (result->value.integer, a->value.integer, p->value.integer);
5914 else
5915 {
5916 gfc_set_model_kind (kind);
5917 mpfr_fmod (result->value.real, a->value.real, p->value.real,
5918 GFC_RND_MODE);
5919 }
5920
6de9cd9a
DN
5921 return range_check (result, "MOD");
5922}
5923
5924
5925gfc_expr *
edf1eac2 5926gfc_simplify_modulo (gfc_expr *a, gfc_expr *p)
6de9cd9a
DN
5927{
5928 gfc_expr *result;
991bb832 5929 int kind;
6de9cd9a 5930
53dede15
JD
5931 /* First check p. */
5932 if (p->expr_type != EXPR_CONSTANT)
6de9cd9a
DN
5933 return NULL;
5934
53dede15
JD
5935 /* p shall not be 0. */
5936 switch (p->ts.type)
6de9cd9a 5937 {
b7e75771
JD
5938 case BT_INTEGER:
5939 if (mpz_cmp_ui (p->value.integer, 0) == 0)
5940 {
53dede15
JD
5941 gfc_error ("Argument %qs of MODULO at %L shall not be zero",
5942 "P", &p->where);
b7e75771
JD
5943 return &gfc_bad_expr;
5944 }
b7e75771 5945 break;
b7e75771
JD
5946 case BT_REAL:
5947 if (mpfr_cmp_ui (p->value.real, 0) == 0)
5948 {
53dede15
JD
5949 gfc_error ("Argument %qs of MODULO at %L shall not be zero",
5950 "P", &p->where);
b7e75771
JD
5951 return &gfc_bad_expr;
5952 }
b7e75771 5953 break;
b7e75771
JD
5954 default:
5955 gfc_internal_error ("gfc_simplify_modulo(): Bad arguments");
6de9cd9a
DN
5956 }
5957
53dede15
JD
5958 if (a->expr_type != EXPR_CONSTANT)
5959 return NULL;
5960
5961 kind = a->ts.kind > p->ts.kind ? a->ts.kind : p->ts.kind;
5962 result = gfc_get_constant_expr (a->ts.type, kind, &a->where);
5963
5964 if (a->ts.type == BT_INTEGER)
5965 mpz_fdiv_r (result->value.integer, a->value.integer, p->value.integer);
5966 else
5967 {
5968 gfc_set_model_kind (kind);
5969 mpfr_fmod (result->value.real, a->value.real, p->value.real,
5970 GFC_RND_MODE);
5971 if (mpfr_cmp_ui (result->value.real, 0) != 0)
5972 {
5973 if (mpfr_signbit (a->value.real) != mpfr_signbit (p->value.real))
5974 mpfr_add (result->value.real, result->value.real, p->value.real,
5975 GFC_RND_MODE);
5976 }
5977 else
5978 mpfr_copysign (result->value.real, result->value.real,
5979 p->value.real, GFC_RND_MODE);
5980 }
5981
6de9cd9a
DN
5982 return range_check (result, "MODULO");
5983}
5984
5985
6de9cd9a 5986gfc_expr *
edf1eac2 5987gfc_simplify_nearest (gfc_expr *x, gfc_expr *s)
6de9cd9a
DN
5988{
5989 gfc_expr *result;
c9d4cc5d 5990 mpfr_exp_t emin, emax;
b6f63e89 5991 int kind;
6de9cd9a 5992
9f32d037 5993 if (x->expr_type != EXPR_CONSTANT || s->expr_type != EXPR_CONSTANT)
6de9cd9a
DN
5994 return NULL;
5995
e48d66a9
SK
5996 result = gfc_copy_expr (x);
5997
b6f63e89
TB
5998 /* Save current values of emin and emax. */
5999 emin = mpfr_get_emin ();
6000 emax = mpfr_get_emax ();
6001
6002 /* Set emin and emax for the current model number. */
6003 kind = gfc_validate_kind (BT_REAL, x->ts.kind, 0);
c9d4cc5d 6004 mpfr_set_emin ((mpfr_exp_t) gfc_real_kinds[kind].min_exponent -
b6f63e89 6005 mpfr_get_prec(result->value.real) + 1);
c9d4cc5d
JB
6006 mpfr_set_emax ((mpfr_exp_t) gfc_real_kinds[kind].max_exponent - 1);
6007 mpfr_check_range (result->value.real, 0, MPFR_RNDU);
b6f63e89
TB
6008
6009 if (mpfr_sgn (s->value.real) > 0)
6010 {
6011 mpfr_nextabove (result->value.real);
c9d4cc5d 6012 mpfr_subnormalize (result->value.real, 0, MPFR_RNDU);
b6f63e89
TB
6013 }
6014 else
6015 {
6016 mpfr_nextbelow (result->value.real);
c9d4cc5d 6017 mpfr_subnormalize (result->value.real, 0, MPFR_RNDD);
b6f63e89
TB
6018 }
6019
6020 mpfr_set_emin (emin);
6021 mpfr_set_emax (emax);
6de9cd9a 6022
b6f63e89
TB
6023 /* Only NaN can occur. Do not use range check as it gives an
6024 error for denormal numbers. */
c61819ff 6025 if (mpfr_nan_p (result->value.real) && flag_range_check)
b6f63e89
TB
6026 {
6027 gfc_error ("Result of NEAREST is NaN at %L", &result->where);
d93712d9 6028 gfc_free_expr (result);
b6f63e89
TB
6029 return &gfc_bad_expr;
6030 }
6031
6032 return result;
6de9cd9a
DN
6033}
6034
6035
6036static gfc_expr *
edf1eac2 6037simplify_nint (const char *name, gfc_expr *e, gfc_expr *k)
6de9cd9a 6038{
8e1fa5d6
SK
6039 gfc_expr *itrunc, *result;
6040 int kind;
6de9cd9a 6041
9d64df18 6042 kind = get_kind (BT_INTEGER, k, name, gfc_default_integer_kind);
6de9cd9a
DN
6043 if (kind == -1)
6044 return &gfc_bad_expr;
6045
6046 if (e->expr_type != EXPR_CONSTANT)
6047 return NULL;
6048
6de9cd9a 6049 itrunc = gfc_copy_expr (e);
edf1eac2 6050 mpfr_round (itrunc->value.real, e->value.real);
6de9cd9a 6051
b7e75771 6052 result = gfc_get_constant_expr (BT_INTEGER, kind, &e->where);
7278e4dc 6053 gfc_mpfr_to_mpz (result->value.integer, itrunc->value.real, &e->where);
6de9cd9a
DN
6054
6055 gfc_free_expr (itrunc);
6de9cd9a
DN
6056
6057 return range_check (result, name);
6058}
6059
6060
bec93d79 6061gfc_expr *
edf1eac2 6062gfc_simplify_new_line (gfc_expr *e)
bec93d79
TB
6063{
6064 gfc_expr *result;
6065
b7e75771 6066 result = gfc_get_character_expr (e->ts.kind, &e->where, NULL, 1);
bec93d79 6067 result->value.character.string[0] = '\n';
b7e75771 6068
bec93d79
TB
6069 return result;
6070}
6071
6072
6de9cd9a 6073gfc_expr *
edf1eac2 6074gfc_simplify_nint (gfc_expr *e, gfc_expr *k)
6de9cd9a 6075{
6de9cd9a
DN
6076 return simplify_nint ("NINT", e, k);
6077}
6078
6079
6080gfc_expr *
edf1eac2 6081gfc_simplify_idnint (gfc_expr *e)
6de9cd9a 6082{
6de9cd9a
DN
6083 return simplify_nint ("IDNINT", e, NULL);
6084}
6085
843192c0 6086static int norm2_scale;
6de9cd9a 6087
0cd0559e 6088static gfc_expr *
843192c0 6089norm2_add_squared (gfc_expr *result, gfc_expr *e)
0cd0559e
TB
6090{
6091 mpfr_t tmp;
6092
6093 gcc_assert (e->ts.type == BT_REAL && e->expr_type == EXPR_CONSTANT);
6094 gcc_assert (result->ts.type == BT_REAL
6095 && result->expr_type == EXPR_CONSTANT);
6096
6097 gfc_set_model_kind (result->ts.kind);
843192c0 6098 int index = gfc_validate_kind (BT_REAL, result->ts.kind, false);
acb156cc
JB
6099 mpfr_exp_t exp;
6100 if (mpfr_regular_p (result->value.real))
843192c0
JJ
6101 {
6102 exp = mpfr_get_exp (result->value.real);
6103 /* If result is getting close to overflowing, scale down. */
6104 if (exp >= gfc_real_kinds[index].max_exponent - 4
6105 && norm2_scale <= gfc_real_kinds[index].max_exponent - 2)
6106 {
6107 norm2_scale += 2;
6108 mpfr_div_ui (result->value.real, result->value.real, 16,
6109 GFC_RND_MODE);
6110 }
6111 }
6112
0cd0559e 6113 mpfr_init (tmp);
acb156cc 6114 if (mpfr_regular_p (e->value.real))
843192c0
JJ
6115 {
6116 exp = mpfr_get_exp (e->value.real);
6117 /* If e**2 would overflow or close to overflowing, scale down. */
6118 if (exp - norm2_scale >= gfc_real_kinds[index].max_exponent / 2 - 2)
6119 {
6120 int new_scale = gfc_real_kinds[index].max_exponent / 2 + 4;
6121 mpfr_set_ui (tmp, 1, GFC_RND_MODE);
6122 mpfr_set_exp (tmp, new_scale - norm2_scale);
6123 mpfr_div (result->value.real, result->value.real, tmp, GFC_RND_MODE);
6124 mpfr_div (result->value.real, result->value.real, tmp, GFC_RND_MODE);
6125 norm2_scale = new_scale;
6126 }
6127 }
6128 if (norm2_scale)
6129 {
6130 mpfr_set_ui (tmp, 1, GFC_RND_MODE);
6131 mpfr_set_exp (tmp, norm2_scale);
6132 mpfr_div (tmp, e->value.real, tmp, GFC_RND_MODE);
6133 }
6134 else
6135 mpfr_set (tmp, e->value.real, GFC_RND_MODE);
6136 mpfr_pow_ui (tmp, tmp, 2, GFC_RND_MODE);
0cd0559e
TB
6137 mpfr_add (result->value.real, result->value.real, tmp,
6138 GFC_RND_MODE);
6139 mpfr_clear (tmp);
6140
6141 return result;
6142}
6143
6144
6145static gfc_expr *
843192c0 6146norm2_do_sqrt (gfc_expr *result, gfc_expr *e)
0cd0559e
TB
6147{
6148 gcc_assert (e->ts.type == BT_REAL && e->expr_type == EXPR_CONSTANT);
6149 gcc_assert (result->ts.type == BT_REAL
6150 && result->expr_type == EXPR_CONSTANT);
6151
843192c0
JJ
6152 if (result != e)
6153 mpfr_set (result->value.real, e->value.real, GFC_RND_MODE);
0cd0559e 6154 mpfr_sqrt (result->value.real, result->value.real, GFC_RND_MODE);
acb156cc 6155 if (norm2_scale && mpfr_regular_p (result->value.real))
843192c0
JJ
6156 {
6157 mpfr_t tmp;
6158 mpfr_init (tmp);
6159 mpfr_set_ui (tmp, 1, GFC_RND_MODE);
6160 mpfr_set_exp (tmp, norm2_scale);
6161 mpfr_mul (result->value.real, result->value.real, tmp, GFC_RND_MODE);
6162 mpfr_clear (tmp);
6163 }
6164 norm2_scale = 0;
6165
0cd0559e
TB
6166 return result;
6167}
6168
6169
6170gfc_expr *
6171gfc_simplify_norm2 (gfc_expr *e, gfc_expr *dim)
6172{
6173 gfc_expr *result;
6f76317a 6174 bool size_zero;
0cd0559e 6175
6f76317a 6176 size_zero = gfc_is_size_zero_array (e);
94e6b5e5 6177
6f76317a 6178 if (!(is_constant_array_expr (e) || size_zero)
0cd0559e
TB
6179 || (dim != NULL && !gfc_is_constant_expr (dim)))
6180 return NULL;
6181
6182 result = transformational_result (e, dim, e->ts.type, e->ts.kind, &e->where);
6183 init_result_expr (result, 0, NULL);
6184
6f76317a
TK
6185 if (size_zero)
6186 return result;
6187
843192c0 6188 norm2_scale = 0;
0cd0559e
TB
6189 if (!dim || e->rank == 1)
6190 {
6191 result = simplify_transformation_to_scalar (result, e, NULL,
843192c0 6192 norm2_add_squared);
0cd0559e 6193 mpfr_sqrt (result->value.real, result->value.real, GFC_RND_MODE);
acb156cc 6194 if (norm2_scale && mpfr_regular_p (result->value.real))
843192c0
JJ
6195 {
6196 mpfr_t tmp;
6197 mpfr_init (tmp);
6198 mpfr_set_ui (tmp, 1, GFC_RND_MODE);
6199 mpfr_set_exp (tmp, norm2_scale);
6200 mpfr_mul (result->value.real, result->value.real, tmp, GFC_RND_MODE);
6201 mpfr_clear (tmp);
6202 }
6203 norm2_scale = 0;
0cd0559e
TB
6204 }
6205 else
6206 result = simplify_transformation_to_array (result, e, dim, NULL,
843192c0
JJ
6207 norm2_add_squared,
6208 norm2_do_sqrt);
0cd0559e
TB
6209
6210 return result;
6211}
6212
6213
6de9cd9a 6214gfc_expr *
edf1eac2 6215gfc_simplify_not (gfc_expr *e)
6de9cd9a
DN
6216{
6217 gfc_expr *result;
6de9cd9a
DN
6218
6219 if (e->expr_type != EXPR_CONSTANT)
6220 return NULL;
6221
b7e75771 6222 result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
6de9cd9a
DN
6223 mpz_com (result->value.integer, e->value.integer);
6224
6de9cd9a
DN
6225 return range_check (result, "NOT");
6226}
6227
6228
6229gfc_expr *
edf1eac2 6230gfc_simplify_null (gfc_expr *mold)
6de9cd9a
DN
6231{
6232 gfc_expr *result;
6233
b7e75771 6234 if (mold)
6de9cd9a 6235 {
b7e75771
JD
6236 result = gfc_copy_expr (mold);
6237 result->expr_type = EXPR_NULL;
6de9cd9a 6238 }
def66134 6239 else
b7e75771 6240 result = gfc_get_null_expr (NULL);
6de9cd9a
DN
6241
6242 return result;
6243}
6244
6245
d0a4a61c 6246gfc_expr *
05fc16dd 6247gfc_simplify_num_images (gfc_expr *distance ATTRIBUTE_UNUSED, gfc_expr *failed)
d0a4a61c
TB
6248{
6249 gfc_expr *result;
64f002ed 6250
f19626cf 6251 if (flag_coarray == GFC_FCOARRAY_NONE)
64f002ed 6252 {
ddc05d11 6253 gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
64f002ed
TB
6254 return &gfc_bad_expr;
6255 }
6256
f19626cf 6257 if (flag_coarray != GFC_FCOARRAY_SINGLE)
60386f50
TB
6258 return NULL;
6259
05fc16dd
TB
6260 if (failed && failed->expr_type != EXPR_CONSTANT)
6261 return NULL;
6262
d0a4a61c 6263 /* FIXME: gfc_current_locus is wrong. */
b7e75771
JD
6264 result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
6265 &gfc_current_locus);
05fc16dd
TB
6266
6267 if (failed && failed->value.logical != 0)
6268 mpz_set_si (result->value.integer, 0);
6269 else
6270 mpz_set_si (result->value.integer, 1);
6271
d0a4a61c
TB
6272 return result;
6273}
6274
6275
5d723e54 6276gfc_expr *
edf1eac2 6277gfc_simplify_or (gfc_expr *x, gfc_expr *y)
5d723e54
FXC
6278{
6279 gfc_expr *result;
6280 int kind;
6281
6282 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
6283 return NULL;
6284
6285 kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;
b7e75771
JD
6286
6287 switch (x->ts.type)
5d723e54 6288 {
b7e75771
JD
6289 case BT_INTEGER:
6290 result = gfc_get_constant_expr (BT_INTEGER, kind, &x->where);
6291 mpz_ior (result->value.integer, x->value.integer, y->value.integer);
6292 return range_check (result, "OR");
6293
6294 case BT_LOGICAL:
6295 return gfc_get_logical_expr (kind, &x->where,
6296 x->value.logical || y->value.logical);
6297 default:
6298 gcc_unreachable();
5d723e54 6299 }
5d723e54
FXC
6300}
6301
6302
7ba8c18c
DF
6303gfc_expr *
6304gfc_simplify_pack (gfc_expr *array, gfc_expr *mask, gfc_expr *vector)
6305{
6306 gfc_expr *result;
6307 gfc_constructor *array_ctor, *mask_ctor, *vector_ctor;
6308
524af0d6
JB
6309 if (!is_constant_array_expr (array)
6310 || !is_constant_array_expr (vector)
7ba8c18c 6311 || (!gfc_is_constant_expr (mask)
524af0d6 6312 && !is_constant_array_expr (mask)))
7ba8c18c
DF
6313 return NULL;
6314
b7e75771 6315 result = gfc_get_array_expr (array->ts.type, array->ts.kind, &array->where);
15c2ef5a
PT
6316 if (array->ts.type == BT_DERIVED)
6317 result->ts.u.derived = array->ts.u.derived;
7ba8c18c 6318
b7e75771
JD
6319 array_ctor = gfc_constructor_first (array->value.constructor);
6320 vector_ctor = vector
6321 ? gfc_constructor_first (vector->value.constructor)
6322 : NULL;
7ba8c18c
DF
6323
6324 if (mask->expr_type == EXPR_CONSTANT
6325 && mask->value.logical)
6326 {
6327 /* Copy all elements of ARRAY to RESULT. */
6328 while (array_ctor)
6329 {
b7e75771
JD
6330 gfc_constructor_append_expr (&result->value.constructor,
6331 gfc_copy_expr (array_ctor->expr),
6332 NULL);
7ba8c18c 6333
b7e75771
JD
6334 array_ctor = gfc_constructor_next (array_ctor);
6335 vector_ctor = gfc_constructor_next (vector_ctor);
7ba8c18c
DF
6336 }
6337 }
6338 else if (mask->expr_type == EXPR_ARRAY)
6339 {
8b704316 6340 /* Copy only those elements of ARRAY to RESULT whose
7ba8c18c 6341 MASK equals .TRUE.. */
b7e75771 6342 mask_ctor = gfc_constructor_first (mask->value.constructor);
7ba8c18c
DF
6343 while (mask_ctor)
6344 {
6345 if (mask_ctor->expr->value.logical)
6346 {
b7e75771
JD
6347 gfc_constructor_append_expr (&result->value.constructor,
6348 gfc_copy_expr (array_ctor->expr),
6349 NULL);
6350 vector_ctor = gfc_constructor_next (vector_ctor);
7ba8c18c
DF
6351 }
6352
b7e75771
JD
6353 array_ctor = gfc_constructor_next (array_ctor);
6354 mask_ctor = gfc_constructor_next (mask_ctor);
7ba8c18c
DF
6355 }
6356 }
6357
6358 /* Append any left-over elements from VECTOR to RESULT. */
6359 while (vector_ctor)
6360 {
b7e75771
JD
6361 gfc_constructor_append_expr (&result->value.constructor,
6362 gfc_copy_expr (vector_ctor->expr),
6363 NULL);
6364 vector_ctor = gfc_constructor_next (vector_ctor);
7ba8c18c
DF
6365 }
6366
6367 result->shape = gfc_get_shape (1);
6368 gfc_array_size (result, &result->shape[0]);
6369
6370 if (array->ts.type == BT_CHARACTER)
bc21d315 6371 result->ts.u.cl = array->ts.u.cl;
7ba8c18c
DF
6372
6373 return result;
6374}
6375
6376
0cd0559e
TB
6377static gfc_expr *
6378do_xor (gfc_expr *result, gfc_expr *e)
6379{
6380 gcc_assert (e->ts.type == BT_LOGICAL && e->expr_type == EXPR_CONSTANT);
6381 gcc_assert (result->ts.type == BT_LOGICAL
6382 && result->expr_type == EXPR_CONSTANT);
6383
6384 result->value.logical = result->value.logical != e->value.logical;
6385 return result;
6386}
6387
6388
419af57c
TK
6389gfc_expr *
6390gfc_simplify_is_contiguous (gfc_expr *array)
6391{
6392 if (gfc_is_simply_contiguous (array, false, true))
6393 return gfc_get_logical_expr (gfc_default_logical_kind, &array->where, 1);
6394
6395 if (gfc_is_not_contiguous (array))
6396 return gfc_get_logical_expr (gfc_default_logical_kind, &array->where, 0);
6397
6398 return NULL;
6399}
6400
0cd0559e
TB
6401
6402gfc_expr *
6403gfc_simplify_parity (gfc_expr *e, gfc_expr *dim)
6404{
195a95c4 6405 return simplify_transformation (e, dim, NULL, 0, do_xor);
0cd0559e
TB
6406}
6407
6408
ad5f4de2
FXC
6409gfc_expr *
6410gfc_simplify_popcnt (gfc_expr *e)
6411{
6412 int res, k;
6413 mpz_t x;
6414
6415 if (e->expr_type != EXPR_CONSTANT)
6416 return NULL;
6417
6418 k = gfc_validate_kind (e->ts.type, e->ts.kind, false);
6419
6420 /* Convert argument to unsigned, then count the '1' bits. */
6421 mpz_init_set (x, e->value.integer);
6422 convert_mpz_to_unsigned (x, gfc_integer_kinds[k].bit_size);
6423 res = mpz_popcount (x);
6424 mpz_clear (x);
6425
6426 return gfc_get_int_expr (gfc_default_integer_kind, &e->where, res);
6427}
6428
6429
6430gfc_expr *
6431gfc_simplify_poppar (gfc_expr *e)
6432{
6433 gfc_expr *popcnt;
ad5f4de2
FXC
6434 int i;
6435
6436 if (e->expr_type != EXPR_CONSTANT)
6437 return NULL;
6438
6439 popcnt = gfc_simplify_popcnt (e);
6440 gcc_assert (popcnt);
6441
51f03c6b
JJ
6442 bool fail = gfc_extract_int (popcnt, &i);
6443 gcc_assert (!fail);
ad5f4de2
FXC
6444
6445 return gfc_get_int_expr (gfc_default_integer_kind, &e->where, i % 2);
6446}
6447
6448
6de9cd9a 6449gfc_expr *
edf1eac2 6450gfc_simplify_precision (gfc_expr *e)
6de9cd9a 6451{
b7e75771
JD
6452 int i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
6453 return gfc_get_int_expr (gfc_default_integer_kind, &e->where,
6454 gfc_real_kinds[i].precision);
6de9cd9a
DN
6455}
6456
6457
a16d978f
DF
6458gfc_expr *
6459gfc_simplify_product (gfc_expr *array, gfc_expr *dim, gfc_expr *mask)
6460{
195a95c4 6461 return simplify_transformation (array, dim, mask, 1, gfc_multiply);
a16d978f
DF
6462}
6463
6464
6de9cd9a 6465gfc_expr *
edf1eac2 6466gfc_simplify_radix (gfc_expr *e)
6de9cd9a 6467{
6de9cd9a 6468 int i;
e7a2d5fb 6469 i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
b7e75771 6470
6de9cd9a
DN
6471 switch (e->ts.type)
6472 {
b7e75771
JD
6473 case BT_INTEGER:
6474 i = gfc_integer_kinds[i].radix;
6475 break;
6de9cd9a 6476
b7e75771
JD
6477 case BT_REAL:
6478 i = gfc_real_kinds[i].radix;
6479 break;
6de9cd9a 6480
b7e75771
JD
6481 default:
6482 gcc_unreachable ();
6de9cd9a
DN
6483 }
6484
b7e75771 6485 return gfc_get_int_expr (gfc_default_integer_kind, &e->where, i);
6de9cd9a
DN
6486}
6487
6488
6489gfc_expr *
edf1eac2 6490gfc_simplify_range (gfc_expr *e)
6de9cd9a 6491{
6de9cd9a 6492 int i;
e7a2d5fb 6493 i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
6de9cd9a
DN
6494
6495 switch (e->ts.type)
6496 {
b7e75771
JD
6497 case BT_INTEGER:
6498 i = gfc_integer_kinds[i].range;
6499 break;
6de9cd9a 6500
b7e75771
JD
6501 case BT_REAL:
6502 case BT_COMPLEX:
6503 i = gfc_real_kinds[i].range;
6504 break;
6de9cd9a 6505
b7e75771
JD
6506 default:
6507 gcc_unreachable ();
6de9cd9a
DN
6508 }
6509
b7e75771 6510 return gfc_get_int_expr (gfc_default_integer_kind, &e->where, i);
6de9cd9a
DN
6511}
6512
6513
2514987f
TB
6514gfc_expr *
6515gfc_simplify_rank (gfc_expr *e)
6516{
c62c6622
TB
6517 /* Assumed rank. */
6518 if (e->rank == -1)
6519 return NULL;
6520
2514987f
TB
6521 return gfc_get_int_expr (gfc_default_integer_kind, &e->where, e->rank);
6522}
6523
6524
6de9cd9a 6525gfc_expr *
edf1eac2 6526gfc_simplify_real (gfc_expr *e, gfc_expr *k)
6de9cd9a 6527{
9e23c1aa 6528 gfc_expr *result = NULL;
e23390d2 6529 int kind, tmp1, tmp2;
6de9cd9a 6530
8dc63166
SK
6531 /* Convert BOZ to real, and return without range checking. */
6532 if (e->ts.type == BT_BOZ)
6533 {
6534 /* Determine kind for conversion of the BOZ. */
6535 if (k)
6536 gfc_extract_int (k, &kind);
6537 else
6538 kind = gfc_default_real_kind;
6539
6540 if (!gfc_boz2real (e, kind))
6541 return NULL;
6542 result = gfc_copy_expr (e);
6543 return result;
6544 }
6545
6de9cd9a
DN
6546 if (e->ts.type == BT_COMPLEX)
6547 kind = get_kind (BT_REAL, k, "REAL", e->ts.kind);
6548 else
9d64df18 6549 kind = get_kind (BT_REAL, k, "REAL", gfc_default_real_kind);
6de9cd9a
DN
6550
6551 if (kind == -1)
6552 return &gfc_bad_expr;
6553
6554 if (e->expr_type != EXPR_CONSTANT)
6555 return NULL;
6556
e23390d2
SK
6557 /* For explicit conversion, turn off -Wconversion and -Wconversion-extra
6558 warnings. */
6559 tmp1 = warn_conversion;
6560 tmp2 = warn_conversion_extra;
6561 warn_conversion = warn_conversion_extra = 0;
6562
b7e75771 6563 result = gfc_convert_constant (e, BT_REAL, kind);
e23390d2
SK
6564
6565 warn_conversion = tmp1;
6566 warn_conversion_extra = tmp2;
6567
b7e75771
JD
6568 if (result == &gfc_bad_expr)
6569 return &gfc_bad_expr;
d93712d9 6570
6de9cd9a
DN
6571 return range_check (result, "REAL");
6572}
6573
6970fcc8
SK
6574
6575gfc_expr *
edf1eac2 6576gfc_simplify_realpart (gfc_expr *e)
6970fcc8
SK
6577{
6578 gfc_expr *result;
6579
6580 if (e->expr_type != EXPR_CONSTANT)
6581 return NULL;
6582
b7e75771 6583 result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
eb6f9a86 6584 mpc_real (result->value.real, e->value.complex, GFC_RND_MODE);
b7e75771 6585
6970fcc8
SK
6586 return range_check (result, "REALPART");
6587}
6588
6de9cd9a 6589gfc_expr *
edf1eac2 6590gfc_simplify_repeat (gfc_expr *e, gfc_expr *n)
6de9cd9a
DN
6591{
6592 gfc_expr *result;
f622221a 6593 gfc_charlen_t len;
f1412ca5 6594 mpz_t ncopies;
64f4bedf 6595 bool have_length = false;
6de9cd9a 6596
f1412ca5
FXC
6597 /* If NCOPIES isn't a constant, there's nothing we can do. */
6598 if (n->expr_type != EXPR_CONSTANT)
6de9cd9a
DN
6599 return NULL;
6600
f1412ca5
FXC
6601 /* If NCOPIES is negative, it's an error. */
6602 if (mpz_sgn (n->value.integer) < 0)
6de9cd9a 6603 {
f1412ca5
FXC
6604 gfc_error ("Argument NCOPIES of REPEAT intrinsic is negative at %L",
6605 &n->where);
6de9cd9a
DN
6606 return &gfc_bad_expr;
6607 }
6608
f1412ca5 6609 /* If we don't know the character length, we can do no more. */
bc21d315
JW
6610 if (e->ts.u.cl && e->ts.u.cl->length
6611 && e->ts.u.cl->length->expr_type == EXPR_CONSTANT)
64f4bedf 6612 {
f622221a 6613 len = gfc_mpz_get_hwi (e->ts.u.cl->length->value.integer);
64f4bedf
PT
6614 have_length = true;
6615 }
6616 else if (e->expr_type == EXPR_CONSTANT
bc21d315 6617 && (e->ts.u.cl == NULL || e->ts.u.cl->length == NULL))
64f4bedf
PT
6618 {
6619 len = e->value.character.length;
6620 }
6621 else
f1412ca5
FXC
6622 return NULL;
6623
6624 /* If the source length is 0, any value of NCOPIES is valid
6625 and everything behaves as if NCOPIES == 0. */
6626 mpz_init (ncopies);
64f4bedf 6627 if (len == 0)
f1412ca5
FXC
6628 mpz_set_ui (ncopies, 0);
6629 else
6630 mpz_set (ncopies, n->value.integer);
6631
6632 /* Check that NCOPIES isn't too large. */
64f4bedf 6633 if (len)
f1412ca5 6634 {
64f4bedf 6635 mpz_t max, mlen;
f1412ca5
FXC
6636 int i;
6637
6638 /* Compute the maximum value allowed for NCOPIES: huge(cl) / len. */
6639 mpz_init (max);
6640 i = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
64f4bedf
PT
6641
6642 if (have_length)
6643 {
6644 mpz_tdiv_q (max, gfc_integer_kinds[i].huge,
bc21d315 6645 e->ts.u.cl->length->value.integer);
64f4bedf
PT
6646 }
6647 else
6648 {
f622221a
JB
6649 mpz_init (mlen);
6650 gfc_mpz_set_hwi (mlen, len);
64f4bedf
PT
6651 mpz_tdiv_q (max, gfc_integer_kinds[i].huge, mlen);
6652 mpz_clear (mlen);
6653 }
f1412ca5
FXC
6654
6655 /* The check itself. */
6656 if (mpz_cmp (ncopies, max) > 0)
6657 {
6658 mpz_clear (max);
6659 mpz_clear (ncopies);
6660 gfc_error ("Argument NCOPIES of REPEAT intrinsic is too large at %L",
6661 &n->where);
6662 return &gfc_bad_expr;
6663 }
6664
6665 mpz_clear (max);
6666 }
6667 mpz_clear (ncopies);
6668
71172460 6669 /* For further simplification, we need the character string to be
f1412ca5
FXC
6670 constant. */
6671 if (e->expr_type != EXPR_CONSTANT)
6672 return NULL;
6673
f622221a 6674 HOST_WIDE_INT ncop;
8b704316
PT
6675 if (len ||
6676 (e->ts.u.cl->length &&
02205aa4 6677 mpz_sgn (e->ts.u.cl->length->value.integer) != 0))
f0fc6ae6 6678 {
f622221a 6679 bool fail = gfc_extract_hwi (n, &ncop);
51f03c6b 6680 gcc_assert (!fail);
f0fc6ae6 6681 }
f1412ca5
FXC
6682 else
6683 ncop = 0;
6684
f1412ca5 6685 if (ncop == 0)
b7e75771 6686 return gfc_get_character_expr (e->ts.kind, &e->where, NULL, 0);
6de9cd9a 6687
b7e75771 6688 len = e->value.character.length;
f622221a
JB
6689 gfc_charlen_t nlen = ncop * len;
6690
eae4d8fb
JB
6691 /* Here's a semi-arbitrary limit. If the string is longer than 1 GB
6692 (2**28 elements * 4 bytes (wide chars) per element) defer to
f622221a
JB
6693 runtime instead of consuming (unbounded) memory and CPU at
6694 compile time. */
eae4d8fb
JB
6695 if (nlen > 268435456)
6696 {
6697 gfc_warning_now (0, "Evaluation of string longer than 2**28 at %L"
6698 " deferred to runtime, expect bugs", &e->where);
6699 return NULL;
6700 }
6de9cd9a 6701
b7e75771 6702 result = gfc_get_character_expr (e->ts.kind, &e->where, NULL, nlen);
f622221a
JB
6703 for (size_t i = 0; i < (size_t) ncop; i++)
6704 for (size_t j = 0; j < (size_t) len; j++)
00660189 6705 result->value.character.string[j+i*len]= e->value.character.string[j];
6de9cd9a
DN
6706
6707 result->value.character.string[nlen] = '\0'; /* For debugger */
6708 return result;
6709}
6710
6711
6712/* This one is a bear, but mainly has to do with shuffling elements. */
6713
6714gfc_expr *
edf1eac2
SK
6715gfc_simplify_reshape (gfc_expr *source, gfc_expr *shape_exp,
6716 gfc_expr *pad, gfc_expr *order_exp)
6de9cd9a 6717{
6de9cd9a
DN
6718 int order[GFC_MAX_DIMENSIONS], shape[GFC_MAX_DIMENSIONS];
6719 int i, rank, npad, x[GFC_MAX_DIMENSIONS];
6de9cd9a
DN
6720 mpz_t index, size;
6721 unsigned long j;
6722 size_t nsource;
b7e75771 6723 gfc_expr *e, *result;
6de9cd9a 6724
207bde5f 6725 /* Check that argument expression types are OK. */
535ff342
DF
6726 if (!is_constant_array_expr (source)
6727 || !is_constant_array_expr (shape_exp)
6728 || !is_constant_array_expr (pad)
6729 || !is_constant_array_expr (order_exp))
6de9cd9a
DN
6730 return NULL;
6731
a5edb32e
JD
6732 if (source->shape == NULL)
6733 return NULL;
6734
207bde5f
JD
6735 /* Proceed with simplification, unpacking the array. */
6736
6de9cd9a
DN
6737 mpz_init (index);
6738 rank = 0;
6de9cd9a 6739
6e12721a
SK
6740 for (i = 0; i < GFC_MAX_DIMENSIONS; i++)
6741 x[i] = 0;
6742
6de9cd9a
DN
6743 for (;;)
6744 {
b7e75771 6745 e = gfc_constructor_lookup_expr (shape_exp->value.constructor, rank);
6de9cd9a
DN
6746 if (e == NULL)
6747 break;
6748
535ff342 6749 gfc_extract_int (e, &shape[rank]);
6de9cd9a 6750
535ff342
DF
6751 gcc_assert (rank >= 0 && rank < GFC_MAX_DIMENSIONS);
6752 gcc_assert (shape[rank] >= 0);
6de9cd9a
DN
6753
6754 rank++;
6755 }
6756
535ff342 6757 gcc_assert (rank > 0);
6de9cd9a
DN
6758
6759 /* Now unpack the order array if present. */
6760 if (order_exp == NULL)
6761 {
6762 for (i = 0; i < rank; i++)
6763 order[i] = i;
6de9cd9a
DN
6764 }
6765 else
6766 {
6e12721a
SK
6767 mpz_t size;
6768 int order_size, shape_size;
6769
6770 if (order_exp->rank != shape_exp->rank)
6771 {
6772 gfc_error ("Shapes of ORDER at %L and SHAPE at %L are different",
6773 &order_exp->where, &shape_exp->where);
6774 return &gfc_bad_expr;
6775 }
6776
6777 gfc_array_size (shape_exp, &size);
6778 shape_size = mpz_get_ui (size);
6779 mpz_clear (size);
6780 gfc_array_size (order_exp, &size);
6781 order_size = mpz_get_ui (size);
6782 mpz_clear (size);
6783 if (order_size != shape_size)
6784 {
6785 gfc_error ("Sizes of ORDER at %L and SHAPE at %L are different",
6786 &order_exp->where, &shape_exp->where);
6787 return &gfc_bad_expr;
6788 }
6de9cd9a
DN
6789
6790 for (i = 0; i < rank; i++)
6791 {
b7e75771 6792 e = gfc_constructor_lookup_expr (order_exp->value.constructor, i);
535ff342 6793 gcc_assert (e);
6de9cd9a 6794
535ff342 6795 gfc_extract_int (e, &order[i]);
d93712d9 6796
8cad1ad5
SK
6797 if (order[i] < 1 || order[i] > rank)
6798 {
6799 gfc_error ("Element with a value of %d in ORDER at %L must be "
6800 "in the range [1, ..., %d] for the RESHAPE intrinsic "
6801 "near %L", order[i], &order_exp->where, rank,
6802 &shape_exp->where);
6803 return &gfc_bad_expr;
6804 }
6805
535ff342 6806 order[i]--;
6e12721a
SK
6807 if (x[order[i]] != 0)
6808 {
6809 gfc_error ("ORDER at %L is not a permutation of the size of "
6810 "SHAPE at %L", &order_exp->where, &shape_exp->where);
6811 return &gfc_bad_expr;
6812 }
6de9cd9a
DN
6813 x[order[i]] = 1;
6814 }
6815 }
6816
6817 /* Count the elements in the source and padding arrays. */
6818
6819 npad = 0;
6820 if (pad != NULL)
6821 {
6822 gfc_array_size (pad, &size);
6823 npad = mpz_get_ui (size);
6824 mpz_clear (size);
6825 }
6826
6827 gfc_array_size (source, &size);
6828 nsource = mpz_get_ui (size);
6829 mpz_clear (size);
6830
6831 /* If it weren't for that pesky permutation we could just loop
6832 through the source and round out any shortage with pad elements.
6833 But no, someone just had to have the compiler do something the
6834 user should be doing. */
6835
6836 for (i = 0; i < rank; i++)
6837 x[i] = 0;
6838
b7e75771
JD
6839 result = gfc_get_array_expr (source->ts.type, source->ts.kind,
6840 &source->where);
15c2ef5a
PT
6841 if (source->ts.type == BT_DERIVED)
6842 result->ts.u.derived = source->ts.u.derived;
b7e75771
JD
6843 result->rank = rank;
6844 result->shape = gfc_get_shape (rank);
6845 for (i = 0; i < rank; i++)
6846 mpz_init_set_ui (result->shape[i], shape[i]);
6847
f7cfd28c 6848 while (nsource > 0 || npad > 0)
6de9cd9a
DN
6849 {
6850 /* Figure out which element to extract. */
6851 mpz_set_ui (index, 0);
6852
6853 for (i = rank - 1; i >= 0; i--)
6854 {
6855 mpz_add_ui (index, index, x[order[i]]);
6856 if (i != 0)
6857 mpz_mul_ui (index, index, shape[order[i - 1]]);
6858 }
6859
6860 if (mpz_cmp_ui (index, INT_MAX) > 0)
d93712d9 6861 gfc_internal_error ("Reshaped array too large at %C");
6de9cd9a
DN
6862
6863 j = mpz_get_ui (index);
6864
6865 if (j < nsource)
b7e75771 6866 e = gfc_constructor_lookup_expr (source->value.constructor, j);
6de9cd9a
DN
6867 else
6868 {
b4cb2a41
SK
6869 if (npad <= 0)
6870 {
6871 mpz_clear (index);
6872 return NULL;
6873 }
535ff342 6874 j = j - nsource;
6de9cd9a 6875 j = j % npad;
b7e75771 6876 e = gfc_constructor_lookup_expr (pad->value.constructor, j);
6de9cd9a 6877 }
535ff342 6878 gcc_assert (e);
6de9cd9a 6879
b7e75771
JD
6880 gfc_constructor_append_expr (&result->value.constructor,
6881 gfc_copy_expr (e), &e->where);
6de9cd9a
DN
6882
6883 /* Calculate the next element. */
6884 i = 0;
6885
6886inc:
6887 if (++x[i] < shape[i])
6888 continue;
6889 x[i++] = 0;
6890 if (i < rank)
6891 goto inc;
6892
6893 break;
6894 }
6895
6896 mpz_clear (index);
6897
b7e75771 6898 return result;
6de9cd9a
DN
6899}
6900
6901
cc6d3bde 6902gfc_expr *
edf1eac2 6903gfc_simplify_rrspacing (gfc_expr *x)
cc6d3bde
SK
6904{
6905 gfc_expr *result;
6906 int i;
6907 long int e, p;
6908
6909 if (x->expr_type != EXPR_CONSTANT)
6910 return NULL;
6de9cd9a 6911
cc6d3bde
SK
6912 i = gfc_validate_kind (x->ts.type, x->ts.kind, false);
6913
b7e75771 6914 result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where);
cc6d3bde 6915
d2af8cc6
FXC
6916 /* RRSPACING(+/- 0.0) = 0.0 */
6917 if (mpfr_zero_p (x->value.real))
cc6d3bde
SK
6918 {
6919 mpfr_set_ui (result->value.real, 0, GFC_RND_MODE);
6920 return result;
6921 }
6922
d2af8cc6
FXC
6923 /* RRSPACING(inf) = NaN */
6924 if (mpfr_inf_p (x->value.real))
6925 {
6926 mpfr_set_nan (result->value.real);
6927 return result;
6928 }
6929
6930 /* RRSPACING(NaN) = same NaN */
6931 if (mpfr_nan_p (x->value.real))
6932 {
6933 mpfr_set (result->value.real, x->value.real, GFC_RND_MODE);
6934 return result;
6935 }
6936
cc6d3bde 6937 /* | x * 2**(-e) | * 2**p. */
d2af8cc6 6938 mpfr_abs (result->value.real, x->value.real, GFC_RND_MODE);
cc6d3bde
SK
6939 e = - (long int) mpfr_get_exp (x->value.real);
6940 mpfr_mul_2si (result->value.real, result->value.real, e, GFC_RND_MODE);
6941
6942 p = (long int) gfc_real_kinds[i].digits;
6943 mpfr_mul_2si (result->value.real, result->value.real, p, GFC_RND_MODE);
6944
6945 return range_check (result, "RRSPACING");
6946}
b814a64e 6947
6de9cd9a
DN
6948
6949gfc_expr *
edf1eac2 6950gfc_simplify_scale (gfc_expr *x, gfc_expr *i)
6de9cd9a
DN
6951{
6952 int k, neg_flag, power, exp_range;
f8e566e5 6953 mpfr_t scale, radix;
6de9cd9a
DN
6954 gfc_expr *result;
6955
6956 if (x->expr_type != EXPR_CONSTANT || i->expr_type != EXPR_CONSTANT)
6957 return NULL;
6958
b7e75771 6959 result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where);
6de9cd9a 6960
d2af8cc6 6961 if (mpfr_zero_p (x->value.real))
6de9cd9a 6962 {
f8e566e5 6963 mpfr_set_ui (result->value.real, 0, GFC_RND_MODE);
6de9cd9a
DN
6964 return result;
6965 }
6966
e7a2d5fb 6967 k = gfc_validate_kind (BT_REAL, x->ts.kind, false);
6de9cd9a
DN
6968
6969 exp_range = gfc_real_kinds[k].max_exponent - gfc_real_kinds[k].min_exponent;
6970
6971 /* This check filters out values of i that would overflow an int. */
6972 if (mpz_cmp_si (i->value.integer, exp_range + 2) > 0
6973 || mpz_cmp_si (i->value.integer, -exp_range - 2) < 0)
6974 {
6975 gfc_error ("Result of SCALE overflows its kind at %L", &result->where);
d93712d9 6976 gfc_free_expr (result);
6de9cd9a
DN
6977 return &gfc_bad_expr;
6978 }
6979
6980 /* Compute scale = radix ** power. */
6981 power = mpz_get_si (i->value.integer);
6982
6983 if (power >= 0)
6984 neg_flag = 0;
6985 else
6986 {
6987 neg_flag = 1;
6988 power = -power;
6989 }
6990
f8e566e5
SK
6991 gfc_set_model_kind (x->ts.kind);
6992 mpfr_init (scale);
6993 mpfr_init (radix);
6994 mpfr_set_ui (radix, gfc_real_kinds[k].radix, GFC_RND_MODE);
6995 mpfr_pow_ui (scale, radix, power, GFC_RND_MODE);
6de9cd9a
DN
6996
6997 if (neg_flag)
f8e566e5 6998 mpfr_div (result->value.real, x->value.real, scale, GFC_RND_MODE);
6de9cd9a 6999 else
f8e566e5 7000 mpfr_mul (result->value.real, x->value.real, scale, GFC_RND_MODE);
6de9cd9a 7001
7306494a 7002 mpfr_clears (scale, radix, NULL);
6de9cd9a
DN
7003
7004 return range_check (result, "SCALE");
7005}
7006
7007
00660189
FXC
7008/* Variants of strspn and strcspn that operate on wide characters. */
7009
7010static size_t
7011wide_strspn (const gfc_char_t *s1, const gfc_char_t *s2)
7012{
7013 size_t i = 0;
7014 const gfc_char_t *c;
7015
7016 while (s1[i])
7017 {
7018 for (c = s2; *c; c++)
7019 {
7020 if (s1[i] == *c)
7021 break;
7022 }
7023 if (*c == '\0')
7024 break;
7025 i++;
7026 }
7027
7028 return i;
7029}
7030
7031static size_t
7032wide_strcspn (const gfc_char_t *s1, const gfc_char_t *s2)
7033{
7034 size_t i = 0;
7035 const gfc_char_t *c;
7036
7037 while (s1[i])
7038 {
7039 for (c = s2; *c; c++)
7040 {
7041 if (s1[i] == *c)
7042 break;
7043 }
7044 if (*c)
7045 break;
7046 i++;
7047 }
7048
7049 return i;
7050}
7051
7052
6de9cd9a 7053gfc_expr *
5cda5098 7054gfc_simplify_scan (gfc_expr *e, gfc_expr *c, gfc_expr *b, gfc_expr *kind)
6de9cd9a
DN
7055{
7056 gfc_expr *result;
7057 int back;
7058 size_t i;
7059 size_t indx, len, lenc;
5cda5098
FXC
7060 int k = get_kind (BT_INTEGER, kind, "SCAN", gfc_default_integer_kind);
7061
7062 if (k == -1)
7063 return &gfc_bad_expr;
6de9cd9a 7064
61aa9333
TB
7065 if (e->expr_type != EXPR_CONSTANT || c->expr_type != EXPR_CONSTANT
7066 || ( b != NULL && b->expr_type != EXPR_CONSTANT))
6de9cd9a
DN
7067 return NULL;
7068
7069 if (b != NULL && b->value.logical != 0)
7070 back = 1;
7071 else
7072 back = 0;
7073
6de9cd9a
DN
7074 len = e->value.character.length;
7075 lenc = c->value.character.length;
7076
7077 if (len == 0 || lenc == 0)
7078 {
7079 indx = 0;
7080 }
7081 else
7082 {
7083 if (back == 0)
edf1eac2 7084 {
00660189
FXC
7085 indx = wide_strcspn (e->value.character.string,
7086 c->value.character.string) + 1;
edf1eac2
SK
7087 if (indx > len)
7088 indx = 0;
7089 }
6de9cd9a 7090 else
8ba6ea87
ML
7091 for (indx = len; indx > 0; indx--)
7092 {
7093 for (i = 0; i < lenc; i++)
7094 {
7095 if (c->value.character.string[i]
7096 == e->value.character.string[indx - 1])
7097 break;
7098 }
7099 if (i < lenc)
7100 break;
7101 }
6de9cd9a 7102 }
b7e75771
JD
7103
7104 result = gfc_get_int_expr (k, &e->where, indx);
6de9cd9a
DN
7105 return range_check (result, "SCAN");
7106}
7107
7108
a39fafac
FXC
7109gfc_expr *
7110gfc_simplify_selected_char_kind (gfc_expr *e)
7111{
7112 int kind;
a39fafac
FXC
7113
7114 if (e->expr_type != EXPR_CONSTANT)
7115 return NULL;
7116
7117 if (gfc_compare_with_Cstring (e, "ascii", false) == 0
7118 || gfc_compare_with_Cstring (e, "default", false) == 0)
7119 kind = 1;
dad80a1b
JD
7120 else if (gfc_compare_with_Cstring (e, "iso_10646", false) == 0)
7121 kind = 4;
a39fafac
FXC
7122 else
7123 kind = -1;
7124
b7e75771 7125 return gfc_get_int_expr (gfc_default_integer_kind, &e->where, kind);
a39fafac
FXC
7126}
7127
7128
6de9cd9a 7129gfc_expr *
edf1eac2 7130gfc_simplify_selected_int_kind (gfc_expr *e)
6de9cd9a
DN
7131{
7132 int i, kind, range;
6de9cd9a 7133
51f03c6b 7134 if (e->expr_type != EXPR_CONSTANT || gfc_extract_int (e, &range))
6de9cd9a
DN
7135 return NULL;
7136
7137 kind = INT_MAX;
7138
7139 for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
7140 if (gfc_integer_kinds[i].range >= range
7141 && gfc_integer_kinds[i].kind < kind)
7142 kind = gfc_integer_kinds[i].kind;
7143
7144 if (kind == INT_MAX)
7145 kind = -1;
7146
b7e75771 7147 return gfc_get_int_expr (gfc_default_integer_kind, &e->where, kind);
6de9cd9a
DN
7148}
7149
7150
7151gfc_expr *
01349049 7152gfc_simplify_selected_real_kind (gfc_expr *p, gfc_expr *q, gfc_expr *rdx)
6de9cd9a 7153{
01349049
TB
7154 int range, precision, radix, i, kind, found_precision, found_range,
7155 found_radix;
7156 locus *loc = &gfc_current_locus;
6de9cd9a
DN
7157
7158 if (p == NULL)
7159 precision = 0;
7160 else
7161 {
7162 if (p->expr_type != EXPR_CONSTANT
51f03c6b 7163 || gfc_extract_int (p, &precision))
6de9cd9a 7164 return NULL;
01349049 7165 loc = &p->where;
6de9cd9a
DN
7166 }
7167
7168 if (q == NULL)
7169 range = 0;
7170 else
7171 {
7172 if (q->expr_type != EXPR_CONSTANT
51f03c6b 7173 || gfc_extract_int (q, &range))
6de9cd9a 7174 return NULL;
01349049
TB
7175
7176 if (!loc)
7177 loc = &q->where;
7178 }
7179
7180 if (rdx == NULL)
7181 radix = 0;
7182 else
7183 {
7184 if (rdx->expr_type != EXPR_CONSTANT
51f03c6b 7185 || gfc_extract_int (rdx, &radix))
01349049
TB
7186 return NULL;
7187
7188 if (!loc)
7189 loc = &rdx->where;
6de9cd9a
DN
7190 }
7191
7192 kind = INT_MAX;
7193 found_precision = 0;
7194 found_range = 0;
01349049 7195 found_radix = 0;
6de9cd9a
DN
7196
7197 for (i = 0; gfc_real_kinds[i].kind != 0; i++)
7198 {
7199 if (gfc_real_kinds[i].precision >= precision)
7200 found_precision = 1;
7201
7202 if (gfc_real_kinds[i].range >= range)
7203 found_range = 1;
7204
8b198102 7205 if (radix == 0 || gfc_real_kinds[i].radix == radix)
01349049
TB
7206 found_radix = 1;
7207
6de9cd9a 7208 if (gfc_real_kinds[i].precision >= precision
01349049 7209 && gfc_real_kinds[i].range >= range
8b198102
FXC
7210 && (radix == 0 || gfc_real_kinds[i].radix == radix)
7211 && gfc_real_kinds[i].kind < kind)
6de9cd9a
DN
7212 kind = gfc_real_kinds[i].kind;
7213 }
7214
7215 if (kind == INT_MAX)
7216 {
01349049 7217 if (found_radix && found_range && !found_precision)
6de9cd9a 7218 kind = -1;
01349049
TB
7219 else if (found_radix && found_precision && !found_range)
7220 kind = -2;
7221 else if (found_radix && !found_precision && !found_range)
7222 kind = -3;
7223 else if (found_radix)
7224 kind = -4;
7225 else
7226 kind = -5;
6de9cd9a
DN
7227 }
7228
01349049 7229 return gfc_get_int_expr (gfc_default_integer_kind, loc, kind);
6de9cd9a
DN
7230}
7231
7232
7233gfc_expr *
edf1eac2 7234gfc_simplify_set_exponent (gfc_expr *x, gfc_expr *i)
6de9cd9a
DN
7235{
7236 gfc_expr *result;
03ddaf35 7237 mpfr_t exp, absv, log2, pow2, frac;
6de9cd9a
DN
7238 unsigned long exp2;
7239
7240 if (x->expr_type != EXPR_CONSTANT || i->expr_type != EXPR_CONSTANT)
7241 return NULL;
7242
b7e75771 7243 result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where);
6de9cd9a 7244
d2af8cc6
FXC
7245 /* SET_EXPONENT (+/-0.0, I) = +/- 0.0
7246 SET_EXPONENT (NaN) = same NaN */
7247 if (mpfr_zero_p (x->value.real) || mpfr_nan_p (x->value.real))
6de9cd9a 7248 {
d2af8cc6
FXC
7249 mpfr_set (result->value.real, x->value.real, GFC_RND_MODE);
7250 return result;
7251 }
7252
7253 /* SET_EXPONENT (inf) = NaN */
7254 if (mpfr_inf_p (x->value.real))
7255 {
7256 mpfr_set_nan (result->value.real);
6de9cd9a
DN
7257 return result;
7258 }
7259
7306494a 7260 gfc_set_model_kind (x->ts.kind);
f8e566e5 7261 mpfr_init (absv);
03ddaf35
TS
7262 mpfr_init (log2);
7263 mpfr_init (exp);
f8e566e5
SK
7264 mpfr_init (pow2);
7265 mpfr_init (frac);
6de9cd9a 7266
f8e566e5 7267 mpfr_abs (absv, x->value.real, GFC_RND_MODE);
03ddaf35 7268 mpfr_log2 (log2, absv, GFC_RND_MODE);
6de9cd9a 7269
03ddaf35
TS
7270 mpfr_trunc (log2, log2);
7271 mpfr_add_ui (exp, log2, 1, GFC_RND_MODE);
6de9cd9a
DN
7272
7273 /* Old exponent value, and fraction. */
03ddaf35 7274 mpfr_ui_pow (pow2, 2, exp, GFC_RND_MODE);
6de9cd9a 7275
f8e566e5 7276 mpfr_div (frac, absv, pow2, GFC_RND_MODE);
6de9cd9a
DN
7277
7278 /* New exponent. */
7279 exp2 = (unsigned long) mpz_get_d (i->value.integer);
f8e566e5 7280 mpfr_mul_2exp (result->value.real, frac, exp2, GFC_RND_MODE);
6de9cd9a 7281
7306494a 7282 mpfr_clears (absv, log2, pow2, frac, NULL);
6de9cd9a
DN
7283
7284 return range_check (result, "SET_EXPONENT");
7285}
7286
7287
7288gfc_expr *
7320cf09 7289gfc_simplify_shape (gfc_expr *source, gfc_expr *kind)
6de9cd9a
DN
7290{
7291 mpz_t shape[GFC_MAX_DIMENSIONS];
7292 gfc_expr *result, *e, *f;
7293 gfc_array_ref *ar;
7294 int n;
524af0d6 7295 bool t;
7320cf09 7296 int k = get_kind (BT_INTEGER, kind, "SHAPE", gfc_default_integer_kind);
6de9cd9a 7297
d357d991
MM
7298 if (source->rank == -1)
7299 return NULL;
7300
7320cf09 7301 result = gfc_get_array_expr (BT_INTEGER, k, &source->where);
27bf39a8
ME
7302 result->shape = gfc_get_shape (1);
7303 mpz_init (result->shape[0]);
64a96f5b 7304
7320cf09
TB
7305 if (source->rank == 0)
7306 return result;
6de9cd9a 7307
69dcd06a
DK
7308 if (source->expr_type == EXPR_VARIABLE)
7309 {
7310 ar = gfc_find_array_ref (source);
7311 t = gfc_array_ref_shape (ar, shape);
7312 }
7313 else if (source->shape)
7314 {
524af0d6 7315 t = true;
69dcd06a
DK
7316 for (n = 0; n < source->rank; n++)
7317 {
7318 mpz_init (shape[n]);
7319 mpz_set (shape[n], source->shape[n]);
7320 }
7321 }
7322 else
524af0d6 7323 t = false;
6de9cd9a
DN
7324
7325 for (n = 0; n < source->rank; n++)
7326 {
7320cf09 7327 e = gfc_get_constant_expr (BT_INTEGER, k, &source->where);
6de9cd9a 7328
524af0d6 7329 if (t)
1634e53f 7330 mpz_set (e->value.integer, shape[n]);
6de9cd9a
DN
7331 else
7332 {
7333 mpz_set_ui (e->value.integer, n + 1);
7334
1634e53f 7335 f = simplify_size (source, e, k);
6de9cd9a
DN
7336 gfc_free_expr (e);
7337 if (f == NULL)
7338 {
7339 gfc_free_expr (result);
7340 return NULL;
7341 }
7342 else
69dcd06a 7343 e = f;
6de9cd9a
DN
7344 }
7345
1634e53f
TB
7346 if (e == &gfc_bad_expr || range_check (e, "SHAPE") == &gfc_bad_expr)
7347 {
7348 gfc_free_expr (result);
7349 if (t)
7350 gfc_clear_shape (shape, source->rank);
7351 return &gfc_bad_expr;
7352 }
7353
b7e75771 7354 gfc_constructor_append_expr (&result->value.constructor, e, NULL);
6de9cd9a
DN
7355 }
7356
1634e53f
TB
7357 if (t)
7358 gfc_clear_shape (shape, source->rank);
7359
27bf39a8
ME
7360 mpz_set_si (result->shape[0], source->rank);
7361
6de9cd9a
DN
7362 return result;
7363}
7364
7365
1634e53f
TB
7366static gfc_expr *
7367simplify_size (gfc_expr *array, gfc_expr *dim, int k)
6de9cd9a
DN
7368{
7369 mpz_t size;
9231ff56 7370 gfc_expr *return_value;
6de9cd9a
DN
7371 int d;
7372
69dcd06a
DK
7373 /* For unary operations, the size of the result is given by the size
7374 of the operand. For binary ones, it's the size of the first operand
7375 unless it is scalar, then it is the size of the second. */
7376 if (array->expr_type == EXPR_OP && !array->value.op.uop)
7377 {
7378 gfc_expr* replacement;
7379 gfc_expr* simplified;
7380
7381 switch (array->value.op.op)
7382 {
7383 /* Unary operations. */
7384 case INTRINSIC_NOT:
7385 case INTRINSIC_UPLUS:
7386 case INTRINSIC_UMINUS:
1b3f07c7 7387 case INTRINSIC_PARENTHESES:
69dcd06a
DK
7388 replacement = array->value.op.op1;
7389 break;
7390
7391 /* Binary operations. If any one of the operands is scalar, take
7392 the other one's size. If both of them are arrays, it does not
7393 matter -- try to find one with known shape, if possible. */
7394 default:
7395 if (array->value.op.op1->rank == 0)
7396 replacement = array->value.op.op2;
7397 else if (array->value.op.op2->rank == 0)
7398 replacement = array->value.op.op1;
7399 else
7400 {
1634e53f 7401 simplified = simplify_size (array->value.op.op1, dim, k);
69dcd06a
DK
7402 if (simplified)
7403 return simplified;
7404
7405 replacement = array->value.op.op2;
7406 }
7407 break;
7408 }
7409
7410 /* Try to reduce it directly if possible. */
1634e53f 7411 simplified = simplify_size (replacement, dim, k);
69dcd06a
DK
7412
7413 /* Otherwise, we build a new SIZE call. This is hopefully at least
7414 simpler than the original one. */
7415 if (!simplified)
1634e53f
TB
7416 {
7417 gfc_expr *kind = gfc_get_int_expr (gfc_default_integer_kind, NULL, k);
7418 simplified = gfc_build_intrinsic_call (gfc_current_ns,
7419 GFC_ISYM_SIZE, "size",
7420 array->where, 3,
7421 gfc_copy_expr (replacement),
7422 gfc_copy_expr (dim),
7423 kind);
7424 }
69dcd06a
DK
7425 return simplified;
7426 }
7427
6de9cd9a
DN
7428 if (dim == NULL)
7429 {
524af0d6 7430 if (!gfc_array_size (array, &size))
6de9cd9a
DN
7431 return NULL;
7432 }
7433 else
7434 {
7435 if (dim->expr_type != EXPR_CONSTANT)
7436 return NULL;
7437
7438 d = mpz_get_ui (dim->value.integer) - 1;
524af0d6 7439 if (!gfc_array_dimen_size (array, d, &size))
6de9cd9a
DN
7440 return NULL;
7441 }
7442
1634e53f
TB
7443 return_value = gfc_get_constant_expr (BT_INTEGER, k, &array->where);
7444 mpz_set (return_value->value.integer, size);
9231ff56 7445 mpz_clear (size);
1634e53f 7446
9231ff56 7447 return return_value;
6de9cd9a
DN
7448}
7449
7450
1634e53f
TB
7451gfc_expr *
7452gfc_simplify_size (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
7453{
7454 gfc_expr *result;
7455 int k = get_kind (BT_INTEGER, kind, "SIZE", gfc_default_integer_kind);
7456
7457 if (k == -1)
7458 return &gfc_bad_expr;
7459
7460 result = simplify_size (array, dim, k);
7461 if (result == NULL || result == &gfc_bad_expr)
7462 return result;
7463
7464 return range_check (result, "SIZE");
7465}
7466
7467
1a8c1e35
TB
7468/* SIZEOF and C_SIZEOF return the size in bytes of an array element
7469 multiplied by the array size. */
7470
7471gfc_expr *
7472gfc_simplify_sizeof (gfc_expr *x)
7473{
7474 gfc_expr *result = NULL;
7475 mpz_t array_size;
cdd17931 7476 size_t res_size;
1a8c1e35
TB
7477
7478 if (x->ts.type == BT_CLASS || x->ts.deferred)
7479 return NULL;
7480
7481 if (x->ts.type == BT_CHARACTER
7482 && (!x->ts.u.cl || !x->ts.u.cl->length
7483 || x->ts.u.cl->length->expr_type != EXPR_CONSTANT))
7484 return NULL;
7485
7486 if (x->rank && x->expr_type != EXPR_ARRAY
524af0d6 7487 && !gfc_array_size (x, &array_size))
1a8c1e35
TB
7488 return NULL;
7489
7490 result = gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind,
7491 &x->where);
cdd17931
HA
7492 gfc_target_expr_size (x, &res_size);
7493 mpz_set_si (result->value.integer, res_size);
1a8c1e35 7494
1a8c1e35
TB
7495 return result;
7496}
7497
7498
7499/* STORAGE_SIZE returns the size in bits of a single array element. */
7500
7501gfc_expr *
7502gfc_simplify_storage_size (gfc_expr *x,
7503 gfc_expr *kind)
7504{
7505 gfc_expr *result = NULL;
7506 int k;
cdd17931 7507 size_t siz;
1a8c1e35
TB
7508
7509 if (x->ts.type == BT_CLASS || x->ts.deferred)
7510 return NULL;
7511
cc6be82e 7512 if (x->ts.type == BT_CHARACTER && x->expr_type != EXPR_CONSTANT
1a8c1e35
TB
7513 && (!x->ts.u.cl || !x->ts.u.cl->length
7514 || x->ts.u.cl->length->expr_type != EXPR_CONSTANT))
7515 return NULL;
7516
7517 k = get_kind (BT_INTEGER, kind, "STORAGE_SIZE", gfc_default_integer_kind);
7518 if (k == -1)
7519 return &gfc_bad_expr;
7520
a634323a 7521 result = gfc_get_constant_expr (BT_INTEGER, k, &x->where);
e361d18d 7522
cdd17931
HA
7523 gfc_element_size (x, &siz);
7524 mpz_set_si (result->value.integer, siz);
1a8c1e35 7525 mpz_mul_ui (result->value.integer, result->value.integer, BITS_PER_UNIT);
1634e53f
TB
7526
7527 return range_check (result, "STORAGE_SIZE");
1a8c1e35
TB
7528}
7529
7530
6de9cd9a 7531gfc_expr *
edf1eac2 7532gfc_simplify_sign (gfc_expr *x, gfc_expr *y)
6de9cd9a
DN
7533{
7534 gfc_expr *result;
7535
7536 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
7537 return NULL;
7538
b7e75771 7539 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
6de9cd9a
DN
7540
7541 switch (x->ts.type)
7542 {
b7e75771
JD
7543 case BT_INTEGER:
7544 mpz_abs (result->value.integer, x->value.integer);
7545 if (mpz_sgn (y->value.integer) < 0)
7546 mpz_neg (result->value.integer, result->value.integer);
7547 break;
6de9cd9a 7548
b7e75771 7549 case BT_REAL:
c61819ff 7550 if (flag_sign_zero)
b7e75771
JD
7551 mpfr_copysign (result->value.real, x->value.real, y->value.real,
7552 GFC_RND_MODE);
7553 else
7554 mpfr_setsign (result->value.real, x->value.real,
7555 mpfr_sgn (y->value.real) < 0 ? 1 : 0, GFC_RND_MODE);
7556 break;
6de9cd9a 7557
b7e75771
JD
7558 default:
7559 gfc_internal_error ("Bad type in gfc_simplify_sign");
6de9cd9a
DN
7560 }
7561
7562 return result;
7563}
7564
7565
7566gfc_expr *
edf1eac2 7567gfc_simplify_sin (gfc_expr *x)
6de9cd9a
DN
7568{
7569 gfc_expr *result;
6de9cd9a
DN
7570
7571 if (x->expr_type != EXPR_CONSTANT)
7572 return NULL;
7573
b7e75771 7574 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
6de9cd9a
DN
7575
7576 switch (x->ts.type)
7577 {
b7e75771
JD
7578 case BT_REAL:
7579 mpfr_sin (result->value.real, x->value.real, GFC_RND_MODE);
7580 break;
6de9cd9a 7581
b7e75771
JD
7582 case BT_COMPLEX:
7583 gfc_set_model (x->value.real);
7584 mpc_sin (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
7585 break;
6de9cd9a 7586
b7e75771
JD
7587 default:
7588 gfc_internal_error ("in gfc_simplify_sin(): Bad type");
6de9cd9a
DN
7589 }
7590
7591 return range_check (result, "SIN");
7592}
7593
7594
7595gfc_expr *
edf1eac2 7596gfc_simplify_sinh (gfc_expr *x)
6de9cd9a
DN
7597{
7598 gfc_expr *result;
7599
7600 if (x->expr_type != EXPR_CONSTANT)
7601 return NULL;
7602
b7e75771 7603 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
6de9cd9a 7604
b7e75771
JD
7605 switch (x->ts.type)
7606 {
7607 case BT_REAL:
7608 mpfr_sinh (result->value.real, x->value.real, GFC_RND_MODE);
7609 break;
7610
7611 case BT_COMPLEX:
7612 mpc_sinh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
7613 break;
504ed63a 7614
b7e75771
JD
7615 default:
7616 gcc_unreachable ();
7617 }
6de9cd9a
DN
7618
7619 return range_check (result, "SINH");
7620}
7621
7622
7623/* The argument is always a double precision real that is converted to
7624 single precision. TODO: Rounding! */
7625
7626gfc_expr *
edf1eac2 7627gfc_simplify_sngl (gfc_expr *a)
6de9cd9a
DN
7628{
7629 gfc_expr *result;
e23390d2 7630 int tmp1, tmp2;
6de9cd9a
DN
7631
7632 if (a->expr_type != EXPR_CONSTANT)
7633 return NULL;
7634
e23390d2
SK
7635 /* For explicit conversion, turn off -Wconversion and -Wconversion-extra
7636 warnings. */
7637 tmp1 = warn_conversion;
7638 tmp2 = warn_conversion_extra;
7639 warn_conversion = warn_conversion_extra = 0;
7640
9d64df18 7641 result = gfc_real2real (a, gfc_default_real_kind);
e23390d2
SK
7642
7643 warn_conversion = tmp1;
7644 warn_conversion_extra = tmp2;
7645
6de9cd9a
DN
7646 return range_check (result, "SNGL");
7647}
7648
6de9cd9a 7649
cc6d3bde 7650gfc_expr *
edf1eac2 7651gfc_simplify_spacing (gfc_expr *x)
cc6d3bde
SK
7652{
7653 gfc_expr *result;
7654 int i;
7655 long int en, ep;
6de9cd9a 7656
cc6d3bde
SK
7657 if (x->expr_type != EXPR_CONSTANT)
7658 return NULL;
7659
7660 i = gfc_validate_kind (x->ts.type, x->ts.kind, false);
b7e75771 7661 result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where);
cc6d3bde 7662
d2af8cc6
FXC
7663 /* SPACING(+/- 0.0) = SPACING(TINY(0.0)) = TINY(0.0) */
7664 if (mpfr_zero_p (x->value.real))
cc6d3bde
SK
7665 {
7666 mpfr_set (result->value.real, gfc_real_kinds[i].tiny, GFC_RND_MODE);
7667 return result;
7668 }
7669
d2af8cc6
FXC
7670 /* SPACING(inf) = NaN */
7671 if (mpfr_inf_p (x->value.real))
7672 {
7673 mpfr_set_nan (result->value.real);
7674 return result;
7675 }
7676
7677 /* SPACING(NaN) = same NaN */
7678 if (mpfr_nan_p (x->value.real))
7679 {
7680 mpfr_set (result->value.real, x->value.real, GFC_RND_MODE);
7681 return result;
7682 }
7683
cc6d3bde 7684 /* In the Fortran 95 standard, the result is b**(e - p) where b, e, and p
8b704316 7685 are the radix, exponent of x, and precision. This excludes the
cc6d3bde
SK
7686 possibility of subnormal numbers. Fortran 2003 states the result is
7687 b**max(e - p, emin - 1). */
7688
7689 ep = (long int) mpfr_get_exp (x->value.real) - gfc_real_kinds[i].digits;
7690 en = (long int) gfc_real_kinds[i].min_exponent - 1;
7691 en = en > ep ? en : ep;
7692
7693 mpfr_set_ui (result->value.real, 1, GFC_RND_MODE);
7694 mpfr_mul_2si (result->value.real, result->value.real, en, GFC_RND_MODE);
7695
7696 return range_check (result, "SPACING");
7697}
b814a64e 7698
6de9cd9a 7699
c430a6f9
DF
7700gfc_expr *
7701gfc_simplify_spread (gfc_expr *source, gfc_expr *dim_expr, gfc_expr *ncopies_expr)
7702{
9231aa17
SK
7703 gfc_expr *result = NULL;
7704 int nelem, i, j, dim, ncopies;
0e6640d8 7705 mpz_t size;
c430a6f9
DF
7706
7707 if ((!gfc_is_constant_expr (source)
7708 && !is_constant_array_expr (source))
7709 || !gfc_is_constant_expr (dim_expr)
7710 || !gfc_is_constant_expr (ncopies_expr))
7711 return NULL;
7712
7713 gcc_assert (dim_expr->ts.type == BT_INTEGER);
7714 gfc_extract_int (dim_expr, &dim);
7715 dim -= 1; /* zero-base DIM */
7716
7717 gcc_assert (ncopies_expr->ts.type == BT_INTEGER);
7718 gfc_extract_int (ncopies_expr, &ncopies);
7719 ncopies = MAX (ncopies, 0);
7720
0e6640d8
PT
7721 /* Do not allow the array size to exceed the limit for an array
7722 constructor. */
e5e85f2b
TB
7723 if (source->expr_type == EXPR_ARRAY)
7724 {
524af0d6 7725 if (!gfc_array_size (source, &size))
e5e85f2b
TB
7726 gfc_internal_error ("Failure getting length of a constant array.");
7727 }
7728 else
7729 mpz_init_set_ui (size, 1);
7730
9231aa17
SK
7731 nelem = mpz_get_si (size) * ncopies;
7732 if (nelem > flag_max_array_constructor)
7733 {
b7b848f5 7734 if (gfc_init_expr_flag)
9231aa17
SK
7735 {
7736 gfc_error ("The number of elements (%d) in the array constructor "
7737 "at %L requires an increase of the allowed %d upper "
7738 "limit. See %<-fmax-array-constructor%> option.",
7739 nelem, &source->where, flag_max_array_constructor);
7740 return &gfc_bad_expr;
7741 }
7742 else
7743 return NULL;
7744 }
0e6640d8 7745
ee0b3cea
TK
7746 if (source->expr_type == EXPR_CONSTANT
7747 || source->expr_type == EXPR_STRUCTURE)
c430a6f9
DF
7748 {
7749 gcc_assert (dim == 0);
7750
b7e75771
JD
7751 result = gfc_get_array_expr (source->ts.type, source->ts.kind,
7752 &source->where);
15c2ef5a
PT
7753 if (source->ts.type == BT_DERIVED)
7754 result->ts.u.derived = source->ts.u.derived;
c430a6f9
DF
7755 result->rank = 1;
7756 result->shape = gfc_get_shape (result->rank);
7757 mpz_init_set_si (result->shape[0], ncopies);
7758
7759 for (i = 0; i < ncopies; ++i)
b7e75771
JD
7760 gfc_constructor_append_expr (&result->value.constructor,
7761 gfc_copy_expr (source), NULL);
c430a6f9
DF
7762 }
7763 else if (source->expr_type == EXPR_ARRAY)
7764 {
b7e75771
JD
7765 int offset, rstride[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS];
7766 gfc_constructor *source_ctor;
c430a6f9
DF
7767
7768 gcc_assert (source->rank < GFC_MAX_DIMENSIONS);
7769 gcc_assert (dim >= 0 && dim <= source->rank);
7770
b7e75771
JD
7771 result = gfc_get_array_expr (source->ts.type, source->ts.kind,
7772 &source->where);
15c2ef5a
PT
7773 if (source->ts.type == BT_DERIVED)
7774 result->ts.u.derived = source->ts.u.derived;
c430a6f9
DF
7775 result->rank = source->rank + 1;
7776 result->shape = gfc_get_shape (result->rank);
7777
c430a6f9
DF
7778 for (i = 0, j = 0; i < result->rank; ++i)
7779 {
7780 if (i != dim)
7781 mpz_init_set (result->shape[i], source->shape[j++]);
7782 else
7783 mpz_init_set_si (result->shape[i], ncopies);
7784
7785 extent[i] = mpz_get_si (result->shape[i]);
7786 rstride[i] = (i == 0) ? 1 : rstride[i-1] * extent[i-1];
c430a6f9
DF
7787 }
7788
b7e75771
JD
7789 offset = 0;
7790 for (source_ctor = gfc_constructor_first (source->value.constructor);
7791 source_ctor; source_ctor = gfc_constructor_next (source_ctor))
c430a6f9 7792 {
c430a6f9 7793 for (i = 0; i < ncopies; ++i)
b7e75771
JD
7794 gfc_constructor_insert_expr (&result->value.constructor,
7795 gfc_copy_expr (source_ctor->expr),
7796 NULL, offset + i * rstride[dim]);
c430a6f9 7797
b7e75771 7798 offset += (dim == 0 ? ncopies : 1);
c430a6f9
DF
7799 }
7800 }
7801 else
b1c1d761 7802 {
98d4439c 7803 gfc_error ("Simplification of SPREAD at %C not yet implemented");
b1c1d761
SK
7804 return &gfc_bad_expr;
7805 }
c430a6f9
DF
7806
7807 if (source->ts.type == BT_CHARACTER)
bc21d315 7808 result->ts.u.cl = source->ts.u.cl;
c430a6f9
DF
7809
7810 return result;
7811}
7812
7813
6de9cd9a 7814gfc_expr *
edf1eac2 7815gfc_simplify_sqrt (gfc_expr *e)
6de9cd9a 7816{
b7e75771 7817 gfc_expr *result = NULL;
6de9cd9a
DN
7818
7819 if (e->expr_type != EXPR_CONSTANT)
7820 return NULL;
7821
6de9cd9a
DN
7822 switch (e->ts.type)
7823 {
b7e75771
JD
7824 case BT_REAL:
7825 if (mpfr_cmp_si (e->value.real, 0) < 0)
7826 {
7827 gfc_error ("Argument of SQRT at %L has a negative value",
7828 &e->where);
7829 return &gfc_bad_expr;
7830 }
7831 result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
7832 mpfr_sqrt (result->value.real, e->value.real, GFC_RND_MODE);
7833 break;
6de9cd9a 7834
b7e75771
JD
7835 case BT_COMPLEX:
7836 gfc_set_model (e->value.real);
6de9cd9a 7837
b7e75771
JD
7838 result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
7839 mpc_sqrt (result->value.complex, e->value.complex, GFC_MPC_RND_MODE);
7840 break;
6de9cd9a 7841
b7e75771
JD
7842 default:
7843 gfc_internal_error ("invalid argument of SQRT at %L", &e->where);
6de9cd9a
DN
7844 }
7845
7846 return range_check (result, "SQRT");
6de9cd9a
DN
7847}
7848
7849
a16d978f
DF
7850gfc_expr *
7851gfc_simplify_sum (gfc_expr *array, gfc_expr *dim, gfc_expr *mask)
7852{
195a95c4 7853 return simplify_transformation (array, dim, mask, 0, gfc_add);
a16d978f
DF
7854}
7855
7856
57391dda
FR
7857/* Simplify COTAN(X) where X has the unit of radian. */
7858
8e8c2744
FR
7859gfc_expr *
7860gfc_simplify_cotan (gfc_expr *x)
7861{
7862 gfc_expr *result;
7863 mpc_t swp, *val;
7864
7865 if (x->expr_type != EXPR_CONSTANT)
7866 return NULL;
7867
7868 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
7869
7870 switch (x->ts.type)
7871 {
0a4613f0
JJ
7872 case BT_REAL:
7873 mpfr_cot (result->value.real, x->value.real, GFC_RND_MODE);
7874 break;
8e8c2744 7875
0a4613f0
JJ
7876 case BT_COMPLEX:
7877 /* There is no builtin mpc_cot, so compute cot = cos / sin. */
7878 val = &result->value.complex;
7879 mpc_init2 (swp, mpfr_get_default_prec ());
57391dda
FR
7880 mpc_sin_cos (*val, swp, x->value.complex, GFC_MPC_RND_MODE,
7881 GFC_MPC_RND_MODE);
0a4613f0
JJ
7882 mpc_div (*val, swp, *val, GFC_MPC_RND_MODE);
7883 mpc_clear (swp);
7884 break;
8e8c2744 7885
0a4613f0
JJ
7886 default:
7887 gcc_unreachable ();
8e8c2744
FR
7888 }
7889
7890 return range_check (result, "COTAN");
7891}
7892
7893
6de9cd9a 7894gfc_expr *
edf1eac2 7895gfc_simplify_tan (gfc_expr *x)
6de9cd9a 7896{
f8e566e5 7897 gfc_expr *result;
6de9cd9a
DN
7898
7899 if (x->expr_type != EXPR_CONSTANT)
7900 return NULL;
7901
b7e75771 7902 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
6de9cd9a 7903
b7e75771
JD
7904 switch (x->ts.type)
7905 {
7906 case BT_REAL:
7907 mpfr_tan (result->value.real, x->value.real, GFC_RND_MODE);
7908 break;
7909
7910 case BT_COMPLEX:
7911 mpc_tan (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
7912 break;
7913
7914 default:
7915 gcc_unreachable ();
7916 }
6de9cd9a
DN
7917
7918 return range_check (result, "TAN");
7919}
7920
7921
7922gfc_expr *
edf1eac2 7923gfc_simplify_tanh (gfc_expr *x)
6de9cd9a
DN
7924{
7925 gfc_expr *result;
6de9cd9a
DN
7926
7927 if (x->expr_type != EXPR_CONSTANT)
7928 return NULL;
7929
b7e75771 7930 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
6de9cd9a 7931
b7e75771
JD
7932 switch (x->ts.type)
7933 {
7934 case BT_REAL:
7935 mpfr_tanh (result->value.real, x->value.real, GFC_RND_MODE);
7936 break;
6de9cd9a 7937
b7e75771
JD
7938 case BT_COMPLEX:
7939 mpc_tanh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
7940 break;
7941
7942 default:
7943 gcc_unreachable ();
7944 }
6de9cd9a 7945
b7e75771 7946 return range_check (result, "TANH");
6de9cd9a
DN
7947}
7948
7949
7950gfc_expr *
edf1eac2 7951gfc_simplify_tiny (gfc_expr *e)
6de9cd9a
DN
7952{
7953 gfc_expr *result;
7954 int i;
7955
e7a2d5fb 7956 i = gfc_validate_kind (BT_REAL, e->ts.kind, false);
6de9cd9a 7957
b7e75771 7958 result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
f8e566e5 7959 mpfr_set (result->value.real, gfc_real_kinds[i].tiny, GFC_RND_MODE);
6de9cd9a
DN
7960
7961 return result;
7962}
7963
7964
414f00e9
SB
7965gfc_expr *
7966gfc_simplify_trailz (gfc_expr *e)
7967{
414f00e9
SB
7968 unsigned long tz, bs;
7969 int i;
7970
7971 if (e->expr_type != EXPR_CONSTANT)
7972 return NULL;
7973
7974 i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
7975 bs = gfc_integer_kinds[i].bit_size;
7976 tz = mpz_scan1 (e->value.integer, 0);
7977
b7e75771
JD
7978 return gfc_get_int_expr (gfc_default_integer_kind,
7979 &e->where, MIN (tz, bs));
414f00e9
SB
7980}
7981
7982
a4a11197 7983gfc_expr *
edf1eac2 7984gfc_simplify_transfer (gfc_expr *source, gfc_expr *mold, gfc_expr *size)
a4a11197 7985{
7433458d
PT
7986 gfc_expr *result;
7987 gfc_expr *mold_element;
7988 size_t source_size;
7989 size_t result_size;
7433458d
PT
7990 size_t buffer_size;
7991 mpz_t tmp;
7992 unsigned char *buffer;
86dbed7d
TK
7993 size_t result_length;
7994
a900a060
SK
7995 if (!gfc_is_constant_expr (source) || !gfc_is_constant_expr (size))
7996 return NULL;
a4a11197 7997
a900a060
SK
7998 if (!gfc_resolve_expr (mold))
7999 return NULL;
8000 if (gfc_init_expr_flag && !gfc_is_constant_expr (mold))
7433458d
PT
8001 return NULL;
8002
f8862a1b 8003 if (!gfc_calculate_transfer_sizes (source, mold, size, &source_size,
524af0d6 8004 &result_size, &result_length))
2dc95548
PT
8005 return NULL;
8006
7433458d 8007 /* Calculate the size of the source. */
b0369790 8008 if (source->expr_type == EXPR_ARRAY && !gfc_array_size (source, &tmp))
7433458d
PT
8009 gfc_internal_error ("Failure getting length of a constant array.");
8010
7433458d 8011 /* Create an empty new expression with the appropriate characteristics. */
b7e75771
JD
8012 result = gfc_get_constant_expr (mold->ts.type, mold->ts.kind,
8013 &source->where);
7433458d
PT
8014 result->ts = mold->ts;
8015
b0369790 8016 mold_element = (mold->expr_type == EXPR_ARRAY && mold->value.constructor)
b7e75771 8017 ? gfc_constructor_first (mold->value.constructor)->expr
7433458d
PT
8018 : mold;
8019
8020 /* Set result character length, if needed. Note that this needs to be
8b704316 8021 set even for array expressions, in order to pass this information into
7433458d 8022 gfc_target_interpret_expr. */
d9183bb7 8023 if (result->ts.type == BT_CHARACTER && gfc_is_constant_expr (mold_element))
7433458d 8024 result->value.character.length = mold_element->value.character.length;
8b704316 8025
7433458d 8026 /* Set the number of elements in the result, and determine its size. */
d9183bb7 8027
e7c8ff56 8028 if (mold->expr_type == EXPR_ARRAY || mold->rank || size)
7433458d 8029 {
7433458d
PT
8030 result->expr_type = EXPR_ARRAY;
8031 result->rank = 1;
7433458d
PT
8032 result->shape = gfc_get_shape (1);
8033 mpz_init_set_ui (result->shape[0], result_length);
7433458d
PT
8034 }
8035 else
86dbed7d 8036 result->rank = 0;
92ebaacd 8037
7433458d
PT
8038 /* Allocate the buffer to store the binary version of the source. */
8039 buffer_size = MAX (source_size, result_size);
8040 buffer = (unsigned char*)alloca (buffer_size);
47ed69db 8041 memset (buffer, 0, buffer_size);
7433458d
PT
8042
8043 /* Now write source to the buffer. */
8044 gfc_target_encode_expr (source, buffer, buffer_size);
8045
8046 /* And read the buffer back into the new expression. */
86dbed7d 8047 gfc_target_interpret_expr (buffer, buffer_size, result, false);
7433458d
PT
8048
8049 return result;
a4a11197
PT
8050}
8051
8052
8ec259c1
DF
8053gfc_expr *
8054gfc_simplify_transpose (gfc_expr *matrix)
8055{
b7e75771 8056 int row, matrix_rows, col, matrix_cols;
8ec259c1 8057 gfc_expr *result;
8ec259c1
DF
8058
8059 if (!is_constant_array_expr (matrix))
8060 return NULL;
8061
8062 gcc_assert (matrix->rank == 2);
8063
b7e75771
JD
8064 result = gfc_get_array_expr (matrix->ts.type, matrix->ts.kind,
8065 &matrix->where);
8ec259c1
DF
8066 result->rank = 2;
8067 result->shape = gfc_get_shape (result->rank);
8068 mpz_set (result->shape[0], matrix->shape[1]);
8069 mpz_set (result->shape[1], matrix->shape[0]);
8070
8071 if (matrix->ts.type == BT_CHARACTER)
bc21d315 8072 result->ts.u.cl = matrix->ts.u.cl;
15c2ef5a
PT
8073 else if (matrix->ts.type == BT_DERIVED)
8074 result->ts.u.derived = matrix->ts.u.derived;
8ec259c1
DF
8075
8076 matrix_rows = mpz_get_si (matrix->shape[0]);
b7e75771
JD
8077 matrix_cols = mpz_get_si (matrix->shape[1]);
8078 for (row = 0; row < matrix_rows; ++row)
8079 for (col = 0; col < matrix_cols; ++col)
8080 {
8081 gfc_expr *e = gfc_constructor_lookup_expr (matrix->value.constructor,
8082 col * matrix_rows + row);
8b704316 8083 gfc_constructor_insert_expr (&result->value.constructor,
b7e75771
JD
8084 gfc_copy_expr (e), &matrix->where,
8085 row * matrix_cols + col);
8086 }
8ec259c1
DF
8087
8088 return result;
8089}
8090
8091
6de9cd9a 8092gfc_expr *
edf1eac2 8093gfc_simplify_trim (gfc_expr *e)
6de9cd9a
DN
8094{
8095 gfc_expr *result;
8096 int count, i, len, lentrim;
8097
8098 if (e->expr_type != EXPR_CONSTANT)
8099 return NULL;
8100
8101 len = e->value.character.length;
6de9cd9a
DN
8102 for (count = 0, i = 1; i <= len; ++i)
8103 {
8104 if (e->value.character.string[len - i] == ' ')
8105 count++;
8106 else
8107 break;
8108 }
8109
8110 lentrim = len - count;
8111
b7e75771 8112 result = gfc_get_character_expr (e->ts.kind, &e->where, NULL, lentrim);
6de9cd9a
DN
8113 for (i = 0; i < lentrim; i++)
8114 result->value.character.string[i] = e->value.character.string[i];
8115
6de9cd9a
DN
8116 return result;
8117}
8118
8119
64f002ed
TB
8120gfc_expr *
8121gfc_simplify_image_index (gfc_expr *coarray, gfc_expr *sub)
8122{
8123 gfc_expr *result;
8124 gfc_ref *ref;
8125 gfc_array_spec *as;
8126 gfc_constructor *sub_cons;
8127 bool first_image;
8128 int d;
8129
8130 if (!is_constant_array_expr (sub))
5af07930 8131 return NULL;
64f002ed
TB
8132
8133 /* Follow any component references. */
8134 as = coarray->symtree->n.sym->as;
8135 for (ref = coarray->ref; ref; ref = ref->next)
8136 if (ref->type == REF_COMPONENT)
8137 as = ref->u.ar.as;
8138
8139 if (as->type == AS_DEFERRED)
5af07930 8140 return NULL;
64f002ed
TB
8141
8142 /* "valid sequence of cosubscripts" are required; thus, return 0 unless
8143 the cosubscript addresses the first image. */
8144
8145 sub_cons = gfc_constructor_first (sub->value.constructor);
8146 first_image = true;
8147
8148 for (d = 1; d <= as->corank; d++)
8149 {
8150 gfc_expr *ca_bound;
8151 int cmp;
8152
e84b920c 8153 gcc_assert (sub_cons != NULL);
64f002ed
TB
8154
8155 ca_bound = simplify_bound_dim (coarray, NULL, d + as->rank, 0, as,
8156 NULL, true);
8157 if (ca_bound == NULL)
5af07930 8158 return NULL;
64f002ed
TB
8159
8160 if (ca_bound == &gfc_bad_expr)
8161 return ca_bound;
8162
8163 cmp = mpz_cmp (ca_bound->value.integer, sub_cons->expr->value.integer);
8164
8165 if (cmp == 0)
8166 {
8167 gfc_free_expr (ca_bound);
8168 sub_cons = gfc_constructor_next (sub_cons);
8169 continue;
8170 }
8171
8172 first_image = false;
8173
8174 if (cmp > 0)
8175 {
8176 gfc_error ("Out of bounds in IMAGE_INDEX at %L for dimension %d, "
8177 "SUB has %ld and COARRAY lower bound is %ld)",
8178 &coarray->where, d,
8179 mpz_get_si (sub_cons->expr->value.integer),
8180 mpz_get_si (ca_bound->value.integer));
8181 gfc_free_expr (ca_bound);
8182 return &gfc_bad_expr;
8183 }
8184
8185 gfc_free_expr (ca_bound);
8186
8187 /* Check whether upperbound is valid for the multi-images case. */
8188 if (d < as->corank)
8189 {
8190 ca_bound = simplify_bound_dim (coarray, NULL, d + as->rank, 1, as,
8191 NULL, true);
8192 if (ca_bound == &gfc_bad_expr)
8193 return ca_bound;
8194
8195 if (ca_bound && ca_bound->expr_type == EXPR_CONSTANT
8196 && mpz_cmp (ca_bound->value.integer,
8197 sub_cons->expr->value.integer) < 0)
8198 {
8199 gfc_error ("Out of bounds in IMAGE_INDEX at %L for dimension %d, "
8200 "SUB has %ld and COARRAY upper bound is %ld)",
8201 &coarray->where, d,
8202 mpz_get_si (sub_cons->expr->value.integer),
8203 mpz_get_si (ca_bound->value.integer));
8204 gfc_free_expr (ca_bound);
8205 return &gfc_bad_expr;
8206 }
8207
8208 if (ca_bound)
8209 gfc_free_expr (ca_bound);
8210 }
8211
8212 sub_cons = gfc_constructor_next (sub_cons);
8213 }
8214
e84b920c 8215 gcc_assert (sub_cons == NULL);
5af07930 8216
f19626cf 8217 if (flag_coarray != GFC_FCOARRAY_SINGLE && !first_image)
5af07930
TB
8218 return NULL;
8219
64f002ed
TB
8220 result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
8221 &gfc_current_locus);
8222 if (first_image)
8223 mpz_set_si (result->value.integer, 1);
8224 else
8225 mpz_set_si (result->value.integer, 0);
8226
8227 return result;
64f002ed
TB
8228}
8229
ef78bc3c
AV
8230gfc_expr *
8231gfc_simplify_image_status (gfc_expr *image, gfc_expr *team ATTRIBUTE_UNUSED)
8232{
8233 if (flag_coarray == GFC_FCOARRAY_NONE)
8234 {
8235 gfc_current_locus = *gfc_current_intrinsic_where;
8236 gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
8237 return &gfc_bad_expr;
8238 }
8239
8240 /* Simplification is possible for fcoarray = single only. For all other modes
8241 the result depends on runtime conditions. */
8242 if (flag_coarray != GFC_FCOARRAY_SINGLE)
8243 return NULL;
8244
8245 if (gfc_is_constant_expr (image))
8246 {
8247 gfc_expr *result;
8248 result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
8249 &image->where);
8250 if (mpz_get_si (image->value.integer) == 1)
8251 mpz_set_si (result->value.integer, 0);
8252 else
8253 mpz_set_si (result->value.integer, GFC_STAT_STOPPED_IMAGE);
8254 return result;
8255 }
8256 else
8257 return NULL;
8258}
8259
64f002ed
TB
8260
8261gfc_expr *
05fc16dd
TB
8262gfc_simplify_this_image (gfc_expr *coarray, gfc_expr *dim,
8263 gfc_expr *distance ATTRIBUTE_UNUSED)
64f002ed 8264{
f19626cf 8265 if (flag_coarray != GFC_FCOARRAY_SINGLE)
60386f50
TB
8266 return NULL;
8267
05fc16dd
TB
8268 /* If no coarray argument has been passed or when the first argument
8269 is actually a distance argment. */
8270 if (coarray == NULL || !gfc_is_coarray (coarray))
64f002ed
TB
8271 {
8272 gfc_expr *result;
8273 /* FIXME: gfc_current_locus is wrong. */
8274 result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
8275 &gfc_current_locus);
8276 mpz_set_si (result->value.integer, 1);
8277 return result;
8278 }
8279
492792ed
TB
8280 /* For -fcoarray=single, this_image(A) is the same as lcobound(A). */
8281 return simplify_cobound (coarray, dim, NULL, 0);
64f002ed
TB
8282}
8283
8284
6de9cd9a 8285gfc_expr *
5cda5098 8286gfc_simplify_ubound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
6de9cd9a 8287{
5cda5098 8288 return simplify_bound (array, dim, kind, 1);
6de9cd9a
DN
8289}
8290
64f002ed
TB
8291gfc_expr *
8292gfc_simplify_ucobound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
8293{
a3935ffc 8294 return simplify_cobound (array, dim, kind, 1);
64f002ed
TB
8295}
8296
6de9cd9a 8297
c430a6f9
DF
8298gfc_expr *
8299gfc_simplify_unpack (gfc_expr *vector, gfc_expr *mask, gfc_expr *field)
8300{
8301 gfc_expr *result, *e;
8302 gfc_constructor *vector_ctor, *mask_ctor, *field_ctor;
8303
8304 if (!is_constant_array_expr (vector)
8305 || !is_constant_array_expr (mask)
8306 || (!gfc_is_constant_expr (field)
524af0d6 8307 && !is_constant_array_expr (field)))
c430a6f9
DF
8308 return NULL;
8309
b7e75771
JD
8310 result = gfc_get_array_expr (vector->ts.type, vector->ts.kind,
8311 &vector->where);
15c2ef5a
PT
8312 if (vector->ts.type == BT_DERIVED)
8313 result->ts.u.derived = vector->ts.u.derived;
c430a6f9
DF
8314 result->rank = mask->rank;
8315 result->shape = gfc_copy_shape (mask->shape, mask->rank);
8316
8317 if (vector->ts.type == BT_CHARACTER)
bc21d315 8318 result->ts.u.cl = vector->ts.u.cl;
c430a6f9 8319
b7e75771
JD
8320 vector_ctor = gfc_constructor_first (vector->value.constructor);
8321 mask_ctor = gfc_constructor_first (mask->value.constructor);
8322 field_ctor
8323 = field->expr_type == EXPR_ARRAY
8324 ? gfc_constructor_first (field->value.constructor)
8325 : NULL;
c430a6f9
DF
8326
8327 while (mask_ctor)
8328 {
8329 if (mask_ctor->expr->value.logical)
8330 {
8331 gcc_assert (vector_ctor);
8332 e = gfc_copy_expr (vector_ctor->expr);
b7e75771 8333 vector_ctor = gfc_constructor_next (vector_ctor);
c430a6f9
DF
8334 }
8335 else if (field->expr_type == EXPR_ARRAY)
8336 e = gfc_copy_expr (field_ctor->expr);
8337 else
8338 e = gfc_copy_expr (field);
8339
b7e75771 8340 gfc_constructor_append_expr (&result->value.constructor, e, NULL);
c430a6f9 8341
b7e75771
JD
8342 mask_ctor = gfc_constructor_next (mask_ctor);
8343 field_ctor = gfc_constructor_next (field_ctor);
c430a6f9
DF
8344 }
8345
8346 return result;
8347}
8348
8349
6de9cd9a 8350gfc_expr *
5cda5098 8351gfc_simplify_verify (gfc_expr *s, gfc_expr *set, gfc_expr *b, gfc_expr *kind)
6de9cd9a
DN
8352{
8353 gfc_expr *result;
8354 int back;
8355 size_t index, len, lenset;
8356 size_t i;
5cda5098
FXC
8357 int k = get_kind (BT_INTEGER, kind, "VERIFY", gfc_default_integer_kind);
8358
8359 if (k == -1)
8360 return &gfc_bad_expr;
6de9cd9a 8361
61aa9333
TB
8362 if (s->expr_type != EXPR_CONSTANT || set->expr_type != EXPR_CONSTANT
8363 || ( b != NULL && b->expr_type != EXPR_CONSTANT))
6de9cd9a
DN
8364 return NULL;
8365
8366 if (b != NULL && b->value.logical != 0)
8367 back = 1;
8368 else
8369 back = 0;
8370
b7e75771 8371 result = gfc_get_constant_expr (BT_INTEGER, k, &s->where);
6de9cd9a
DN
8372
8373 len = s->value.character.length;
8374 lenset = set->value.character.length;
8375
8376 if (len == 0)
8377 {
8378 mpz_set_ui (result->value.integer, 0);
8379 return result;
8380 }
8381
8382 if (back == 0)
8383 {
8384 if (lenset == 0)
8385 {
9202989a 8386 mpz_set_ui (result->value.integer, 1);
6de9cd9a
DN
8387 return result;
8388 }
8389
00660189
FXC
8390 index = wide_strspn (s->value.character.string,
8391 set->value.character.string) + 1;
6de9cd9a
DN
8392 if (index > len)
8393 index = 0;
8394
8395 }
8396 else
8397 {
8398 if (lenset == 0)
8399 {
9202989a 8400 mpz_set_ui (result->value.integer, len);
6de9cd9a
DN
8401 return result;
8402 }
8403 for (index = len; index > 0; index --)
edf1eac2
SK
8404 {
8405 for (i = 0; i < lenset; i++)
8406 {
8407 if (s->value.character.string[index - 1]
8408 == set->value.character.string[i])
8409 break;
8410 }
8411 if (i == lenset)
8412 break;
8413 }
6de9cd9a
DN
8414 }
8415
8416 mpz_set_ui (result->value.integer, index);
8417 return result;
8418}
8419
5d723e54
FXC
8420
8421gfc_expr *
edf1eac2 8422gfc_simplify_xor (gfc_expr *x, gfc_expr *y)
5d723e54
FXC
8423{
8424 gfc_expr *result;
8425 int kind;
8426
8427 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
8428 return NULL;
8429
8430 kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;
b7e75771
JD
8431
8432 switch (x->ts.type)
5d723e54 8433 {
b7e75771
JD
8434 case BT_INTEGER:
8435 result = gfc_get_constant_expr (BT_INTEGER, kind, &x->where);
8436 mpz_xor (result->value.integer, x->value.integer, y->value.integer);
8437 return range_check (result, "XOR");
8438
8439 case BT_LOGICAL:
8440 return gfc_get_logical_expr (kind, &x->where,
8441 (x->value.logical && !y->value.logical)
8442 || (!x->value.logical && y->value.logical));
5d723e54 8443
b7e75771
JD
8444 default:
8445 gcc_unreachable ();
8446 }
5d723e54
FXC
8447}
8448
8449
6de9cd9a
DN
8450/****************** Constant simplification *****************/
8451
8452/* Master function to convert one constant to another. While this is
8453 used as a simplification function, it requires the destination type
8454 and kind information which is supplied by a special case in
8455 do_simplify(). */
8456
8457gfc_expr *
edf1eac2 8458gfc_convert_constant (gfc_expr *e, bt type, int kind)
6de9cd9a 8459{
0ada0dc0
PT
8460 gfc_expr *result, *(*f) (gfc_expr *, int);
8461 gfc_constructor *c, *t;
6de9cd9a
DN
8462
8463 switch (e->ts.type)
8464 {
8465 case BT_INTEGER:
8466 switch (type)
8467 {
8468 case BT_INTEGER:
8469 f = gfc_int2int;
8470 break;
8471 case BT_REAL:
8472 f = gfc_int2real;
8473 break;
8474 case BT_COMPLEX:
8475 f = gfc_int2complex;
8476 break;
c3a29423
RS
8477 case BT_LOGICAL:
8478 f = gfc_int2log;
8479 break;
6de9cd9a
DN
8480 default:
8481 goto oops;
8482 }
8483 break;
8484
8485 case BT_REAL:
8486 switch (type)
8487 {
8488 case BT_INTEGER:
8489 f = gfc_real2int;
8490 break;
8491 case BT_REAL:
8492 f = gfc_real2real;
8493 break;
8494 case BT_COMPLEX:
8495 f = gfc_real2complex;
8496 break;
8497 default:
8498 goto oops;
8499 }
8500 break;
8501
8502 case BT_COMPLEX:
8503 switch (type)
8504 {
8505 case BT_INTEGER:
8506 f = gfc_complex2int;
8507 break;
8508 case BT_REAL:
8509 f = gfc_complex2real;
8510 break;
8511 case BT_COMPLEX:
8512 f = gfc_complex2complex;
8513 break;
8514
8515 default:
8516 goto oops;
8517 }
8518 break;
8519
8520 case BT_LOGICAL:
c3a29423
RS
8521 switch (type)
8522 {
8523 case BT_INTEGER:
8524 f = gfc_log2int;
8525 break;
8526 case BT_LOGICAL:
8527 f = gfc_log2log;
8528 break;
8529 default:
8530 goto oops;
8531 }
6de9cd9a
DN
8532 break;
8533
d3642f89
FW
8534 case BT_HOLLERITH:
8535 switch (type)
8536 {
8537 case BT_INTEGER:
8538 f = gfc_hollerith2int;
8539 break;
8540
8541 case BT_REAL:
8542 f = gfc_hollerith2real;
8543 break;
8544
8545 case BT_COMPLEX:
8546 f = gfc_hollerith2complex;
8547 break;
8548
8549 case BT_CHARACTER:
8550 f = gfc_hollerith2character;
8551 break;
8552
8553 case BT_LOGICAL:
8554 f = gfc_hollerith2logical;
8555 break;
8556
8557 default:
8558 goto oops;
8559 }
8560 break;
8561
b01fff48 8562 case BT_CHARACTER:
2afeb1ca
ME
8563 switch (type)
8564 {
8565 case BT_INTEGER:
8566 f = gfc_character2int;
8567 break;
8568
8569 case BT_REAL:
8570 f = gfc_character2real;
8571 break;
8572
8573 case BT_COMPLEX:
8574 f = gfc_character2complex;
8575 break;
8576
8577 case BT_CHARACTER:
8578 f = gfc_character2character;
8579 break;
8580
8581 case BT_LOGICAL:
8582 f = gfc_character2logical;
8583 break;
8584
8585 default:
8586 goto oops;
8587 }
b01fff48
TK
8588 break;
8589
6de9cd9a
DN
8590 default:
8591 oops:
e9b75848 8592 return &gfc_bad_expr;
6de9cd9a
DN
8593 }
8594
8595 result = NULL;
8596
8597 switch (e->expr_type)
8598 {
8599 case EXPR_CONSTANT:
8600 result = f (e, kind);
8601 if (result == NULL)
8602 return &gfc_bad_expr;
8603 break;
8604
8605 case EXPR_ARRAY:
8606 if (!gfc_is_constant_expr (e))
8607 break;
8608
b7e75771
JD
8609 result = gfc_get_array_expr (type, kind, &e->where);
8610 result->shape = gfc_copy_shape (e->shape, e->rank);
8611 result->rank = e->rank;
6de9cd9a 8612
b7e75771
JD
8613 for (c = gfc_constructor_first (e->value.constructor);
8614 c; c = gfc_constructor_next (c))
6de9cd9a 8615 {
b7e75771 8616 gfc_expr *tmp;
6de9cd9a 8617 if (c->iterator == NULL)
949d0060 8618 {
0ada0dc0
PT
8619 if (c->expr->expr_type == EXPR_ARRAY)
8620 tmp = gfc_convert_constant (c->expr, type, kind);
c20a90e0 8621 else if (c->expr->expr_type == EXPR_OP)
22aa73bd 8622 {
c20a90e0
SK
8623 if (!gfc_simplify_expr (c->expr, 1))
8624 return &gfc_bad_expr;
22aa73bd
SK
8625 tmp = f (c->expr, kind);
8626 }
0ada0dc0
PT
8627 else
8628 tmp = f (c->expr, kind);
949d0060 8629 }
6de9cd9a 8630 else
0ada0dc0
PT
8631 tmp = gfc_convert_constant (c->expr, type, kind);
8632
8633 if (tmp == NULL || tmp == &gfc_bad_expr)
6de9cd9a 8634 {
0ada0dc0
PT
8635 gfc_free_expr (result);
8636 return NULL;
6de9cd9a 8637 }
0ada0dc0
PT
8638
8639 t = gfc_constructor_append_expr (&result->value.constructor,
8640 tmp, &c->where);
8641 if (c->iterator)
8642 t->iterator = gfc_copy_iterator (c->iterator);
6de9cd9a
DN
8643 }
8644
6de9cd9a
DN
8645 break;
8646
8647 default:
8648 break;
8649 }
8650
8651 return result;
8652}
d393bbd7
FXC
8653
8654
8655/* Function for converting character constants. */
8656gfc_expr *
8657gfc_convert_char_constant (gfc_expr *e, bt type ATTRIBUTE_UNUSED, int kind)
8658{
8659 gfc_expr *result;
8660 int i;
8661
8662 if (!gfc_is_constant_expr (e))
8663 return NULL;
8664
691da334
FXC
8665 if (e->expr_type == EXPR_CONSTANT)
8666 {
8667 /* Simple case of a scalar. */
b7e75771 8668 result = gfc_get_constant_expr (BT_CHARACTER, kind, &e->where);
691da334 8669 if (result == NULL)
d393bbd7 8670 return &gfc_bad_expr;
d393bbd7 8671
691da334
FXC
8672 result->value.character.length = e->value.character.length;
8673 result->value.character.string
8674 = gfc_get_wide_string (e->value.character.length + 1);
8675 memcpy (result->value.character.string, e->value.character.string,
8676 (e->value.character.length + 1) * sizeof (gfc_char_t));
8677
8678 /* Check we only have values representable in the destination kind. */
8679 for (i = 0; i < result->value.character.length; i++)
8680 if (!gfc_check_character_range (result->value.character.string[i],
8681 kind))
8682 {
a4d9b221 8683 gfc_error ("Character %qs in string at %L cannot be converted "
691da334
FXC
8684 "into character kind %d",
8685 gfc_print_wide_char (result->value.character.string[i]),
8686 &e->where, kind);
47109217 8687 gfc_free_expr (result);
691da334
FXC
8688 return &gfc_bad_expr;
8689 }
8690
8691 return result;
8692 }
8693 else if (e->expr_type == EXPR_ARRAY)
8694 {
8695 /* For an array constructor, we convert each constructor element. */
b7e75771 8696 gfc_constructor *c;
691da334 8697
b7e75771
JD
8698 result = gfc_get_array_expr (type, kind, &e->where);
8699 result->shape = gfc_copy_shape (e->shape, e->rank);
8700 result->rank = e->rank;
8701 result->ts.u.cl = e->ts.u.cl;
691da334 8702
b7e75771
JD
8703 for (c = gfc_constructor_first (e->value.constructor);
8704 c; c = gfc_constructor_next (c))
8705 {
8706 gfc_expr *tmp = gfc_convert_char_constant (c->expr, type, kind);
8707 if (tmp == &gfc_bad_expr)
691da334 8708 {
b7e75771 8709 gfc_free_expr (result);
691da334
FXC
8710 return &gfc_bad_expr;
8711 }
8712
b7e75771 8713 if (tmp == NULL)
691da334 8714 {
b7e75771 8715 gfc_free_expr (result);
691da334
FXC
8716 return NULL;
8717 }
691da334 8718
b7e75771
JD
8719 gfc_constructor_append_expr (&result->value.constructor,
8720 tmp, &c->where);
8721 }
691da334
FXC
8722
8723 return result;
8724 }
8725 else
8726 return NULL;
d393bbd7 8727}
d000aa67
TB
8728
8729
8730gfc_expr *
8731gfc_simplify_compiler_options (void)
8732{
41804a5b
TB
8733 char *str;
8734 gfc_expr *result;
8735
8736 str = gfc_get_option_string ();
8737 result = gfc_get_character_expr (gfc_default_character_kind,
8738 &gfc_current_locus, str, strlen (str));
cede9502 8739 free (str);
41804a5b 8740 return result;
d000aa67
TB
8741}
8742
8743
8744gfc_expr *
8745gfc_simplify_compiler_version (void)
8746{
41804a5b
TB
8747 char *buffer;
8748 size_t len;
8749
ed17fc41
SK
8750 len = strlen ("GCC version ") + strlen (version_string);
8751 buffer = XALLOCAVEC (char, len + 1);
8752 snprintf (buffer, len + 1, "GCC version %s", version_string);
d000aa67 8753 return gfc_get_character_expr (gfc_default_character_kind,
41804a5b 8754 &gfc_current_locus, buffer, len);
d000aa67 8755}
0e360db9
FXC
8756
8757/* Simplification routines for intrinsics of IEEE modules. */
8758
8759gfc_expr *
8760simplify_ieee_selected_real_kind (gfc_expr *expr)
8761{
741b52b5
SK
8762 gfc_actual_arglist *arg;
8763 gfc_expr *p = NULL, *q = NULL, *rdx = NULL;
8764
8765 arg = expr->value.function.actual;
8766 p = arg->expr;
8767 if (arg->next)
8768 {
8769 q = arg->next->expr;
8770 if (arg->next->next)
8771 rdx = arg->next->next->expr;
8772 }
0e360db9
FXC
8773
8774 /* Currently, if IEEE is supported and this module is built, it means
8775 all our floating-point types conform to IEEE. Hence, we simply handle
8776 IEEE_SELECTED_REAL_KIND like SELECTED_REAL_KIND. */
8777 return gfc_simplify_selected_real_kind (p, q, rdx);
8778}
8779
8780gfc_expr *
8781simplify_ieee_support (gfc_expr *expr)
8782{
8783 /* We consider that if the IEEE modules are loaded, we have full support
8784 for flags, halting and rounding, which are the three functions
8785 (IEEE_SUPPORT_{FLAG,HALTING,ROUNDING}) allowed in constant
8786 expressions. One day, we will need libgfortran to detect support and
8787 communicate it back to us, allowing for partial support. */
8788
8789 return gfc_get_logical_expr (gfc_default_logical_kind, &expr->where,
8790 true);
8791}
8792
8793bool
8794matches_ieee_function_name (gfc_symbol *sym, const char *name)
8795{
8796 int n = strlen(name);
8797
8798 if (!strncmp(sym->name, name, n))
8799 return true;
8800
8801 /* If a generic was used and renamed, we need more work to find out.
8802 Compare the specific name. */
8803 if (sym->generic && !strncmp(sym->generic->sym->name, name, n))
8804 return true;
8805
8806 return false;
8807}
8808
8809gfc_expr *
8810gfc_simplify_ieee_functions (gfc_expr *expr)
8811{
8812 gfc_symbol* sym = expr->symtree->n.sym;
8813
8814 if (matches_ieee_function_name(sym, "ieee_selected_real_kind"))
8815 return simplify_ieee_selected_real_kind (expr);
8816 else if (matches_ieee_function_name(sym, "ieee_support_flag")
8817 || matches_ieee_function_name(sym, "ieee_support_halting")
8818 || matches_ieee_function_name(sym, "ieee_support_rounding"))
8819 return simplify_ieee_support (expr);
8820 else
8821 return NULL;
8822}