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