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