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