]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fortran/array.c
Update copyright years.
[thirdparty/gcc.git] / gcc / fortran / array.c
CommitLineData
6de9cd9a 1/* Array things
8d9254fc 2 Copyright (C) 2000-2020 Free Software Foundation, Inc.
6de9cd9a
DN
3 Contributed by Andy Vaught
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"
d22e4895 22#include "system.h"
953bee7c 23#include "coretypes.h"
1916bcb5 24#include "options.h"
6de9cd9a
DN
25#include "gfortran.h"
26#include "match.h"
b7e75771 27#include "constructor.h"
6de9cd9a 28
6de9cd9a
DN
29/**************** Array reference matching subroutines *****************/
30
31/* Copy an array reference structure. */
32
33gfc_array_ref *
65f8144a 34gfc_copy_array_ref (gfc_array_ref *src)
6de9cd9a
DN
35{
36 gfc_array_ref *dest;
37 int i;
38
39 if (src == NULL)
40 return NULL;
41
42 dest = gfc_get_array_ref ();
43
44 *dest = *src;
45
46 for (i = 0; i < GFC_MAX_DIMENSIONS; i++)
47 {
48 dest->start[i] = gfc_copy_expr (src->start[i]);
49 dest->end[i] = gfc_copy_expr (src->end[i]);
50 dest->stride[i] = gfc_copy_expr (src->stride[i]);
51 }
52
6de9cd9a
DN
53 return dest;
54}
55
56
57/* Match a single dimension of an array reference. This can be a
58 single element or an array section. Any modifications we've made
59 to the ar structure are cleaned up by the caller. If the init
60 is set, we require the subscript to be a valid initialization
61 expression. */
62
63static match
d3a9eea2 64match_subscript (gfc_array_ref *ar, int init, bool match_star)
6de9cd9a 65{
acaed831 66 match m = MATCH_ERROR;
d3a9eea2 67 bool star = false;
6de9cd9a 68 int i;
c988c699 69 bool saw_boz = false;
6de9cd9a 70
d3a9eea2 71 i = ar->dimen + ar->codimen;
6de9cd9a 72
00b9bf8b 73 gfc_gobble_whitespace ();
63645982 74 ar->c_where[i] = gfc_current_locus;
6de9cd9a
DN
75 ar->start[i] = ar->end[i] = ar->stride[i] = NULL;
76
77 /* We can't be sure of the difference between DIMEN_ELEMENT and
78 DIMEN_VECTOR until we know the type of the element itself at
79 resolution time. */
80
81 ar->dimen_type[i] = DIMEN_UNKNOWN;
82
83 if (gfc_match_char (':') == MATCH_YES)
84 goto end_element;
85
86 /* Get start element. */
d3a9eea2
TB
87 if (match_star && (m = gfc_match_char ('*')) == MATCH_YES)
88 star = true;
89
90 if (!star && init)
6de9cd9a 91 m = gfc_match_init_expr (&ar->start[i]);
d3a9eea2 92 else if (!star)
6de9cd9a
DN
93 m = gfc_match_expr (&ar->start[i]);
94
c988c699
SK
95 if (ar->start[i] && ar->start[i]->ts.type == BT_BOZ)
96 {
97 gfc_error ("Invalid BOZ literal constant used in subscript at %C");
98 saw_boz = true;
99 }
100
6273c3c2 101 if (m == MATCH_NO)
6de9cd9a
DN
102 gfc_error ("Expected array subscript at %C");
103 if (m != MATCH_YES)
104 return MATCH_ERROR;
105
106 if (gfc_match_char (':') == MATCH_NO)
d3a9eea2
TB
107 goto matched;
108
109 if (star)
110 {
c4100eae 111 gfc_error ("Unexpected %<*%> in coarray subscript at %C");
d3a9eea2
TB
112 return MATCH_ERROR;
113 }
6de9cd9a
DN
114
115 /* Get an optional end element. Because we've seen the colon, we
116 definitely have a range along this dimension. */
117end_element:
118 ar->dimen_type[i] = DIMEN_RANGE;
119
d3a9eea2
TB
120 if (match_star && (m = gfc_match_char ('*')) == MATCH_YES)
121 star = true;
122 else if (init)
6de9cd9a
DN
123 m = gfc_match_init_expr (&ar->end[i]);
124 else
125 m = gfc_match_expr (&ar->end[i]);
126
c988c699
SK
127 if (ar->end[i] && ar->end[i]->ts.type == BT_BOZ)
128 {
129 gfc_error ("Invalid BOZ literal constant used in subscript at %C");
130 saw_boz = true;
131 }
132
6de9cd9a
DN
133 if (m == MATCH_ERROR)
134 return MATCH_ERROR;
135
136 /* See if we have an optional stride. */
137 if (gfc_match_char (':') == MATCH_YES)
138 {
d3a9eea2
TB
139 if (star)
140 {
141 gfc_error ("Strides not allowed in coarray subscript at %C");
142 return MATCH_ERROR;
143 }
144
6de9cd9a 145 m = init ? gfc_match_init_expr (&ar->stride[i])
65f8144a 146 : gfc_match_expr (&ar->stride[i]);
6de9cd9a 147
c988c699
SK
148 if (ar->stride[i] && ar->stride[i]->ts.type == BT_BOZ)
149 {
150 gfc_error ("Invalid BOZ literal constant used in subscript at %C");
151 saw_boz = true;
152 }
153
6de9cd9a
DN
154 if (m == MATCH_NO)
155 gfc_error ("Expected array subscript stride at %C");
156 if (m != MATCH_YES)
157 return MATCH_ERROR;
158 }
159
d3a9eea2
TB
160matched:
161 if (star)
162 ar->dimen_type[i] = DIMEN_STAR;
163
c988c699 164 return (saw_boz ? MATCH_ERROR : MATCH_YES);
6de9cd9a
DN
165}
166
167
28bc117f
SK
168/* Match an array reference, whether it is the whole array or particular
169 elements or a section. If init is set, the reference has to consist
170 of init expressions. */
6de9cd9a
DN
171
172match
d3a9eea2
TB
173gfc_match_array_ref (gfc_array_ref *ar, gfc_array_spec *as, int init,
174 int corank)
6de9cd9a
DN
175{
176 match m;
d3a9eea2 177 bool matched_bracket = false;
20d0bfce
AF
178 gfc_expr *tmp;
179 bool stat_just_seen = false;
f8862a1b 180 bool team_just_seen = false;
6de9cd9a 181
1a4049e7 182 memset (ar, '\0', sizeof (*ar));
6de9cd9a 183
63645982 184 ar->where = gfc_current_locus;
6de9cd9a 185 ar->as = as;
d3a9eea2
TB
186 ar->type = AR_UNKNOWN;
187
188 if (gfc_match_char ('[') == MATCH_YES)
189 {
190 matched_bracket = true;
191 goto coarray;
192 }
6de9cd9a
DN
193
194 if (gfc_match_char ('(') != MATCH_YES)
195 {
196 ar->type = AR_FULL;
197 ar->dimen = 0;
198 return MATCH_YES;
199 }
200
6de9cd9a
DN
201 for (ar->dimen = 0; ar->dimen < GFC_MAX_DIMENSIONS; ar->dimen++)
202 {
d3a9eea2 203 m = match_subscript (ar, init, false);
6de9cd9a 204 if (m == MATCH_ERROR)
d3a9eea2 205 return MATCH_ERROR;
6de9cd9a
DN
206
207 if (gfc_match_char (')') == MATCH_YES)
d3a9eea2
TB
208 {
209 ar->dimen++;
210 goto coarray;
211 }
6de9cd9a
DN
212
213 if (gfc_match_char (',') != MATCH_YES)
214 {
215 gfc_error ("Invalid form of array reference at %C");
d3a9eea2 216 return MATCH_ERROR;
6de9cd9a
DN
217 }
218 }
219
7fb43006
PT
220 if (ar->dimen >= 7
221 && !gfc_notify_std (GFC_STD_F2008,
222 "Array reference at %C has more than 7 dimensions"))
223 return MATCH_ERROR;
224
31043f6c
FXC
225 gfc_error ("Array reference at %C cannot have more than %d dimensions",
226 GFC_MAX_DIMENSIONS);
6de9cd9a
DN
227 return MATCH_ERROR;
228
d3a9eea2
TB
229coarray:
230 if (!matched_bracket && gfc_match_char ('[') != MATCH_YES)
231 {
232 if (ar->dimen > 0)
233 return MATCH_YES;
234 else
235 return MATCH_ERROR;
236 }
237
f19626cf 238 if (flag_coarray == GFC_FCOARRAY_NONE)
d3a9eea2 239 {
ddc05d11 240 gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
d3a9eea2
TB
241 return MATCH_ERROR;
242 }
243
244 if (corank == 0)
245 {
246 gfc_error ("Unexpected coarray designator at %C");
247 return MATCH_ERROR;
248 }
249
20d0bfce
AF
250 ar->stat = NULL;
251
d3a9eea2
TB
252 for (ar->codimen = 0; ar->codimen + ar->dimen < GFC_MAX_DIMENSIONS; ar->codimen++)
253 {
6273c3c2 254 m = match_subscript (ar, init, true);
d3a9eea2
TB
255 if (m == MATCH_ERROR)
256 return MATCH_ERROR;
257
f8862a1b 258 team_just_seen = false;
20d0bfce 259 stat_just_seen = false;
f8862a1b
DR
260 if (gfc_match (" , team = %e", &tmp) == MATCH_YES && ar->team == NULL)
261 {
262 ar->team = tmp;
263 team_just_seen = true;
264 }
265
266 if (ar->team && !team_just_seen)
267 {
268 gfc_error ("TEAM= attribute in %C misplaced");
269 return MATCH_ERROR;
270 }
271
272 if (gfc_match (" , stat = %e",&tmp) == MATCH_YES && ar->stat == NULL)
20d0bfce
AF
273 {
274 ar->stat = tmp;
275 stat_just_seen = true;
276 }
277
278 if (ar->stat && !stat_just_seen)
279 {
280 gfc_error ("STAT= attribute in %C misplaced");
281 return MATCH_ERROR;
282 }
283
d3a9eea2
TB
284 if (gfc_match_char (']') == MATCH_YES)
285 {
286 ar->codimen++;
7aa0849a
TB
287 if (ar->codimen < corank)
288 {
289 gfc_error ("Too few codimensions at %C, expected %d not %d",
290 corank, ar->codimen);
291 return MATCH_ERROR;
292 }
e84b920c
TB
293 if (ar->codimen > corank)
294 {
295 gfc_error ("Too many codimensions at %C, expected %d not %d",
296 corank, ar->codimen);
297 return MATCH_ERROR;
298 }
d3a9eea2
TB
299 return MATCH_YES;
300 }
301
302 if (gfc_match_char (',') != MATCH_YES)
303 {
7aa0849a 304 if (gfc_match_char ('*') == MATCH_YES)
c4100eae 305 gfc_error ("Unexpected %<*%> for codimension %d of %d at %C",
7aa0849a
TB
306 ar->codimen + 1, corank);
307 else
308 gfc_error ("Invalid form of coarray reference at %C");
309 return MATCH_ERROR;
310 }
6273c3c2
TB
311 else if (ar->dimen_type[ar->codimen + ar->dimen] == DIMEN_STAR)
312 {
c4100eae 313 gfc_error ("Unexpected %<*%> for codimension %d of %d at %C",
6273c3c2
TB
314 ar->codimen + 1, corank);
315 return MATCH_ERROR;
316 }
317
7aa0849a
TB
318 if (ar->codimen >= corank)
319 {
320 gfc_error ("Invalid codimension %d at %C, only %d codimensions exist",
321 ar->codimen + 1, corank);
d3a9eea2
TB
322 return MATCH_ERROR;
323 }
324 }
325
326 gfc_error ("Array reference at %C cannot have more than %d dimensions",
327 GFC_MAX_DIMENSIONS);
328 return MATCH_ERROR;
6de9cd9a 329
6de9cd9a
DN
330}
331
332
333/************** Array specification matching subroutines ***************/
334
335/* Free all of the expressions associated with array bounds
336 specifications. */
337
338void
65f8144a 339gfc_free_array_spec (gfc_array_spec *as)
6de9cd9a
DN
340{
341 int i;
342
343 if (as == NULL)
344 return;
345
974b8e61 346 if (as->corank == 0)
6de9cd9a 347 {
974b8e61
SK
348 for (i = 0; i < as->rank; i++)
349 {
350 gfc_free_expr (as->lower[i]);
351 gfc_free_expr (as->upper[i]);
352 }
353 }
354 else
355 {
356 int n = as->rank + as->corank - (as->cotype == AS_EXPLICIT ? 1 : 0);
357 for (i = 0; i < n; i++)
358 {
359 gfc_free_expr (as->lower[i]);
360 gfc_free_expr (as->upper[i]);
361 }
6de9cd9a
DN
362 }
363
cede9502 364 free (as);
6de9cd9a
DN
365}
366
367
368/* Take an array bound, resolves the expression, that make up the
369 shape and check associated constraints. */
370
524af0d6 371static bool
65f8144a 372resolve_array_bound (gfc_expr *e, int check_constant)
6de9cd9a 373{
6de9cd9a 374 if (e == NULL)
524af0d6 375 return true;
6de9cd9a 376
524af0d6
JB
377 if (!gfc_resolve_expr (e)
378 || !gfc_specification_expr (e))
379 return false;
6de9cd9a 380
2b868bf5 381 if (check_constant && !gfc_is_constant_expr (e))
6de9cd9a 382 {
2b868bf5 383 if (e->expr_type == EXPR_VARIABLE)
c4100eae 384 gfc_error ("Variable %qs at %L in this context must be constant",
2b868bf5
DK
385 e->symtree->n.sym->name, &e->where);
386 else
387 gfc_error ("Expression at %L in this context must be constant",
388 &e->where);
524af0d6 389 return false;
6de9cd9a
DN
390 }
391
524af0d6 392 return true;
6de9cd9a
DN
393}
394
395
396/* Takes an array specification, resolves the expressions that make up
397 the shape and make sure everything is integral. */
398
524af0d6 399bool
65f8144a 400gfc_resolve_array_spec (gfc_array_spec *as, int check_constant)
6de9cd9a
DN
401{
402 gfc_expr *e;
403 int i;
404
405 if (as == NULL)
524af0d6 406 return true;
6de9cd9a 407
9b7df66f
TK
408 if (as->resolved)
409 return true;
410
be59db2d 411 for (i = 0; i < as->rank + as->corank; i++)
6de9cd9a 412 {
d136595d
ML
413 if (i == GFC_MAX_DIMENSIONS)
414 return false;
415
6de9cd9a 416 e = as->lower[i];
524af0d6
JB
417 if (!resolve_array_bound (e, check_constant))
418 return false;
6de9cd9a
DN
419
420 e = as->upper[i];
524af0d6
JB
421 if (!resolve_array_bound (e, check_constant))
422 return false;
52f56431
PT
423
424 if ((as->lower[i] == NULL) || (as->upper[i] == NULL))
425 continue;
426
427 /* If the size is negative in this dimension, set it to zero. */
428 if (as->lower[i]->expr_type == EXPR_CONSTANT
429 && as->upper[i]->expr_type == EXPR_CONSTANT
430 && mpz_cmp (as->upper[i]->value.integer,
431 as->lower[i]->value.integer) < 0)
432 {
433 gfc_free_expr (as->upper[i]);
434 as->upper[i] = gfc_copy_expr (as->lower[i]);
435 mpz_sub_ui (as->upper[i]->value.integer,
436 as->upper[i]->value.integer, 1);
437 }
6de9cd9a
DN
438 }
439
9b7df66f
TK
440 as->resolved = true;
441
524af0d6 442 return true;
6de9cd9a
DN
443}
444
445
446/* Match a single array element specification. The return values as
447 well as the upper and lower bounds of the array spec are filled
448 in according to what we see on the input. The caller makes sure
449 individual specifications make sense as a whole.
450
451
65f8144a
SK
452 Parsed Lower Upper Returned
453 ------------------------------------
b7fdd4ed
SK
454 : NULL NULL AS_DEFERRED (*)
455 x 1 x AS_EXPLICIT
456 x: x NULL AS_ASSUMED_SHAPE
457 x:y x y AS_EXPLICIT
458 x:* x NULL AS_ASSUMED_SIZE
459 * 1 NULL AS_ASSUMED_SIZE
6de9cd9a
DN
460
461 (*) For non-pointer dummy arrays this is AS_ASSUMED_SHAPE. This
462 is fixed during the resolution of formal interfaces.
463
464 Anything else AS_UNKNOWN. */
465
466static array_type
65f8144a 467match_array_element_spec (gfc_array_spec *as)
6de9cd9a
DN
468{
469 gfc_expr **upper, **lower;
470 match m;
c62c6622 471 int rank;
6de9cd9a 472
c62c6622
TB
473 rank = as->rank == -1 ? 0 : as->rank;
474 lower = &as->lower[rank + as->corank - 1];
475 upper = &as->upper[rank + as->corank - 1];
6de9cd9a
DN
476
477 if (gfc_match_char ('*') == MATCH_YES)
478 {
b7e75771 479 *lower = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
6de9cd9a
DN
480 return AS_ASSUMED_SIZE;
481 }
482
483 if (gfc_match_char (':') == MATCH_YES)
484 return AS_DEFERRED;
485
486 m = gfc_match_expr (upper);
487 if (m == MATCH_NO)
488 gfc_error ("Expected expression in array specification at %C");
489 if (m != MATCH_YES)
490 return AS_UNKNOWN;
524af0d6 491 if (!gfc_expr_check_typed (*upper, gfc_current_ns, false))
f37e928c 492 return AS_UNKNOWN;
6de9cd9a 493
a5edb32e
JD
494 if (((*upper)->expr_type == EXPR_CONSTANT
495 && (*upper)->ts.type != BT_INTEGER) ||
496 ((*upper)->expr_type == EXPR_FUNCTION
497 && (*upper)->ts.type == BT_UNKNOWN
498 && (*upper)->symtree
499 && strcmp ((*upper)->symtree->name, "null") == 0))
28bc117f 500 {
a5edb32e
JD
501 gfc_error ("Expecting a scalar INTEGER expression at %C, found %s",
502 gfc_basic_typename ((*upper)->ts.type));
28bc117f
SK
503 return AS_UNKNOWN;
504 }
505
6de9cd9a
DN
506 if (gfc_match_char (':') == MATCH_NO)
507 {
b7e75771 508 *lower = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
6de9cd9a
DN
509 return AS_EXPLICIT;
510 }
511
512 *lower = *upper;
513 *upper = NULL;
514
515 if (gfc_match_char ('*') == MATCH_YES)
516 return AS_ASSUMED_SIZE;
517
518 m = gfc_match_expr (upper);
519 if (m == MATCH_ERROR)
520 return AS_UNKNOWN;
521 if (m == MATCH_NO)
522 return AS_ASSUMED_SHAPE;
524af0d6 523 if (!gfc_expr_check_typed (*upper, gfc_current_ns, false))
f37e928c 524 return AS_UNKNOWN;
6de9cd9a 525
a5edb32e
JD
526 if (((*upper)->expr_type == EXPR_CONSTANT
527 && (*upper)->ts.type != BT_INTEGER) ||
528 ((*upper)->expr_type == EXPR_FUNCTION
529 && (*upper)->ts.type == BT_UNKNOWN
530 && (*upper)->symtree
531 && strcmp ((*upper)->symtree->name, "null") == 0))
28bc117f 532 {
a5edb32e
JD
533 gfc_error ("Expecting a scalar INTEGER expression at %C, found %s",
534 gfc_basic_typename ((*upper)->ts.type));
28bc117f
SK
535 return AS_UNKNOWN;
536 }
537
6de9cd9a
DN
538 return AS_EXPLICIT;
539}
540
541
542/* Matches an array specification, incidentally figuring out what sort
28bc117f
SK
543 it is. Match either a normal array specification, or a coarray spec
544 or both. Optionally allow [:] for coarrays. */
6de9cd9a
DN
545
546match
be59db2d 547gfc_match_array_spec (gfc_array_spec **asp, bool match_dim, bool match_codim)
6de9cd9a
DN
548{
549 array_type current_type;
550 gfc_array_spec *as;
551 int i;
6de9cd9a 552
40a33e3f 553 as = gfc_get_array_spec ();
6de9cd9a 554
be59db2d
TB
555 if (!match_dim)
556 goto coarray;
557
558 if (gfc_match_char ('(') != MATCH_YES)
559 {
560 if (!match_codim)
561 goto done;
562 goto coarray;
563 }
6de9cd9a 564
c62c6622
TB
565 if (gfc_match (" .. )") == MATCH_YES)
566 {
567 as->type = AS_ASSUMED_RANK;
568 as->rank = -1;
569
286f737c 570 if (!gfc_notify_std (GFC_STD_F2018, "Assumed-rank array at %C"))
c62c6622
TB
571 goto cleanup;
572
573 if (!match_codim)
574 goto done;
575 goto coarray;
576 }
577
6de9cd9a
DN
578 for (;;)
579 {
be59db2d 580 as->rank++;
6de9cd9a
DN
581 current_type = match_array_element_spec (as);
582
f5ca06e6
DK
583 /* Note that current_type == AS_ASSUMED_SIZE for both assumed-size
584 and implied-shape specifications. If the rank is at least 2, we can
585 distinguish between them. But for rank 1, we currently return
586 ASSUMED_SIZE; this gets adjusted later when we know for sure
587 whether the symbol parsed is a PARAMETER or not. */
588
6de9cd9a
DN
589 if (as->rank == 1)
590 {
591 if (current_type == AS_UNKNOWN)
592 goto cleanup;
593 as->type = current_type;
594 }
595 else
596 switch (as->type)
65f8144a 597 { /* See how current spec meshes with the existing. */
6de9cd9a
DN
598 case AS_UNKNOWN:
599 goto cleanup;
600
f5ca06e6
DK
601 case AS_IMPLIED_SHAPE:
602 if (current_type != AS_ASSUMED_SHAPE)
603 {
604 gfc_error ("Bad array specification for implied-shape"
605 " array at %C");
606 goto cleanup;
607 }
608 break;
609
6de9cd9a
DN
610 case AS_EXPLICIT:
611 if (current_type == AS_ASSUMED_SIZE)
612 {
613 as->type = AS_ASSUMED_SIZE;
614 break;
615 }
616
617 if (current_type == AS_EXPLICIT)
618 break;
619
65f8144a
SK
620 gfc_error ("Bad array specification for an explicitly shaped "
621 "array at %C");
6de9cd9a
DN
622
623 goto cleanup;
624
625 case AS_ASSUMED_SHAPE:
626 if ((current_type == AS_ASSUMED_SHAPE)
627 || (current_type == AS_DEFERRED))
628 break;
629
65f8144a
SK
630 gfc_error ("Bad array specification for assumed shape "
631 "array at %C");
6de9cd9a
DN
632 goto cleanup;
633
634 case AS_DEFERRED:
635 if (current_type == AS_DEFERRED)
636 break;
637
638 if (current_type == AS_ASSUMED_SHAPE)
639 {
640 as->type = AS_ASSUMED_SHAPE;
641 break;
642 }
643
644 gfc_error ("Bad specification for deferred shape array at %C");
645 goto cleanup;
646
647 case AS_ASSUMED_SIZE:
f5ca06e6
DK
648 if (as->rank == 2 && current_type == AS_ASSUMED_SIZE)
649 {
650 as->type = AS_IMPLIED_SHAPE;
651 break;
652 }
653
6de9cd9a
DN
654 gfc_error ("Bad specification for assumed size array at %C");
655 goto cleanup;
c62c6622
TB
656
657 case AS_ASSUMED_RANK:
8b704316 658 gcc_unreachable ();
6de9cd9a
DN
659 }
660
661 if (gfc_match_char (')') == MATCH_YES)
662 break;
663
664 if (gfc_match_char (',') != MATCH_YES)
665 {
666 gfc_error ("Expected another dimension in array declaration at %C");
667 goto cleanup;
668 }
669
be59db2d 670 if (as->rank + as->corank >= GFC_MAX_DIMENSIONS)
6de9cd9a 671 {
31043f6c
FXC
672 gfc_error ("Array specification at %C has more than %d dimensions",
673 GFC_MAX_DIMENSIONS);
6de9cd9a
DN
674 goto cleanup;
675 }
676
be59db2d 677 if (as->corank + as->rank >= 7
524af0d6
JB
678 && !gfc_notify_std (GFC_STD_F2008, "Array specification at %C "
679 "with more than 7 dimensions"))
a4cd1610 680 goto cleanup;
be59db2d 681 }
a4cd1610 682
be59db2d
TB
683 if (!match_codim)
684 goto done;
685
686coarray:
687 if (gfc_match_char ('[') != MATCH_YES)
688 goto done;
689
524af0d6 690 if (!gfc_notify_std (GFC_STD_F2008, "Coarray declaration at %C"))
be59db2d
TB
691 goto cleanup;
692
f19626cf 693 if (flag_coarray == GFC_FCOARRAY_NONE)
f4d1d50a 694 {
ddc05d11 695 gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
d3a9eea2 696 goto cleanup;
f4d1d50a
TB
697 }
698
e85df92e
TB
699 if (as->rank >= GFC_MAX_DIMENSIONS)
700 {
701 gfc_error ("Array specification at %C has more than %d "
702 "dimensions", GFC_MAX_DIMENSIONS);
703 goto cleanup;
704 }
705
be59db2d
TB
706 for (;;)
707 {
708 as->corank++;
709 current_type = match_array_element_spec (as);
710
711 if (current_type == AS_UNKNOWN)
712 goto cleanup;
713
be59db2d 714 if (as->corank == 1)
178f9aa1 715 as->cotype = current_type;
be59db2d 716 else
178f9aa1 717 switch (as->cotype)
be59db2d 718 { /* See how current spec meshes with the existing. */
f5ca06e6 719 case AS_IMPLIED_SHAPE:
be59db2d
TB
720 case AS_UNKNOWN:
721 goto cleanup;
722
723 case AS_EXPLICIT:
724 if (current_type == AS_ASSUMED_SIZE)
725 {
178f9aa1 726 as->cotype = AS_ASSUMED_SIZE;
be59db2d
TB
727 break;
728 }
729
730 if (current_type == AS_EXPLICIT)
731 break;
732
733 gfc_error ("Bad array specification for an explicitly "
734 "shaped array at %C");
735
736 goto cleanup;
737
738 case AS_ASSUMED_SHAPE:
739 if ((current_type == AS_ASSUMED_SHAPE)
740 || (current_type == AS_DEFERRED))
741 break;
742
743 gfc_error ("Bad array specification for assumed shape "
744 "array at %C");
745 goto cleanup;
746
747 case AS_DEFERRED:
748 if (current_type == AS_DEFERRED)
749 break;
750
751 if (current_type == AS_ASSUMED_SHAPE)
752 {
178f9aa1 753 as->cotype = AS_ASSUMED_SHAPE;
be59db2d
TB
754 break;
755 }
756
757 gfc_error ("Bad specification for deferred shape array at %C");
758 goto cleanup;
759
760 case AS_ASSUMED_SIZE:
761 gfc_error ("Bad specification for assumed size array at %C");
762 goto cleanup;
c62c6622
TB
763
764 case AS_ASSUMED_RANK:
8b704316 765 gcc_unreachable ();
be59db2d
TB
766 }
767
768 if (gfc_match_char (']') == MATCH_YES)
769 break;
770
771 if (gfc_match_char (',') != MATCH_YES)
772 {
773 gfc_error ("Expected another dimension in array declaration at %C");
774 goto cleanup;
775 }
776
e85df92e 777 if (as->rank + as->corank >= GFC_MAX_DIMENSIONS)
be59db2d
TB
778 {
779 gfc_error ("Array specification at %C has more than %d "
780 "dimensions", GFC_MAX_DIMENSIONS);
781 goto cleanup;
782 }
783 }
784
785 if (current_type == AS_EXPLICIT)
786 {
a4d9b221 787 gfc_error ("Upper bound of last coarray dimension must be %<*%> at %C");
be59db2d
TB
788 goto cleanup;
789 }
790
178f9aa1
TB
791 if (as->cotype == AS_ASSUMED_SIZE)
792 as->cotype = AS_EXPLICIT;
793
794 if (as->rank == 0)
795 as->type = as->cotype;
be59db2d
TB
796
797done:
798 if (as->rank == 0 && as->corank == 0)
799 {
800 *asp = NULL;
801 gfc_free_array_spec (as);
802 return MATCH_NO;
6de9cd9a
DN
803 }
804
805 /* If a lower bounds of an assumed shape array is blank, put in one. */
806 if (as->type == AS_ASSUMED_SHAPE)
807 {
be59db2d 808 for (i = 0; i < as->rank + as->corank; i++)
6de9cd9a
DN
809 {
810 if (as->lower[i] == NULL)
b7e75771 811 as->lower[i] = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
6de9cd9a
DN
812 }
813 }
be59db2d 814
6de9cd9a 815 *asp = as;
be59db2d 816
6de9cd9a
DN
817 return MATCH_YES;
818
819cleanup:
820 /* Something went wrong. */
821 gfc_free_array_spec (as);
822 return MATCH_ERROR;
823}
824
825
826/* Given a symbol and an array specification, modify the symbol to
827 have that array specification. The error locus is needed in case
828 something goes wrong. On failure, the caller must free the spec. */
829
524af0d6 830bool
65f8144a 831gfc_set_array_spec (gfc_symbol *sym, gfc_array_spec *as, locus *error_loc)
6de9cd9a 832{
be59db2d
TB
833 int i;
834
6de9cd9a 835 if (as == NULL)
524af0d6 836 return true;
6de9cd9a 837
be59db2d 838 if (as->rank
524af0d6
JB
839 && !gfc_add_dimension (&sym->attr, sym->name, error_loc))
840 return false;
be59db2d
TB
841
842 if (as->corank
524af0d6
JB
843 && !gfc_add_codimension (&sym->attr, sym->name, error_loc))
844 return false;
6de9cd9a 845
be59db2d
TB
846 if (sym->as == NULL)
847 {
848 sym->as = as;
524af0d6 849 return true;
be59db2d 850 }
6de9cd9a 851
63fbf586
TB
852 if ((sym->as->type == AS_ASSUMED_RANK && as->corank)
853 || (as->type == AS_ASSUMED_RANK && sym->as->corank))
854 {
c4100eae 855 gfc_error ("The assumed-rank array %qs at %L shall not have a "
63fbf586 856 "codimension", sym->name, error_loc);
524af0d6 857 return false;
63fbf586
TB
858 }
859
be59db2d
TB
860 if (as->corank)
861 {
178f9aa1 862 sym->as->cotype = as->cotype;
be59db2d 863 sym->as->corank = as->corank;
ebb3afe2
SK
864 /* Check F2018:C822. */
865 if (sym->as->rank + sym->as->corank > GFC_MAX_DIMENSIONS)
866 goto too_many;
867
be59db2d
TB
868 for (i = 0; i < as->corank; i++)
869 {
870 sym->as->lower[sym->as->rank + i] = as->lower[i];
871 sym->as->upper[sym->as->rank + i] = as->upper[i];
872 }
873 }
874 else
875 {
876 /* The "sym" has no rank (checked via gfc_add_dimension). Thus
877 the dimension is added - but first the codimensions (if existing
878 need to be shifted to make space for the dimension. */
879 gcc_assert (as->corank == 0 && sym->as->rank == 0);
880
881 sym->as->rank = as->rank;
882 sym->as->type = as->type;
883 sym->as->cray_pointee = as->cray_pointee;
884 sym->as->cp_was_assumed = as->cp_was_assumed;
885
ebb3afe2
SK
886 /* Check F2018:C822. */
887 if (sym->as->rank + sym->as->corank > GFC_MAX_DIMENSIONS)
888 goto too_many;
889
be59db2d
TB
890 for (i = 0; i < sym->as->corank; i++)
891 {
892 sym->as->lower[as->rank + i] = sym->as->lower[i];
893 sym->as->upper[as->rank + i] = sym->as->upper[i];
894 }
895 for (i = 0; i < as->rank; i++)
896 {
897 sym->as->lower[i] = as->lower[i];
898 sym->as->upper[i] = as->upper[i];
899 }
900 }
901
cede9502 902 free (as);
524af0d6 903 return true;
ebb3afe2
SK
904
905too_many:
906
907 gfc_error ("rank + corank of %qs exceeds %d at %C", sym->name,
908 GFC_MAX_DIMENSIONS);
909 return false;
6de9cd9a
DN
910}
911
912
913/* Copy an array specification. */
914
915gfc_array_spec *
65f8144a 916gfc_copy_array_spec (gfc_array_spec *src)
6de9cd9a
DN
917{
918 gfc_array_spec *dest;
919 int i;
920
921 if (src == NULL)
922 return NULL;
923
924 dest = gfc_get_array_spec ();
925
926 *dest = *src;
927
be59db2d 928 for (i = 0; i < dest->rank + dest->corank; i++)
6de9cd9a
DN
929 {
930 dest->lower[i] = gfc_copy_expr (dest->lower[i]);
931 dest->upper[i] = gfc_copy_expr (dest->upper[i]);
932 }
933
934 return dest;
935}
936
65f8144a 937
6de9cd9a
DN
938/* Returns nonzero if the two expressions are equal. Only handles integer
939 constants. */
940
941static int
65f8144a 942compare_bounds (gfc_expr *bound1, gfc_expr *bound2)
6de9cd9a
DN
943{
944 if (bound1 == NULL || bound2 == NULL
945 || bound1->expr_type != EXPR_CONSTANT
946 || bound2->expr_type != EXPR_CONSTANT
947 || bound1->ts.type != BT_INTEGER
948 || bound2->ts.type != BT_INTEGER)
949 gfc_internal_error ("gfc_compare_array_spec(): Array spec clobbered");
950
951 if (mpz_cmp (bound1->value.integer, bound2->value.integer) == 0)
952 return 1;
953 else
954 return 0;
955}
956
65f8144a 957
6de9cd9a
DN
958/* Compares two array specifications. They must be constant or deferred
959 shape. */
960
961int
65f8144a 962gfc_compare_array_spec (gfc_array_spec *as1, gfc_array_spec *as2)
6de9cd9a
DN
963{
964 int i;
965
966 if (as1 == NULL && as2 == NULL)
967 return 1;
968
969 if (as1 == NULL || as2 == NULL)
970 return 0;
971
972 if (as1->rank != as2->rank)
973 return 0;
974
be59db2d
TB
975 if (as1->corank != as2->corank)
976 return 0;
977
6de9cd9a
DN
978 if (as1->rank == 0)
979 return 1;
980
981 if (as1->type != as2->type)
982 return 0;
983
984 if (as1->type == AS_EXPLICIT)
be59db2d 985 for (i = 0; i < as1->rank + as1->corank; i++)
6de9cd9a
DN
986 {
987 if (compare_bounds (as1->lower[i], as2->lower[i]) == 0)
988 return 0;
989
990 if (compare_bounds (as1->upper[i], as2->upper[i]) == 0)
991 return 0;
992 }
993
994 return 1;
995}
996
997
998/****************** Array constructor functions ******************/
999
6de9cd9a
DN
1000
1001/* Given an expression node that might be an array constructor and a
1002 symbol, make sure that no iterators in this or child constructors
1003 use the symbol as an implied-DO iterator. Returns nonzero if a
1004 duplicate was found. */
1005
1006static int
b7e75771 1007check_duplicate_iterator (gfc_constructor_base base, gfc_symbol *master)
6de9cd9a 1008{
b7e75771 1009 gfc_constructor *c;
6de9cd9a
DN
1010 gfc_expr *e;
1011
b7e75771 1012 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
6de9cd9a
DN
1013 {
1014 e = c->expr;
1015
1016 if (e->expr_type == EXPR_ARRAY
1017 && check_duplicate_iterator (e->value.constructor, master))
1018 return 1;
1019
1020 if (c->iterator == NULL)
1021 continue;
1022
1023 if (c->iterator->var->symtree->n.sym == master)
1024 {
c4100eae 1025 gfc_error ("DO-iterator %qs at %L is inside iterator of the "
65f8144a 1026 "same name", master->name, &c->where);
6de9cd9a
DN
1027
1028 return 1;
1029 }
1030 }
1031
1032 return 0;
1033}
1034
1035
1036/* Forward declaration because these functions are mutually recursive. */
b7e75771 1037static match match_array_cons_element (gfc_constructor_base *);
6de9cd9a
DN
1038
1039/* Match a list of array elements. */
1040
1041static match
b7e75771 1042match_array_list (gfc_constructor_base *result)
6de9cd9a 1043{
b7e75771
JD
1044 gfc_constructor_base head;
1045 gfc_constructor *p;
6de9cd9a
DN
1046 gfc_iterator iter;
1047 locus old_loc;
1048 gfc_expr *e;
1049 match m;
1050 int n;
1051
63645982 1052 old_loc = gfc_current_locus;
6de9cd9a
DN
1053
1054 if (gfc_match_char ('(') == MATCH_NO)
1055 return MATCH_NO;
1056
1057 memset (&iter, '\0', sizeof (gfc_iterator));
1058 head = NULL;
1059
1060 m = match_array_cons_element (&head);
1061 if (m != MATCH_YES)
1062 goto cleanup;
1063
6de9cd9a
DN
1064 if (gfc_match_char (',') != MATCH_YES)
1065 {
1066 m = MATCH_NO;
1067 goto cleanup;
1068 }
1069
1070 for (n = 1;; n++)
1071 {
cdc6637d 1072 m = gfc_match_iterator (&iter, 0);
6de9cd9a
DN
1073 if (m == MATCH_YES)
1074 break;
1075 if (m == MATCH_ERROR)
1076 goto cleanup;
1077
b7e75771 1078 m = match_array_cons_element (&head);
6de9cd9a
DN
1079 if (m == MATCH_ERROR)
1080 goto cleanup;
1081 if (m == MATCH_NO)
1082 {
1083 if (n > 2)
1084 goto syntax;
1085 m = MATCH_NO;
1086 goto cleanup; /* Could be a complex constant */
1087 }
1088
6de9cd9a
DN
1089 if (gfc_match_char (',') != MATCH_YES)
1090 {
1091 if (n > 2)
1092 goto syntax;
1093 m = MATCH_NO;
1094 goto cleanup;
1095 }
1096 }
1097
1098 if (gfc_match_char (')') != MATCH_YES)
1099 goto syntax;
1100
1101 if (check_duplicate_iterator (head, iter.var->symtree->n.sym))
1102 {
1103 m = MATCH_ERROR;
1104 goto cleanup;
1105 }
1106
b7e75771 1107 e = gfc_get_array_expr (BT_UNKNOWN, 0, &old_loc);
6de9cd9a
DN
1108 e->value.constructor = head;
1109
b7e75771 1110 p = gfc_constructor_append_expr (result, e, &gfc_current_locus);
6de9cd9a
DN
1111 p->iterator = gfc_get_iterator ();
1112 *p->iterator = iter;
1113
6de9cd9a
DN
1114 return MATCH_YES;
1115
1116syntax:
1117 gfc_error ("Syntax error in array constructor at %C");
1118 m = MATCH_ERROR;
1119
1120cleanup:
b7e75771 1121 gfc_constructor_free (head);
6de9cd9a 1122 gfc_free_iterator (&iter, 0);
63645982 1123 gfc_current_locus = old_loc;
6de9cd9a
DN
1124 return m;
1125}
1126
1127
1128/* Match a single element of an array constructor, which can be a
1129 single expression or a list of elements. */
1130
1131static match
b7e75771 1132match_array_cons_element (gfc_constructor_base *result)
6de9cd9a 1133{
6de9cd9a
DN
1134 gfc_expr *expr;
1135 match m;
1136
1137 m = match_array_list (result);
1138 if (m != MATCH_NO)
1139 return m;
1140
1141 m = gfc_match_expr (&expr);
1142 if (m != MATCH_YES)
1143 return m;
1144
8dc63166
SK
1145 if (expr->ts.type == BT_BOZ)
1146 {
1147 gfc_error ("BOZ literal constant at %L cannot appear in an "
1148 "array constructor", &expr->where);
1149 goto done;
1150 }
1151
2f2fc325
SK
1152 if (expr->expr_type == EXPR_FUNCTION
1153 && expr->ts.type == BT_UNKNOWN
1154 && strcmp(expr->symtree->name, "null") == 0)
8dc63166 1155 {
2f2fc325 1156 gfc_error ("NULL() at %C cannot appear in an array constructor");
8dc63166
SK
1157 goto done;
1158 }
2f2fc325 1159
b7e75771 1160 gfc_constructor_append_expr (result, expr, &gfc_current_locus);
6de9cd9a 1161 return MATCH_YES;
8dc63166
SK
1162
1163done:
1164 gfc_free_expr (expr);
1165 return MATCH_ERROR;
6de9cd9a
DN
1166}
1167
1168
be0fb548
SK
1169/* Convert components of an array constructor to the type in ts. */
1170
1171static match
1172walk_array_constructor (gfc_typespec *ts, gfc_constructor_base head)
1173{
1174 gfc_constructor *c;
1175 gfc_expr *e;
1176 match m;
1177
1178 for (c = gfc_constructor_first (head); c; c = gfc_constructor_next (c))
1179 {
1180 e = c->expr;
1181 if (e->expr_type == EXPR_ARRAY && e->ts.type == BT_UNKNOWN
1182 && !e->ref && e->value.constructor)
1183 {
1184 m = walk_array_constructor (ts, e->value.constructor);
1185 if (m == MATCH_ERROR)
1186 return m;
1187 }
8405874a
ME
1188 else if (!gfc_convert_type_warn (e, ts, 1, 1, true)
1189 && e->ts.type != BT_UNKNOWN)
be0fb548 1190 return MATCH_ERROR;
8405874a 1191 }
be0fb548
SK
1192 return MATCH_YES;
1193}
1194
6de9cd9a
DN
1195/* Match an array constructor. */
1196
1197match
65f8144a 1198gfc_match_array_constructor (gfc_expr **result)
6de9cd9a 1199{
2cf0ff98 1200 gfc_constructor *c;
45f596d9 1201 gfc_constructor_base head;
6de9cd9a 1202 gfc_expr *expr;
c03fc95d 1203 gfc_typespec ts;
6de9cd9a
DN
1204 locus where;
1205 match m;
acc75ae3 1206 const char *end_delim;
c03fc95d 1207 bool seen_ts;
6de9cd9a 1208
87c9fca5
SK
1209 head = NULL;
1210 seen_ts = false;
1211
6de9cd9a 1212 if (gfc_match (" (/") == MATCH_NO)
acc75ae3
EE
1213 {
1214 if (gfc_match (" [") == MATCH_NO)
65f8144a 1215 return MATCH_NO;
acc75ae3 1216 else
65f8144a 1217 {
524af0d6
JB
1218 if (!gfc_notify_std (GFC_STD_F2003, "[...] "
1219 "style array constructors at %C"))
65f8144a
SK
1220 return MATCH_ERROR;
1221 end_delim = " ]";
1222 }
acc75ae3
EE
1223 }
1224 else
1225 end_delim = " /)";
6de9cd9a 1226
63645982 1227 where = gfc_current_locus;
c03fc95d
DK
1228
1229 /* Try to match an optional "type-spec ::" */
fc2655fb 1230 gfc_clear_ts (&ts);
8d48826b
SK
1231 m = gfc_match_type_spec (&ts);
1232 if (m == MATCH_YES)
c03fc95d
DK
1233 {
1234 seen_ts = (gfc_match (" ::") == MATCH_YES);
1235
1236 if (seen_ts)
1237 {
524af0d6
JB
1238 if (!gfc_notify_std (GFC_STD_F2003, "Array constructor "
1239 "including type specification at %C"))
87c9fca5 1240 goto cleanup;
e69afb29
SK
1241
1242 if (ts.deferred)
1243 {
1244 gfc_error ("Type-spec at %L cannot contain a deferred "
1245 "type parameter", &where);
1246 goto cleanup;
1247 }
e81e83d0
SK
1248
1249 if (ts.type == BT_CHARACTER
1250 && ts.u.cl && !ts.u.cl->length && !ts.u.cl->length_from_typespec)
1251 {
1252 gfc_error ("Type-spec at %L cannot contain an asterisk for a "
1253 "type parameter", &where);
e81e83d0
SK
1254 goto cleanup;
1255 }
c03fc95d
DK
1256 }
1257 }
8d48826b 1258 else if (m == MATCH_ERROR)
87c9fca5 1259 goto cleanup;
c03fc95d 1260
87c9fca5
SK
1261 if (!seen_ts)
1262 gfc_current_locus = where;
6de9cd9a 1263
acc75ae3 1264 if (gfc_match (end_delim) == MATCH_YES)
ab21e272 1265 {
c03fc95d
DK
1266 if (seen_ts)
1267 goto done;
1268 else
1269 {
1270 gfc_error ("Empty array constructor at %C is not allowed");
1271 goto cleanup;
1272 }
ab21e272 1273 }
6de9cd9a
DN
1274
1275 for (;;)
1276 {
b7e75771 1277 m = match_array_cons_element (&head);
6de9cd9a
DN
1278 if (m == MATCH_ERROR)
1279 goto cleanup;
1280 if (m == MATCH_NO)
1281 goto syntax;
1282
6de9cd9a
DN
1283 if (gfc_match_char (',') == MATCH_NO)
1284 break;
1285 }
1286
acc75ae3 1287 if (gfc_match (end_delim) == MATCH_NO)
6de9cd9a
DN
1288 goto syntax;
1289
c03fc95d 1290done:
6de9cd9a 1291 /* Size must be calculated at resolution time. */
c03fc95d 1292 if (seen_ts)
b7e75771
JD
1293 {
1294 expr = gfc_get_array_expr (ts.type, ts.kind, &where);
1295 expr->ts = ts;
67f0527a
SK
1296
1297 /* If the typespec is CHARACTER, check that array elements can
1298 be converted. See PR fortran/67803. */
1299 if (ts.type == BT_CHARACTER)
1300 {
67f0527a
SK
1301 c = gfc_constructor_first (head);
1302 for (; c; c = gfc_constructor_next (c))
1303 {
1304 if (gfc_numeric_ts (&c->expr->ts)
1305 || c->expr->ts.type == BT_LOGICAL)
1306 {
1307 gfc_error ("Incompatible typespec for array element at %L",
1308 &c->expr->where);
1309 return MATCH_ERROR;
1310 }
1311
1312 /* Special case null(). */
1313 if (c->expr->expr_type == EXPR_FUNCTION
1314 && c->expr->ts.type == BT_UNKNOWN
1315 && strcmp (c->expr->symtree->name, "null") == 0)
1316 {
1317 gfc_error ("Incompatible typespec for array element at %L",
1318 &c->expr->where);
1319 return MATCH_ERROR;
1320 }
1321 }
1322 }
2cf0ff98 1323
be0fb548
SK
1324 /* Walk the constructor, and if possible, do type conversion for
1325 numeric types. */
2cf0ff98
SK
1326 if (gfc_numeric_ts (&ts))
1327 {
be0fb548
SK
1328 m = walk_array_constructor (&ts, head);
1329 if (m == MATCH_ERROR)
1330 return m;
2cf0ff98 1331 }
b7e75771 1332 }
c03fc95d 1333 else
b7e75771
JD
1334 expr = gfc_get_array_expr (BT_UNKNOWN, 0, &where);
1335
1336 expr->value.constructor = head;
bc21d315
JW
1337 if (expr->ts.u.cl)
1338 expr->ts.u.cl->length_from_typespec = seen_ts;
c03fc95d 1339
6de9cd9a 1340 *result = expr;
67f0527a 1341
6de9cd9a
DN
1342 return MATCH_YES;
1343
1344syntax:
1345 gfc_error ("Syntax error in array constructor at %C");
1346
1347cleanup:
b7e75771 1348 gfc_constructor_free (head);
6de9cd9a
DN
1349 return MATCH_ERROR;
1350}
1351
1352
1353
1354/************** Check array constructors for correctness **************/
1355
1356/* Given an expression, compare it's type with the type of the current
1357 constructor. Returns nonzero if an error was issued. The
1358 cons_state variable keeps track of whether the type of the
1359 constructor being read or resolved is known to be good, bad or just
1360 starting out. */
1361
1362static gfc_typespec constructor_ts;
1363static enum
1364{ CONS_START, CONS_GOOD, CONS_BAD }
1365cons_state;
1366
1367static int
c03fc95d 1368check_element_type (gfc_expr *expr, bool convert)
6de9cd9a 1369{
6de9cd9a 1370 if (cons_state == CONS_BAD)
1f2959f0 1371 return 0; /* Suppress further errors */
6de9cd9a
DN
1372
1373 if (cons_state == CONS_START)
1374 {
1375 if (expr->ts.type == BT_UNKNOWN)
1376 cons_state = CONS_BAD;
1377 else
1378 {
1379 cons_state = CONS_GOOD;
1380 constructor_ts = expr->ts;
1381 }
1382
1383 return 0;
1384 }
1385
1386 if (gfc_compare_types (&constructor_ts, &expr->ts))
1387 return 0;
1388
c03fc95d 1389 if (convert)
8405874a 1390 return gfc_convert_type_warn (expr, &constructor_ts, 1, 1, true) ? 0 : 1;
c03fc95d 1391
6de9cd9a
DN
1392 gfc_error ("Element in %s array constructor at %L is %s",
1393 gfc_typename (&constructor_ts), &expr->where,
f61e54e5 1394 gfc_typename (expr));
6de9cd9a
DN
1395
1396 cons_state = CONS_BAD;
1397 return 1;
1398}
1399
1400
f7b529fa 1401/* Recursive work function for gfc_check_constructor_type(). */
6de9cd9a 1402
524af0d6 1403static bool
b7e75771 1404check_constructor_type (gfc_constructor_base base, bool convert)
6de9cd9a 1405{
b7e75771 1406 gfc_constructor *c;
6de9cd9a
DN
1407 gfc_expr *e;
1408
b7e75771 1409 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
6de9cd9a
DN
1410 {
1411 e = c->expr;
1412
1413 if (e->expr_type == EXPR_ARRAY)
1414 {
524af0d6
JB
1415 if (!check_constructor_type (e->value.constructor, convert))
1416 return false;
6de9cd9a
DN
1417
1418 continue;
1419 }
1420
c03fc95d 1421 if (check_element_type (e, convert))
524af0d6 1422 return false;
6de9cd9a
DN
1423 }
1424
524af0d6 1425 return true;
6de9cd9a
DN
1426}
1427
1428
1429/* Check that all elements of an array constructor are the same type.
524af0d6 1430 On false, an error has been generated. */
6de9cd9a 1431
524af0d6 1432bool
65f8144a 1433gfc_check_constructor_type (gfc_expr *e)
6de9cd9a 1434{
524af0d6 1435 bool t;
6de9cd9a 1436
c03fc95d
DK
1437 if (e->ts.type != BT_UNKNOWN)
1438 {
1439 cons_state = CONS_GOOD;
1440 constructor_ts = e->ts;
1441 }
1442 else
1443 {
1444 cons_state = CONS_START;
1445 gfc_clear_ts (&constructor_ts);
1446 }
6de9cd9a 1447
c03fc95d
DK
1448 /* If e->ts.type != BT_UNKNOWN, the array constructor included a
1449 typespec, and we will now convert the values on the fly. */
1450 t = check_constructor_type (e->value.constructor, e->ts.type != BT_UNKNOWN);
524af0d6 1451 if (t && e->ts.type == BT_UNKNOWN)
6de9cd9a
DN
1452 e->ts = constructor_ts;
1453
1454 return t;
1455}
1456
1457
1458
1459typedef struct cons_stack
1460{
1461 gfc_iterator *iterator;
1462 struct cons_stack *previous;
1463}
1464cons_stack;
1465
1466static cons_stack *base;
1467
524af0d6 1468static bool check_constructor (gfc_constructor_base, bool (*) (gfc_expr *));
6de9cd9a
DN
1469
1470/* Check an EXPR_VARIABLE expression in a constructor to make sure
1471 that that variable is an iteration variables. */
1472
524af0d6 1473bool
65f8144a 1474gfc_check_iter_variable (gfc_expr *expr)
6de9cd9a 1475{
6de9cd9a
DN
1476 gfc_symbol *sym;
1477 cons_stack *c;
1478
1479 sym = expr->symtree->n.sym;
1480
a48a9173 1481 for (c = base; c && c->iterator; c = c->previous)
6de9cd9a 1482 if (sym == c->iterator->var->symtree->n.sym)
524af0d6 1483 return true;
6de9cd9a 1484
524af0d6 1485 return false;
6de9cd9a
DN
1486}
1487
1488
1489/* Recursive work function for gfc_check_constructor(). This amounts
1490 to calling the check function for each expression in the
1491 constructor, giving variables with the names of iterators a pass. */
1492
524af0d6
JB
1493static bool
1494check_constructor (gfc_constructor_base ctor, bool (*check_function) (gfc_expr *))
6de9cd9a
DN
1495{
1496 cons_stack element;
1497 gfc_expr *e;
524af0d6 1498 bool t;
b7e75771 1499 gfc_constructor *c;
6de9cd9a 1500
b7e75771 1501 for (c = gfc_constructor_first (ctor); c; c = gfc_constructor_next (c))
6de9cd9a
DN
1502 {
1503 e = c->expr;
1504
7430df97
JW
1505 if (!e)
1506 continue;
1507
6de9cd9a
DN
1508 if (e->expr_type != EXPR_ARRAY)
1509 {
524af0d6
JB
1510 if (!(*check_function)(e))
1511 return false;
6de9cd9a
DN
1512 continue;
1513 }
1514
1515 element.previous = base;
1516 element.iterator = c->iterator;
1517
1518 base = &element;
1519 t = check_constructor (e->value.constructor, check_function);
1520 base = element.previous;
1521
524af0d6
JB
1522 if (!t)
1523 return false;
6de9cd9a
DN
1524 }
1525
1526 /* Nothing went wrong, so all OK. */
524af0d6 1527 return true;
6de9cd9a
DN
1528}
1529
1530
1531/* Checks a constructor to see if it is a particular kind of
1532 expression -- specification, restricted, or initialization as
1533 determined by the check_function. */
1534
524af0d6
JB
1535bool
1536gfc_check_constructor (gfc_expr *expr, bool (*check_function) (gfc_expr *))
6de9cd9a
DN
1537{
1538 cons_stack *base_save;
524af0d6 1539 bool t;
6de9cd9a
DN
1540
1541 base_save = base;
1542 base = NULL;
1543
1544 t = check_constructor (expr->value.constructor, check_function);
1545 base = base_save;
1546
1547 return t;
1548}
1549
1550
1551
1552/**************** Simplification of array constructors ****************/
1553
1554iterator_stack *iter_stack;
1555
1556typedef struct
1557{
b7e75771 1558 gfc_constructor_base base;
6de9cd9a
DN
1559 int extract_count, extract_n;
1560 gfc_expr *extracted;
1561 mpz_t *count;
1562
1563 mpz_t *offset;
1564 gfc_component *component;
21ea4922 1565 mpz_t *repeat;
6de9cd9a 1566
524af0d6 1567 bool (*expand_work_function) (gfc_expr *);
6de9cd9a
DN
1568}
1569expand_info;
1570
1571static expand_info current_expand;
1572
524af0d6 1573static bool expand_constructor (gfc_constructor_base);
6de9cd9a
DN
1574
1575
1576/* Work function that counts the number of elements present in a
1577 constructor. */
1578
524af0d6 1579static bool
65f8144a 1580count_elements (gfc_expr *e)
6de9cd9a
DN
1581{
1582 mpz_t result;
1583
1584 if (e->rank == 0)
1585 mpz_add_ui (*current_expand.count, *current_expand.count, 1);
1586 else
1587 {
524af0d6 1588 if (!gfc_array_size (e, &result))
6de9cd9a
DN
1589 {
1590 gfc_free_expr (e);
524af0d6 1591 return false;
6de9cd9a
DN
1592 }
1593
1594 mpz_add (*current_expand.count, *current_expand.count, result);
1595 mpz_clear (result);
1596 }
1597
1598 gfc_free_expr (e);
524af0d6 1599 return true;
6de9cd9a
DN
1600}
1601
1602
1603/* Work function that extracts a particular element from an array
1604 constructor, freeing the rest. */
1605
524af0d6 1606static bool
65f8144a 1607extract_element (gfc_expr *e)
6de9cd9a 1608{
6de9cd9a
DN
1609 if (e->rank != 0)
1610 { /* Something unextractable */
1611 gfc_free_expr (e);
524af0d6 1612 return false;
6de9cd9a
DN
1613 }
1614
1615 if (current_expand.extract_count == current_expand.extract_n)
1616 current_expand.extracted = e;
1617 else
1618 gfc_free_expr (e);
1619
1620 current_expand.extract_count++;
8b704316 1621
524af0d6 1622 return true;
6de9cd9a
DN
1623}
1624
1625
1626/* Work function that constructs a new constructor out of the old one,
1627 stringing new elements together. */
1628
524af0d6 1629static bool
65f8144a 1630expand (gfc_expr *e)
6de9cd9a 1631{
b7e75771
JD
1632 gfc_constructor *c = gfc_constructor_append_expr (&current_expand.base,
1633 e, &e->where);
6de9cd9a 1634
b7e75771 1635 c->n.component = current_expand.component;
524af0d6 1636 return true;
6de9cd9a
DN
1637}
1638
1639
1640/* Given an initialization expression that is a variable reference,
1641 substitute the current value of the iteration variable. */
1642
1643void
65f8144a 1644gfc_simplify_iterator_var (gfc_expr *e)
6de9cd9a
DN
1645{
1646 iterator_stack *p;
1647
1648 for (p = iter_stack; p; p = p->prev)
1649 if (e->symtree == p->variable)
1650 break;
1651
1652 if (p == NULL)
1653 return; /* Variable not found */
1654
b7e75771 1655 gfc_replace_expr (e, gfc_get_int_expr (gfc_default_integer_kind, NULL, 0));
6de9cd9a
DN
1656
1657 mpz_set (e->value.integer, p->value);
1658
1659 return;
1660}
1661
1662
1663/* Expand an expression with that is inside of a constructor,
1664 recursing into other constructors if present. */
1665
524af0d6 1666static bool
65f8144a 1667expand_expr (gfc_expr *e)
6de9cd9a 1668{
6de9cd9a
DN
1669 if (e->expr_type == EXPR_ARRAY)
1670 return expand_constructor (e->value.constructor);
1671
1672 e = gfc_copy_expr (e);
1673
524af0d6 1674 if (!gfc_simplify_expr (e, 1))
6de9cd9a
DN
1675 {
1676 gfc_free_expr (e);
524af0d6 1677 return false;
6de9cd9a
DN
1678 }
1679
1680 return current_expand.expand_work_function (e);
1681}
1682
1683
524af0d6 1684static bool
65f8144a 1685expand_iterator (gfc_constructor *c)
6de9cd9a
DN
1686{
1687 gfc_expr *start, *end, *step;
1688 iterator_stack frame;
1689 mpz_t trip;
524af0d6 1690 bool t;
6de9cd9a
DN
1691
1692 end = step = NULL;
1693
524af0d6 1694 t = false;
6de9cd9a
DN
1695
1696 mpz_init (trip);
1697 mpz_init (frame.value);
66914102 1698 frame.prev = NULL;
6de9cd9a
DN
1699
1700 start = gfc_copy_expr (c->iterator->start);
524af0d6 1701 if (!gfc_simplify_expr (start, 1))
6de9cd9a
DN
1702 goto cleanup;
1703
1704 if (start->expr_type != EXPR_CONSTANT || start->ts.type != BT_INTEGER)
1705 goto cleanup;
1706
1707 end = gfc_copy_expr (c->iterator->end);
524af0d6 1708 if (!gfc_simplify_expr (end, 1))
6de9cd9a
DN
1709 goto cleanup;
1710
1711 if (end->expr_type != EXPR_CONSTANT || end->ts.type != BT_INTEGER)
1712 goto cleanup;
1713
1714 step = gfc_copy_expr (c->iterator->step);
524af0d6 1715 if (!gfc_simplify_expr (step, 1))
6de9cd9a
DN
1716 goto cleanup;
1717
1718 if (step->expr_type != EXPR_CONSTANT || step->ts.type != BT_INTEGER)
1719 goto cleanup;
1720
1721 if (mpz_sgn (step->value.integer) == 0)
1722 {
1723 gfc_error ("Iterator step at %L cannot be zero", &step->where);
1724 goto cleanup;
1725 }
1726
1727 /* Calculate the trip count of the loop. */
1728 mpz_sub (trip, end->value.integer, start->value.integer);
1729 mpz_add (trip, trip, step->value.integer);
1730 mpz_tdiv_q (trip, trip, step->value.integer);
1731
1732 mpz_set (frame.value, start->value.integer);
1733
1734 frame.prev = iter_stack;
1735 frame.variable = c->iterator->var->symtree;
1736 iter_stack = &frame;
1737
1738 while (mpz_sgn (trip) > 0)
1739 {
524af0d6 1740 if (!expand_expr (c->expr))
6de9cd9a
DN
1741 goto cleanup;
1742
1743 mpz_add (frame.value, frame.value, step->value.integer);
1744 mpz_sub_ui (trip, trip, 1);
1745 }
1746
524af0d6 1747 t = true;
6de9cd9a
DN
1748
1749cleanup:
1750 gfc_free_expr (start);
1751 gfc_free_expr (end);
1752 gfc_free_expr (step);
1753
1754 mpz_clear (trip);
1755 mpz_clear (frame.value);
1756
1757 iter_stack = frame.prev;
1758
1759 return t;
1760}
1761
1762
1763/* Expand a constructor into constant constructors without any
1764 iterators, calling the work function for each of the expanded
1765 expressions. The work function needs to either save or free the
1766 passed expression. */
1767
524af0d6 1768static bool
b7e75771 1769expand_constructor (gfc_constructor_base base)
6de9cd9a 1770{
b7e75771 1771 gfc_constructor *c;
6de9cd9a
DN
1772 gfc_expr *e;
1773
b7e75771 1774 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next(c))
6de9cd9a
DN
1775 {
1776 if (c->iterator != NULL)
1777 {
524af0d6
JB
1778 if (!expand_iterator (c))
1779 return false;
6de9cd9a
DN
1780 continue;
1781 }
1782
1783 e = c->expr;
1784
1785 if (e->expr_type == EXPR_ARRAY)
1786 {
524af0d6
JB
1787 if (!expand_constructor (e->value.constructor))
1788 return false;
6de9cd9a
DN
1789
1790 continue;
1791 }
1792
1793 e = gfc_copy_expr (e);
524af0d6 1794 if (!gfc_simplify_expr (e, 1))
6de9cd9a
DN
1795 {
1796 gfc_free_expr (e);
524af0d6 1797 return false;
6de9cd9a 1798 }
4a4fc7fe 1799 e->from_constructor = 1;
b7e75771 1800 current_expand.offset = &c->offset;
21ea4922 1801 current_expand.repeat = &c->repeat;
b7e75771 1802 current_expand.component = c->n.component;
524af0d6
JB
1803 if (!current_expand.expand_work_function(e))
1804 return false;
6de9cd9a 1805 }
524af0d6 1806 return true;
6de9cd9a
DN
1807}
1808
1809
b7e75771
JD
1810/* Given an array expression and an element number (starting at zero),
1811 return a pointer to the array element. NULL is returned if the
1812 size of the array has been exceeded. The expression node returned
1813 remains a part of the array and should not be freed. Access is not
1814 efficient at all, but this is another place where things do not
1815 have to be particularly fast. */
1816
1817static gfc_expr *
1818gfc_get_array_element (gfc_expr *array, int element)
1819{
1820 expand_info expand_save;
1821 gfc_expr *e;
524af0d6 1822 bool rc;
b7e75771
JD
1823
1824 expand_save = current_expand;
1825 current_expand.extract_n = element;
1826 current_expand.expand_work_function = extract_element;
1827 current_expand.extracted = NULL;
1828 current_expand.extract_count = 0;
1829
1830 iter_stack = NULL;
1831
1832 rc = expand_constructor (array->value.constructor);
1833 e = current_expand.extracted;
1834 current_expand = expand_save;
1835
524af0d6 1836 if (!rc)
b7e75771
JD
1837 return NULL;
1838
1839 return e;
1840}
1841
1842
6de9cd9a
DN
1843/* Top level subroutine for expanding constructors. We only expand
1844 constructor if they are small enough. */
1845
524af0d6 1846bool
928f0490 1847gfc_expand_constructor (gfc_expr *e, bool fatal)
6de9cd9a
DN
1848{
1849 expand_info expand_save;
1850 gfc_expr *f;
524af0d6 1851 bool rc;
6de9cd9a 1852
b7e75771
JD
1853 /* If we can successfully get an array element at the max array size then
1854 the array is too big to expand, so we just return. */
c61819ff 1855 f = gfc_get_array_element (e, flag_max_array_constructor);
6de9cd9a
DN
1856 if (f != NULL)
1857 {
1858 gfc_free_expr (f);
928f0490
TB
1859 if (fatal)
1860 {
1861 gfc_error ("The number of elements in the array constructor "
1862 "at %L requires an increase of the allowed %d "
c4100eae 1863 "upper limit. See %<-fmax-array-constructor%> "
c61819ff 1864 "option", &e->where, flag_max_array_constructor);
524af0d6 1865 return false;
928f0490 1866 }
524af0d6 1867 return true;
6de9cd9a
DN
1868 }
1869
b7e75771 1870 /* We now know the array is not too big so go ahead and try to expand it. */
6de9cd9a 1871 expand_save = current_expand;
b7e75771 1872 current_expand.base = NULL;
6de9cd9a
DN
1873
1874 iter_stack = NULL;
1875
1876 current_expand.expand_work_function = expand;
1877
524af0d6 1878 if (!expand_constructor (e->value.constructor))
6de9cd9a 1879 {
b7e75771 1880 gfc_constructor_free (current_expand.base);
524af0d6 1881 rc = false;
6de9cd9a
DN
1882 goto done;
1883 }
1884
b7e75771
JD
1885 gfc_constructor_free (e->value.constructor);
1886 e->value.constructor = current_expand.base;
6de9cd9a 1887
524af0d6 1888 rc = true;
6de9cd9a
DN
1889
1890done:
1891 current_expand = expand_save;
1892
1893 return rc;
1894}
1895
1896
1897/* Work function for checking that an element of a constructor is a
1898 constant, after removal of any iteration variables. We return
524af0d6 1899 false if not so. */
6de9cd9a 1900
524af0d6 1901static bool
f2ff577a 1902is_constant_element (gfc_expr *e)
6de9cd9a
DN
1903{
1904 int rv;
1905
1906 rv = gfc_is_constant_expr (e);
1907 gfc_free_expr (e);
1908
524af0d6 1909 return rv ? true : false;
6de9cd9a
DN
1910}
1911
1912
1913/* Given an array constructor, determine if the constructor is
1914 constant or not by expanding it and making sure that all elements
1915 are constants. This is a bit of a hack since something like (/ (i,
1916 i=1,100000000) /) will take a while as* opposed to a more clever
1917 function that traverses the expression tree. FIXME. */
1918
1919int
65f8144a 1920gfc_constant_ac (gfc_expr *e)
6de9cd9a
DN
1921{
1922 expand_info expand_save;
524af0d6 1923 bool rc;
6de9cd9a 1924
b7e75771
JD
1925 iter_stack = NULL;
1926 expand_save = current_expand;
1927 current_expand.expand_work_function = is_constant_element;
6de9cd9a 1928
b7e75771 1929 rc = expand_constructor (e->value.constructor);
6de9cd9a 1930
b7e75771 1931 current_expand = expand_save;
524af0d6 1932 if (!rc)
6de9cd9a
DN
1933 return 0;
1934
1935 return 1;
1936}
1937
1938
1939/* Returns nonzero if an array constructor has been completely
1940 expanded (no iterators) and zero if iterators are present. */
1941
1942int
65f8144a 1943gfc_expanded_ac (gfc_expr *e)
6de9cd9a 1944{
b7e75771 1945 gfc_constructor *c;
6de9cd9a
DN
1946
1947 if (e->expr_type == EXPR_ARRAY)
b7e75771
JD
1948 for (c = gfc_constructor_first (e->value.constructor);
1949 c; c = gfc_constructor_next (c))
1950 if (c->iterator != NULL || !gfc_expanded_ac (c->expr))
6de9cd9a
DN
1951 return 0;
1952
1953 return 1;
1954}
1955
1956
1957/*************** Type resolution of array constructors ***************/
1958
ca27d5ae
MM
1959
1960/* The symbol expr_is_sought_symbol_ref will try to find. */
1961static const gfc_symbol *sought_symbol = NULL;
1962
1963
1964/* Tells whether the expression E is a variable reference to the symbol
1965 in the static variable SOUGHT_SYMBOL, and sets the locus pointer WHERE
1966 accordingly.
1967 To be used with gfc_expr_walker: if a reference is found we don't need
1968 to look further so we return 1 to skip any further walk. */
1969
1970static int
1971expr_is_sought_symbol_ref (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
1972 void *where)
1973{
1974 gfc_expr *expr = *e;
1975 locus *sym_loc = (locus *)where;
1976
1977 if (expr->expr_type == EXPR_VARIABLE
1978 && expr->symtree->n.sym == sought_symbol)
1979 {
1980 *sym_loc = expr->where;
1981 return 1;
1982 }
1983
1984 return 0;
1985}
1986
1987
1988/* Tells whether the expression EXPR contains a reference to the symbol
1989 SYM and in that case sets the position SYM_LOC where the reference is. */
1990
1991static bool
1992find_symbol_in_expr (gfc_symbol *sym, gfc_expr *expr, locus *sym_loc)
1993{
1994 int ret;
1995
1996 sought_symbol = sym;
1997 ret = gfc_expr_walker (&expr, &expr_is_sought_symbol_ref, sym_loc);
1998 sought_symbol = NULL;
1999 return ret;
2000}
2001
2002
6de9cd9a
DN
2003/* Recursive array list resolution function. All of the elements must
2004 be of the same type. */
2005
524af0d6 2006static bool
b7e75771 2007resolve_array_list (gfc_constructor_base base)
6de9cd9a 2008{
524af0d6 2009 bool t;
b7e75771 2010 gfc_constructor *c;
ca27d5ae 2011 gfc_iterator *iter;
6de9cd9a 2012
524af0d6 2013 t = true;
6de9cd9a 2014
b7e75771 2015 for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
6de9cd9a 2016 {
ca27d5ae
MM
2017 iter = c->iterator;
2018 if (iter != NULL)
2019 {
2020 gfc_symbol *iter_var;
2021 locus iter_var_loc;
8b704316 2022
524af0d6
JB
2023 if (!gfc_resolve_iterator (iter, false, true))
2024 t = false;
ca27d5ae
MM
2025
2026 /* Check for bounds referencing the iterator variable. */
2027 gcc_assert (iter->var->expr_type == EXPR_VARIABLE);
2028 iter_var = iter->var->symtree->n.sym;
2029 if (find_symbol_in_expr (iter_var, iter->start, &iter_var_loc))
2030 {
524af0d6
JB
2031 if (!gfc_notify_std (GFC_STD_LEGACY, "AC-IMPLIED-DO initial "
2032 "expression references control variable "
2033 "at %L", &iter_var_loc))
2034 t = false;
ca27d5ae
MM
2035 }
2036 if (find_symbol_in_expr (iter_var, iter->end, &iter_var_loc))
2037 {
524af0d6
JB
2038 if (!gfc_notify_std (GFC_STD_LEGACY, "AC-IMPLIED-DO final "
2039 "expression references control variable "
2040 "at %L", &iter_var_loc))
2041 t = false;
ca27d5ae
MM
2042 }
2043 if (find_symbol_in_expr (iter_var, iter->step, &iter_var_loc))
2044 {
524af0d6
JB
2045 if (!gfc_notify_std (GFC_STD_LEGACY, "AC-IMPLIED-DO step "
2046 "expression references control variable "
2047 "at %L", &iter_var_loc))
2048 t = false;
ca27d5ae
MM
2049 }
2050 }
6de9cd9a 2051
524af0d6
JB
2052 if (!gfc_resolve_expr (c->expr))
2053 t = false;
8b704316
PT
2054
2055 if (UNLIMITED_POLY (c->expr))
2056 {
2057 gfc_error ("Array constructor value at %L shall not be unlimited "
2058 "polymorphic [F2008: C4106]", &c->expr->where);
524af0d6 2059 t = false;
8b704316 2060 }
6de9cd9a
DN
2061 }
2062
2063 return t;
2064}
2065
88fec49f 2066/* Resolve character array constructor. If it has a specified constant character
df2fba9e 2067 length, pad/truncate the elements here; if the length is not specified and
88fec49f
DK
2068 all elements are of compile-time known length, emit an error as this is
2069 invalid. */
6de9cd9a 2070
524af0d6 2071bool
65f8144a 2072gfc_resolve_character_array_constructor (gfc_expr *expr)
df7cc9b5 2073{
65f8144a 2074 gfc_constructor *p;
6b271a2e 2075 HOST_WIDE_INT found_length;
df7cc9b5
FW
2076
2077 gcc_assert (expr->expr_type == EXPR_ARRAY);
2078 gcc_assert (expr->ts.type == BT_CHARACTER);
2079
bc21d315 2080 if (expr->ts.u.cl == NULL)
4a90ae54 2081 {
b7e75771
JD
2082 for (p = gfc_constructor_first (expr->value.constructor);
2083 p; p = gfc_constructor_next (p))
bc21d315 2084 if (p->expr->ts.u.cl != NULL)
1855915a
PT
2085 {
2086 /* Ensure that if there is a char_len around that it is
2087 used; otherwise the middle-end confuses them! */
bc21d315 2088 expr->ts.u.cl = p->expr->ts.u.cl;
1855915a
PT
2089 goto got_charlen;
2090 }
2091
b76e28c6 2092 expr->ts.u.cl = gfc_new_charlen (gfc_current_ns, NULL);
4a90ae54
FW
2093 }
2094
1855915a
PT
2095got_charlen:
2096
1832cbf8
TK
2097 /* Early exit for zero size arrays. */
2098 if (expr->shape)
2099 {
2100 mpz_t size;
2101 HOST_WIDE_INT arraysize;
2102
2103 gfc_array_size (expr, &size);
2104 arraysize = mpz_get_ui (size);
2105 mpz_clear (size);
2106
2107 if (arraysize == 0)
2108 return true;
2109 }
2110
88fec49f
DK
2111 found_length = -1;
2112
bc21d315 2113 if (expr->ts.u.cl->length == NULL)
df7cc9b5 2114 {
88fec49f
DK
2115 /* Check that all constant string elements have the same length until
2116 we reach the end or find a variable-length one. */
1855915a 2117
b7e75771
JD
2118 for (p = gfc_constructor_first (expr->value.constructor);
2119 p; p = gfc_constructor_next (p))
1855915a 2120 {
6b271a2e 2121 HOST_WIDE_INT current_length = -1;
1855915a
PT
2122 gfc_ref *ref;
2123 for (ref = p->expr->ref; ref; ref = ref->next)
2124 if (ref->type == REF_SUBSTRING
010b9a3e 2125 && ref->u.ss.start
65f8144a 2126 && ref->u.ss.start->expr_type == EXPR_CONSTANT
010b9a3e 2127 && ref->u.ss.end
65f8144a 2128 && ref->u.ss.end->expr_type == EXPR_CONSTANT)
1855915a
PT
2129 break;
2130
2131 if (p->expr->expr_type == EXPR_CONSTANT)
88fec49f 2132 current_length = p->expr->value.character.length;
1855915a 2133 else if (ref)
6b271a2e
JB
2134 current_length = gfc_mpz_get_hwi (ref->u.ss.end->value.integer)
2135 - gfc_mpz_get_hwi (ref->u.ss.start->value.integer) + 1;
bc21d315
JW
2136 else if (p->expr->ts.u.cl && p->expr->ts.u.cl->length
2137 && p->expr->ts.u.cl->length->expr_type == EXPR_CONSTANT)
6b271a2e 2138 current_length = gfc_mpz_get_hwi (p->expr->ts.u.cl->length->value.integer);
1855915a 2139 else
524af0d6 2140 return true;
df7cc9b5 2141
14ee7de0
SK
2142 if (current_length < 0)
2143 current_length = 0;
88fec49f
DK
2144
2145 if (found_length == -1)
2146 found_length = current_length;
2147 else if (found_length != current_length)
2148 {
6b271a2e
JB
2149 gfc_error ("Different CHARACTER lengths (%ld/%ld) in array"
2150 " constructor at %L", (long) found_length,
2151 (long) current_length, &p->expr->where);
524af0d6 2152 return false;
88fec49f
DK
2153 }
2154
2155 gcc_assert (found_length == current_length);
df7cc9b5 2156 }
88fec49f
DK
2157
2158 gcc_assert (found_length != -1);
2159
2160 /* Update the character length of the array constructor. */
f622221a 2161 expr->ts.u.cl->length = gfc_get_int_expr (gfc_charlen_int_kind,
b7e75771 2162 NULL, found_length);
df7cc9b5 2163 }
8b704316 2164 else
c03fc95d
DK
2165 {
2166 /* We've got a character length specified. It should be an integer,
2167 otherwise an error is signalled elsewhere. */
bc21d315 2168 gcc_assert (expr->ts.u.cl->length);
c03fc95d
DK
2169
2170 /* If we've got a constant character length, pad according to this.
2171 gfc_extract_int does check for BT_INTEGER and EXPR_CONSTANT and sets
2172 max_length only if they pass. */
6b271a2e 2173 gfc_extract_hwi (expr->ts.u.cl->length, &found_length);
88fec49f 2174
df2fba9e 2175 /* Now pad/truncate the elements accordingly to the specified character
88fec49f
DK
2176 length. This is ok inside this conditional, as in the case above
2177 (without typespec) all elements are verified to have the same length
2178 anyway. */
2179 if (found_length != -1)
b7e75771
JD
2180 for (p = gfc_constructor_first (expr->value.constructor);
2181 p; p = gfc_constructor_next (p))
d2848082
DK
2182 if (p->expr->expr_type == EXPR_CONSTANT)
2183 {
2184 gfc_expr *cl = NULL;
6b271a2e 2185 HOST_WIDE_INT current_length = -1;
d2848082
DK
2186 bool has_ts;
2187
bc21d315 2188 if (p->expr->ts.u.cl && p->expr->ts.u.cl->length)
d2848082 2189 {
bc21d315 2190 cl = p->expr->ts.u.cl->length;
6b271a2e 2191 gfc_extract_hwi (cl, &current_length);
d2848082
DK
2192 }
2193
2194 /* If gfc_extract_int above set current_length, we implicitly
2195 know the type is BT_INTEGER and it's EXPR_CONSTANT. */
2196
fc2655fb 2197 has_ts = expr->ts.u.cl->length_from_typespec;
d2848082
DK
2198
2199 if (! cl
a48a9173 2200 || (current_length != -1 && current_length != found_length))
d2848082
DK
2201 gfc_set_constant_character_len (found_length, p->expr,
2202 has_ts ? -1 : found_length);
2203 }
c03fc95d
DK
2204 }
2205
524af0d6 2206 return true;
df7cc9b5
FW
2207}
2208
65f8144a 2209
df7cc9b5 2210/* Resolve all of the expressions in an array list. */
6de9cd9a 2211
524af0d6 2212bool
65f8144a 2213gfc_resolve_array_constructor (gfc_expr *expr)
6de9cd9a 2214{
524af0d6 2215 bool t;
6de9cd9a
DN
2216
2217 t = resolve_array_list (expr->value.constructor);
524af0d6 2218 if (t)
6de9cd9a 2219 t = gfc_check_constructor_type (expr);
88fec49f
DK
2220
2221 /* gfc_resolve_character_array_constructor is called in gfc_resolve_expr after
2222 the call to this function, so we don't need to call it here; if it was
2223 called twice, an error message there would be duplicated. */
6de9cd9a
DN
2224
2225 return t;
2226}
2227
2228
2229/* Copy an iterator structure. */
2230
b7e75771
JD
2231gfc_iterator *
2232gfc_copy_iterator (gfc_iterator *src)
6de9cd9a
DN
2233{
2234 gfc_iterator *dest;
2235
2236 if (src == NULL)
2237 return NULL;
2238
2239 dest = gfc_get_iterator ();
2240
2241 dest->var = gfc_copy_expr (src->var);
2242 dest->start = gfc_copy_expr (src->start);
2243 dest->end = gfc_copy_expr (src->end);
2244 dest->step = gfc_copy_expr (src->step);
170a8bd6 2245 dest->unroll = src->unroll;
2bd86b95
HA
2246 dest->ivdep = src->ivdep;
2247 dest->vector = src->vector;
2248 dest->novector = src->novector;
6de9cd9a
DN
2249
2250 return dest;
2251}
2252
2253
6de9cd9a
DN
2254/********* Subroutines for determining the size of an array *********/
2255
1f2959f0 2256/* These are needed just to accommodate RESHAPE(). There are no
6de9cd9a 2257 diagnostics here, we just return a negative number if something
f7b529fa 2258 goes wrong. */
6de9cd9a
DN
2259
2260
2261/* Get the size of single dimension of an array specification. The
2262 array is guaranteed to be one dimensional. */
2263
524af0d6 2264bool
65f8144a 2265spec_dimen_size (gfc_array_spec *as, int dimen, mpz_t *result)
6de9cd9a 2266{
6de9cd9a 2267 if (as == NULL)
524af0d6 2268 return false;
6de9cd9a
DN
2269
2270 if (dimen < 0 || dimen > as->rank - 1)
2271 gfc_internal_error ("spec_dimen_size(): Bad dimension");
2272
2273 if (as->type != AS_EXPLICIT
70570ec1
PT
2274 || !as->lower[dimen]
2275 || !as->upper[dimen])
2276 return false;
2277
2278 if (as->lower[dimen]->expr_type != EXPR_CONSTANT
1505f3b5
JD
2279 || as->upper[dimen]->expr_type != EXPR_CONSTANT
2280 || as->lower[dimen]->ts.type != BT_INTEGER
2281 || as->upper[dimen]->ts.type != BT_INTEGER)
524af0d6 2282 return false;
6de9cd9a
DN
2283
2284 mpz_init (*result);
2285
2286 mpz_sub (*result, as->upper[dimen]->value.integer,
2287 as->lower[dimen]->value.integer);
2288
2289 mpz_add_ui (*result, *result, 1);
2290
524af0d6 2291 return true;
6de9cd9a
DN
2292}
2293
2294
524af0d6 2295bool
65f8144a 2296spec_size (gfc_array_spec *as, mpz_t *result)
6de9cd9a
DN
2297{
2298 mpz_t size;
2299 int d;
2300
81bcd96b 2301 if (!as || as->type == AS_ASSUMED_RANK)
524af0d6 2302 return false;
c62c6622 2303
6de9cd9a
DN
2304 mpz_init_set_ui (*result, 1);
2305
2306 for (d = 0; d < as->rank; d++)
2307 {
524af0d6 2308 if (!spec_dimen_size (as, d, &size))
6de9cd9a
DN
2309 {
2310 mpz_clear (*result);
524af0d6 2311 return false;
6de9cd9a
DN
2312 }
2313
2314 mpz_mul (*result, *result, size);
2315 mpz_clear (size);
2316 }
2317
524af0d6 2318 return true;
6de9cd9a
DN
2319}
2320
2321
ee247636
TK
2322/* Get the number of elements in an array section. Optionally, also supply
2323 the end value. */
6de9cd9a 2324
524af0d6 2325bool
ee247636 2326gfc_ref_dimen_size (gfc_array_ref *ar, int dimen, mpz_t *result, mpz_t *end)
6de9cd9a
DN
2327{
2328 mpz_t upper, lower, stride;
8cd61b3c 2329 mpz_t diff;
524af0d6 2330 bool t;
28ae01cd 2331 gfc_expr *stride_expr = NULL;
6de9cd9a 2332
2c6e2eb1 2333 if (dimen < 0 || ar == NULL)
543af7ab 2334 gfc_internal_error ("gfc_ref_dimen_size(): Bad dimension");
6de9cd9a 2335
2c6e2eb1
HA
2336 if (dimen > ar->dimen - 1)
2337 {
2338 gfc_error ("Bad array dimension at %L", &ar->c_where[dimen]);
2339 return false;
2340 }
2341
6de9cd9a
DN
2342 switch (ar->dimen_type[dimen])
2343 {
2344 case DIMEN_ELEMENT:
2345 mpz_init (*result);
2346 mpz_set_ui (*result, 1);
524af0d6 2347 t = true;
6de9cd9a
DN
2348 break;
2349
2350 case DIMEN_VECTOR:
2351 t = gfc_array_size (ar->start[dimen], result); /* Recurse! */
2352 break;
2353
2354 case DIMEN_RANGE:
8cd61b3c
TK
2355
2356 mpz_init (stride);
2357
2358 if (ar->stride[dimen] == NULL)
2359 mpz_set_ui (stride, 1);
2360 else
2361 {
28ae01cd 2362 stride_expr = gfc_copy_expr(ar->stride[dimen]);
8fb2cc6b 2363
28ae01cd
NK
2364 if(!gfc_simplify_expr(stride_expr, 1))
2365 gfc_internal_error("Simplification error");
8fb2cc6b
TK
2366
2367 if (stride_expr->expr_type != EXPR_CONSTANT
2368 || mpz_cmp_ui (stride_expr->value.integer, 0) == 0)
8cd61b3c
TK
2369 {
2370 mpz_clear (stride);
2371 return false;
2372 }
28ae01cd
NK
2373 mpz_set (stride, stride_expr->value.integer);
2374 gfc_free_expr(stride_expr);
8cd61b3c
TK
2375 }
2376
2377 /* Calculate the number of elements via gfc_dep_differce, but only if
2378 start and end are both supplied in the reference or the array spec.
2379 This is to guard against strange but valid code like
2380
2381 subroutine foo(a,n)
2382 real a(1:n)
2383 n = 3
2384 print *,size(a(n-1:))
2385
2386 where the user changes the value of a variable. If we have to
2387 determine end as well, we cannot do this using gfc_dep_difference.
2388 Fall back to the constants-only code then. */
2389
2390 if (end == NULL)
2391 {
2392 bool use_dep;
2393
2394 use_dep = gfc_dep_difference (ar->end[dimen], ar->start[dimen],
2395 &diff);
2396 if (!use_dep && ar->end[dimen] == NULL && ar->start[dimen] == NULL)
2397 use_dep = gfc_dep_difference (ar->as->upper[dimen],
2398 ar->as->lower[dimen], &diff);
2399
2400 if (use_dep)
2401 {
2402 mpz_init (*result);
2403 mpz_add (*result, diff, stride);
2404 mpz_div (*result, *result, stride);
2405 if (mpz_cmp_ui (*result, 0) < 0)
2406 mpz_set_ui (*result, 0);
2407
2408 mpz_clear (stride);
2409 mpz_clear (diff);
2410 return true;
2411 }
2412
2413 }
2414
2415 /* Constant-only code here, which covers more cases
2416 like a(:4) etc. */
6de9cd9a
DN
2417 mpz_init (upper);
2418 mpz_init (lower);
524af0d6 2419 t = false;
6de9cd9a
DN
2420
2421 if (ar->start[dimen] == NULL)
2422 {
2423 if (ar->as->lower[dimen] == NULL
15c918bc
SK
2424 || ar->as->lower[dimen]->expr_type != EXPR_CONSTANT
2425 || ar->as->lower[dimen]->ts.type != BT_INTEGER)
6de9cd9a
DN
2426 goto cleanup;
2427 mpz_set (lower, ar->as->lower[dimen]->value.integer);
2428 }
2429 else
2430 {
2431 if (ar->start[dimen]->expr_type != EXPR_CONSTANT)
2432 goto cleanup;
2433 mpz_set (lower, ar->start[dimen]->value.integer);
2434 }
2435
2436 if (ar->end[dimen] == NULL)
2437 {
2438 if (ar->as->upper[dimen] == NULL
15c918bc
SK
2439 || ar->as->upper[dimen]->expr_type != EXPR_CONSTANT
2440 || ar->as->upper[dimen]->ts.type != BT_INTEGER)
6de9cd9a
DN
2441 goto cleanup;
2442 mpz_set (upper, ar->as->upper[dimen]->value.integer);
2443 }
2444 else
2445 {
2446 if (ar->end[dimen]->expr_type != EXPR_CONSTANT)
2447 goto cleanup;
2448 mpz_set (upper, ar->end[dimen]->value.integer);
2449 }
2450
6de9cd9a
DN
2451 mpz_init (*result);
2452 mpz_sub (*result, upper, lower);
2453 mpz_add (*result, *result, stride);
2454 mpz_div (*result, *result, stride);
2455
2456 /* Zero stride caught earlier. */
2457 if (mpz_cmp_ui (*result, 0) < 0)
2458 mpz_set_ui (*result, 0);
524af0d6 2459 t = true;
6de9cd9a 2460
ee247636
TK
2461 if (end)
2462 {
2463 mpz_init (*end);
2464
2465 mpz_sub_ui (*end, *result, 1UL);
2466 mpz_mul (*end, *end, stride);
2467 mpz_add (*end, *end, lower);
2468 }
2469
6de9cd9a
DN
2470 cleanup:
2471 mpz_clear (upper);
2472 mpz_clear (lower);
2473 mpz_clear (stride);
2474 return t;
2475
2476 default:
543af7ab 2477 gfc_internal_error ("gfc_ref_dimen_size(): Bad dimen_type");
6de9cd9a
DN
2478 }
2479
2480 return t;
2481}
2482
2483
524af0d6 2484static bool
65f8144a 2485ref_size (gfc_array_ref *ar, mpz_t *result)
6de9cd9a
DN
2486{
2487 mpz_t size;
2488 int d;
2489
2490 mpz_init_set_ui (*result, 1);
2491
2492 for (d = 0; d < ar->dimen; d++)
2493 {
524af0d6 2494 if (!gfc_ref_dimen_size (ar, d, &size, NULL))
6de9cd9a
DN
2495 {
2496 mpz_clear (*result);
524af0d6 2497 return false;
6de9cd9a
DN
2498 }
2499
2500 mpz_mul (*result, *result, size);
2501 mpz_clear (size);
2502 }
2503
524af0d6 2504 return true;
6de9cd9a
DN
2505}
2506
2507
2508/* Given an array expression and a dimension, figure out how many
524af0d6
JB
2509 elements it has along that dimension. Returns true if we were
2510 able to return a result in the 'result' variable, false
6de9cd9a
DN
2511 otherwise. */
2512
524af0d6 2513bool
65f8144a 2514gfc_array_dimen_size (gfc_expr *array, int dimen, mpz_t *result)
6de9cd9a
DN
2515{
2516 gfc_ref *ref;
2517 int i;
2518
fc2655fb
TB
2519 gcc_assert (array != NULL);
2520
c49ea23d 2521 if (array->ts.type == BT_CLASS)
524af0d6 2522 return false;
c49ea23d 2523
c62c6622 2524 if (array->rank == -1)
524af0d6 2525 return false;
c62c6622 2526
fc2655fb 2527 if (dimen < 0 || dimen > array->rank - 1)
6de9cd9a
DN
2528 gfc_internal_error ("gfc_array_dimen_size(): Bad dimension");
2529
2530 switch (array->expr_type)
2531 {
2532 case EXPR_VARIABLE:
2533 case EXPR_FUNCTION:
2534 for (ref = array->ref; ref; ref = ref->next)
2535 {
2536 if (ref->type != REF_ARRAY)
2537 continue;
2538
2539 if (ref->u.ar.type == AR_FULL)
2540 return spec_dimen_size (ref->u.ar.as, dimen, result);
2541
2542 if (ref->u.ar.type == AR_SECTION)
2543 {
2544 for (i = 0; dimen >= 0; i++)
2545 if (ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
2546 dimen--;
2547
ee247636 2548 return gfc_ref_dimen_size (&ref->u.ar, i - 1, result, NULL);
6de9cd9a
DN
2549 }
2550 }
2551
e15e9be3
PT
2552 if (array->shape && array->shape[dimen])
2553 {
2554 mpz_init_set (*result, array->shape[dimen]);
524af0d6 2555 return true;
e15e9be3
PT
2556 }
2557
23f6293e 2558 if (array->symtree->n.sym->attr.generic
03d838ba 2559 && array->value.function.esym != NULL)
23f6293e 2560 {
524af0d6
JB
2561 if (!spec_dimen_size (array->value.function.esym->as, dimen, result))
2562 return false;
23f6293e 2563 }
524af0d6
JB
2564 else if (!spec_dimen_size (array->symtree->n.sym->as, dimen, result))
2565 return false;
6de9cd9a
DN
2566
2567 break;
2568
2569 case EXPR_ARRAY:
2570 if (array->shape == NULL) {
2571 /* Expressions with rank > 1 should have "shape" properly set */
2572 if ( array->rank != 1 )
2573 gfc_internal_error ("gfc_array_dimen_size(): Bad EXPR_ARRAY expr");
2574 return gfc_array_size(array, result);
2575 }
2576
2577 /* Fall through */
2578 default:
2579 if (array->shape == NULL)
524af0d6 2580 return false;
6de9cd9a
DN
2581
2582 mpz_init_set (*result, array->shape[dimen]);
2583
2584 break;
2585 }
2586
524af0d6 2587 return true;
6de9cd9a
DN
2588}
2589
2590
2591/* Given an array expression, figure out how many elements are in the
524af0d6
JB
2592 array. Returns true if this is possible, and sets the 'result'
2593 variable. Otherwise returns false. */
6de9cd9a 2594
524af0d6 2595bool
65f8144a 2596gfc_array_size (gfc_expr *array, mpz_t *result)
6de9cd9a
DN
2597{
2598 expand_info expand_save;
2599 gfc_ref *ref;
a3d3c0f5 2600 int i;
524af0d6 2601 bool t;
6de9cd9a 2602
c49ea23d 2603 if (array->ts.type == BT_CLASS)
524af0d6 2604 return false;
c49ea23d 2605
6de9cd9a
DN
2606 switch (array->expr_type)
2607 {
2608 case EXPR_ARRAY:
a3d3c0f5 2609 gfc_push_suppress_errors ();
6de9cd9a
DN
2610
2611 expand_save = current_expand;
2612
2613 current_expand.count = result;
2614 mpz_init_set_ui (*result, 0);
2615
2616 current_expand.expand_work_function = count_elements;
2617 iter_stack = NULL;
2618
2619 t = expand_constructor (array->value.constructor);
a3d3c0f5
DK
2620
2621 gfc_pop_suppress_errors ();
6de9cd9a 2622
524af0d6 2623 if (!t)
6de9cd9a
DN
2624 mpz_clear (*result);
2625 current_expand = expand_save;
2626 return t;
2627
2628 case EXPR_VARIABLE:
2629 for (ref = array->ref; ref; ref = ref->next)
2630 {
2631 if (ref->type != REF_ARRAY)
2632 continue;
2633
2634 if (ref->u.ar.type == AR_FULL)
2635 return spec_size (ref->u.ar.as, result);
2636
2637 if (ref->u.ar.type == AR_SECTION)
2638 return ref_size (&ref->u.ar, result);
2639 }
2640
2641 return spec_size (array->symtree->n.sym->as, result);
2642
2643
2644 default:
2645 if (array->rank == 0 || array->shape == NULL)
524af0d6 2646 return false;
6de9cd9a
DN
2647
2648 mpz_init_set_ui (*result, 1);
2649
2650 for (i = 0; i < array->rank; i++)
2651 mpz_mul (*result, *result, array->shape[i]);
2652
2653 break;
2654 }
2655
524af0d6 2656 return true;
6de9cd9a
DN
2657}
2658
2659
2660/* Given an array reference, return the shape of the reference in an
2661 array of mpz_t integers. */
2662
524af0d6 2663bool
65f8144a 2664gfc_array_ref_shape (gfc_array_ref *ar, mpz_t *shape)
6de9cd9a
DN
2665{
2666 int d;
2667 int i;
2668
2669 d = 0;
2670
2671 switch (ar->type)
2672 {
2673 case AR_FULL:
2674 for (; d < ar->as->rank; d++)
524af0d6 2675 if (!spec_dimen_size (ar->as, d, &shape[d]))
6de9cd9a
DN
2676 goto cleanup;
2677
524af0d6 2678 return true;
6de9cd9a
DN
2679
2680 case AR_SECTION:
2681 for (i = 0; i < ar->dimen; i++)
2682 {
2683 if (ar->dimen_type[i] != DIMEN_ELEMENT)
2684 {
524af0d6 2685 if (!gfc_ref_dimen_size (ar, i, &shape[d], NULL))
6de9cd9a
DN
2686 goto cleanup;
2687 d++;
2688 }
2689 }
2690
524af0d6 2691 return true;
6de9cd9a
DN
2692
2693 default:
2694 break;
2695 }
2696
2697cleanup:
7d7212ec 2698 gfc_clear_shape (shape, d);
524af0d6 2699 return false;
6de9cd9a
DN
2700}
2701
2702
2703/* Given an array expression, find the array reference structure that
2704 characterizes the reference. */
2705
2706gfc_array_ref *
eb401400 2707gfc_find_array_ref (gfc_expr *e, bool allow_null)
6de9cd9a
DN
2708{
2709 gfc_ref *ref;
2710
2711 for (ref = e->ref; ref; ref = ref->next)
2712 if (ref->type == REF_ARRAY
db171167 2713 && (ref->u.ar.type == AR_FULL || ref->u.ar.type == AR_SECTION))
6de9cd9a
DN
2714 break;
2715
2716 if (ref == NULL)
eb401400
AV
2717 {
2718 if (allow_null)
2719 return NULL;
2720 else
2721 gfc_internal_error ("gfc_find_array_ref(): No ref found");
2722 }
6de9cd9a
DN
2723
2724 return &ref->u.ar;
2725}
4077d207
TS
2726
2727
2728/* Find out if an array shape is known at compile time. */
2729
7a28353e 2730bool
4077d207
TS
2731gfc_is_compile_time_shape (gfc_array_spec *as)
2732{
4077d207 2733 if (as->type != AS_EXPLICIT)
7a28353e 2734 return false;
4077d207 2735
7a28353e 2736 for (int i = 0; i < as->rank; i++)
4077d207
TS
2737 if (!gfc_is_constant_expr (as->lower[i])
2738 || !gfc_is_constant_expr (as->upper[i]))
7a28353e 2739 return false;
4077d207 2740
7a28353e 2741 return true;
4077d207 2742}