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