LCOV - code coverage report
Current view: top level - gcc/fortran - array.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.5 % 1319 1220
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 51 51
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Array things
       2              :    Copyright (C) 2000-2026 Free Software Foundation, Inc.
       3              :    Contributed by Andy Vaught
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify it under
       8              : the terms of the GNU General Public License as published by the Free
       9              : Software Foundation; either version 3, or (at your option) any later
      10              : version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15              : for more details.
      16              : 
      17              : You should have received a copy of the GNU General Public License
      18              : along with GCC; see the file COPYING3.  If not see
      19              : <http://www.gnu.org/licenses/>.  */
      20              : 
      21              : #include "config.h"
      22              : #include "system.h"
      23              : #include "coretypes.h"
      24              : #include "options.h"
      25              : #include "gfortran.h"
      26              : #include "parse.h"
      27              : #include "match.h"
      28              : #include "constructor.h"
      29              : 
      30              : /**************** Array reference matching subroutines *****************/
      31              : 
      32              : /* Copy an array reference structure.  */
      33              : 
      34              : gfc_array_ref *
      35       169647 : gfc_copy_array_ref (gfc_array_ref *src)
      36              : {
      37       169647 :   gfc_array_ref *dest;
      38       169647 :   int i;
      39              : 
      40       169647 :   if (src == NULL)
      41              :     return NULL;
      42              : 
      43       169647 :   dest = gfc_get_array_ref ();
      44              : 
      45       169647 :   *dest = *src;
      46              : 
      47      2714352 :   for (i = 0; i < GFC_MAX_DIMENSIONS; i++)
      48              :     {
      49      2544705 :       dest->start[i] = gfc_copy_expr (src->start[i]);
      50      2544705 :       dest->end[i] = gfc_copy_expr (src->end[i]);
      51      2544705 :       dest->stride[i] = gfc_copy_expr (src->stride[i]);
      52              :     }
      53              : 
      54       169647 :   dest->stat = gfc_copy_expr (src->stat);
      55       169647 :   dest->team = gfc_copy_expr (src->team);
      56              : 
      57       169647 :   return dest;
      58              : }
      59              : 
      60              : 
      61              : /* Match a single dimension of an array reference.  This can be a
      62              :    single element or an array section.  Any modifications we've made
      63              :    to the ar structure are cleaned up by the caller.  If the init
      64              :    is set, we require the subscript to be a valid initialization
      65              :    expression.  */
      66              : 
      67              : static match
      68       367496 : match_subscript (gfc_array_ref *ar, int init, bool match_star)
      69              : {
      70       367496 :   match m = MATCH_ERROR;
      71       367496 :   bool star = false;
      72       367496 :   int i;
      73       367496 :   bool saw_boz = false;
      74              : 
      75       367496 :   i = ar->dimen + ar->codimen;
      76              : 
      77       367496 :   gfc_gobble_whitespace ();
      78       367496 :   ar->c_where[i] = gfc_current_locus;
      79       367496 :   ar->start[i] = ar->end[i] = ar->stride[i] = NULL;
      80              : 
      81              :   /* We can't be sure of the difference between DIMEN_ELEMENT and
      82              :      DIMEN_VECTOR until we know the type of the element itself at
      83              :      resolution time.  */
      84              : 
      85       367496 :   ar->dimen_type[i] = DIMEN_UNKNOWN;
      86              : 
      87       367496 :   if (gfc_match_char (':') == MATCH_YES)
      88        43812 :     goto end_element;
      89              : 
      90              :   /* Get start element.  */
      91       323684 :   if (match_star && (m = gfc_match_char ('*')) == MATCH_YES)
      92              :     star = true;
      93              : 
      94       323684 :   if (!star && init)
      95         1636 :     m = gfc_match_init_expr (&ar->start[i]);
      96       322048 :   else if (!star)
      97       321265 :     m = gfc_match_expr (&ar->start[i]);
      98              : 
      99       323684 :   if (ar->start[i] && ar->start[i]->ts.type == BT_BOZ)
     100              :     {
     101            1 :       gfc_error ("Invalid BOZ literal constant used in subscript at %C");
     102            1 :       saw_boz = true;
     103              :     }
     104              : 
     105       323684 :   if (m == MATCH_NO)
     106            4 :     gfc_error ("Expected array subscript at %C");
     107       323684 :   if (m != MATCH_YES)
     108              :     return MATCH_ERROR;
     109              : 
     110       323674 :   if (gfc_match_char (':') == MATCH_NO)
     111       288377 :     goto matched;
     112              : 
     113        35297 :   if (star)
     114              :     {
     115            0 :       gfc_error ("Unexpected %<*%> in coarray subscript at %C");
     116            0 :       return MATCH_ERROR;
     117              :     }
     118              : 
     119              :   /* Get an optional end element.  Because we've seen the colon, we
     120              :      definitely have a range along this dimension.  */
     121        35297 : end_element:
     122        79109 :   ar->dimen_type[i] = DIMEN_RANGE;
     123              : 
     124        79109 :   if (match_star && (m = gfc_match_char ('*')) == MATCH_YES)
     125              :     star = true;
     126        78917 :   else if (init)
     127          371 :     m = gfc_match_init_expr (&ar->end[i]);
     128              :   else
     129        78546 :     m = gfc_match_expr (&ar->end[i]);
     130              : 
     131        79109 :   if (ar->end[i] && ar->end[i]->ts.type == BT_BOZ)
     132              :     {
     133            1 :       gfc_error ("Invalid BOZ literal constant used in subscript at %C");
     134            1 :       saw_boz = true;
     135              :     }
     136              : 
     137        79109 :   if (m == MATCH_ERROR)
     138              :     return MATCH_ERROR;
     139              : 
     140        79109 :   if (star && ar->start[i] == NULL)
     141              :     {
     142            2 :       gfc_error ("Missing lower bound in assumed size "
     143              :                  "coarray specification at %C");
     144            2 :       return MATCH_ERROR;
     145              :     }
     146              : 
     147              :   /* See if we have an optional stride.  */
     148        79107 :   if (gfc_match_char (':') == MATCH_YES)
     149              :     {
     150        16805 :       if (star)
     151              :         {
     152            0 :           gfc_error ("Strides not allowed in coarray subscript at %C");
     153            0 :           return MATCH_ERROR;
     154              :         }
     155              : 
     156        16805 :       m = init ? gfc_match_init_expr (&ar->stride[i])
     157        16804 :                : gfc_match_expr (&ar->stride[i]);
     158              : 
     159        16805 :       if (ar->stride[i] && ar->stride[i]->ts.type == BT_BOZ)
     160              :         {
     161            1 :           gfc_error ("Invalid BOZ literal constant used in subscript at %C");
     162            1 :           saw_boz = true;
     163              :         }
     164              : 
     165        16805 :       if (m == MATCH_NO)
     166            0 :         gfc_error ("Expected array subscript stride at %C");
     167        16805 :       if (m != MATCH_YES)
     168              :         return MATCH_ERROR;
     169              :     }
     170              : 
     171        62302 : matched:
     172       367484 :   if (star)
     173          973 :     ar->dimen_type[i] = DIMEN_STAR;
     174              : 
     175       367484 :   return (saw_boz ? MATCH_ERROR : MATCH_YES);
     176              : }
     177              : 
     178              : /** Match one of TEAM=, TEAM_NUMBER= or STAT=.  */
     179              : 
     180              : match
     181         5692 : match_team_or_stat (gfc_array_ref *ar)
     182              : {
     183         5692 :   gfc_expr *tmp;
     184         5692 :   bool team_error = false;
     185              : 
     186         5692 :   if (gfc_match (" team = %e", &tmp) == MATCH_YES)
     187              :     {
     188           75 :       if (ar->team == NULL && ar->team_type == TEAM_UNSET)
     189              :         {
     190           69 :           ar->team = tmp;
     191           69 :           ar->team_type = TEAM_TEAM;
     192              :         }
     193            6 :       else if (ar->team_type == TEAM_TEAM)
     194              :         {
     195            3 :           gfc_error ("Duplicate TEAM= attribute in %C");
     196            3 :           return MATCH_ERROR;
     197              :         }
     198              :       else
     199              :         team_error = true;
     200              :     }
     201         5617 :   else if (gfc_match (" team_number = %e", &tmp) == MATCH_YES)
     202              :     {
     203          102 :       if (!gfc_notify_std (GFC_STD_F2018, "TEAM_NUMBER= not supported at %C"))
     204              :         return MATCH_ERROR;
     205           99 :       if (ar->team == NULL && ar->team_type == TEAM_UNSET)
     206              :         {
     207           96 :           ar->team = tmp;
     208           96 :           ar->team_type = TEAM_NUMBER;
     209              :         }
     210            3 :       else if (ar->team_type == TEAM_NUMBER)
     211              :         {
     212            3 :           gfc_error ("Duplicate TEAM_NUMBER= attribute in %C");
     213            3 :           return MATCH_ERROR;
     214              :         }
     215              :       else
     216              :         team_error = true;
     217              :     }
     218         5515 :   else if (gfc_match (" stat = %e", &tmp) == MATCH_YES)
     219              :     {
     220          113 :       if (ar->stat == NULL)
     221              :         {
     222          107 :           if (gfc_is_coindexed (tmp))
     223              :             {
     224            3 :               gfc_error ("Expression in STAT= at %C must not be coindexed");
     225            3 :               gfc_free_expr (tmp);
     226            3 :               return MATCH_ERROR;
     227              :             }
     228          104 :           ar->stat = tmp;
     229              :         }
     230              :       else
     231              :         {
     232            6 :           gfc_error ("Duplicate STAT= attribute in %C");
     233            6 :           return MATCH_ERROR;
     234              :         }
     235              :     }
     236              :   else
     237              :     return MATCH_NO;
     238              : 
     239          272 :   if (ar->team && team_error)
     240              :     {
     241            3 :       gfc_error ("Only one of TEAM= or TEAM_NUMBER= may appear in a "
     242              :                  "coarray reference at %C");
     243            3 :       return MATCH_ERROR;
     244              :     }
     245              : 
     246              :   return MATCH_YES;
     247              : }
     248              : 
     249              : /* Match an array reference, whether it is the whole array or particular
     250              :    elements or a section.  If init is set, the reference has to consist
     251              :    of init expressions.  */
     252              : 
     253              : match
     254       732629 : gfc_match_array_ref (gfc_array_ref *ar, gfc_array_spec *as, int init,
     255              :                      int corank, bool coarray_only)
     256              : {
     257       732629 :   match m;
     258       732629 :   bool matched_bracket = false;
     259              : 
     260       732629 :   memset (ar, '\0', sizeof (*ar));
     261              : 
     262       732629 :   ar->where = gfc_current_locus;
     263       732629 :   ar->as = as;
     264       732629 :   ar->type = AR_UNKNOWN;
     265              : 
     266       732629 :   if (gfc_match_char ('[') == MATCH_YES)
     267              :     {
     268         3399 :        matched_bracket = true;
     269         3399 :        goto coarray;
     270              :     }
     271       729230 :   else if (coarray_only && corank != 0)
     272         1833 :     goto coarray;
     273              : 
     274       727397 :   if (gfc_match_char ('(') != MATCH_YES)
     275              :     {
     276       447386 :       ar->type = AR_FULL;
     277       447386 :       ar->dimen = 0;
     278       447386 :       if (corank != 0)
     279              :         {
     280       178000 :           for (int i = 0; i < GFC_MAX_DIMENSIONS; ++i)
     281       166875 :             ar->dimen_type[i] = DIMEN_THIS_IMAGE;
     282        11125 :           ar->codimen = corank;
     283              :         }
     284       447386 :       return MATCH_YES;
     285              :     }
     286              : 
     287       362093 :   for (ar->dimen = 0; ar->dimen < GFC_MAX_DIMENSIONS; ar->dimen++)
     288              :     {
     289       362093 :       m = match_subscript (ar, init, false);
     290       362093 :       if (m == MATCH_ERROR)
     291              :         return MATCH_ERROR;
     292              : 
     293       362080 :       if (gfc_match_char (')') == MATCH_YES)
     294              :         {
     295       279986 :           ar->dimen++;
     296       279986 :           goto coarray;
     297              :         }
     298              : 
     299        82094 :       if (gfc_match_char (',') != MATCH_YES)
     300              :         {
     301           12 :           gfc_error ("Invalid form of array reference at %C");
     302           12 :           return MATCH_ERROR;
     303              :         }
     304              :     }
     305              : 
     306            0 :   if (ar->dimen >= 7
     307            0 :       && !gfc_notify_std (GFC_STD_F2008,
     308              :                           "Array reference at %C has more than 7 dimensions"))
     309              :     return MATCH_ERROR;
     310              : 
     311            0 :   gfc_error ("Array reference at %C cannot have more than %d dimensions",
     312              :              GFC_MAX_DIMENSIONS);
     313            0 :   return MATCH_ERROR;
     314              : 
     315       285218 : coarray:
     316       285218 :   if (!matched_bracket && gfc_match_char ('[') != MATCH_YES)
     317              :     {
     318       280472 :       int dim = coarray_only ? 0 : ar->dimen;
     319       280472 :       if (dim > 0 || coarray_only)
     320              :         {
     321       280472 :           if (corank != 0)
     322              :             {
     323       102798 :               for (int i = dim; i < GFC_MAX_DIMENSIONS; ++i)
     324        96038 :                 ar->dimen_type[i] = DIMEN_THIS_IMAGE;
     325         6760 :               ar->codimen = corank;
     326              :             }
     327       280472 :           return MATCH_YES;
     328              :         }
     329              :       else
     330              :         return MATCH_ERROR;
     331              :     }
     332              : 
     333         4746 :   if (flag_coarray == GFC_FCOARRAY_NONE)
     334              :     {
     335            0 :       gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
     336              :       return MATCH_ERROR;
     337              :     }
     338              : 
     339         4746 :   if (corank == 0)
     340              :     {
     341            0 :         gfc_error ("Unexpected coarray designator at %C");
     342            0 :         return MATCH_ERROR;
     343              :     }
     344              : 
     345         4746 :   ar->team_type = TEAM_UNSET;
     346              : 
     347         5403 :   for (ar->codimen = 0; ar->codimen + ar->dimen < GFC_MAX_DIMENSIONS;
     348              :        ar->codimen++)
     349              :     {
     350         5403 :       m = match_subscript (ar, init, true);
     351         5403 :       if (m == MATCH_ERROR)
     352              :         return MATCH_ERROR;
     353              : 
     354         5401 :       if (gfc_match_char (',') != MATCH_YES)
     355              :         {
     356         4529 :           if (gfc_match_char ('*') == MATCH_YES)
     357            0 :             gfc_error ("Unexpected %<*%> for codimension %d of %d at %C",
     358            0 :                        ar->codimen + 1, corank);
     359              :           else
     360              :             {
     361         4529 :               goto image_selector;
     362              :             }
     363            0 :           return MATCH_ERROR;
     364              :         }
     365          872 :       else if (ar->dimen_type[ar->codimen + ar->dimen] == DIMEN_STAR)
     366              :         {
     367            2 :           gfc_error ("Unexpected %<*%> for codimension %d of %d at %C",
     368              :                      ar->codimen + 1, corank);
     369            2 :           return MATCH_ERROR;
     370              :         }
     371              : 
     372          870 :       m = match_team_or_stat (ar);
     373          870 :       if (m == MATCH_ERROR)
     374              :         return MATCH_ERROR;
     375          864 :       else if (m == MATCH_YES)
     376          203 :         goto image_selector;
     377              : 
     378          661 :       if (gfc_match_char (']') == MATCH_YES)
     379            0 :         goto rank_check;
     380              : 
     381          661 :       if (ar->codimen >= corank)
     382              :         {
     383            4 :           gfc_error ("Invalid codimension %d at %C, only %d codimensions exist",
     384              :                      ar->codimen + 1, corank);
     385            4 :           return MATCH_ERROR;
     386              :         }
     387              :     }
     388              : 
     389            0 :   gfc_error ("Array reference at %C cannot have more than %d dimensions",
     390              :              GFC_MAX_DIMENSIONS);
     391            0 :   return MATCH_ERROR;
     392              : 
     393         4822 : image_selector:
     394         4822 :   for (;;)
     395              :     {
     396         4822 :       m = match_team_or_stat (ar);
     397         4822 :       if (m == MATCH_ERROR)
     398              :         return MATCH_ERROR;
     399              : 
     400         4807 :       if (gfc_match_char (']') == MATCH_YES)
     401         4699 :         goto rank_check;
     402              : 
     403          108 :       if (gfc_match_char (',') != MATCH_YES)
     404              :         {
     405           18 :           gfc_error ("Invalid form of coarray reference at %C");
     406           18 :           return MATCH_ERROR;
     407              :         }
     408              :     }
     409              : 
     410              :   return MATCH_ERROR;
     411              : 
     412         4699 : rank_check:
     413         4699 :   ar->codimen++;
     414         4699 :   if (ar->codimen < corank)
     415              :     {
     416           18 :       gfc_error ("Too few codimensions at %C, expected %d not %d", corank,
     417              :                  ar->codimen);
     418           18 :       return MATCH_ERROR;
     419              :     }
     420         4681 :   if (ar->codimen > corank)
     421              :     {
     422            2 :       gfc_error ("Too many codimensions at %C, expected %d not %d", corank,
     423              :                  ar->codimen);
     424            2 :       return MATCH_ERROR;
     425              :     }
     426              :   return MATCH_YES;
     427              : }
     428              : 
     429              : 
     430              : /************** Array specification matching subroutines ***************/
     431              : 
     432              : /* Free all of the expressions associated with array bounds
     433              :    specifications.  */
     434              : 
     435              : void
     436      7127698 : gfc_free_array_spec (gfc_array_spec *as)
     437              : {
     438      7127698 :   int i;
     439              : 
     440      7127698 :   if (as == NULL)
     441              :     return;
     442              : 
     443       427821 :   if (as->corank == 0)
     444              :     {
     445       642369 :       for (i = 0; i < as->rank; i++)
     446              :         {
     447       217933 :           gfc_free_expr (as->lower[i]);
     448       217933 :           gfc_free_expr (as->upper[i]);
     449              :         }
     450              :     }
     451              :   else
     452              :     {
     453         3385 :       int n = as->rank + as->corank - (as->cotype == AS_EXPLICIT ? 1 : 0);
     454         7694 :       for (i = 0; i < n; i++)
     455              :         {
     456         4309 :           gfc_free_expr (as->lower[i]);
     457         4309 :           gfc_free_expr (as->upper[i]);
     458              :         }
     459              :     }
     460              : 
     461       427821 :   free (as);
     462              : }
     463              : 
     464              : 
     465              : /* Take an array bound, resolves the expression, that make up the
     466              :    shape and check associated constraints.  */
     467              : 
     468              : static bool
     469       342619 : resolve_array_bound (gfc_expr *e, int check_constant)
     470              : {
     471       342619 :   if (e == NULL)
     472              :     return true;
     473              : 
     474       195945 :   if (!gfc_resolve_expr (e)
     475       195945 :       || !gfc_specification_expr (e))
     476           36 :     return false;
     477              : 
     478       195909 :   if (check_constant && !gfc_is_constant_expr (e))
     479              :     {
     480            0 :       if (e->expr_type == EXPR_VARIABLE)
     481            0 :         gfc_error ("Variable %qs at %L in this context must be constant",
     482            0 :                    e->symtree->n.sym->name, &e->where);
     483              :       else
     484            0 :         gfc_error ("Expression at %L in this context must be constant",
     485              :                    &e->where);
     486            0 :       return false;
     487              :     }
     488              : 
     489              :   return true;
     490              : }
     491              : 
     492              : 
     493              : /* Takes an array specification, resolves the expressions that make up
     494              :    the shape and make sure everything is integral.  */
     495              : 
     496              : bool
     497      2833970 : gfc_resolve_array_spec (gfc_array_spec *as, int check_constant)
     498              : {
     499      2833970 :   gfc_expr *e;
     500      2833970 :   int i;
     501              : 
     502      2833970 :   if (as == NULL)
     503              :     return true;
     504              : 
     505       339490 :   if (as->resolved)
     506              :     return true;
     507              : 
     508       335007 :   for (i = 0; i < as->rank + as->corank; i++)
     509              :     {
     510       171315 :       if (i == GFC_MAX_DIMENSIONS)
     511              :         return false;
     512              : 
     513       171312 :       e = as->lower[i];
     514       171312 :       if (!resolve_array_bound (e, check_constant))
     515              :         return false;
     516              : 
     517       171307 :       e = as->upper[i];
     518       171307 :       if (!resolve_array_bound (e, check_constant))
     519              :         return false;
     520              : 
     521       171276 :       if ((as->lower[i] == NULL) || (as->upper[i] == NULL))
     522        99389 :         continue;
     523              : 
     524              :       /* If the size is negative in this dimension, set it to zero.  */
     525        71887 :       if (as->lower[i]->expr_type == EXPR_CONSTANT
     526        71163 :             && as->upper[i]->expr_type == EXPR_CONSTANT
     527        62383 :             && mpz_cmp (as->upper[i]->value.integer,
     528        62383 :                         as->lower[i]->value.integer) < 0)
     529              :         {
     530         1243 :           gfc_free_expr (as->upper[i]);
     531         1243 :           as->upper[i] = gfc_copy_expr (as->lower[i]);
     532         1243 :           mpz_sub_ui (as->upper[i]->value.integer,
     533         1243 :                       as->upper[i]->value.integer, 1);
     534              :         }
     535              :     }
     536              : 
     537       163692 :   as->resolved = true;
     538              : 
     539       163692 :   return true;
     540              : }
     541              : 
     542              : 
     543              : /* Match a single array element specification.  The return values as
     544              :    well as the upper and lower bounds of the array spec are filled
     545              :    in according to what we see on the input.  The caller makes sure
     546              :    individual specifications make sense as a whole.
     547              : 
     548              : 
     549              :         Parsed       Lower   Upper  Returned
     550              :         ------------------------------------
     551              :           :           NULL    NULL   AS_DEFERRED (*)
     552              :           x            1       x     AS_EXPLICIT
     553              :           x:           x      NULL   AS_ASSUMED_SHAPE
     554              :           x:y          x       y     AS_EXPLICIT
     555              :           x:*          x      NULL   AS_ASSUMED_SIZE
     556              :           *            1      NULL   AS_ASSUMED_SIZE
     557              : 
     558              :   (*) For non-pointer dummy arrays this is AS_ASSUMED_SHAPE.  This
     559              :   is fixed during the resolution of formal interfaces.
     560              : 
     561              :    Anything else AS_UNKNOWN.  */
     562              : 
     563              : static array_type
     564       108243 : match_array_element_spec (gfc_array_spec *as)
     565              : {
     566       108243 :   gfc_expr **upper, **lower;
     567       108243 :   match m;
     568       108243 :   int rank;
     569       108243 :   bool is_pdt_template;
     570              : 
     571       108243 :   rank = as->rank == -1 ? 0 : as->rank;
     572       108243 :   lower = &as->lower[rank + as->corank - 1];
     573       108243 :   upper = &as->upper[rank + as->corank - 1];
     574              : 
     575       108243 :   if (gfc_match_char ('*') == MATCH_YES)
     576              :     {
     577         8002 :       *lower = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
     578         8002 :       return AS_ASSUMED_SIZE;
     579              :     }
     580              : 
     581       100241 :   if (gfc_match_char (':') == MATCH_YES)
     582              :     {
     583        38861 :       locus old_loc = gfc_current_locus;
     584        38861 :       if (gfc_match_char ('*') == MATCH_YES)
     585              :         {
     586              :           /* F2018:R821: "assumed-implied-spec  is  [ lower-bound : ] *".  */
     587            3 :           gfc_error ("A lower bound must precede colon in "
     588              :                      "assumed-size array specification at %L", &old_loc);
     589            3 :           return AS_UNKNOWN;
     590              :         }
     591              :       else
     592              :         {
     593              :           return AS_DEFERRED;
     594              :         }
     595              :     }
     596              : 
     597        61380 :   m = gfc_match_expr (upper);
     598        61380 :   if (m == MATCH_NO)
     599            1 :     gfc_error ("Expected expression in array specification at %C");
     600        61380 :   if (m != MATCH_YES)
     601              :     return AS_UNKNOWN;
     602        61378 :   if (!gfc_expr_check_typed (*upper, gfc_current_ns, false))
     603              :     return AS_UNKNOWN;
     604              : 
     605        61371 :   if (((*upper)->expr_type == EXPR_CONSTANT
     606        61371 :         && (*upper)->ts.type != BT_INTEGER) ||
     607              :       ((*upper)->expr_type == EXPR_FUNCTION
     608          689 :         && (*upper)->ts.type == BT_UNKNOWN
     609          688 :         && (*upper)->symtree
     610          688 :         && strcmp ((*upper)->symtree->name, "null") == 0))
     611              :     {
     612            5 :       gfc_error ("Expecting a scalar INTEGER expression at %C, found %s",
     613              :                  gfc_basic_typename ((*upper)->ts.type));
     614            5 :       return AS_UNKNOWN;
     615              :     }
     616              : 
     617       122732 :   is_pdt_template = gfc_current_block ()
     618        55115 :                     && gfc_current_block ()->attr.pdt_template
     619        61614 :                     && gfc_current_block ()->f2k_derived;
     620              : 
     621        61366 :   if ((*upper)->expr_type != EXPR_CONSTANT && is_pdt_template)
     622          231 :     gfc_correct_parm_expr (gfc_current_block (), upper);
     623              : 
     624        61366 :   if (gfc_match_char (':') == MATCH_NO)
     625              :     {
     626        54109 :       *lower = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
     627        54109 :       return AS_EXPLICIT;
     628              :     }
     629              : 
     630         7257 :   *lower = *upper;
     631         7257 :   *upper = NULL;
     632              : 
     633         7257 :   if (gfc_match_char ('*') == MATCH_YES)
     634              :     return AS_ASSUMED_SIZE;
     635              : 
     636         6748 :   m = gfc_match_expr (upper);
     637         6748 :   if (m == MATCH_ERROR)
     638              :     return AS_UNKNOWN;
     639         6748 :   if (m == MATCH_NO)
     640              :     return AS_ASSUMED_SHAPE;
     641         5898 :   if (!gfc_expr_check_typed (*upper, gfc_current_ns, false))
     642              :     return AS_UNKNOWN;
     643              : 
     644         5898 :   if (((*upper)->expr_type == EXPR_CONSTANT
     645         5898 :         && (*upper)->ts.type != BT_INTEGER) ||
     646              :       ((*upper)->expr_type == EXPR_FUNCTION
     647           76 :         && (*upper)->ts.type == BT_UNKNOWN
     648           76 :         && (*upper)->symtree
     649           76 :         && strcmp ((*upper)->symtree->name, "null") == 0))
     650              :     {
     651            1 :       gfc_error ("Expecting a scalar INTEGER expression at %C, found %s",
     652              :                  gfc_basic_typename ((*upper)->ts.type));
     653            1 :       return AS_UNKNOWN;
     654              :     }
     655              : 
     656         5897 :   if ((*upper)->expr_type != EXPR_CONSTANT && is_pdt_template)
     657            6 :     gfc_correct_parm_expr (gfc_current_block (), upper);
     658              : 
     659              :   return AS_EXPLICIT;
     660              : }
     661              : 
     662              : 
     663              : /* Matches an array specification, incidentally figuring out what sort
     664              :    it is.  Match either a normal array specification, or a coarray spec
     665              :    or both.  Optionally allow [:] for coarrays.  */
     666              : 
     667              : match
     668       303133 : gfc_match_array_spec (gfc_array_spec **asp, bool match_dim, bool match_codim)
     669              : {
     670       303133 :   array_type current_type;
     671       303133 :   gfc_array_spec *as;
     672       303133 :   int i;
     673              : 
     674       303133 :   as = gfc_get_array_spec ();
     675              : 
     676       303133 :   if (!match_dim)
     677           96 :     goto coarray;
     678              : 
     679       303037 :   if (gfc_match_char ('(') != MATCH_YES)
     680              :     {
     681       220428 :       if (!match_codim)
     682         1160 :         goto done;
     683       219268 :       goto coarray;
     684              :     }
     685              : 
     686        82609 :   if (gfc_match (" .. )") == MATCH_YES)
     687              :     {
     688         4901 :       as->type = AS_ASSUMED_RANK;
     689         4901 :       as->rank = -1;
     690              : 
     691         4901 :       if (!gfc_notify_std (GFC_STD_F2018, "Assumed-rank array at %C"))
     692           29 :         goto cleanup;
     693              : 
     694         4872 :       if (!match_codim)
     695         2092 :         goto done;
     696         2780 :       goto coarray;
     697              :     }
     698              : 
     699       105939 :   for (;;)
     700              :     {
     701       105939 :       as->rank++;
     702       105939 :       current_type = match_array_element_spec (as);
     703       105939 :       if (current_type == AS_UNKNOWN)
     704           17 :         goto cleanup;
     705              : 
     706              :       /* Note that current_type == AS_ASSUMED_SIZE for both assumed-size
     707              :          and implied-shape specifications.  If the rank is at least 2, we can
     708              :          distinguish between them.  But for rank 1, we currently return
     709              :          ASSUMED_SIZE; this gets adjusted later when we know for sure
     710              :          whether the symbol parsed is a PARAMETER or not.  */
     711              : 
     712       105922 :       if (as->rank == 1)
     713              :         {
     714        77692 :           as->type = current_type;
     715              :         }
     716              :       else
     717        28230 :         switch (as->type)
     718              :           {             /* See how current spec meshes with the existing.  */
     719            0 :           case AS_UNKNOWN:
     720            0 :             goto cleanup;
     721              : 
     722           41 :           case AS_IMPLIED_SHAPE:
     723           41 :             if (current_type != AS_ASSUMED_SIZE)
     724              :               {
     725            3 :                 gfc_error ("Bad array specification for implied-shape"
     726              :                            " array at %C");
     727            3 :                 goto cleanup;
     728              :               }
     729              :             break;
     730              : 
     731        17556 :           case AS_EXPLICIT:
     732        17556 :             if (current_type == AS_ASSUMED_SIZE)
     733              :               {
     734          623 :                 as->type = AS_ASSUMED_SIZE;
     735          623 :                 break;
     736              :               }
     737              : 
     738        16933 :             if (current_type == AS_EXPLICIT)
     739              :               break;
     740              : 
     741            0 :             gfc_error ("Bad array specification for an explicitly shaped "
     742              :                        "array at %C");
     743              : 
     744            0 :             goto cleanup;
     745              : 
     746          236 :           case AS_ASSUMED_SHAPE:
     747          236 :             if ((current_type == AS_ASSUMED_SHAPE)
     748          236 :                 || (current_type == AS_DEFERRED))
     749              :               break;
     750              : 
     751            0 :             gfc_error ("Bad array specification for assumed shape "
     752              :                        "array at %C");
     753            0 :             goto cleanup;
     754              : 
     755        10320 :           case AS_DEFERRED:
     756        10320 :             if (current_type == AS_DEFERRED)
     757              :               break;
     758              : 
     759            1 :             if (current_type == AS_ASSUMED_SHAPE)
     760              :               {
     761            0 :                 as->type = AS_ASSUMED_SHAPE;
     762            0 :                 break;
     763              :               }
     764              : 
     765            1 :             gfc_error ("Bad specification for deferred shape array at %C");
     766            1 :             goto cleanup;
     767              : 
     768           77 :           case AS_ASSUMED_SIZE:
     769           77 :             if (as->rank == 2 && current_type == AS_ASSUMED_SIZE)
     770              :               {
     771           75 :                 as->type = AS_IMPLIED_SHAPE;
     772           75 :                 break;
     773              :               }
     774              : 
     775            2 :             gfc_error ("Bad specification for assumed size array at %C");
     776            2 :             goto cleanup;
     777              : 
     778            0 :           case AS_ASSUMED_RANK:
     779            0 :             gcc_unreachable ();
     780              :           }
     781              : 
     782       105916 :       if (gfc_match_char (')') == MATCH_YES)
     783              :         break;
     784              : 
     785        28237 :       if (gfc_match_char (',') != MATCH_YES)
     786              :         {
     787            2 :           gfc_error ("Expected another dimension in array declaration at %C");
     788            2 :           goto cleanup;
     789              :         }
     790              : 
     791        28235 :       if (as->rank + as->corank >= GFC_MAX_DIMENSIONS)
     792              :         {
     793            2 :           gfc_error ("Array specification at %C has more than %d dimensions",
     794              :                      GFC_MAX_DIMENSIONS);
     795            2 :           goto cleanup;
     796              :         }
     797              : 
     798        28233 :       if (as->corank + as->rank >= 7
     799        28233 :           && !gfc_notify_std (GFC_STD_F2008, "Array specification at %C "
     800              :                               "with more than 7 dimensions"))
     801            2 :         goto cleanup;
     802              :     }
     803              : 
     804        77679 :   if (!match_codim)
     805        19164 :     goto done;
     806              : 
     807        58515 : coarray:
     808       280659 :   if (gfc_match_char ('[')  != MATCH_YES)
     809       279000 :     goto done;
     810              : 
     811         1659 :   if (!gfc_notify_std (GFC_STD_F2008, "Coarray declaration at %C"))
     812            3 :     goto cleanup;
     813              : 
     814         1656 :   if (flag_coarray == GFC_FCOARRAY_NONE)
     815              :     {
     816            1 :       gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
     817              :       goto cleanup;
     818              :     }
     819              : 
     820         1655 :   if (as->rank >= GFC_MAX_DIMENSIONS)
     821              :     {
     822            0 :       gfc_error ("Array specification at %C has more than %d "
     823              :                  "dimensions", GFC_MAX_DIMENSIONS);
     824            0 :       goto cleanup;
     825              :     }
     826              : 
     827         2304 :   for (;;)
     828              :     {
     829         2304 :       as->corank++;
     830         2304 :       current_type = match_array_element_spec (as);
     831              : 
     832         2304 :       if (current_type == AS_UNKNOWN)
     833            1 :         goto cleanup;
     834              : 
     835         2303 :       if (as->corank == 1)
     836         1654 :         as->cotype = current_type;
     837              :       else
     838          649 :         switch (as->cotype)
     839              :           { /* See how current spec meshes with the existing.  */
     840            0 :             case AS_IMPLIED_SHAPE:
     841            0 :             case AS_UNKNOWN:
     842            0 :               goto cleanup;
     843              : 
     844          426 :             case AS_EXPLICIT:
     845          426 :               if (current_type == AS_ASSUMED_SIZE)
     846              :                 {
     847          221 :                   as->cotype = AS_ASSUMED_SIZE;
     848          221 :                   break;
     849              :                 }
     850              : 
     851          205 :               if (current_type == AS_EXPLICIT)
     852              :                 break;
     853              : 
     854            0 :               gfc_error ("Bad array specification for an explicitly "
     855              :                          "shaped array at %C");
     856              : 
     857            0 :               goto cleanup;
     858              : 
     859            0 :             case AS_ASSUMED_SHAPE:
     860            0 :               if ((current_type == AS_ASSUMED_SHAPE)
     861            0 :                   || (current_type == AS_DEFERRED))
     862              :                 break;
     863              : 
     864            0 :               gfc_error ("Bad array specification for assumed shape "
     865              :                          "array at %C");
     866            0 :               goto cleanup;
     867              : 
     868          223 :             case AS_DEFERRED:
     869          223 :               if (current_type == AS_DEFERRED)
     870              :                 break;
     871              : 
     872            0 :               if (current_type == AS_ASSUMED_SHAPE)
     873              :                 {
     874            0 :                   as->cotype = AS_ASSUMED_SHAPE;
     875            0 :                   break;
     876              :                 }
     877              : 
     878            0 :               gfc_error ("Bad specification for deferred shape array at %C");
     879            0 :               goto cleanup;
     880              : 
     881            0 :             case AS_ASSUMED_SIZE:
     882            0 :               gfc_error ("Bad specification for assumed size array at %C");
     883            0 :               goto cleanup;
     884              : 
     885            0 :             case AS_ASSUMED_RANK:
     886            0 :               gcc_unreachable ();
     887              :           }
     888              : 
     889         2303 :       if (gfc_match_char (']') == MATCH_YES)
     890              :         break;
     891              : 
     892          651 :       if (gfc_match_char (',') != MATCH_YES)
     893              :         {
     894            0 :           gfc_error ("Expected another dimension in array declaration at %C");
     895            0 :           goto cleanup;
     896              :         }
     897              : 
     898          651 :       if (as->rank + as->corank >= GFC_MAX_DIMENSIONS)
     899              :         {
     900            2 :           gfc_error ("Array specification at %C has more than %d "
     901              :                      "dimensions", GFC_MAX_DIMENSIONS);
     902            2 :           goto cleanup;
     903              :         }
     904              :     }
     905              : 
     906         1652 :   if (current_type == AS_EXPLICIT)
     907              :     {
     908            1 :       gfc_error ("Upper bound of last coarray dimension must be %<*%> at %C");
     909            1 :       goto cleanup;
     910              :     }
     911              : 
     912         1651 :   if (as->cotype == AS_ASSUMED_SIZE)
     913          956 :     as->cotype = AS_EXPLICIT;
     914              : 
     915         1651 :   if (as->rank == 0)
     916          946 :     as->type = as->cotype;
     917              : 
     918          705 : done:
     919       303067 :   if (as->rank == 0 && as->corank == 0)
     920              :     {
     921       219571 :       *asp = NULL;
     922       219571 :       gfc_free_array_spec (as);
     923       219571 :       return MATCH_NO;
     924              :     }
     925              : 
     926              :   /* If a lower bounds of an assumed shape array is blank, put in one.  */
     927        83496 :   if (as->type == AS_ASSUMED_SHAPE)
     928              :     {
     929         1470 :       for (i = 0; i < as->rank + as->corank; i++)
     930              :         {
     931          856 :           if (as->lower[i] == NULL)
     932            1 :             as->lower[i] = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
     933              :         }
     934              :     }
     935              : 
     936        83496 :   *asp = as;
     937              : 
     938        83496 :   return MATCH_YES;
     939              : 
     940           65 : cleanup:
     941              :   /* Something went wrong.  */
     942           65 :   gfc_free_array_spec (as);
     943           65 :   return MATCH_ERROR;
     944              : }
     945              : 
     946              : /* Given a symbol and an array specification, modify the symbol to
     947              :    have that array specification.  The error locus is needed in case
     948              :    something goes wrong.  On failure, the caller must free the spec.  */
     949              : 
     950              : bool
     951       267538 : gfc_set_array_spec (gfc_symbol *sym, gfc_array_spec *as, locus *error_loc)
     952              : {
     953       267538 :   int i;
     954       267538 :   symbol_attribute *attr;
     955              : 
     956       267538 :   if (as == NULL)
     957              :     return true;
     958              : 
     959              :   /* If the symbol corresponds to a submodule module procedure the array spec is
     960              :      already set, so do not attempt to set it again here. */
     961        79627 :   attr = &sym->attr;
     962        79627 :   if (gfc_submodule_procedure(attr))
     963              :     return true;
     964              : 
     965        79626 :   if (as->rank
     966        79626 :       && !gfc_add_dimension (&sym->attr, sym->name, error_loc))
     967              :     return false;
     968              : 
     969        79620 :   if (as->corank
     970        79620 :       && !gfc_add_codimension (&sym->attr, sym->name, error_loc))
     971              :     return false;
     972              : 
     973        79615 :   if (sym->as == NULL)
     974              :     {
     975        79589 :       sym->as = as;
     976        79589 :       return true;
     977              :     }
     978              : 
     979           26 :   if ((sym->as->type == AS_ASSUMED_RANK && as->corank)
     980           24 :       || (as->type == AS_ASSUMED_RANK && sym->as->corank))
     981              :     {
     982            4 :       gfc_error ("The assumed-rank array %qs at %L shall not have a "
     983              :                  "codimension", sym->name, error_loc);
     984            4 :       return false;
     985              :     }
     986              : 
     987              :   /* Check F2018:C822.  */
     988           22 :   if (sym->as->rank + sym->as->corank > GFC_MAX_DIMENSIONS)
     989            2 :     goto too_many;
     990              : 
     991           20 :   if (as->corank)
     992              :     {
     993            7 :       sym->as->cotype = as->cotype;
     994            7 :       sym->as->corank = as->corank;
     995              :       /* Check F2018:C822.  */
     996            7 :       if (sym->as->rank + sym->as->corank > GFC_MAX_DIMENSIONS)
     997            2 :         goto too_many;
     998              : 
     999           10 :       for (i = 0; i < as->corank; i++)
    1000              :         {
    1001            5 :           sym->as->lower[sym->as->rank + i] = as->lower[i];
    1002            5 :           sym->as->upper[sym->as->rank + i] = as->upper[i];
    1003              :         }
    1004              :     }
    1005              :   else
    1006              :     {
    1007              :       /* The "sym" has no rank (checked via gfc_add_dimension). Thus
    1008              :          the dimension is added - but first the codimensions (if existing
    1009              :          need to be shifted to make space for the dimension.  */
    1010           13 :       gcc_assert (as->corank == 0 && sym->as->rank == 0);
    1011              : 
    1012           13 :       sym->as->rank = as->rank;
    1013           13 :       sym->as->type = as->type;
    1014           13 :       sym->as->cray_pointee = as->cray_pointee;
    1015           13 :       sym->as->cp_was_assumed = as->cp_was_assumed;
    1016              : 
    1017              :       /* Check F2018:C822.  */
    1018           13 :       if (sym->as->rank + sym->as->corank > GFC_MAX_DIMENSIONS)
    1019            1 :         goto too_many;
    1020              : 
    1021           60 :       for (i = sym->as->corank - 1; i >= 0; i--)
    1022              :         {
    1023           48 :           sym->as->lower[as->rank + i] = sym->as->lower[i];
    1024           48 :           sym->as->upper[as->rank + i] = sym->as->upper[i];
    1025              :         }
    1026           43 :       for (i = 0; i < as->rank; i++)
    1027              :         {
    1028           31 :           sym->as->lower[i] = as->lower[i];
    1029           31 :           sym->as->upper[i] = as->upper[i];
    1030              :         }
    1031              :     }
    1032              : 
    1033           17 :   free (as);
    1034           17 :   return true;
    1035              : 
    1036            5 : too_many:
    1037              : 
    1038            5 :   gfc_error ("rank + corank of %qs exceeds %d at %C", sym->name,
    1039              :              GFC_MAX_DIMENSIONS);
    1040            5 :   return false;
    1041              : }
    1042              : 
    1043              : 
    1044              : /* Copy an array specification.  */
    1045              : 
    1046              : gfc_array_spec *
    1047       291879 : gfc_copy_array_spec (gfc_array_spec *src)
    1048              : {
    1049       291879 :   gfc_array_spec *dest;
    1050       291879 :   int i;
    1051              : 
    1052       291879 :   if (src == NULL)
    1053              :     return NULL;
    1054              : 
    1055        46078 :   dest = gfc_get_array_spec ();
    1056              : 
    1057        46078 :   *dest = *src;
    1058              : 
    1059        91961 :   for (i = 0; i < dest->rank + dest->corank; i++)
    1060              :     {
    1061        45883 :       dest->lower[i] = gfc_copy_expr (dest->lower[i]);
    1062        45883 :       dest->upper[i] = gfc_copy_expr (dest->upper[i]);
    1063              :     }
    1064              : 
    1065              :   return dest;
    1066              : }
    1067              : 
    1068              : 
    1069              : /* Returns nonzero if the two expressions are equal.
    1070              :    We should not need to support more than constant values, as that's what is
    1071              :    allowed in derived type component array spec.  However, we may create types
    1072              :    with non-constant array spec for dummy variable class container types, for
    1073              :    which the _data component holds the array spec of the variable declaration.
    1074              :    So we have to support non-constant bounds as well.  */
    1075              : 
    1076              : static bool
    1077          390 : compare_bounds (gfc_expr *bound1, gfc_expr *bound2)
    1078              : {
    1079          390 :   if (bound1 == NULL || bound2 == NULL
    1080          376 :       || bound1->ts.type != BT_INTEGER
    1081          376 :       || bound2->ts.type != BT_INTEGER)
    1082              :     return false;
    1083              : 
    1084              :   /* What qualifies as identical bounds?  We could probably just check that the
    1085              :      expressions are exact clones.  We avoid rewriting a specific comparison
    1086              :      function and re-use instead the rather involved gfc_dep_compare_expr which
    1087              :      is just a bit more permissive, as it can also detect identical values for
    1088              :      some mismatching expressions (extra parenthesis, swapped operands, unary
    1089              :      plus, etc).  It probably only makes a difference in corner cases.  */
    1090          375 :   return gfc_dep_compare_expr (bound1, bound2) == 0;
    1091              : }
    1092              : 
    1093              : 
    1094              : /* Compares two array specifications.  They must be constant or deferred
    1095              :    shape.  */
    1096              : 
    1097              : bool
    1098          701 : gfc_compare_array_spec (gfc_array_spec *as1, gfc_array_spec *as2)
    1099              : {
    1100          701 :   int i;
    1101              : 
    1102          701 :   if (as1 == NULL && as2 == NULL)
    1103              :     return 1;
    1104              : 
    1105          701 :   if (as1 == NULL || as2 == NULL)
    1106              :     return 0;
    1107              : 
    1108          701 :   if (as1->rank != as2->rank)
    1109              :     return 0;
    1110              : 
    1111          699 :   if (as1->corank != as2->corank)
    1112              :     return 0;
    1113              : 
    1114          699 :   if (as1->rank == 0)
    1115              :     return 1;
    1116              : 
    1117          683 :   if (as1->type != as2->type)
    1118              :     return 0;
    1119              : 
    1120          321 :   if (as1->cotype != as2->cotype)
    1121              :     return 0;
    1122              : 
    1123          321 :   if (as1->type == AS_EXPLICIT)
    1124          274 :     for (i = 0; i < as1->rank + as1->corank; i++)
    1125              :       {
    1126          195 :         if (!compare_bounds (as1->lower[i], as2->lower[i]))
    1127              :           return 0;
    1128              : 
    1129          195 :         if (!compare_bounds (as1->upper[i], as2->upper[i]))
    1130              :           return 0;
    1131              :       }
    1132              : 
    1133              :   return 1;
    1134              : }
    1135              : 
    1136              : 
    1137              : /****************** Array constructor functions ******************/
    1138              : 
    1139              : 
    1140              : /* Given an expression node that might be an array constructor and a
    1141              :    symbol, make sure that no iterators in this or child constructors
    1142              :    use the symbol as an implied-DO iterator.  Returns nonzero if a
    1143              :    duplicate was found.  */
    1144              : 
    1145              : static bool
    1146         8505 : check_duplicate_iterator (gfc_constructor_base base, gfc_symbol *master)
    1147              : {
    1148         8505 :   gfc_constructor *c;
    1149         8505 :   gfc_expr *e;
    1150              : 
    1151        17317 :   for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
    1152              :     {
    1153         8812 :       e = c->expr;
    1154              : 
    1155         8812 :       if (e->expr_type == EXPR_ARRAY
    1156         8812 :           && check_duplicate_iterator (e->value.constructor, master))
    1157              :         return 1;
    1158              : 
    1159         8812 :       if (c->iterator == NULL)
    1160         8176 :         continue;
    1161              : 
    1162          636 :       if (c->iterator->var->symtree->n.sym == master)
    1163              :         {
    1164            0 :           gfc_error ("DO-iterator %qs at %L is inside iterator of the "
    1165              :                      "same name", master->name, &c->where);
    1166              : 
    1167            0 :           return 1;
    1168              :         }
    1169              :     }
    1170              : 
    1171              :   return 0;
    1172              : }
    1173              : 
    1174              : 
    1175              : /* Forward declaration because these functions are mutually recursive.  */
    1176              : static match match_array_cons_element (gfc_constructor_base *);
    1177              : 
    1178              : /* Match a list of array elements.  */
    1179              : 
    1180              : static match
    1181       450013 : match_array_list (gfc_constructor_base *result)
    1182              : {
    1183       450013 :   gfc_constructor_base head;
    1184       450013 :   gfc_constructor *p;
    1185       450013 :   gfc_iterator iter;
    1186       450013 :   locus old_loc;
    1187       450013 :   gfc_expr *e;
    1188       450013 :   match m;
    1189       450013 :   int n;
    1190              : 
    1191       450013 :   old_loc = gfc_current_locus;
    1192              : 
    1193       450013 :   if (gfc_match_char ('(') == MATCH_NO)
    1194              :     return MATCH_NO;
    1195              : 
    1196        10188 :   memset (&iter, '\0', sizeof (gfc_iterator));
    1197        10188 :   head = NULL;
    1198              : 
    1199        10188 :   m = match_array_cons_element (&head);
    1200        10188 :   if (m != MATCH_YES)
    1201          159 :     goto cleanup;
    1202              : 
    1203        10029 :   if (gfc_match_char (',') != MATCH_YES)
    1204              :     {
    1205          579 :       m = MATCH_NO;
    1206          579 :       goto cleanup;
    1207              :     }
    1208              : 
    1209           58 :   for (n = 1;; n++)
    1210              :     {
    1211         9508 :       m = gfc_match_iterator (&iter, 0);
    1212         9508 :       if (m == MATCH_YES)
    1213              :         break;
    1214         1746 :       if (m == MATCH_ERROR)
    1215            1 :         goto cleanup;
    1216              : 
    1217         1745 :       m = match_array_cons_element (&head);
    1218         1745 :       if (m == MATCH_ERROR)
    1219            0 :         goto cleanup;
    1220         1745 :       if (m == MATCH_NO)
    1221              :         {
    1222            0 :           if (n > 2)
    1223            0 :             goto syntax;
    1224            0 :           m = MATCH_NO;
    1225            0 :           goto cleanup;         /* Could be a complex constant */
    1226              :         }
    1227              : 
    1228         1745 :       if (gfc_match_char (',') != MATCH_YES)
    1229              :         {
    1230         1687 :           if (n > 2)
    1231            0 :             goto syntax;
    1232         1687 :           m = MATCH_NO;
    1233         1687 :           goto cleanup;
    1234              :         }
    1235              :     }
    1236              : 
    1237         7762 :   if (gfc_match_char (')') != MATCH_YES)
    1238            0 :     goto syntax;
    1239              : 
    1240         7762 :   if (check_duplicate_iterator (head, iter.var->symtree->n.sym))
    1241              :     {
    1242            0 :       m = MATCH_ERROR;
    1243            0 :       goto cleanup;
    1244              :     }
    1245              : 
    1246         7762 :   e = gfc_get_array_expr (BT_UNKNOWN, 0, &old_loc);
    1247         7762 :   e->value.constructor = head;
    1248              : 
    1249         7762 :   p = gfc_constructor_append_expr (result, e, &gfc_current_locus);
    1250         7762 :   p->iterator = gfc_get_iterator ();
    1251         7762 :   *p->iterator = iter;
    1252              : 
    1253         7762 :   return MATCH_YES;
    1254              : 
    1255            0 : syntax:
    1256            0 :   gfc_error ("Syntax error in array constructor at %C");
    1257            0 :   m = MATCH_ERROR;
    1258              : 
    1259         2426 : cleanup:
    1260         2426 :   gfc_constructor_free (head);
    1261         2426 :   gfc_free_iterator (&iter, 0);
    1262         2426 :   gfc_current_locus = old_loc;
    1263         2426 :   return m;
    1264              : }
    1265              : 
    1266              : 
    1267              : /* Match a single element of an array constructor, which can be a
    1268              :    single expression or a list of elements.  */
    1269              : 
    1270              : static match
    1271       450013 : match_array_cons_element (gfc_constructor_base *result)
    1272              : {
    1273       450013 :   gfc_expr *expr;
    1274       450013 :   match m;
    1275              : 
    1276       450013 :   m = match_array_list (result);
    1277       450013 :   if (m != MATCH_NO)
    1278              :     return m;
    1279              : 
    1280       442249 :   m = gfc_match_expr (&expr);
    1281       442249 :   if (m != MATCH_YES)
    1282              :     return m;
    1283              : 
    1284       442081 :   if (expr->ts.type == BT_BOZ)
    1285              :     {
    1286            4 :       gfc_error ("BOZ literal constant at %L cannot appear in an "
    1287              :                  "array constructor", &expr->where);
    1288            4 :       goto done;
    1289              :     }
    1290              : 
    1291       442077 :   if (expr->expr_type == EXPR_FUNCTION
    1292        13730 :       && expr->ts.type == BT_UNKNOWN
    1293        13730 :       && strcmp(expr->symtree->name, "null") == 0)
    1294              :     {
    1295            3 :       gfc_error ("NULL() at %C cannot appear in an array constructor");
    1296            3 :       goto done;
    1297              :     }
    1298              : 
    1299       442074 :   gfc_constructor_append_expr (result, expr, &gfc_current_locus);
    1300       442074 :   return MATCH_YES;
    1301              : 
    1302            7 : done:
    1303            7 :   gfc_free_expr (expr);
    1304            7 :   return MATCH_ERROR;
    1305              : }
    1306              : 
    1307              : 
    1308              : /* Convert components of an array constructor to the type in ts.  */
    1309              : 
    1310              : static match
    1311         3672 : walk_array_constructor (gfc_typespec *ts, gfc_constructor_base head)
    1312              : {
    1313         3672 :   gfc_constructor *c;
    1314         3672 :   gfc_expr *e;
    1315         3672 :   match m;
    1316              : 
    1317         8020 :   for (c = gfc_constructor_first (head); c; c = gfc_constructor_next (c))
    1318              :     {
    1319         4356 :       e = c->expr;
    1320         4356 :       if (e->expr_type == EXPR_ARRAY && e->ts.type == BT_UNKNOWN
    1321          126 :           && !e->ref && e->value.constructor)
    1322              :         {
    1323          126 :           m = walk_array_constructor (ts, e->value.constructor);
    1324          126 :           if (m == MATCH_ERROR)
    1325              :             return m;
    1326              :         }
    1327         4230 :       else if (!gfc_convert_type_warn (e, ts, 1, 1, true)
    1328         4230 :                && e->ts.type != BT_UNKNOWN)
    1329              :         return MATCH_ERROR;
    1330              :     }
    1331              :   return MATCH_YES;
    1332              : }
    1333              : 
    1334              : /* Match an array constructor.  */
    1335              : 
    1336              : match
    1337      4334352 : gfc_match_array_constructor (gfc_expr **result)
    1338              : {
    1339      4334352 :   gfc_constructor *c;
    1340      4334352 :   gfc_constructor_base head;
    1341      4334352 :   gfc_expr *expr;
    1342      4334352 :   gfc_typespec ts;
    1343      4334352 :   locus where;
    1344      4334352 :   match m;
    1345      4334352 :   const char *end_delim;
    1346      4334352 :   bool seen_ts;
    1347      4334352 :   gfc_namespace *old_ns = gfc_current_ns;
    1348              : 
    1349      4334352 :   head = NULL;
    1350      4334352 :   seen_ts = false;
    1351              : 
    1352      4334352 :   if (gfc_match (" (/") == MATCH_NO)
    1353              :     {
    1354      4272108 :       if (gfc_match (" [") == MATCH_NO)
    1355              :         return MATCH_NO;
    1356              :       else
    1357              :         {
    1358        69297 :           if (!gfc_notify_std (GFC_STD_F2003, "[...] "
    1359              :                                "style array constructors at %C"))
    1360              :             return MATCH_ERROR;
    1361              :           end_delim = " ]";
    1362              :         }
    1363              :     }
    1364              :   else
    1365              :     end_delim = " /)";
    1366              : 
    1367       131541 :   where = gfc_current_locus;
    1368              : 
    1369              :   /* Try to match an optional "type-spec ::"  */
    1370       131541 :   gfc_clear_ts (&ts);
    1371       131541 :   m = gfc_match_type_spec (&ts);
    1372       131541 :   gfc_current_ns = old_ns;
    1373              : 
    1374       131541 :   if (m == MATCH_YES)
    1375              :     {
    1376         7115 :       seen_ts = (gfc_match (" ::") == MATCH_YES);
    1377              : 
    1378         7115 :       if (seen_ts)
    1379              :         {
    1380         5800 :           if (!gfc_notify_std (GFC_STD_F2003, "Array constructor "
    1381              :                                "including type specification at %C"))
    1382            1 :             goto cleanup;
    1383              : 
    1384         5799 :           if (ts.deferred)
    1385              :             {
    1386            1 :               gfc_error ("Type-spec at %L cannot contain a deferred "
    1387              :                          "type parameter", &where);
    1388            1 :               goto cleanup;
    1389              :             }
    1390              : 
    1391         5798 :           if (ts.type == BT_CHARACTER
    1392         1652 :               && ts.u.cl && !ts.u.cl->length && !ts.u.cl->length_from_typespec)
    1393              :             {
    1394            1 :               gfc_error ("Type-spec at %L cannot contain an asterisk for a "
    1395              :                          "type parameter", &where);
    1396            1 :               goto cleanup;
    1397              :             }
    1398              :         }
    1399              :     }
    1400       124426 :   else if (m == MATCH_ERROR)
    1401           21 :     goto cleanup;
    1402              : 
    1403         7112 :   if (!seen_ts)
    1404       125720 :     gfc_current_locus = where;
    1405              : 
    1406       131517 :   if (gfc_match (end_delim) == MATCH_YES)
    1407              :     {
    1408         1980 :       if (seen_ts)
    1409         1979 :         goto done;
    1410              :       else
    1411              :         {
    1412            1 :           gfc_error ("Empty array constructor at %C is not allowed");
    1413            1 :           goto cleanup;
    1414              :         }
    1415              :     }
    1416              : 
    1417       438080 :   for (;;)
    1418              :     {
    1419       438080 :       m = match_array_cons_element (&head);
    1420       438080 :       if (m == MATCH_ERROR)
    1421           17 :         goto cleanup;
    1422       438063 :       if (m == MATCH_NO)
    1423            1 :         goto syntax;
    1424              : 
    1425       438062 :       if (gfc_match_char (',') == MATCH_NO)
    1426              :         break;
    1427              :     }
    1428              : 
    1429       129519 :   if (gfc_match (end_delim) == MATCH_NO)
    1430            6 :     goto syntax;
    1431              : 
    1432       131492 : done:
    1433              :   /* Size must be calculated at resolution time.  */
    1434       131492 :   if (seen_ts)
    1435              :     {
    1436         5792 :       expr = gfc_get_array_expr (ts.type, ts.kind, &where);
    1437         5792 :       expr->ts = ts;
    1438              : 
    1439              :       /* If the typespec is CHARACTER, check that array elements can
    1440              :          be converted.  See PR fortran/67803.  */
    1441         5792 :       if (ts.type == BT_CHARACTER)
    1442              :         {
    1443         1651 :           c = gfc_constructor_first (head);
    1444         5412 :           for (; c; c = gfc_constructor_next (c))
    1445              :             {
    1446         2115 :               if (gfc_numeric_ts (&c->expr->ts)
    1447         2115 :                   || c->expr->ts.type == BT_LOGICAL)
    1448              :                 {
    1449            5 :                   gfc_error ("Incompatible typespec for array element at %L",
    1450            5 :                              &c->expr->where);
    1451            5 :                   return MATCH_ERROR;
    1452              :                 }
    1453              : 
    1454              :               /* Special case null().  */
    1455         2110 :               if (c->expr->expr_type == EXPR_FUNCTION
    1456           54 :                   && c->expr->ts.type == BT_UNKNOWN
    1457           54 :                   && strcmp (c->expr->symtree->name, "null") == 0)
    1458              :                 {
    1459            0 :                   gfc_error ("Incompatible typespec for array element at %L",
    1460              :                              &c->expr->where);
    1461            0 :                   return MATCH_ERROR;
    1462              :                 }
    1463              :             }
    1464              :         }
    1465              : 
    1466              :       /* Walk the constructor, and if possible, do type conversion for
    1467              :          numeric types.  */
    1468         5787 :       if (gfc_numeric_ts (&ts))
    1469              :         {
    1470         3546 :           m = walk_array_constructor (&ts, head);
    1471         3546 :           if (m == MATCH_ERROR)
    1472              :             return m;
    1473              :         }
    1474              :     }
    1475              :   else
    1476       125700 :     expr = gfc_get_array_expr (BT_UNKNOWN, 0, &where);
    1477              : 
    1478       131480 :   expr->value.constructor = head;
    1479       131480 :   if (expr->ts.type == BT_CHARACTER && expr->ts.u.cl)
    1480         1646 :     expr->ts.u.cl->length_from_typespec = seen_ts;
    1481              : 
    1482       131480 :   *result = expr;
    1483              : 
    1484       131480 :   return MATCH_YES;
    1485              : 
    1486            7 : syntax:
    1487            7 :   gfc_error ("Syntax error in array constructor at %C");
    1488              : 
    1489           49 : cleanup:
    1490           49 :   gfc_constructor_free (head);
    1491           49 :   return MATCH_ERROR;
    1492              : }
    1493              : 
    1494              : 
    1495              : 
    1496              : /************** Check array constructors for correctness **************/
    1497              : 
    1498              : /* Given an expression, compare it's type with the type of the current
    1499              :    constructor.  Returns nonzero if an error was issued.  The
    1500              :    cons_state variable keeps track of whether the type of the
    1501              :    constructor being read or resolved is known to be good, bad or just
    1502              :    starting out.  */
    1503              : 
    1504              : static gfc_typespec constructor_ts;
    1505              : static enum
    1506              : { CONS_START, CONS_GOOD, CONS_BAD }
    1507              : cons_state;
    1508              : 
    1509              : static int
    1510      1042985 : check_element_type (gfc_expr *expr, bool convert)
    1511              : {
    1512      1042985 :   if (cons_state == CONS_BAD)
    1513              :     return 0;                   /* Suppress further errors */
    1514              : 
    1515      1042985 :   if (cons_state == CONS_START)
    1516              :     {
    1517        55769 :       if (expr->ts.type == BT_UNKNOWN)
    1518            0 :         cons_state = CONS_BAD;
    1519              :       else
    1520              :         {
    1521        55769 :           cons_state = CONS_GOOD;
    1522        55769 :           constructor_ts = expr->ts;
    1523              :         }
    1524              : 
    1525        55769 :       return 0;
    1526              :     }
    1527              : 
    1528       987216 :   if (gfc_compare_types (&constructor_ts, &expr->ts))
    1529              :     return 0;
    1530              : 
    1531          348 :   if (convert)
    1532          348 :     return gfc_convert_type_warn (expr, &constructor_ts, 1, 1, true) ? 0 : 1;
    1533              : 
    1534            0 :   gfc_error ("Element in %s array constructor at %L is %s",
    1535              :              gfc_typename (&constructor_ts), &expr->where,
    1536              :              gfc_typename (expr));
    1537              : 
    1538            0 :   cons_state = CONS_BAD;
    1539            0 :   return 1;
    1540              : }
    1541              : 
    1542              : 
    1543              : /* Recursive work function for gfc_check_constructor_type().  */
    1544              : 
    1545              : static bool
    1546        94034 : check_constructor_type (gfc_constructor_base base, bool convert)
    1547              : {
    1548        94034 :   gfc_constructor *c;
    1549        94034 :   gfc_expr *e;
    1550              : 
    1551      1144826 :   for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
    1552              :     {
    1553      1050938 :       e = c->expr;
    1554              : 
    1555              :       /* Simplify non-constant expressions (like parenthesized arrays) so type
    1556              :          conversion can work on the simplified result.  This handles cases like
    1557              :          [integer :: ([1.0])] where ([1.0]) is an EXPR_OP that needs to be
    1558              :          simplified to an EXPR_ARRAY before type conversion.  */
    1559      1050938 :       if (convert && e->expr_type != EXPR_CONSTANT
    1560        11321 :           && e->expr_type != EXPR_ARRAY)
    1561        10110 :         gfc_simplify_expr (e, 0);
    1562              : 
    1563      1050938 :       if (e->expr_type == EXPR_ARRAY)
    1564              :         {
    1565              :           /* If the outer constructor has no type-spec (convert=false) and
    1566              :              the nested array has an explicit type-spec, process it separately
    1567              :              so its elements get converted according to its type-spec.  This
    1568              :              handles cases like [[character(16) :: ['a','b']]] where the outer
    1569              :              constructor has no type-spec but the inner one does.
    1570              :              gfc_check_constructor_type will also update the global
    1571              :              constructor_ts and cons_state which propagates the type info
    1572              :              to the outer constructor.
    1573              :              For character types, length_from_typespec indicates an explicit
    1574              :              type-spec was provided.  */
    1575         7953 :           if (!convert && e->ts.type == BT_CHARACTER
    1576          445 :               && e->ts.u.cl && e->ts.u.cl->length_from_typespec)
    1577              :             {
    1578          102 :               if (!gfc_check_constructor_type (e))
    1579              :                 return false;
    1580              :             }
    1581              :           else
    1582              :             {
    1583         7851 :               if (!check_constructor_type (e->value.constructor, convert))
    1584              :                 return false;
    1585              :             }
    1586              : 
    1587         7896 :           continue;
    1588              :         }
    1589              : 
    1590      1042985 :       if (check_element_type (e, convert))
    1591              :         return false;
    1592              :     }
    1593              : 
    1594              :   return true;
    1595              : }
    1596              : 
    1597              : 
    1598              : /* Check that all elements of an array constructor are the same type.
    1599              :    On false, an error has been generated.  */
    1600              : 
    1601              : bool
    1602        86183 : gfc_check_constructor_type (gfc_expr *e)
    1603              : {
    1604        86183 :   bool t;
    1605              : 
    1606        86183 :   if (e->ts.type != BT_UNKNOWN)
    1607              :     {
    1608        30303 :       cons_state = CONS_GOOD;
    1609        30303 :       constructor_ts = e->ts;
    1610              :     }
    1611              :   else
    1612              :     {
    1613        55880 :       cons_state = CONS_START;
    1614        55880 :       gfc_clear_ts (&constructor_ts);
    1615              :     }
    1616              : 
    1617              :   /* If e->ts.type != BT_UNKNOWN, the array constructor included a
    1618              :      typespec, and we will now convert the values on the fly.  */
    1619        86183 :   t = check_constructor_type (e->value.constructor, e->ts.type != BT_UNKNOWN);
    1620        86183 :   if (t && e->ts.type == BT_UNKNOWN)
    1621        55880 :     e->ts = constructor_ts;
    1622              : 
    1623        86183 :   return t;
    1624              : }
    1625              : 
    1626              : 
    1627              : 
    1628              : typedef struct cons_stack
    1629              : {
    1630              :   gfc_iterator *iterator;
    1631              :   struct cons_stack *previous;
    1632              : }
    1633              : cons_stack;
    1634              : 
    1635              : static cons_stack *base;
    1636              : 
    1637              : static bool check_constructor (gfc_constructor_base, bool (*) (gfc_expr *));
    1638              : 
    1639              : /* Check an EXPR_VARIABLE expression in a constructor to make sure
    1640              :    that that variable is an iteration variable.  */
    1641              : 
    1642              : bool
    1643         7292 : gfc_check_iter_variable (gfc_expr *expr)
    1644              : {
    1645         7292 :   gfc_symbol *sym;
    1646         7292 :   cons_stack *c;
    1647              : 
    1648         7292 :   sym = expr->symtree->n.sym;
    1649              : 
    1650         7302 :   for (c = base; c && c->iterator; c = c->previous)
    1651           26 :     if (sym == c->iterator->var->symtree->n.sym)
    1652              :       return true;
    1653              : 
    1654              :   return false;
    1655              : }
    1656              : 
    1657              : 
    1658              : /* Recursive work function for gfc_check_constructor().  This amounts
    1659              :    to calling the check function for each expression in the
    1660              :    constructor, giving variables with the names of iterators a pass.  */
    1661              : 
    1662              : static bool
    1663         7209 : check_constructor (gfc_constructor_base ctor, bool (*check_function) (gfc_expr *))
    1664              : {
    1665         7209 :   cons_stack element;
    1666         7209 :   gfc_expr *e;
    1667         7209 :   bool t;
    1668         7209 :   gfc_constructor *c;
    1669              : 
    1670       355265 :   for (c = gfc_constructor_first (ctor); c; c = gfc_constructor_next (c))
    1671              :     {
    1672       348082 :       e = c->expr;
    1673              : 
    1674       348082 :       if (!e)
    1675            0 :         continue;
    1676              : 
    1677              :       /* Allow procedures as potential target of a procedure pointer.  */
    1678       348082 :       if (e->expr_type == EXPR_VARIABLE
    1679          214 :           && e->ts.type == BT_PROCEDURE
    1680           91 :           && e->symtree->n.sym->attr.flavor == FL_PROCEDURE)
    1681           91 :         continue;
    1682              : 
    1683       347991 :       if (e->expr_type != EXPR_ARRAY)
    1684              :         {
    1685       347745 :           if (!(*check_function)(e))
    1686              :             return false;
    1687       347725 :           continue;
    1688              :         }
    1689              : 
    1690          246 :       element.previous = base;
    1691          246 :       element.iterator = c->iterator;
    1692              : 
    1693          246 :       base = &element;
    1694          246 :       t = check_constructor (e->value.constructor, check_function);
    1695          246 :       base = element.previous;
    1696              : 
    1697          246 :       if (!t)
    1698              :         return false;
    1699              :     }
    1700              : 
    1701              :   /* Nothing went wrong, so all OK.  */
    1702              :   return true;
    1703              : }
    1704              : 
    1705              : 
    1706              : /* Checks a constructor to see if it is a particular kind of
    1707              :    expression -- specification, restricted, or initialization as
    1708              :    determined by the check_function.  */
    1709              : 
    1710              : bool
    1711         6963 : gfc_check_constructor (gfc_expr *expr, bool (*check_function) (gfc_expr *))
    1712              : {
    1713         6963 :   cons_stack *base_save;
    1714         6963 :   bool t;
    1715              : 
    1716         6963 :   base_save = base;
    1717         6963 :   base = NULL;
    1718              : 
    1719         6963 :   t = check_constructor (expr->value.constructor, check_function);
    1720         6963 :   base = base_save;
    1721              : 
    1722         6963 :   return t;
    1723              : }
    1724              : 
    1725              : 
    1726              : 
    1727              : /**************** Simplification of array constructors ****************/
    1728              : 
    1729              : iterator_stack *iter_stack;
    1730              : 
    1731              : typedef struct
    1732              : {
    1733              :   gfc_constructor_base base;
    1734              :   int extract_count, extract_n;
    1735              :   gfc_expr *extracted;
    1736              :   mpz_t *count;
    1737              : 
    1738              :   mpz_t *offset;
    1739              :   gfc_component *component;
    1740              :   mpz_t *repeat;
    1741              : 
    1742              :   bool (*expand_work_function) (gfc_expr *);
    1743              : }
    1744              : expand_info;
    1745              : 
    1746              : static expand_info current_expand;
    1747              : 
    1748              : static bool expand_constructor (gfc_constructor_base);
    1749              : 
    1750              : 
    1751              : /* Work function that counts the number of elements present in a
    1752              :    constructor.  */
    1753              : 
    1754              : static bool
    1755      4356775 : count_elements (gfc_expr *e)
    1756              : {
    1757      4356775 :   mpz_t result;
    1758              : 
    1759      4356775 :   if (e->rank == 0)
    1760      4355144 :     mpz_add_ui (*current_expand.count, *current_expand.count, 1);
    1761              :   else
    1762              :     {
    1763         1631 :       if (!gfc_array_size (e, &result))
    1764              :         {
    1765          509 :           gfc_free_expr (e);
    1766          509 :           return false;
    1767              :         }
    1768              : 
    1769         1122 :       mpz_add (*current_expand.count, *current_expand.count, result);
    1770         1122 :       mpz_clear (result);
    1771              :     }
    1772              : 
    1773      4356266 :   gfc_free_expr (e);
    1774      4356266 :   return true;
    1775              : }
    1776              : 
    1777              : 
    1778              : /* Work function that extracts a particular element from an array
    1779              :    constructor, freeing the rest.  */
    1780              : 
    1781              : static bool
    1782      4954031 : extract_element (gfc_expr *e)
    1783              : {
    1784      4954031 :   if (e->rank != 0)
    1785              :     {                           /* Something unextractable */
    1786         1176 :       gfc_free_expr (e);
    1787         1176 :       return false;
    1788              :     }
    1789              : 
    1790      4952855 :   if (current_expand.extract_count == current_expand.extract_n)
    1791           37 :     current_expand.extracted = e;
    1792              :   else
    1793      4952818 :     gfc_free_expr (e);
    1794              : 
    1795      4952855 :   current_expand.extract_count++;
    1796              : 
    1797      4952855 :   return true;
    1798              : }
    1799              : 
    1800              : 
    1801              : /* Work function that constructs a new constructor out of the old one,
    1802              :    stringing new elements together.  */
    1803              : 
    1804              : static bool
    1805      1299254 : expand (gfc_expr *e)
    1806              : {
    1807      1299254 :   gfc_constructor *c = gfc_constructor_append_expr (&current_expand.base,
    1808              :                                                     e, &e->where);
    1809              : 
    1810      1299254 :   c->n.component = current_expand.component;
    1811      1299254 :   return true;
    1812              : }
    1813              : 
    1814              : 
    1815              : /* Given an initialization expression that is a variable reference,
    1816              :    substitute the current value of the iteration variable.  */
    1817              : 
    1818              : void
    1819     13975528 : gfc_simplify_iterator_var (gfc_expr *e)
    1820              : {
    1821     13975528 :   iterator_stack *p;
    1822              : 
    1823     19238209 :   for (p = iter_stack; p; p = p->prev)
    1824     19118079 :     if (e->symtree == p->variable)
    1825              :       break;
    1826              : 
    1827     13975528 :   if (p == NULL)
    1828              :     return;             /* Variable not found */
    1829              : 
    1830     13855398 :   gfc_replace_expr (e, gfc_get_int_expr (gfc_default_integer_kind, NULL, 0));
    1831              : 
    1832     13855398 :   mpz_set (e->value.integer, p->value);
    1833              : 
    1834     13855398 :   return;
    1835              : }
    1836              : 
    1837              : 
    1838              : /* Expand an expression with that is inside of a constructor,
    1839              :    recursing into other constructors if present.  */
    1840              : 
    1841              : static bool
    1842     11262597 : expand_expr (gfc_expr *e)
    1843              : {
    1844     11262597 :   if (e->expr_type == EXPR_ARRAY)
    1845     11262597 :     return expand_constructor (e->value.constructor);
    1846              : 
    1847            0 :   e = gfc_copy_expr (e);
    1848              : 
    1849            0 :   if (!gfc_simplify_expr (e, 1))
    1850              :     {
    1851            0 :       gfc_free_expr (e);
    1852            0 :       return false;
    1853              :     }
    1854              : 
    1855            0 :   return current_expand.expand_work_function (e);
    1856              : }
    1857              : 
    1858              : 
    1859              : static bool
    1860        28100 : expand_iterator (gfc_constructor *c)
    1861              : {
    1862        28100 :   gfc_expr *start, *end, *step;
    1863        28100 :   iterator_stack frame;
    1864        28100 :   mpz_t trip;
    1865        28100 :   bool t;
    1866              : 
    1867        28100 :   end = step = NULL;
    1868              : 
    1869        28100 :   t = false;
    1870              : 
    1871        28100 :   mpz_init (trip);
    1872        28100 :   mpz_init (frame.value);
    1873        28100 :   frame.prev = NULL;
    1874              : 
    1875        28100 :   start = gfc_copy_expr (c->iterator->start);
    1876        28100 :   if (!gfc_simplify_expr (start, 1))
    1877            0 :     goto cleanup;
    1878              : 
    1879        28100 :   if (start->expr_type != EXPR_CONSTANT || start->ts.type != BT_INTEGER)
    1880          936 :     goto cleanup;
    1881              : 
    1882        27164 :   end = gfc_copy_expr (c->iterator->end);
    1883        27164 :   if (!gfc_simplify_expr (end, 1))
    1884            0 :     goto cleanup;
    1885              : 
    1886        27164 :   if (end->expr_type != EXPR_CONSTANT || end->ts.type != BT_INTEGER)
    1887         3007 :     goto cleanup;
    1888              : 
    1889        24157 :   step = gfc_copy_expr (c->iterator->step);
    1890        24157 :   if (!gfc_simplify_expr (step, 1))
    1891            0 :     goto cleanup;
    1892              : 
    1893        24157 :   if (step->expr_type != EXPR_CONSTANT || step->ts.type != BT_INTEGER)
    1894            0 :     goto cleanup;
    1895              : 
    1896        24157 :   if (mpz_sgn (step->value.integer) == 0)
    1897              :     {
    1898            0 :       gfc_error ("Iterator step at %L cannot be zero", &step->where);
    1899            0 :       goto cleanup;
    1900              :     }
    1901              : 
    1902              :   /* Calculate the trip count of the loop.  */
    1903        24157 :   mpz_sub (trip, end->value.integer, start->value.integer);
    1904        24157 :   mpz_add (trip, trip, step->value.integer);
    1905        24157 :   mpz_tdiv_q (trip, trip, step->value.integer);
    1906              : 
    1907        24157 :   mpz_set (frame.value, start->value.integer);
    1908              : 
    1909        24157 :   frame.prev = iter_stack;
    1910        24157 :   frame.variable = c->iterator->var->symtree;
    1911        24157 :   iter_stack = &frame;
    1912              : 
    1913     11285572 :   while (mpz_sgn (trip) > 0)
    1914              :     {
    1915     11262597 :       if (!expand_expr (c->expr))
    1916         1182 :         goto cleanup;
    1917              : 
    1918     11261415 :       mpz_add (frame.value, frame.value, step->value.integer);
    1919     11261415 :       mpz_sub_ui (trip, trip, 1);
    1920              :     }
    1921              : 
    1922              :   t = true;
    1923              : 
    1924        28100 : cleanup:
    1925        28100 :   gfc_free_expr (start);
    1926        28100 :   gfc_free_expr (end);
    1927        28100 :   gfc_free_expr (step);
    1928              : 
    1929        28100 :   mpz_clear (trip);
    1930        28100 :   mpz_clear (frame.value);
    1931              : 
    1932        28100 :   iter_stack = frame.prev;
    1933              : 
    1934        28100 :   return t;
    1935              : }
    1936              : 
    1937              : /* Variables for noticing if all constructors are empty, and
    1938              :    if any of them had a type.  */
    1939              : 
    1940              : static bool empty_constructor;
    1941              : static gfc_typespec empty_ts;
    1942              : 
    1943              : /* Expand a constructor into constant constructors without any
    1944              :    iterators, calling the work function for each of the expanded
    1945              :    expressions.  The work function needs to either save or free the
    1946              :    passed expression.  */
    1947              : 
    1948              : static bool
    1949     11560437 : expand_constructor (gfc_constructor_base base)
    1950              : {
    1951     11560437 :   gfc_constructor *c;
    1952     11560437 :   gfc_expr *e;
    1953              : 
    1954     29282006 :   for (c = gfc_constructor_first (base); c; c = gfc_constructor_next(c))
    1955              :     {
    1956     17729562 :       if (c->iterator != NULL)
    1957              :         {
    1958        28100 :           if (!expand_iterator (c))
    1959              :             return false;
    1960        22975 :           continue;
    1961              :         }
    1962              : 
    1963     17701462 :       e = c->expr;
    1964              : 
    1965     17701462 :       if (e == NULL)
    1966              :         return false;
    1967              : 
    1968     17701462 :       if (empty_constructor)
    1969        95087 :         empty_ts = e->ts;
    1970              : 
    1971              :       /* Simplify constant array expression/section within constructor.  */
    1972     17701462 :       if (e->expr_type == EXPR_VARIABLE && e->rank > 0 && e->ref
    1973         4240 :           && e->symtree && e->symtree->n.sym
    1974         4240 :           && e->symtree->n.sym->attr.flavor == FL_PARAMETER)
    1975          577 :         gfc_simplify_expr (e, 0);
    1976              : 
    1977     17701462 :       if (e->expr_type == EXPR_ARRAY)
    1978              :         {
    1979        10717 :           if (!expand_constructor (e->value.constructor))
    1980              :             return false;
    1981              : 
    1982        10686 :           continue;
    1983              :         }
    1984              : 
    1985     17690745 :       empty_constructor = false;
    1986     17690745 :       e = gfc_copy_expr (e);
    1987     17690745 :       if (!gfc_simplify_expr (e, 1))
    1988              :         {
    1989          200 :           gfc_free_expr (e);
    1990          200 :           return false;
    1991              :         }
    1992     17690545 :       e->from_constructor = 1;
    1993     17690545 :       current_expand.offset = &c->offset;
    1994     17690545 :       current_expand.repeat = &c->repeat;
    1995     17690545 :       current_expand.component = c->n.component;
    1996     17690545 :       if (!current_expand.expand_work_function(e))
    1997              :         return false;
    1998              :     }
    1999              :   return true;
    2000              : }
    2001              : 
    2002              : 
    2003              : /* Given an array expression and an element number (starting at zero),
    2004              :    return a pointer to the array element.  NULL is returned if the
    2005              :    size of the array has been exceeded.  The expression node returned
    2006              :    remains a part of the array and should not be freed.  Access is not
    2007              :    efficient at all, but this is another place where things do not
    2008              :    have to be particularly fast.  */
    2009              : 
    2010              : static gfc_expr *
    2011        92886 : gfc_get_array_element (gfc_expr *array, int element)
    2012              : {
    2013        92886 :   expand_info expand_save;
    2014        92886 :   gfc_expr *e;
    2015        92886 :   bool rc;
    2016              : 
    2017        92886 :   expand_save = current_expand;
    2018        92886 :   current_expand.extract_n = element;
    2019        92886 :   current_expand.expand_work_function = extract_element;
    2020        92886 :   current_expand.extracted = NULL;
    2021        92886 :   current_expand.extract_count = 0;
    2022              : 
    2023        92886 :   iter_stack = NULL;
    2024              : 
    2025        92886 :   rc = expand_constructor (array->value.constructor);
    2026        92886 :   e = current_expand.extracted;
    2027        92886 :   current_expand = expand_save;
    2028              : 
    2029        92886 :   if (!rc)
    2030         1688 :     return NULL;
    2031              : 
    2032              :   return e;
    2033              : }
    2034              : 
    2035              : 
    2036              : /* Top level subroutine for expanding constructors.  We only expand
    2037              :    constructor if they are small enough.  */
    2038              : 
    2039              : bool
    2040        95250 : gfc_expand_constructor (gfc_expr *e, bool fatal)
    2041              : {
    2042        95250 :   expand_info expand_save;
    2043        95250 :   gfc_expr *f;
    2044        95250 :   bool rc;
    2045              : 
    2046        95250 :   if (gfc_is_size_zero_array (e))
    2047              :     return true;
    2048              : 
    2049              :   /* If we can successfully get an array element at the max array size then
    2050              :      the array is too big to expand, so we just return.  */
    2051        92886 :   f = gfc_get_array_element (e, flag_max_array_constructor);
    2052        92886 :   if (f != NULL)
    2053              :     {
    2054           37 :       gfc_free_expr (f);
    2055           37 :       if (fatal)
    2056              :         {
    2057            8 :           gfc_error ("The number of elements in the array constructor "
    2058              :                      "at %L requires an increase of the allowed %d "
    2059              :                      "upper limit.   See %<-fmax-array-constructor%> "
    2060              :                      "option", &e->where, flag_max_array_constructor);
    2061            8 :           return false;
    2062              :         }
    2063              :       return true;
    2064              :     }
    2065              : 
    2066              :   /* We now know the array is not too big so go ahead and try to expand it.  */
    2067        92849 :   expand_save = current_expand;
    2068        92849 :   current_expand.base = NULL;
    2069              : 
    2070        92849 :   iter_stack = NULL;
    2071              : 
    2072        92849 :   empty_constructor = true;
    2073        92849 :   gfc_clear_ts (&empty_ts);
    2074        92849 :   current_expand.expand_work_function = expand;
    2075              : 
    2076        92849 :   if (!expand_constructor (e->value.constructor))
    2077              :     {
    2078          512 :       gfc_constructor_free (current_expand.base);
    2079          512 :       rc = false;
    2080          512 :       goto done;
    2081              :     }
    2082              : 
    2083              :   /* If we don't have an explicit constructor type, and there
    2084              :      were only empty constructors, then take the type from
    2085              :      them.  */
    2086              : 
    2087        92337 :   if (constructor_ts.type == BT_UNKNOWN && empty_constructor)
    2088            8 :     e->ts = empty_ts;
    2089              : 
    2090        92337 :   gfc_constructor_free (e->value.constructor);
    2091        92337 :   e->value.constructor = current_expand.base;
    2092              : 
    2093        92337 :   rc = true;
    2094              : 
    2095        92849 : done:
    2096        92849 :   current_expand = expand_save;
    2097              : 
    2098        92849 :   return rc;
    2099              : }
    2100              : 
    2101              : 
    2102              : /* Work function for checking that an element of a constructor is a
    2103              :    constant, after removal of any iteration variables.  We return
    2104              :    false if not so.  */
    2105              : 
    2106              : static bool
    2107      7080485 : is_constant_element (gfc_expr *e)
    2108              : {
    2109      7080485 :   int rv;
    2110              : 
    2111      7080485 :   rv = gfc_is_constant_expr (e);
    2112      7080485 :   gfc_free_expr (e);
    2113              : 
    2114      7080485 :   return rv ? true : false;
    2115              : }
    2116              : 
    2117              : 
    2118              : /* Given an array constructor, determine if the constructor is
    2119              :    constant or not by expanding it and making sure that all elements
    2120              :    are constants.  This is a bit of a hack since something like (/ (i,
    2121              :    i=1,100000000) /) will take a while as* opposed to a more clever
    2122              :    function that traverses the expression tree. FIXME.  */
    2123              : 
    2124              : bool
    2125         5592 : gfc_constant_ac (gfc_expr *e)
    2126              : {
    2127         5592 :   expand_info expand_save;
    2128         5592 :   bool rc;
    2129              : 
    2130         5592 :   iter_stack = NULL;
    2131         5592 :   expand_save = current_expand;
    2132         5592 :   current_expand.expand_work_function = is_constant_element;
    2133              : 
    2134         5592 :   rc = expand_constructor (e->value.constructor);
    2135              : 
    2136         5592 :   current_expand = expand_save;
    2137         5592 :   if (!rc)
    2138              :     return 0;
    2139              : 
    2140              :   return 1;
    2141              : }
    2142              : 
    2143              : 
    2144              : /* Returns nonzero if an array constructor has been completely
    2145              :    expanded (no iterators) and zero if iterators are present.  */
    2146              : 
    2147              : bool
    2148        27095 : gfc_expanded_ac (gfc_expr *e)
    2149              : {
    2150        27095 :   gfc_constructor *c;
    2151              : 
    2152        27095 :   if (e->expr_type == EXPR_ARRAY)
    2153         5782 :     for (c = gfc_constructor_first (e->value.constructor);
    2154        27547 :          c; c = gfc_constructor_next (c))
    2155        21765 :       if (c->iterator != NULL || !gfc_expanded_ac (c->expr))
    2156            0 :         return 0;
    2157              : 
    2158              :   return 1;
    2159              : }
    2160              : 
    2161              : 
    2162              : /*************** Type resolution of array constructors ***************/
    2163              : 
    2164              : 
    2165              : /* The symbol expr_is_sought_symbol_ref will try to find.  */
    2166              : static const gfc_symbol *sought_symbol = NULL;
    2167              : 
    2168              : 
    2169              : /* Tells whether the expression E is a variable reference to the symbol
    2170              :    in the static variable SOUGHT_SYMBOL, and sets the locus pointer WHERE
    2171              :    accordingly.
    2172              :    To be used with gfc_expr_walker: if a reference is found we don't need
    2173              :    to look further so we return 1 to skip any further walk.  */
    2174              : 
    2175              : static int
    2176        15177 : expr_is_sought_symbol_ref (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
    2177              :                            void *where)
    2178              : {
    2179        15177 :   gfc_expr *expr = *e;
    2180        15177 :   locus *sym_loc = (locus *)where;
    2181              : 
    2182        15177 :   if (expr->expr_type == EXPR_VARIABLE
    2183         1329 :       && expr->symtree->n.sym == sought_symbol)
    2184              :     {
    2185            9 :       *sym_loc = expr->where;
    2186            9 :       return 1;
    2187              :     }
    2188              : 
    2189              :   return 0;
    2190              : }
    2191              : 
    2192              : 
    2193              : /* Tells whether the expression EXPR contains a reference to the symbol
    2194              :    SYM and in that case sets the position SYM_LOC where the reference is.  */
    2195              : 
    2196              : static bool
    2197        14586 : find_symbol_in_expr (gfc_symbol *sym, gfc_expr *expr, locus *sym_loc)
    2198              : {
    2199        14586 :   int ret;
    2200              : 
    2201        14586 :   sought_symbol = sym;
    2202            0 :   ret = gfc_expr_walker (&expr, &expr_is_sought_symbol_ref, sym_loc);
    2203        14586 :   sought_symbol = NULL;
    2204        14586 :   return ret;
    2205              : }
    2206              : 
    2207              : 
    2208              : /* Recursive array list resolution function.  All of the elements must
    2209              :    be of the same type.  */
    2210              : 
    2211              : static bool
    2212        70879 : resolve_array_list (gfc_constructor_base base)
    2213              : {
    2214        70879 :   bool t;
    2215        70879 :   gfc_constructor *c;
    2216        70879 :   gfc_iterator *iter;
    2217        70879 :   gfc_expr *expr1 = NULL;
    2218              : 
    2219        70879 :   t = true;
    2220              : 
    2221       625416 :   for (c = gfc_constructor_first (base); c; c = gfc_constructor_next (c))
    2222              :     {
    2223       554537 :       iter = c->iterator;
    2224       554537 :       if (iter != NULL)
    2225              :         {
    2226         4862 :           gfc_symbol *iter_var;
    2227         4862 :           locus iter_var_loc;
    2228              : 
    2229         4862 :           if (!gfc_resolve_iterator (iter, false, true))
    2230            1 :             t = false;
    2231              : 
    2232              :           /* Check for bounds referencing the iterator variable.  */
    2233         4862 :           gcc_assert (iter->var->expr_type == EXPR_VARIABLE);
    2234         4862 :           iter_var = iter->var->symtree->n.sym;
    2235         4862 :           if (find_symbol_in_expr (iter_var, iter->start, &iter_var_loc))
    2236              :             {
    2237            1 :               if (!gfc_notify_std (GFC_STD_LEGACY, "AC-IMPLIED-DO initial "
    2238              :                                    "expression references control variable "
    2239              :                                    "at %L", &iter_var_loc))
    2240         4862 :                t = false;
    2241              :             }
    2242         4862 :           if (find_symbol_in_expr (iter_var, iter->end, &iter_var_loc))
    2243              :             {
    2244            7 :               if (!gfc_notify_std (GFC_STD_LEGACY, "AC-IMPLIED-DO final "
    2245              :                                    "expression references control variable "
    2246              :                                    "at %L", &iter_var_loc))
    2247         4862 :                t = false;
    2248              :             }
    2249         4862 :           if (find_symbol_in_expr (iter_var, iter->step, &iter_var_loc))
    2250              :             {
    2251            1 :               if (!gfc_notify_std (GFC_STD_LEGACY, "AC-IMPLIED-DO step "
    2252              :                                    "expression references control variable "
    2253              :                                    "at %L", &iter_var_loc))
    2254         4862 :                t = false;
    2255              :             }
    2256              :         }
    2257              : 
    2258       554537 :       if (!gfc_resolve_expr (c->expr))
    2259           61 :         t = false;
    2260              : 
    2261       554537 :       if (UNLIMITED_POLY (c->expr))
    2262              :         {
    2263            1 :           gfc_error ("Array constructor value at %L shall not be unlimited "
    2264              :                      "polymorphic [F2008: C4106]", &c->expr->where);
    2265            1 :           t = false;
    2266              :         }
    2267              : 
    2268              :       /* F2018:C7114 The declared type of an ac-value shall not be abstract.  */
    2269       554537 :       if (c->expr->ts.type == BT_CLASS
    2270           83 :           && c->expr->ts.u.derived
    2271           83 :           && c->expr->ts.u.derived->attr.abstract
    2272            5 :           && CLASS_DATA (c->expr))
    2273              :         {
    2274            5 :           gfc_error ("Array constructor value %qs at %L is of the ABSTRACT "
    2275            5 :                      "type %qs", c->expr->symtree->name, &c->expr->where,
    2276            5 :                      CLASS_DATA (c->expr)->ts.u.derived->name);
    2277            5 :           t = false;
    2278              :         }
    2279              : 
    2280              :       /* For valid expressions, check that the type specification parameters
    2281              :          are the same.  */
    2282       554537 :       if (t && !c->iterator && c->expr && IS_PDT (c->expr))
    2283              :         {
    2284          239 :           if (expr1 == NULL)
    2285              :             expr1 = c->expr;
    2286              :           else
    2287          115 :             t = gfc_check_type_spec_parms (expr1, c->expr, "in array constructor");
    2288              :         }
    2289              :     }
    2290              : 
    2291        70879 :   return t;
    2292              : }
    2293              : 
    2294              : /* Resolve character array constructor. If it has a specified constant character
    2295              :    length, pad/truncate the elements here; if the length is not specified and
    2296              :    all elements are of compile-time known length, emit an error as this is
    2297              :    invalid.  */
    2298              : 
    2299              : bool
    2300        11034 : gfc_resolve_character_array_constructor (gfc_expr *expr)
    2301              : {
    2302        11034 :   gfc_constructor *p;
    2303        11034 :   HOST_WIDE_INT found_length;
    2304        11034 :   bool has_ts;
    2305              : 
    2306        11034 :   gcc_assert (expr->expr_type == EXPR_ARRAY);
    2307        11034 :   gcc_assert (expr->ts.type == BT_CHARACTER);
    2308              : 
    2309              :   /* Check if we have an explicit type-spec with length.  */
    2310        11034 :   has_ts = expr->ts.u.cl && expr->ts.u.cl->length_from_typespec;
    2311              : 
    2312        11034 :   if (expr->ts.u.cl == NULL)
    2313              :     {
    2314          294 :       for (p = gfc_constructor_first (expr->value.constructor);
    2315          413 :            p; p = gfc_constructor_next (p))
    2316          333 :         if (p->expr->ts.u.cl != NULL)
    2317              :           {
    2318              :             /* Ensure that if there is a char_len around that it is
    2319              :                used; otherwise the middle-end confuses them!  */
    2320          214 :             expr->ts.u.cl = p->expr->ts.u.cl;
    2321          214 :             goto got_charlen;
    2322              :           }
    2323              : 
    2324           80 :       expr->ts.u.cl = gfc_new_charlen (gfc_current_ns, NULL);
    2325              :     }
    2326              : 
    2327        10740 : got_charlen:
    2328              : 
    2329              :   /* Early exit for zero size arrays. */
    2330        11034 :   if (expr->shape)
    2331              :     {
    2332        10665 :       mpz_t size;
    2333        10665 :       HOST_WIDE_INT arraysize;
    2334              : 
    2335        10665 :       gfc_array_size (expr, &size);
    2336        10665 :       arraysize = mpz_get_ui (size);
    2337        10665 :       mpz_clear (size);
    2338              : 
    2339        10665 :       if (arraysize == 0)
    2340          470 :         return true;
    2341              :     }
    2342              : 
    2343        10564 :   found_length = -1;
    2344              : 
    2345        10564 :   if (expr->ts.u.cl->length == NULL)
    2346              :     {
    2347              :       /* Check that all constant string elements have the same length until
    2348              :          we reach the end or find a variable-length one.  */
    2349              : 
    2350         6961 :       for (p = gfc_constructor_first (expr->value.constructor);
    2351        32156 :            p; p = gfc_constructor_next (p))
    2352              :         {
    2353        25547 :           HOST_WIDE_INT current_length = -1;
    2354        25547 :           gfc_ref *ref;
    2355        25783 :           for (ref = p->expr->ref; ref; ref = ref->next)
    2356          251 :             if (ref->type == REF_SUBSTRING
    2357           77 :                 && ref->u.ss.start
    2358           77 :                 && ref->u.ss.start->expr_type == EXPR_CONSTANT
    2359           52 :                 && ref->u.ss.end
    2360           39 :                 && ref->u.ss.end->expr_type == EXPR_CONSTANT)
    2361              :               break;
    2362              : 
    2363        25547 :           if (p->expr->expr_type == EXPR_CONSTANT)
    2364        25135 :             current_length = p->expr->value.character.length;
    2365          412 :           else if (ref)
    2366           15 :             current_length = gfc_mpz_get_hwi (ref->u.ss.end->value.integer)
    2367           15 :               - gfc_mpz_get_hwi (ref->u.ss.start->value.integer) + 1;
    2368          397 :           else if (p->expr->ts.u.cl && p->expr->ts.u.cl->length
    2369           51 :                    && p->expr->ts.u.cl->length->expr_type == EXPR_CONSTANT)
    2370           51 :             current_length = gfc_mpz_get_hwi (p->expr->ts.u.cl->length->value.integer);
    2371              :           else
    2372              :             return true;
    2373              : 
    2374        25201 :           if (current_length < 0)
    2375              :             current_length = 0;
    2376              : 
    2377        25201 :           if (found_length == -1)
    2378         6633 :             found_length = current_length;
    2379        18568 :           else if (found_length != current_length)
    2380              :             {
    2381            6 :               gfc_error ("Different CHARACTER lengths (%wd/%wd) in array"
    2382              :                          " constructor at %L", found_length,
    2383            6 :                          current_length, &p->expr->where);
    2384            6 :               return false;
    2385              :             }
    2386              : 
    2387        25195 :           gcc_assert (found_length == current_length);
    2388              :         }
    2389              : 
    2390         6609 :       gcc_assert (found_length != -1);
    2391              : 
    2392              :       /* Update the character length of the array constructor.  */
    2393         6609 :       expr->ts.u.cl->length = gfc_get_int_expr (gfc_charlen_int_kind,
    2394              :                                                 NULL, found_length);
    2395              :     }
    2396              :   else
    2397              :     {
    2398              :       /* We've got a character length specified.  It should be an integer,
    2399              :          otherwise an error is signalled elsewhere.  */
    2400         3603 :       gcc_assert (expr->ts.u.cl->length);
    2401              : 
    2402              :       /* If we've got a constant character length, pad according to this.
    2403              :          gfc_extract_int does check for BT_INTEGER and EXPR_CONSTANT and sets
    2404              :          max_length only if they pass.  */
    2405         3603 :       gfc_extract_hwi (expr->ts.u.cl->length, &found_length);
    2406              : 
    2407              :       /* Now pad/truncate the elements accordingly to the specified character
    2408              :          length.  This is ok inside this conditional, as in the case above
    2409              :          (without typespec) all elements are verified to have the same length
    2410              :          anyway.  */
    2411         3603 :       if (found_length != -1)
    2412         3458 :         for (p = gfc_constructor_first (expr->value.constructor);
    2413        15244 :              p; p = gfc_constructor_next (p))
    2414              :           {
    2415              :             /* For non-constant expressions (like EXPR_OP from concatenation),
    2416              :                try to simplify them first so we can then pad/truncate.  */
    2417        11786 :             if (p->expr->expr_type != EXPR_CONSTANT
    2418         1705 :                 && p->expr->ts.type == BT_CHARACTER)
    2419         1674 :               gfc_simplify_expr (p->expr, 0);
    2420              : 
    2421        11786 :             if (p->expr->expr_type == EXPR_CONSTANT)
    2422              :               {
    2423        10081 :                 gfc_expr *cl = NULL;
    2424        10081 :                 HOST_WIDE_INT current_length = -1;
    2425              : 
    2426        10081 :                 if (p->expr->ts.u.cl && p->expr->ts.u.cl->length)
    2427              :                   {
    2428         2040 :                     cl = p->expr->ts.u.cl->length;
    2429         2040 :                     gfc_extract_hwi (cl, &current_length);
    2430              :                   }
    2431              : 
    2432              :                 /* If gfc_extract_int above set current_length, we implicitly
    2433              :                    know the type is BT_INTEGER and it's EXPR_CONSTANT.  */
    2434              : 
    2435         2040 :                 if (! cl
    2436         2040 :                     || (current_length != -1 && current_length != found_length))
    2437         8281 :                   gfc_set_constant_character_len (found_length, p->expr,
    2438              :                                                   has_ts ? -1 : found_length);
    2439              :               }
    2440         1705 :             else if (p->expr->expr_type == EXPR_ARRAY)
    2441              :               {
    2442              :                 /* For nested array constructors, propagate the type-spec and
    2443              :                    recursively resolve.  This handles cases like
    2444              :                    [character(16) :: ['a','b']] // "|".  The inner constructor
    2445              :                    may have BT_UNKNOWN type initially.  */
    2446           92 :                 if (p->expr->ts.type == BT_UNKNOWN
    2447           61 :                     || p->expr->ts.type == BT_CHARACTER)
    2448              :                   {
    2449           92 :                     if (p->expr->ts.type == BT_CHARACTER
    2450           61 :                         && p->expr->ts.u.cl
    2451           61 :                         && p->expr->ts.u.cl->length_from_typespec)
    2452              :                       {
    2453              :                         /* If the inner array has an explicit type-spec, we must
    2454              :                            honor it first (e.g. truncate/pad to its length),
    2455              :                            before coercing it to the outer length.  */
    2456           48 :                         gfc_resolve_character_array_constructor (p->expr);
    2457              :                       }
    2458              : 
    2459           92 :                     p->expr->ts = expr->ts;
    2460           92 :                     gfc_resolve_character_array_constructor (p->expr);
    2461              :                   }
    2462              :               }
    2463              :           }
    2464              :     }
    2465              : 
    2466              :   return true;
    2467              : }
    2468              : 
    2469              : 
    2470              : /* Resolve all of the expressions in an array list.  */
    2471              : 
    2472              : bool
    2473        70879 : gfc_resolve_array_constructor (gfc_expr *expr)
    2474              : {
    2475        70879 :   bool t;
    2476              : 
    2477        70879 :   t = resolve_array_list (expr->value.constructor);
    2478        70879 :   if (t)
    2479        70806 :     t = gfc_check_constructor_type (expr);
    2480              : 
    2481              :   /* gfc_resolve_character_array_constructor is called in gfc_resolve_expr after
    2482              :      the call to this function, so we don't need to call it here; if it was
    2483              :      called twice, an error message there would be duplicated.  */
    2484              : 
    2485        70879 :   return t;
    2486              : }
    2487              : 
    2488              : 
    2489              : /* Copy an iterator structure.  */
    2490              : 
    2491              : gfc_iterator *
    2492       856564 : gfc_copy_iterator (gfc_iterator *src)
    2493              : {
    2494       856564 :   gfc_iterator *dest;
    2495              : 
    2496       856564 :   if (src == NULL)
    2497              :     return NULL;
    2498              : 
    2499          508 :   dest = gfc_get_iterator ();
    2500              : 
    2501          508 :   dest->var = gfc_copy_expr (src->var);
    2502          508 :   dest->start = gfc_copy_expr (src->start);
    2503          508 :   dest->end = gfc_copy_expr (src->end);
    2504          508 :   dest->step = gfc_copy_expr (src->step);
    2505          508 :   dest->annot = src->annot;
    2506              : 
    2507          508 :   return dest;
    2508              : }
    2509              : 
    2510              : 
    2511              : /********* Subroutines for determining the size of an array *********/
    2512              : 
    2513              : /* These are needed just to accommodate RESHAPE().  There are no
    2514              :    diagnostics here, we just return false if something goes wrong.  */
    2515              : 
    2516              : 
    2517              : /* Get the size of single dimension of an array specification.  The
    2518              :    array is guaranteed to be one dimensional.  */
    2519              : 
    2520              : bool
    2521       554998 : spec_dimen_size (gfc_array_spec *as, int dimen, mpz_t *result)
    2522              : {
    2523       554998 :   if (as == NULL)
    2524              :     return false;
    2525              : 
    2526       541548 :   if (dimen < 0 || dimen > as->rank - 1)
    2527            0 :     gfc_internal_error ("spec_dimen_size(): Bad dimension");
    2528              : 
    2529       541548 :   if (as->type != AS_EXPLICIT
    2530       343807 :       || !as->lower[dimen]
    2531       343807 :       || !as->upper[dimen])
    2532              :     return false;
    2533              : 
    2534       343807 :   if (as->lower[dimen]->expr_type != EXPR_CONSTANT
    2535       343028 :       || as->upper[dimen]->expr_type != EXPR_CONSTANT
    2536       324689 :       || as->lower[dimen]->ts.type != BT_INTEGER
    2537       324689 :       || as->upper[dimen]->ts.type != BT_INTEGER)
    2538              :     return false;
    2539              : 
    2540       324683 :   mpz_init (*result);
    2541              : 
    2542       324683 :   mpz_sub (*result, as->upper[dimen]->value.integer,
    2543       324683 :            as->lower[dimen]->value.integer);
    2544              : 
    2545       324683 :   mpz_add_ui (*result, *result, 1);
    2546              : 
    2547       324683 :   if (mpz_cmp_si (*result, 0) < 0)
    2548            0 :     mpz_set_si (*result, 0);
    2549              : 
    2550              :   return true;
    2551              : }
    2552              : 
    2553              : 
    2554              : bool
    2555        30156 : spec_size (gfc_array_spec *as, mpz_t *result)
    2556              : {
    2557        30156 :   mpz_t size;
    2558        30156 :   int d;
    2559              : 
    2560        30156 :   if (!as || as->type == AS_ASSUMED_RANK)
    2561              :     return false;
    2562              : 
    2563        28706 :   mpz_init_set_ui (*result, 1);
    2564              : 
    2565        78095 :   for (d = 0; d < as->rank; d++)
    2566              :     {
    2567        34642 :       if (!spec_dimen_size (as, d, &size))
    2568              :         {
    2569        13959 :           mpz_clear (*result);
    2570        13959 :           return false;
    2571              :         }
    2572              : 
    2573        20683 :       mpz_mul (*result, *result, size);
    2574        20683 :       mpz_clear (size);
    2575              :     }
    2576              : 
    2577              :   return true;
    2578              : }
    2579              : 
    2580              : 
    2581              : /* Get the number of elements in an array section. Optionally, also supply
    2582              :    the end value.  */
    2583              : 
    2584              : bool
    2585        75800 : gfc_ref_dimen_size (gfc_array_ref *ar, int dimen, mpz_t *result, mpz_t *end)
    2586              : {
    2587        75800 :   mpz_t upper, lower, stride;
    2588        75800 :   mpz_t diff;
    2589        75800 :   bool t;
    2590        75800 :   gfc_expr *stride_expr = NULL;
    2591              : 
    2592        75800 :   if (dimen < 0 || ar == NULL)
    2593            0 :     gfc_internal_error ("gfc_ref_dimen_size(): Bad dimension");
    2594              : 
    2595        75800 :   if (dimen > ar->dimen - 1)
    2596              :     {
    2597            1 :       gfc_error ("Bad array dimension at %L", &ar->c_where[dimen]);
    2598            1 :       return false;
    2599              :     }
    2600              : 
    2601        75799 :   switch (ar->dimen_type[dimen])
    2602              :     {
    2603          164 :     case DIMEN_ELEMENT:
    2604          164 :       mpz_init (*result);
    2605          164 :       mpz_set_ui (*result, 1);
    2606          164 :       t = true;
    2607          164 :       break;
    2608              : 
    2609         1395 :     case DIMEN_VECTOR:
    2610         1395 :       t = gfc_array_size (ar->start[dimen], result); /* Recurse! */
    2611         1395 :       break;
    2612              : 
    2613        74240 :     case DIMEN_RANGE:
    2614              : 
    2615        74240 :       mpz_init (stride);
    2616              : 
    2617        74240 :       if (ar->stride[dimen] == NULL)
    2618        52072 :         mpz_set_ui (stride, 1);
    2619              :       else
    2620              :         {
    2621        22168 :           stride_expr = gfc_copy_expr(ar->stride[dimen]);
    2622              : 
    2623        22168 :           if (!gfc_simplify_expr (stride_expr, 1)
    2624        22166 :              || stride_expr->expr_type != EXPR_CONSTANT
    2625        42504 :              || mpz_cmp_ui (stride_expr->value.integer, 0) == 0)
    2626              :             {
    2627         1834 :               gfc_free_expr (stride_expr);
    2628         1834 :               mpz_clear (stride);
    2629         1834 :               return false;
    2630              :             }
    2631        20334 :           mpz_set (stride, stride_expr->value.integer);
    2632        20334 :           gfc_free_expr(stride_expr);
    2633              :         }
    2634              : 
    2635              :       /* Calculate the number of elements via gfc_dep_difference, but only if
    2636              :          start and end are both supplied in the reference or the array spec.
    2637              :          This is to guard against strange but valid code like
    2638              : 
    2639              :          subroutine foo(a,n)
    2640              :          real a(1:n)
    2641              :          n = 3
    2642              :          print *,size(a(n-1:))
    2643              : 
    2644              :          where the user changes the value of a variable.  If we have to
    2645              :          determine end as well, we cannot do this using gfc_dep_difference.
    2646              :          Fall back to the constants-only code then.  */
    2647              : 
    2648        72406 :       if (end == NULL)
    2649              :         {
    2650        64322 :           bool use_dep;
    2651              : 
    2652        64322 :           use_dep = gfc_dep_difference (ar->end[dimen], ar->start[dimen],
    2653              :                                         &diff);
    2654        64322 :           if (!use_dep && ar->end[dimen] == NULL && ar->start[dimen] == NULL)
    2655        28578 :             use_dep = gfc_dep_difference (ar->as->upper[dimen],
    2656        28578 :                                             ar->as->lower[dimen], &diff);
    2657              : 
    2658        43020 :           if (use_dep)
    2659              :             {
    2660        32742 :               mpz_init (*result);
    2661        32742 :               mpz_add (*result, diff, stride);
    2662        32742 :               mpz_div (*result, *result, stride);
    2663        32742 :               if (mpz_cmp_ui (*result, 0) < 0)
    2664          112 :                 mpz_set_ui (*result, 0);
    2665              : 
    2666        32742 :               mpz_clear (stride);
    2667        32742 :               mpz_clear (diff);
    2668        32742 :               return true;
    2669              :             }
    2670              : 
    2671              :         }
    2672              : 
    2673              :       /*  Constant-only code here, which covers more cases
    2674              :           like a(:4) etc.  */
    2675        39664 :       mpz_init (upper);
    2676        39664 :       mpz_init (lower);
    2677        39664 :       t = false;
    2678              : 
    2679        39664 :       if (ar->start[dimen] == NULL)
    2680              :         {
    2681        29466 :           if (ar->as->lower[dimen] == NULL
    2682        12216 :               || ar->as->lower[dimen]->expr_type != EXPR_CONSTANT
    2683        12213 :               || ar->as->lower[dimen]->ts.type != BT_INTEGER)
    2684        17253 :             goto cleanup;
    2685        12213 :           mpz_set (lower, ar->as->lower[dimen]->value.integer);
    2686              :         }
    2687              :       else
    2688              :         {
    2689        10198 :           if (ar->start[dimen]->expr_type != EXPR_CONSTANT)
    2690         2459 :             goto cleanup;
    2691         7739 :           mpz_set (lower, ar->start[dimen]->value.integer);
    2692              :         }
    2693              : 
    2694        19952 :       if (ar->end[dimen] == NULL)
    2695              :         {
    2696         6420 :           if (ar->as->upper[dimen] == NULL
    2697         4981 :               || ar->as->upper[dimen]->expr_type != EXPR_CONSTANT
    2698         4451 :               || ar->as->upper[dimen]->ts.type != BT_INTEGER)
    2699         1970 :             goto cleanup;
    2700         4450 :           mpz_set (upper, ar->as->upper[dimen]->value.integer);
    2701              :         }
    2702              :       else
    2703              :         {
    2704        13532 :           if (ar->end[dimen]->expr_type != EXPR_CONSTANT)
    2705         4427 :             goto cleanup;
    2706         9105 :           mpz_set (upper, ar->end[dimen]->value.integer);
    2707              :         }
    2708              : 
    2709        13555 :       mpz_init (*result);
    2710        13555 :       mpz_sub (*result, upper, lower);
    2711        13555 :       mpz_add (*result, *result, stride);
    2712        13555 :       mpz_div (*result, *result, stride);
    2713              : 
    2714              :       /* Zero stride caught earlier.  */
    2715        13555 :       if (mpz_cmp_ui (*result, 0) < 0)
    2716            8 :         mpz_set_ui (*result, 0);
    2717        13555 :       t = true;
    2718              : 
    2719        13555 :       if (end)
    2720              :         {
    2721         6380 :           mpz_init (*end);
    2722              : 
    2723         6380 :           mpz_sub_ui (*end, *result, 1UL);
    2724         6380 :           mpz_mul (*end, *end, stride);
    2725         6380 :           mpz_add (*end, *end, lower);
    2726              :         }
    2727              : 
    2728         7175 :     cleanup:
    2729        39664 :       mpz_clear (upper);
    2730        39664 :       mpz_clear (lower);
    2731        39664 :       mpz_clear (stride);
    2732        39664 :       return t;
    2733              : 
    2734            0 :     default:
    2735            0 :       gfc_internal_error ("gfc_ref_dimen_size(): Bad dimen_type");
    2736              :     }
    2737              : 
    2738              :   return t;
    2739              : }
    2740              : 
    2741              : 
    2742              : static bool
    2743         3433 : ref_size (gfc_array_ref *ar, mpz_t *result)
    2744              : {
    2745         3433 :   mpz_t size;
    2746         3433 :   int d;
    2747              : 
    2748         3433 :   mpz_init_set_ui (*result, 1);
    2749              : 
    2750        10459 :   for (d = 0; d < ar->dimen; d++)
    2751              :     {
    2752         3989 :       if (!gfc_ref_dimen_size (ar, d, &size, NULL))
    2753              :         {
    2754          396 :           mpz_clear (*result);
    2755          396 :           return false;
    2756              :         }
    2757              : 
    2758         3593 :       mpz_mul (*result, *result, size);
    2759         3593 :       mpz_clear (size);
    2760              :     }
    2761              : 
    2762              :   return true;
    2763              : }
    2764              : 
    2765              : 
    2766              : /* Given an array expression and a dimension, figure out how many
    2767              :    elements it has along that dimension.  Returns true if we were
    2768              :    able to return a result in the 'result' variable, false
    2769              :    otherwise.  */
    2770              : 
    2771              : bool
    2772       706404 : gfc_array_dimen_size (gfc_expr *array, int dimen, mpz_t *result)
    2773              : {
    2774       706404 :   gfc_ref *ref;
    2775       706404 :   int i;
    2776              : 
    2777       706404 :   gcc_assert (array != NULL);
    2778              : 
    2779       706404 :   if (array->ts.type == BT_CLASS)
    2780              :     return false;
    2781              : 
    2782       694429 :   if (array->rank == -1)
    2783              :     return false;
    2784              : 
    2785       694429 :   if (dimen < 0 || dimen > array->rank - 1)
    2786            0 :     gfc_internal_error ("gfc_array_dimen_size(): Bad dimension");
    2787              : 
    2788       694429 :   switch (array->expr_type)
    2789              :     {
    2790       579150 :     case EXPR_VARIABLE:
    2791       579150 :     case EXPR_FUNCTION:
    2792       632638 :       for (ref = array->ref; ref; ref = ref->next)
    2793              :         {
    2794              :           /* Ultimate component is a procedure pointer.  */
    2795       589431 :           if (ref->type == REF_COMPONENT
    2796        39313 :               && !ref->next
    2797         1053 :               && ref->u.c.component->attr.function
    2798           91 :               && IS_PROC_POINTER (ref->u.c.component))
    2799              :             return false;
    2800              : 
    2801       589340 :           if (ref->type != REF_ARRAY)
    2802        39222 :             continue;
    2803              : 
    2804       550118 :           if (ref->u.ar.type == AR_FULL)
    2805       473418 :             return spec_dimen_size (ref->u.ar.as, dimen, result);
    2806              : 
    2807        76700 :           if (ref->u.ar.type == AR_SECTION)
    2808              :             {
    2809       146122 :               for (i = 0; dimen >= 0; i++)
    2810        83688 :                 if (ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
    2811        78371 :                   dimen--;
    2812              : 
    2813        62434 :               return gfc_ref_dimen_size (&ref->u.ar, i - 1, result, NULL);
    2814              :             }
    2815              :         }
    2816              : 
    2817        43207 :       if (array->shape)
    2818              :         {
    2819        11906 :           mpz_init_set (*result, array->shape[dimen]);
    2820        11906 :           return true;
    2821              :         }
    2822              : 
    2823        31301 :       if (array->symtree->n.sym->attr.generic
    2824           26 :           && array->value.function.esym != NULL)
    2825              :         {
    2826           25 :           if (!spec_dimen_size (array->value.function.esym->as, dimen, result))
    2827              :             return false;
    2828              :         }
    2829        31276 :       else if (!spec_dimen_size (array->symtree->n.sym->as, dimen, result))
    2830              :         return false;
    2831              : 
    2832              :       break;
    2833              : 
    2834       101640 :     case EXPR_ARRAY:
    2835       101640 :       if (array->shape == NULL) {
    2836              :         /* Expressions with rank > 1 should have "shape" properly set */
    2837        61010 :         if ( array->rank != 1 )
    2838            0 :           gfc_internal_error ("gfc_array_dimen_size(): Bad EXPR_ARRAY expr");
    2839        61010 :         return gfc_array_size(array, result);
    2840              :       }
    2841              : 
    2842              :       /* Fall through */
    2843        54269 :     default:
    2844        54269 :       if (array->shape == NULL)
    2845              :         return false;
    2846              : 
    2847        46699 :       mpz_init_set (*result, array->shape[dimen]);
    2848              : 
    2849        46699 :       break;
    2850              :     }
    2851              : 
    2852              :   return true;
    2853              : }
    2854              : 
    2855              : 
    2856              : /* Given an array expression, figure out how many elements are in the
    2857              :    array.  Returns true if this is possible, and sets the 'result'
    2858              :    variable.  Otherwise returns false.  */
    2859              : 
    2860              : bool
    2861       127660 : gfc_array_size (gfc_expr *array, mpz_t *result)
    2862              : {
    2863       127660 :   expand_info expand_save;
    2864       127660 :   gfc_ref *ref;
    2865       127660 :   int i;
    2866       127660 :   bool t;
    2867              : 
    2868       127660 :   if (array->ts.type == BT_CLASS)
    2869              :     return false;
    2870              : 
    2871       126625 :   switch (array->expr_type)
    2872              :     {
    2873        95796 :     case EXPR_ARRAY:
    2874        95796 :       gfc_push_suppress_errors ();
    2875              : 
    2876        95796 :       expand_save = current_expand;
    2877              : 
    2878        95796 :       current_expand.count = result;
    2879        95796 :       mpz_init_set_ui (*result, 0);
    2880              : 
    2881        95796 :       current_expand.expand_work_function = count_elements;
    2882        95796 :       iter_stack = NULL;
    2883              : 
    2884        95796 :       t = expand_constructor (array->value.constructor);
    2885              : 
    2886        95796 :       gfc_pop_suppress_errors ();
    2887              : 
    2888        95796 :       if (!t)
    2889         2095 :         mpz_clear (*result);
    2890        95796 :       current_expand = expand_save;
    2891        95796 :       return t;
    2892              : 
    2893        25934 :     case EXPR_VARIABLE:
    2894        28246 :       for (ref = array->ref; ref; ref = ref->next)
    2895              :         {
    2896        28245 :           if (ref->type != REF_ARRAY)
    2897         1821 :             continue;
    2898              : 
    2899        26424 :           if (ref->u.ar.type == AR_FULL)
    2900        22500 :             return spec_size (ref->u.ar.as, result);
    2901              : 
    2902         3924 :           if (ref->u.ar.type == AR_SECTION)
    2903         3433 :             return ref_size (&ref->u.ar, result);
    2904              :         }
    2905              : 
    2906            1 :       return spec_size (array->symtree->n.sym->as, result);
    2907              : 
    2908              : 
    2909         4895 :     default:
    2910         4895 :       if (array->rank == 0 || array->shape == NULL)
    2911              :         return false;
    2912              : 
    2913         3443 :       mpz_init_set_ui (*result, 1);
    2914              : 
    2915        10703 :       for (i = 0; i < array->rank; i++)
    2916         3817 :         mpz_mul (*result, *result, array->shape[i]);
    2917              : 
    2918              :       break;
    2919              :     }
    2920              : 
    2921              :   return true;
    2922              : }
    2923              : 
    2924              : 
    2925              : /* Given an array reference, return the shape of the reference in an
    2926              :    array of mpz_t integers.  */
    2927              : 
    2928              : bool
    2929        10946 : gfc_array_ref_shape (gfc_array_ref *ar, mpz_t *shape)
    2930              : {
    2931        10946 :   int d;
    2932        10946 :   int i;
    2933              : 
    2934        10946 :   d = 0;
    2935              : 
    2936        10946 :   switch (ar->type)
    2937              :     {
    2938              :     case AR_FULL:
    2939        17319 :       for (; d < ar->as->rank; d++)
    2940        15041 :         if (!spec_dimen_size (ar->as, d, &shape[d]))
    2941         8589 :           goto cleanup;
    2942              : 
    2943              :       return true;
    2944              : 
    2945              :     case AR_SECTION:
    2946          199 :       for (i = 0; i < ar->dimen; i++)
    2947              :         {
    2948          157 :           if (ar->dimen_type[i] != DIMEN_ELEMENT)
    2949              :             {
    2950          129 :               if (!gfc_ref_dimen_size (ar, i, &shape[d], NULL))
    2951           37 :                 goto cleanup;
    2952           92 :               d++;
    2953              :             }
    2954              :         }
    2955              : 
    2956              :       return true;
    2957              : 
    2958              :     default:
    2959              :       break;
    2960              :     }
    2961              : 
    2962         8626 : cleanup:
    2963         8626 :   gfc_clear_shape (shape, d);
    2964         8626 :   return false;
    2965              : }
    2966              : 
    2967              : 
    2968              : /* Given an array expression, find the array reference structure that
    2969              :    characterizes the reference.  */
    2970              : 
    2971              : gfc_array_ref *
    2972        96191 : gfc_find_array_ref (gfc_expr *e, bool allow_null)
    2973              : {
    2974        96191 :   gfc_ref *ref;
    2975              : 
    2976       107205 :   for (ref = e->ref; ref; ref = ref->next)
    2977       100044 :     if (ref->type == REF_ARRAY
    2978        93946 :         && (ref->u.ar.type == AR_FULL || ref->u.ar.type == AR_SECTION))
    2979              :       break;
    2980              : 
    2981        96191 :   if (ref == NULL)
    2982              :     {
    2983         7161 :       if (allow_null)
    2984              :         return NULL;
    2985              :       else
    2986            0 :         gfc_internal_error ("gfc_find_array_ref(): No ref found");
    2987              :     }
    2988              : 
    2989        89030 :   return &ref->u.ar;
    2990              : }
    2991              : 
    2992              : 
    2993              : /* Find out if an array shape is known at compile time.  */
    2994              : 
    2995              : bool
    2996           74 : gfc_is_compile_time_shape (gfc_array_spec *as)
    2997              : {
    2998           74 :   if (as->type != AS_EXPLICIT)
    2999              :     return false;
    3000              : 
    3001          152 :   for (int i = 0; i < as->rank; i++)
    3002           90 :     if (!gfc_is_constant_expr (as->lower[i])
    3003           90 :         || !gfc_is_constant_expr (as->upper[i]))
    3004            9 :       return false;
    3005              : 
    3006              :   return true;
    3007              : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.