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