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