LCOV - code coverage report
Current view: top level - gcc/fortran - io.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 89.0 % 2415 2150
Test Date: 2026-06-20 15:32:29 Functions: 100.0 % 62 62
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Deal with I/O statements & related stuff.
       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 "match.h"
      27              : #include "parse.h"
      28              : #include "constructor.h"
      29              : 
      30              : gfc_st_label
      31              : format_asterisk = {0, NULL, NULL, -1, ST_LABEL_FORMAT, ST_LABEL_FORMAT, NULL,
      32              :                    0, {NULL, {NULL}}, NULL, 0};
      33              : 
      34              : typedef struct
      35              : {
      36              :   const char *name, *spec, *value;
      37              :   bt type;
      38              : }
      39              : io_tag;
      40              : 
      41              : static const io_tag
      42              :         tag_readonly    = {"READONLY", " readonly", NULL, BT_UNKNOWN },
      43              :         tag_shared      = {"SHARE", " shared", NULL, BT_UNKNOWN },
      44              :         tag_noshared    = {"SHARE", " noshared", NULL, BT_UNKNOWN },
      45              :         tag_e_share     = {"SHARE", " share =", " %e", BT_CHARACTER },
      46              :         tag_v_share     = {"SHARE", " share =", " %v", BT_CHARACTER },
      47              :         tag_cc          = {"CARRIAGECONTROL", " carriagecontrol =", " %e",
      48              :                            BT_CHARACTER },
      49              :         tag_v_cc        = {"CARRIAGECONTROL", " carriagecontrol =", " %v",
      50              :                            BT_CHARACTER },
      51              :         tag_file        = {"FILE", " file =", " %e", BT_CHARACTER },
      52              :         tag_status      = {"STATUS", " status =", " %e", BT_CHARACTER},
      53              :         tag_e_access    = {"ACCESS", " access =", " %e", BT_CHARACTER},
      54              :         tag_e_form      = {"FORM", " form =", " %e", BT_CHARACTER},
      55              :         tag_e_recl      = {"RECL", " recl =", " %e", BT_INTEGER},
      56              :         tag_e_blank     = {"BLANK", " blank =", " %e", BT_CHARACTER},
      57              :         tag_e_position  = {"POSITION", " position =", " %e", BT_CHARACTER},
      58              :         tag_e_action    = {"ACTION", " action =", " %e", BT_CHARACTER},
      59              :         tag_e_delim     = {"DELIM", " delim =", " %e", BT_CHARACTER},
      60              :         tag_e_pad       = {"PAD", " pad =", " %e", BT_CHARACTER},
      61              :         tag_e_decimal   = {"DECIMAL", " decimal =", " %e", BT_CHARACTER},
      62              :         tag_e_encoding  = {"ENCODING", " encoding =", " %e", BT_CHARACTER},
      63              :         tag_e_async     = {"ASYNCHRONOUS", " asynchronous =", " %e", BT_CHARACTER},
      64              :         tag_e_round     = {"ROUND", " round =", " %e", BT_CHARACTER},
      65              :         tag_e_sign      = {"SIGN", " sign =", " %e", BT_CHARACTER},
      66              :         tag_unit        = {"UNIT", " unit =", " %e", BT_INTEGER},
      67              :         tag_advance     = {"ADVANCE", " advance =", " %e", BT_CHARACTER},
      68              :         tag_rec         = {"REC", " rec =", " %e", BT_INTEGER},
      69              :         tag_spos        = {"POSITION", " pos =", " %e", BT_INTEGER},
      70              :         tag_format      = {"FORMAT", NULL, NULL, BT_CHARACTER},
      71              :         tag_iomsg       = {"IOMSG", " iomsg =", " %e", BT_CHARACTER},
      72              :         tag_iostat      = {"IOSTAT", " iostat =", " %v", BT_INTEGER},
      73              :         tag_size        = {"SIZE", " size =", " %v", BT_INTEGER},
      74              :         tag_exist       = {"EXIST", " exist =", " %v", BT_LOGICAL},
      75              :         tag_opened      = {"OPENED", " opened =", " %v", BT_LOGICAL},
      76              :         tag_named       = {"NAMED", " named =", " %v", BT_LOGICAL},
      77              :         tag_name        = {"NAME", " name =", " %v", BT_CHARACTER},
      78              :         tag_number      = {"NUMBER", " number =", " %v", BT_INTEGER},
      79              :         tag_s_access    = {"ACCESS", " access =", " %v", BT_CHARACTER},
      80              :         tag_sequential  = {"SEQUENTIAL", " sequential =", " %v", BT_CHARACTER},
      81              :         tag_direct      = {"DIRECT", " direct =", " %v", BT_CHARACTER},
      82              :         tag_s_form      = {"FORM", " form =", " %v", BT_CHARACTER},
      83              :         tag_formatted   = {"FORMATTED", " formatted =", " %v", BT_CHARACTER},
      84              :         tag_unformatted = {"UNFORMATTED", " unformatted =", " %v", BT_CHARACTER},
      85              :         tag_s_recl      = {"RECL", " recl =", " %v", BT_INTEGER},
      86              :         tag_nextrec     = {"NEXTREC", " nextrec =", " %v", BT_INTEGER},
      87              :         tag_s_blank     = {"BLANK", " blank =", " %v", BT_CHARACTER},
      88              :         tag_s_position  = {"POSITION", " position =", " %v", BT_CHARACTER},
      89              :         tag_s_action    = {"ACTION", " action =", " %v", BT_CHARACTER},
      90              :         tag_read        = {"READ", " read =", " %v", BT_CHARACTER},
      91              :         tag_write       = {"WRITE", " write =", " %v", BT_CHARACTER},
      92              :         tag_readwrite   = {"READWRITE", " readwrite =", " %v", BT_CHARACTER},
      93              :         tag_s_delim     = {"DELIM", " delim =", " %v", BT_CHARACTER},
      94              :         tag_s_pad       = {"PAD", " pad =", " %v", BT_CHARACTER},
      95              :         tag_s_decimal   = {"DECIMAL", " decimal =", " %v", BT_CHARACTER},
      96              :         tag_s_encoding  = {"ENCODING", " encoding =", " %v", BT_CHARACTER},
      97              :         tag_s_async     = {"ASYNCHRONOUS", " asynchronous =", " %v", BT_CHARACTER},
      98              :         tag_s_round     = {"ROUND", " round =", " %v", BT_CHARACTER},
      99              :         tag_s_sign      = {"SIGN", " sign =", " %v", BT_CHARACTER},
     100              :         tag_iolength    = {"IOLENGTH", " iolength =", " %v", BT_INTEGER},
     101              :         tag_convert     = {"CONVERT", " convert =", " %e", BT_CHARACTER},
     102              :         tag_strm_out    = {"POS", " pos =", " %v", BT_INTEGER},
     103              :         tag_err         = {"ERR", " err =", " %l", BT_UNKNOWN},
     104              :         tag_end         = {"END", " end =", " %l", BT_UNKNOWN},
     105              :         tag_eor         = {"EOR", " eor =", " %l", BT_UNKNOWN},
     106              :         tag_id          = {"ID", " id =", " %e", BT_INTEGER},
     107              :         tag_pending     = {"PENDING", " pending =", " %v", BT_LOGICAL},
     108              :         tag_newunit     = {"NEWUNIT", " newunit =", " %v", BT_INTEGER},
     109              :         tag_s_iqstream  = {"STREAM", " stream =", " %v", BT_CHARACTER};
     110              : 
     111              : static gfc_dt *current_dt;
     112              : 
     113              : #define RESOLVE_TAG(x, y) if (!resolve_tag (x, y)) return false;
     114              : 
     115              : /**************** Fortran 95 FORMAT parser  *****************/
     116              : 
     117              : /* FORMAT tokens returned by format_lex().  */
     118              : enum format_token
     119              : {
     120              :   FMT_NONE, FMT_UNKNOWN, FMT_SIGNED_INT, FMT_ZERO, FMT_POSINT, FMT_PERIOD,
     121              :   FMT_COMMA, FMT_COLON, FMT_SLASH, FMT_DOLLAR, FMT_LPAREN, FMT_RPAREN, FMT_X,
     122              :   FMT_SIGN, FMT_BLANK, FMT_CHAR, FMT_P, FMT_IBOZ, FMT_F, FMT_E, FMT_EN, FMT_ES,
     123              :   FMT_G, FMT_L, FMT_A, FMT_D, FMT_H, FMT_END, FMT_ERROR, FMT_DC, FMT_DP, FMT_T,
     124              :   FMT_TR, FMT_TL, FMT_STAR, FMT_RC, FMT_RD, FMT_RN, FMT_RP, FMT_RU, FMT_RZ,
     125              :   FMT_DT, FMT_EX, FMT_LPS, FMT_LPZ, FMT_LZ
     126              : };
     127              : 
     128              : /* Local variables for checking format strings.  The saved_token is
     129              :    used to back up by a single format token during the parsing
     130              :    process.  */
     131              : static gfc_char_t *format_string;
     132              : static int format_string_pos;
     133              : static int format_length, use_last_char;
     134              : static char error_element;
     135              : static locus format_locus;
     136              : 
     137              : static format_token saved_token;
     138              : 
     139              : static enum
     140              : { MODE_STRING, MODE_FORMAT, MODE_COPY }
     141              : mode;
     142              : 
     143              : 
     144              : /* Return the next character in the format string.  */
     145              : 
     146              : static char
     147       165804 : next_char (gfc_instring in_string)
     148              : {
     149       165804 :   static gfc_char_t c;
     150              : 
     151       165804 :   if (use_last_char)
     152              :     {
     153        28421 :       use_last_char = 0;
     154        28421 :       return c;
     155              :     }
     156              : 
     157       137383 :   format_length++;
     158              : 
     159       137383 :   if (mode == MODE_STRING)
     160        79965 :     c = *format_string++;
     161              :   else
     162              :     {
     163        57418 :       c = gfc_next_char_literal (in_string);
     164        57418 :       if (c == '\n')
     165            0 :         c = '\0';
     166              :     }
     167              : 
     168       137383 :   if (flag_backslash && c == '\\')
     169              :     {
     170           48 :       locus old_locus = gfc_current_locus;
     171              : 
     172           48 :       if (gfc_match_special_char (&c) == MATCH_NO)
     173            0 :         gfc_current_locus = old_locus;
     174              : 
     175           48 :       if (!(gfc_option.allow_std & GFC_STD_GNU) && !inhibit_warnings)
     176            0 :         gfc_warning (0, "Extension: backslash character at %C");
     177              :     }
     178              : 
     179       137383 :   if (mode == MODE_COPY)
     180        28649 :     *format_string++ = c;
     181              : 
     182       137383 :   if (mode != MODE_STRING)
     183        57418 :     format_locus = gfc_current_locus;
     184              : 
     185       137383 :   format_string_pos++;
     186              : 
     187       137383 :   c = gfc_wide_toupper (c);
     188       137383 :   return c;
     189              : }
     190              : 
     191              : 
     192              : /* Back up one character position.  Only works once.  */
     193              : 
     194              : static void
     195        28427 : unget_char (void)
     196              : {
     197        28427 :   use_last_char = 1;
     198         2616 : }
     199              : 
     200              : /* Eat up the spaces and return a character.  */
     201              : 
     202              : static char
     203       126657 : next_char_not_space ()
     204              : {
     205       135212 :   char c;
     206       135212 :   do
     207              :     {
     208       135212 :       error_element = c = next_char (NONSTRING);
     209       135212 :       if (c == '\t')
     210            4 :         gfc_warning (OPT_Wtabs, "Nonconforming tab character in format at %C");
     211              :     }
     212       135212 :   while (gfc_is_whitespace (c));
     213       126657 :   return c;
     214              : }
     215              : 
     216              : static int value = 0;
     217              : 
     218              : /* Simple lexical analyzer for getting the next token in a FORMAT
     219              :    statement.  */
     220              : 
     221              : static format_token
     222       121321 : format_lex (void)
     223              : {
     224       121321 :   format_token token;
     225       121321 :   char c, delim;
     226       121321 :   int zflag;
     227       121321 :   int negative_flag;
     228              : 
     229       121321 :   if (saved_token != FMT_NONE)
     230              :     {
     231        27748 :       token = saved_token;
     232        27748 :       saved_token = FMT_NONE;
     233        27748 :       return token;
     234              :     }
     235              : 
     236        93573 :   c = next_char_not_space ();
     237              : 
     238        93573 :   negative_flag = 0;
     239        93573 :   switch (c)
     240              :     {
     241            6 :     case '-':
     242            6 :       negative_flag = 1;
     243              :       /* Falls through.  */
     244              : 
     245           18 :     case '+':
     246           18 :       c = next_char_not_space ();
     247           18 :       if (!ISDIGIT (c))
     248              :         {
     249              :           token = FMT_UNKNOWN;
     250              :           break;
     251              :         }
     252              : 
     253           18 :       value = c - '0';
     254              : 
     255           18 :       do
     256              :         {
     257           18 :           c = next_char_not_space ();
     258           18 :           if (ISDIGIT (c))
     259            0 :             value = 10 * value + (c - '0');
     260              :         }
     261           18 :       while (ISDIGIT (c));
     262              : 
     263           18 :       unget_char ();
     264              : 
     265           18 :       if (negative_flag)
     266            6 :         value = -value;
     267              : 
     268              :       token = FMT_SIGNED_INT;
     269              :       break;
     270              : 
     271        23403 :     case '0':
     272        23403 :     case '1':
     273        23403 :     case '2':
     274        23403 :     case '3':
     275        23403 :     case '4':
     276        23403 :     case '5':
     277        23403 :     case '6':
     278        23403 :     case '7':
     279        23403 :     case '8':
     280        23403 :     case '9':
     281        23403 :       zflag = (c == '0');
     282              : 
     283        23403 :       value = c - '0';
     284              : 
     285        28333 :       do
     286              :         {
     287        28333 :           c = next_char_not_space ();
     288        28333 :           if (ISDIGIT (c))
     289              :             {
     290         4930 :               value = 10 * value + (c - '0');
     291         4930 :               if (c != '0')
     292        28333 :                 zflag = 0;
     293              :             }
     294              :         }
     295        28333 :       while (ISDIGIT (c));
     296              : 
     297        23403 :       unget_char ();
     298        23403 :       token = zflag ? FMT_ZERO : FMT_POSINT;
     299              :       break;
     300              : 
     301              :     case '.':
     302              :       token = FMT_PERIOD;
     303              :       break;
     304              : 
     305        10886 :     case ',':
     306        10886 :       token = FMT_COMMA;
     307        10886 :       break;
     308              : 
     309          101 :     case ':':
     310          101 :       token = FMT_COLON;
     311          101 :       break;
     312              : 
     313              :     case '/':
     314          843 :       token = FMT_SLASH;
     315              :       break;
     316              : 
     317           72 :     case '$':
     318           72 :       token = FMT_DOLLAR;
     319           72 :       break;
     320              : 
     321          962 :     case 'T':
     322          962 :       c = next_char_not_space ();
     323          962 :       switch (c)
     324              :         {
     325              :         case 'L':
     326              :           token = FMT_TL;
     327              :           break;
     328          168 :         case 'R':
     329          168 :           token = FMT_TR;
     330          168 :           break;
     331          605 :         default:
     332          605 :           token = FMT_T;
     333          605 :           unget_char ();
     334              :         }
     335              :       break;
     336              : 
     337        14347 :     case '(':
     338        14347 :       token = FMT_LPAREN;
     339        14347 :       break;
     340              : 
     341        14317 :     case ')':
     342        14317 :       token = FMT_RPAREN;
     343        14317 :       break;
     344              : 
     345         1648 :     case 'X':
     346         1648 :       token = FMT_X;
     347         1648 :       break;
     348              : 
     349          156 :     case 'S':
     350          156 :       c = next_char_not_space ();
     351          156 :       if (c != 'P' && c != 'S')
     352           18 :         unget_char ();
     353              : 
     354              :       token = FMT_SIGN;
     355              :       break;
     356              : 
     357          336 :     case 'B':
     358          336 :       c = next_char_not_space ();
     359          336 :       if (c == 'N' || c == 'Z')
     360              :         token = FMT_BLANK;
     361              :       else
     362              :         {
     363          114 :           unget_char ();
     364          114 :           token = FMT_IBOZ;
     365              :         }
     366              : 
     367              :       break;
     368              : 
     369         2276 :     case '\'':
     370         2276 :     case '"':
     371         2276 :       delim = c;
     372              : 
     373         2276 :       value = 0;
     374              : 
     375        50546 :       for (;;)
     376              :         {
     377        26411 :           c = next_char (INSTRING_WARN);
     378        26411 :           if (c == '\0')
     379              :             {
     380              :               token = FMT_END;
     381              :               break;
     382              :             }
     383              : 
     384        26411 :           if (c == delim)
     385              :             {
     386         2450 :               c = next_char (NONSTRING);
     387              : 
     388         2450 :               if (c == '\0')
     389              :                 {
     390              :                   token = FMT_END;
     391              :                   break;
     392              :                 }
     393              : 
     394         2450 :               if (c != delim)
     395              :                 {
     396         2276 :                   unget_char ();
     397         2276 :                   token = FMT_CHAR;
     398         2276 :                   break;
     399              :                 }
     400              :             }
     401        24135 :           value++;
     402              :         }
     403              :       break;
     404              : 
     405          522 :     case 'P':
     406          522 :       token = FMT_P;
     407          522 :       break;
     408              : 
     409              :     case 'I':
     410              :     case 'O':
     411              :     case 'Z':
     412         4791 :       token = FMT_IBOZ;
     413              :       break;
     414              : 
     415         1903 :     case 'F':
     416         1903 :       token = FMT_F;
     417         1903 :       break;
     418              : 
     419         2238 :     case 'E':
     420         2238 :       c = next_char_not_space ();
     421         2238 :       if (c == 'N' )
     422              :         token = FMT_EN;
     423              :       else if (c == 'S')
     424              :         token = FMT_ES;
     425              :       else if (c == 'X')
     426              :         token = FMT_EX;
     427              :       else
     428              :         {
     429         1315 :           token = FMT_E;
     430         1315 :           unget_char ();
     431              :         }
     432              : 
     433              :       break;
     434              : 
     435         1032 :     case 'G':
     436         1032 :       token = FMT_G;
     437         1032 :       break;
     438              : 
     439          260 :     case 'H':
     440          260 :       token = FMT_H;
     441          260 :       break;
     442              : 
     443          306 :     case 'L':
     444          306 :       c = next_char_not_space ();
     445          306 :       switch (c)
     446              :         {
     447            0 :         case 'P':
     448            0 :           c = next_char_not_space ();
     449            0 :           switch (c)
     450              :           {
     451              :             case 'S':
     452              :               token = FMT_LPS;
     453              :               break;
     454              : 
     455              :             case 'Z':
     456              :               token = FMT_LPZ;
     457              :               break;
     458              : 
     459            0 :             default:
     460            0 :               token = FMT_UNKNOWN;
     461            0 :               unget_char ();
     462            0 :               break;
     463              :           }
     464              :           break;
     465              : 
     466              :         case 'Z':
     467              :           token = FMT_LZ;
     468              :           break;
     469              : 
     470          306 :         default:
     471          306 :           token = FMT_UNKNOWN;
     472          306 :           unget_char ();
     473          306 :           break;
     474              :         }
     475              :       token = FMT_L;
     476              :       break;
     477              : 
     478         7911 :     case 'A':
     479         7911 :       token = FMT_A;
     480         7911 :       break;
     481              : 
     482          405 :     case 'D':
     483          405 :       c = next_char_not_space ();
     484          405 :       if (c == 'P')
     485              :         {
     486           19 :           if (!gfc_notify_std (GFC_STD_F2003, "DP format "
     487              :                                "specifier not allowed at %C"))
     488              :             return FMT_ERROR;
     489              :           token = FMT_DP;
     490              :         }
     491          386 :       else if (c == 'C')
     492              :         {
     493           13 :           if (!gfc_notify_std (GFC_STD_F2003, "DC format "
     494              :                                "specifier not allowed at %C"))
     495              :             return FMT_ERROR;
     496              :           token = FMT_DC;
     497              :         }
     498          373 :       else if (c == 'T')
     499              :         {
     500          240 :           if (!gfc_notify_std (GFC_STD_F2003, "Fortran 2003: DT format "
     501              :               "specifier not allowed at %C"))
     502              :             return FMT_ERROR;
     503          240 :           token = FMT_DT;
     504          240 :           c = next_char_not_space ();
     505          240 :           if (c == '\'' || c == '"')
     506              :             {
     507           59 :               delim = c;
     508           59 :               value = 0;
     509              : 
     510          378 :               for (;;)
     511              :                 {
     512          378 :                   c = next_char (INSTRING_WARN);
     513          378 :                   if (c == '\0')
     514              :                     {
     515              :                       token = FMT_END;
     516              :                       break;
     517              :                     }
     518              : 
     519          378 :                   if (c == delim)
     520              :                     {
     521           60 :                       c = next_char (NONSTRING);
     522           60 :                       if (c == '\0')
     523              :                         {
     524              :                           token = FMT_END;
     525              :                           break;
     526              :                         }
     527           60 :                       if (c == '/')
     528              :                         {
     529              :                           token = FMT_SLASH;
     530              :                           break;
     531              :                         }
     532           59 :                       if (c == delim)
     533            1 :                         continue;
     534           58 :                       unget_char ();
     535           58 :                       break;
     536              :                     }
     537              :                 }
     538              :             }
     539          181 :           else if (c == '/')
     540              :             {
     541              :               token = FMT_SLASH;
     542              :               break;
     543              :             }
     544              :           else
     545          181 :             unget_char ();
     546              :         }
     547              :       else
     548              :         {
     549          133 :           token = FMT_D;
     550          133 :           unget_char ();
     551              :         }
     552              :       break;
     553              : 
     554           72 :     case 'R':
     555           72 :       c = next_char_not_space ();
     556           72 :       switch (c)
     557              :         {
     558              :         case 'C':
     559              :           token = FMT_RC;
     560              :           break;
     561            0 :         case 'D':
     562            0 :           token = FMT_RD;
     563            0 :           break;
     564           48 :         case 'N':
     565           48 :           token = FMT_RN;
     566           48 :           break;
     567            0 :         case 'P':
     568            0 :           token = FMT_RP;
     569            0 :           break;
     570           24 :         case 'U':
     571           24 :           token = FMT_RU;
     572           24 :           break;
     573            0 :         case 'Z':
     574            0 :           token = FMT_RZ;
     575            0 :           break;
     576            0 :         default:
     577            0 :           token = FMT_UNKNOWN;
     578            0 :           unget_char ();
     579            0 :           break;
     580              :         }
     581              :       break;
     582              : 
     583              :     case '\0':
     584            2 :       token = FMT_END;
     585              :       break;
     586              : 
     587          128 :     case '*':
     588          128 :       token = FMT_STAR;
     589          128 :       break;
     590              : 
     591              :     default:
     592            3 :       token = FMT_UNKNOWN;
     593              :       break;
     594              :     }
     595              : 
     596              :   return token;
     597              : }
     598              : 
     599              : 
     600              : static const char *
     601           19 : token_to_string (format_token t)
     602              : {
     603           19 :   switch (t)
     604              :     {
     605              :       case FMT_D:
     606              :         return "D";
     607            5 :       case FMT_G:
     608            5 :         return "G";
     609            6 :       case FMT_E:
     610            6 :         return "E";
     611            1 :       case FMT_EN:
     612            1 :         return "EN";
     613            0 :       case FMT_ES:
     614            0 :         return "ES";
     615            0 :       default:
     616            0 :         return "";
     617              :     }
     618              : }
     619              : 
     620              : /* Check a format statement.  The format string, either from a FORMAT
     621              :    statement or a constant in an I/O statement has already been parsed
     622              :    by itself, and we are checking it for validity.  The dual origin
     623              :    means that the warning message is a little less than great.  */
     624              : 
     625              : static bool
     626        13255 : check_format (bool is_input)
     627              : {
     628        13255 :   const char *posint_required
     629              :     = G_("Positive width required in format string at %L");
     630        13255 :   const char *nonneg_required
     631              :     = G_("Nonnegative width required in format string at %L");
     632        13255 :   const char *unexpected_element
     633              :     = G_("Unexpected element %qc in format string at %L");
     634        13255 :   const char *unexpected_end
     635              :     = G_("Unexpected end of format string in format string at %L");
     636        13255 :   const char *zero_width
     637              :     = G_("Zero width in format descriptor in format string at %L");
     638              : 
     639        13255 :   const char *error = NULL;
     640        13255 :   format_token t, u;
     641        13255 :   int level;
     642        13255 :   int repeat;
     643        13255 :   bool rv;
     644              : 
     645        13255 :   use_last_char = 0;
     646        13255 :   saved_token = FMT_NONE;
     647        13255 :   level = 0;
     648        13255 :   repeat = 0;
     649        13255 :   rv = true;
     650        13255 :   format_string_pos = 0;
     651              : 
     652        13255 :   t = format_lex ();
     653        13255 :   if (t == FMT_ERROR)
     654            0 :     goto fail;
     655        13255 :   if (t != FMT_LPAREN)
     656              :     {
     657            6 :       error = G_("Missing leading left parenthesis in format string at %L");
     658            6 :       goto syntax;
     659              :     }
     660              : 
     661        13249 :   t = format_lex ();
     662        13249 :   if (t == FMT_ERROR)
     663            0 :     goto fail;
     664        13249 :   if (t == FMT_RPAREN)
     665           52 :     goto finished;              /* Empty format is legal */
     666        13197 :   saved_token = t;
     667              : 
     668        25982 : format_item:
     669              :   /* In this state, the next thing has to be a format item.  */
     670        25982 :   t = format_lex ();
     671        25982 :   if (t == FMT_ERROR)
     672            0 :     goto fail;
     673        25982 : format_item_1:
     674        26023 :   switch (t)
     675              :     {
     676          128 :     case FMT_STAR:
     677          128 :       repeat = -1;
     678          128 :       t = format_lex ();
     679          128 :       if (t == FMT_ERROR)
     680            0 :         goto fail;
     681          128 :       if (t == FMT_LPAREN)
     682              :         {
     683          128 :           level++;
     684          128 :           goto format_item;
     685              :         }
     686            0 :       error = G_("Left parenthesis required after %<*%> in format string "
     687              :                  "at %L");
     688            0 :       goto syntax;
     689              : 
     690         5920 :     case FMT_POSINT:
     691         5920 :       repeat = value;
     692         5920 :       t = format_lex ();
     693         5920 :       if (t == FMT_ERROR)
     694            0 :         goto fail;
     695         5920 :       if (t == FMT_LPAREN)
     696              :         {
     697          782 :           level++;
     698          782 :           goto format_item;
     699              :         }
     700              : 
     701         5138 :       if (t == FMT_SLASH)
     702            6 :         goto optional_comma;
     703              : 
     704         5132 :       goto data_desc;
     705              : 
     706          164 :     case FMT_LPAREN:
     707          164 :       level++;
     708          164 :       goto format_item;
     709              : 
     710           30 :     case FMT_SIGNED_INT:
     711           30 :     case FMT_ZERO:
     712              :       /* Signed integer can only precede a P format.  */
     713           30 :       t = format_lex ();
     714           30 :       if (t == FMT_ERROR)
     715            0 :         goto fail;
     716           30 :       if (t != FMT_P)
     717              :         {
     718            1 :           error = G_("Expected P edit descriptor in format string at %L");
     719            1 :           goto syntax;
     720              :         }
     721              : 
     722           29 :       goto data_desc;
     723              : 
     724            0 :     case FMT_P:
     725              :       /* P requires a prior number.  */
     726            0 :       error = G_("P descriptor requires leading scale factor in format "
     727              :                  "string at %L");
     728            0 :       goto syntax;
     729              : 
     730            2 :     case FMT_X:
     731              :       /* X requires a prior number if we're being pedantic.  */
     732            2 :       if (mode != MODE_FORMAT)
     733            1 :         format_locus.nextc += format_string_pos;
     734            2 :       if (!gfc_notify_std (GFC_STD_GNU, "X descriptor requires leading "
     735              :                            "space count at %L", &format_locus))
     736              :         return false;
     737            2 :       goto between_desc;
     738              : 
     739          482 :     case FMT_SIGN:
     740          482 :     case FMT_BLANK:
     741          482 :     case FMT_DP:
     742          482 :     case FMT_DC:
     743          482 :     case FMT_RC:
     744          482 :     case FMT_RD:
     745          482 :     case FMT_RN:
     746          482 :     case FMT_RP:
     747          482 :     case FMT_RU:
     748          482 :     case FMT_RZ:
     749          482 :       goto between_desc;
     750              : 
     751         2276 :     case FMT_CHAR:
     752         2276 :       goto extension_optional_comma;
     753              : 
     754          645 :     case FMT_COLON:
     755          645 :     case FMT_SLASH:
     756          645 :       goto optional_comma;
     757              : 
     758           72 :     case FMT_DOLLAR:
     759           72 :       t = format_lex ();
     760           72 :       if (t == FMT_ERROR)
     761            0 :         goto fail;
     762              : 
     763           72 :       if (!gfc_notify_std (GFC_STD_GNU, "$ descriptor at %L", &format_locus))
     764              :         return false;
     765           72 :       if (t != FMT_RPAREN || level > 0)
     766              :         {
     767           18 :           gfc_warning (0, "$ should be the last specifier in format at %L",
     768              :                        &format_locus);
     769           18 :           goto optional_comma_1;
     770              :         }
     771              : 
     772           54 :       goto finished;
     773              : 
     774        16276 :     case FMT_T:
     775        16276 :     case FMT_TL:
     776        16276 :     case FMT_TR:
     777        16276 :     case FMT_IBOZ:
     778        16276 :     case FMT_F:
     779        16276 :     case FMT_E:
     780        16276 :     case FMT_EN:
     781        16276 :     case FMT_ES:
     782        16276 :     case FMT_EX:
     783        16276 :     case FMT_G:
     784        16276 :     case FMT_L:
     785        16276 :     case FMT_A:
     786        16276 :     case FMT_D:
     787        16276 :     case FMT_H:
     788        16276 :     case FMT_DT:
     789        16276 :       goto data_desc;
     790              : 
     791            0 :     case FMT_END:
     792            0 :       error = unexpected_end;
     793            0 :       goto syntax;
     794              : 
     795           25 :     case FMT_RPAREN:
     796           25 :       if (flag_dec_blank_format_item)
     797           24 :         goto finished;
     798              :       else
     799              :         {
     800            1 :           error = G_("Missing item in format string at %L");
     801            1 :           goto syntax;
     802              :         }
     803              : 
     804            3 :     default:
     805            3 :       error = unexpected_element;
     806            3 :       goto syntax;
     807              :     }
     808              : 
     809        21437 : data_desc:
     810              :   /* In this state, t must currently be a data descriptor.
     811              :      Deal with things that can/must follow the descriptor.  */
     812        21437 :   switch (t)
     813              :     {
     814              :     case FMT_SIGN:
     815              :     case FMT_BLANK:
     816              :     case FMT_DP:
     817              :     case FMT_DC:
     818              :     case FMT_X:
     819              :       break;
     820              : 
     821          522 :     case FMT_P:
     822              :       /* No comma after P allowed only for F, E, EN, ES, D, or G.
     823              :          10.1.1 (1).  */
     824          522 :       t = format_lex ();
     825          522 :       if (t == FMT_ERROR)
     826            0 :         goto fail;
     827          522 :       if (!(gfc_option.allow_std & GFC_STD_F2003) && t != FMT_COMMA
     828            6 :           && t != FMT_F && t != FMT_E && t != FMT_EN && t != FMT_ES
     829            4 :           && t != FMT_D && t != FMT_G && t != FMT_RPAREN && t != FMT_SLASH)
     830              :         {
     831            2 :           error = G_("Comma required after P descriptor in format string "
     832              :                      "at %L");
     833            2 :           goto syntax;
     834              :         }
     835          517 :       if (t != FMT_COMMA)
     836              :         {
     837          479 :           if (t == FMT_POSINT)
     838              :             {
     839            6 :               t = format_lex ();
     840            6 :               if (t == FMT_ERROR)
     841            0 :                 goto fail;
     842              :             }
     843          479 :           if (t != FMT_F && t != FMT_E && t != FMT_EN && t != FMT_ES
     844          479 :               && t != FMT_D && t != FMT_G && t != FMT_RPAREN && t != FMT_SLASH)
     845              :             {
     846            0 :               error = G_("Comma required after P descriptor in format string "
     847              :                          "at %L");
     848            0 :               goto syntax;
     849              :             }
     850              :         }
     851              : 
     852          520 :       saved_token = t;
     853          520 :       goto optional_comma;
     854              : 
     855          961 :     case FMT_T:
     856          961 :     case FMT_TL:
     857          961 :     case FMT_TR:
     858          961 :       t = format_lex ();
     859          961 :       if (t != FMT_POSINT)
     860              :         {
     861            1 :           error = G_("Positive width required with T descriptor in format "
     862              :                      "string at %L");
     863            1 :           goto syntax;
     864              :         }
     865              :       break;
     866              : 
     867          306 :     case FMT_L:
     868          306 :       t = format_lex ();
     869          306 :       if (t == FMT_ERROR)
     870            0 :         goto fail;
     871          306 :       if (t == FMT_POSINT)
     872              :         break;
     873           96 :       if (mode != MODE_FORMAT)
     874           96 :         format_locus.nextc += format_string_pos;
     875           96 :       if (t == FMT_ZERO)
     876              :         {
     877            0 :           switch (gfc_notification_std (GFC_STD_GNU))
     878              :             {
     879            0 :               case WARNING:
     880            0 :                 gfc_warning (0, "Extension: Zero width after L "
     881              :                              "descriptor at %L", &format_locus);
     882            0 :                 break;
     883            0 :               case ERROR:
     884            0 :                 gfc_error ("Extension: Zero width after L "
     885              :                              "descriptor at %L", &format_locus);
     886            0 :                 goto fail;
     887              :               case SILENT:
     888              :                 break;
     889            0 :               default:
     890            0 :                 gcc_unreachable ();
     891              :             }
     892              :         }
     893              :       else
     894              :         {
     895           96 :           saved_token = t;
     896           96 :           gfc_notify_std (GFC_STD_GNU, "Missing positive width after "
     897              :                           "L descriptor at %L", &format_locus);
     898              :         }
     899              :       break;
     900              : 
     901         7905 :     case FMT_A:
     902         7905 :       t = format_lex ();
     903         7905 :       if (t == FMT_ERROR)
     904            0 :         goto fail;
     905         7905 :       if (t == FMT_ZERO)
     906              :         {
     907            0 :           error = zero_width;
     908            0 :           goto syntax;
     909              :         }
     910         7905 :       if (t != FMT_POSINT)
     911         6332 :         saved_token = t;
     912              :       break;
     913              : 
     914         2905 :     case FMT_D:
     915         2905 :     case FMT_E:
     916         2905 :     case FMT_EX:
     917         2905 :     case FMT_G:
     918         2905 :     case FMT_EN:
     919         2905 :     case FMT_ES:
     920         2905 :       u = format_lex ();
     921         2905 :       if (t == FMT_G && u == FMT_ZERO)
     922              :         {
     923          403 :           if (is_input)
     924              :             {
     925            0 :               error = zero_width;
     926            0 :               goto syntax;
     927              :             }
     928          403 :           if (!gfc_notify_std (GFC_STD_F2008, "%<G0%> in format at %L",
     929              :                                &format_locus))
     930              :             return false;
     931          402 :           u = format_lex ();
     932          402 :           if (u != FMT_PERIOD)
     933              :             {
     934          360 :               saved_token = u;
     935          360 :               break;
     936              :             }
     937           42 :           u = format_lex ();
     938           42 :           if (u != FMT_POSINT)
     939              :             {
     940            0 :               error = posint_required;
     941            0 :               goto syntax;
     942              :             }
     943           42 :           u = format_lex ();
     944           42 :           if (u == FMT_E)
     945              :             {
     946            0 :               error = G_("E specifier not allowed with g0 descriptor in "
     947              :                          "format string at %L");
     948            0 :               goto syntax;
     949              :             }
     950           42 :           saved_token = u;
     951           42 :           break;
     952              :         }
     953              : 
     954         2502 :       if (u != FMT_POSINT)
     955              :         {
     956          768 :           if (flag_dec)
     957              :             {
     958           35 :               if (flag_dec_format_defaults)
     959              :                 {
     960              :                   /* Assume a default width based on the variable size.  */
     961           30 :                   saved_token = u;
     962           30 :                   break;
     963              :                 }
     964              :               else
     965              :                 {
     966            5 :                   gfc_error ("Positive width required in format "
     967              :                              "specifier %s at %L", token_to_string (t),
     968              :                              &format_locus);
     969            5 :                   saved_token = u;
     970            5 :                   goto fail;
     971              :                 }
     972              :             }
     973              : 
     974          733 :           format_locus.nextc += format_string_pos;
     975          733 :           if (!gfc_notify_std (GFC_STD_F2018,
     976              :                                "positive width required at %L",
     977              :                                &format_locus))
     978              :             {
     979            1 :               saved_token = u;
     980            1 :               goto fail;
     981              :             }
     982          732 :           if (flag_dec_format_defaults)
     983              :             {
     984              :               /* Assume a default width based on the variable size.  */
     985           30 :               saved_token = u;
     986           30 :               break;
     987              :             }
     988              :         }
     989              : 
     990         2436 :       u = format_lex ();
     991         2436 :       if (u == FMT_ERROR)
     992            0 :         goto fail;
     993         2436 :       if (u != FMT_PERIOD)
     994              :         {
     995              :           /* Warn if -std=legacy, otherwise error.  */
     996           14 :           format_locus.nextc += format_string_pos;
     997           14 :           if (gfc_option.warn_std != 0)
     998              :             {
     999            2 :               gfc_error ("Period required in format "
    1000              :                              "specifier %s at %L", token_to_string (t),
    1001              :                              &format_locus);
    1002            2 :               saved_token = u;
    1003            2 :               goto fail;
    1004              :             }
    1005              :           else
    1006           12 :             gfc_warning (0, "Period required in format "
    1007              :                          "specifier %s at %L", token_to_string (t),
    1008              :                           &format_locus);
    1009              :           /* If we go to finished, we need to unwind this
    1010              :              before the next round.  */
    1011           12 :           format_locus.nextc -= format_string_pos;
    1012           12 :           saved_token = u;
    1013           12 :           break;
    1014              :         }
    1015              : 
    1016         2422 :       u = format_lex ();
    1017         2422 :       if (u == FMT_ERROR)
    1018            0 :         goto fail;
    1019         2422 :       if (u != FMT_ZERO && u != FMT_POSINT)
    1020              :         {
    1021            0 :           error = nonneg_required;
    1022            0 :           goto syntax;
    1023              :         }
    1024              : 
    1025         2422 :       if (t == FMT_D)
    1026              :         break;
    1027              : 
    1028              :       /* Look for optional exponent.  */
    1029         2296 :       u = format_lex ();
    1030         2296 :       if (u == FMT_ERROR)
    1031            0 :         goto fail;
    1032         2296 :       if (u != FMT_E)
    1033         1798 :         saved_token = u;
    1034              :       else
    1035              :         {
    1036          498 :           u = format_lex ();
    1037          498 :           if (u == FMT_ERROR)
    1038            0 :             goto fail;
    1039          498 :           if (u != FMT_POSINT)
    1040              :             {
    1041          108 :               if (u == FMT_ZERO)
    1042              :                 {
    1043          108 :                   if (!gfc_notify_std (GFC_STD_F2018,
    1044              :                                       "Positive exponent width required in "
    1045              :                                       "format string at %L", &format_locus))
    1046              :                     {
    1047            0 :                       saved_token = u;
    1048            0 :                       goto fail;
    1049              :                     }
    1050              :                 }
    1051              :               else
    1052              :                 {
    1053            0 :                   error = G_("Positive exponent width required in format "
    1054              :                              "string at %L");
    1055            0 :                   goto syntax;
    1056              :                 }
    1057              :             }
    1058              :         }
    1059              : 
    1060              :       break;
    1061              : 
    1062          239 :     case FMT_DT:
    1063          239 :       t = format_lex ();
    1064          239 :       if (t == FMT_ERROR)
    1065            0 :         goto fail;
    1066          239 :       switch (t)
    1067              :         {
    1068          173 :         case FMT_RPAREN:
    1069          173 :           level--;
    1070          173 :           if (level < 0)
    1071          167 :             goto finished;
    1072            6 :           goto between_desc;
    1073              : 
    1074           36 :         case FMT_COMMA:
    1075           36 :           goto format_item;
    1076              : 
    1077            6 :         case FMT_COLON:
    1078            6 :           goto format_item_1;
    1079              : 
    1080           60 :         case FMT_LPAREN:
    1081              : 
    1082           60 :   dtio_vlist:
    1083           60 :           t = format_lex ();
    1084           60 :           if (t == FMT_ERROR)
    1085            0 :             goto fail;
    1086              : 
    1087           60 :           if (t != FMT_POSINT)
    1088              :             {
    1089            0 :               error = posint_required;
    1090            0 :               goto syntax;
    1091              :             }
    1092              : 
    1093           60 :           t = format_lex ();
    1094           60 :           if (t == FMT_ERROR)
    1095            0 :             goto fail;
    1096              : 
    1097           60 :           if (t == FMT_COMMA)
    1098           36 :             goto dtio_vlist;
    1099           24 :           if (t != FMT_RPAREN)
    1100              :             {
    1101            0 :               error = G_("Right parenthesis expected at %C in format string "
    1102              :                          "at %L");
    1103            0 :               goto syntax;
    1104              :             }
    1105           24 :           goto between_desc;
    1106              : 
    1107            0 :         default:
    1108            0 :           error = unexpected_element;
    1109            0 :           goto syntax;
    1110              :         }
    1111         1902 :       break;
    1112              : 
    1113         1902 :     case FMT_F:
    1114         1902 :       t = format_lex ();
    1115         1902 :       if (t == FMT_ERROR)
    1116            0 :         goto fail;
    1117         1902 :       if (t != FMT_ZERO && t != FMT_POSINT)
    1118              :         {
    1119           52 :           if (flag_dec_format_defaults)
    1120              :             {
    1121              :               /* Assume the default width is expected here and continue lexing.  */
    1122           48 :               value = 0; /* It doesn't matter what we set the value to here.  */
    1123           48 :               saved_token = t;
    1124           48 :               break;
    1125              :             }
    1126            4 :           error = nonneg_required;
    1127            4 :           goto syntax;
    1128              :         }
    1129         1850 :       else if (is_input && t == FMT_ZERO)
    1130              :         {
    1131            1 :           error = posint_required;
    1132            1 :           goto syntax;
    1133              :         }
    1134              : 
    1135         1849 :       t = format_lex ();
    1136         1849 :       if (t == FMT_ERROR)
    1137            0 :         goto fail;
    1138         1849 :       if (t != FMT_PERIOD)
    1139              :         {
    1140              :           /* Warn if -std=legacy, otherwise error.  */
    1141            7 :           if (gfc_option.warn_std != 0)
    1142              :             {
    1143            1 :               error = G_("Period required in format specifier in format "
    1144              :                          "string at %L");
    1145            1 :               goto syntax;
    1146              :             }
    1147            6 :           if (mode != MODE_FORMAT)
    1148            6 :             format_locus.nextc += format_string_pos;
    1149            6 :           gfc_warning (0, "Period required in format specifier at %L",
    1150              :                        &format_locus);
    1151            6 :           saved_token = t;
    1152            6 :           break;
    1153              :         }
    1154              : 
    1155         1842 :       t = format_lex ();
    1156         1842 :       if (t == FMT_ERROR)
    1157            0 :         goto fail;
    1158         1842 :       if (t != FMT_ZERO && t != FMT_POSINT)
    1159              :         {
    1160            0 :           error = nonneg_required;
    1161            0 :           goto syntax;
    1162              :         }
    1163              : 
    1164              :       break;
    1165              : 
    1166          260 :     case FMT_H:
    1167          260 :       if (!(gfc_option.allow_std & GFC_STD_LEGACY))
    1168              :         {
    1169            0 :           error = G_("The H format specifier at %L is a Fortran 95 deleted"
    1170              :                      " feature");
    1171            0 :           goto syntax;
    1172              :         }
    1173          260 :       if (mode != MODE_FORMAT)
    1174          160 :         format_locus.nextc += format_string_pos;
    1175          260 :       gfc_warning (0, "The H format specifier at %L is"
    1176              :                    " a Fortran 95 deleted feature", &format_locus);
    1177          260 :       if (mode == MODE_STRING)
    1178              :         {
    1179           61 :           format_string += value;
    1180           61 :           format_length -= value;
    1181           61 :           format_string_pos += repeat;
    1182              :         }
    1183              :       else
    1184              :         {
    1185         1492 :           while (repeat > 0)
    1186              :            {
    1187         1293 :              next_char (INSTRING_WARN);
    1188         1293 :              repeat -- ;
    1189              :            }
    1190              :         }
    1191              :      break;
    1192              : 
    1193         4791 :     case FMT_IBOZ:
    1194         4791 :       t = format_lex ();
    1195         4791 :       if (t == FMT_ERROR)
    1196            0 :         goto fail;
    1197         4791 :       if (t != FMT_ZERO && t != FMT_POSINT)
    1198              :         {
    1199           67 :           if (flag_dec_format_defaults)
    1200              :             {
    1201              :               /* Assume the default width is expected here and continue lexing.  */
    1202           60 :               value = 0; /* It doesn't matter what we set the value to here.  */
    1203           60 :               saved_token = t;
    1204              :             }
    1205              :           else
    1206              :             {
    1207            7 :               error = nonneg_required;
    1208            7 :               goto syntax;
    1209              :             }
    1210              :         }
    1211         4724 :       else if (is_input && t == FMT_ZERO)
    1212              :         {
    1213            2 :           error = posint_required;
    1214            2 :           goto syntax;
    1215              :         }
    1216              : 
    1217         4782 :       t = format_lex ();
    1218         4782 :       if (t == FMT_ERROR)
    1219            0 :         goto fail;
    1220         4782 :       if (t != FMT_PERIOD)
    1221         4338 :         saved_token = t;
    1222              :       else
    1223              :         {
    1224          444 :           t = format_lex ();
    1225          444 :           if (t == FMT_ERROR)
    1226            0 :             goto fail;
    1227          444 :           if (t != FMT_ZERO && t != FMT_POSINT)
    1228              :             {
    1229            0 :               error = nonneg_required;
    1230            0 :               goto syntax;
    1231              :             }
    1232              :         }
    1233              : 
    1234              :       break;
    1235              : 
    1236            0 :     default:
    1237            0 :       error = unexpected_element;
    1238            0 :       goto syntax;
    1239              :     }
    1240              : 
    1241          336 : between_desc:
    1242              :   /* Between a descriptor and what comes next.  */
    1243        22233 :   t = format_lex ();
    1244        22233 :   if (t == FMT_ERROR)
    1245            0 :     goto fail;
    1246        22233 :   switch (t)
    1247              :     {
    1248              : 
    1249         9260 :     case FMT_COMMA:
    1250         9260 :       goto format_item;
    1251              : 
    1252        12686 :     case FMT_RPAREN:
    1253        12686 :       level--;
    1254        12686 :       if (level < 0)
    1255        11878 :         goto finished;
    1256          808 :       goto between_desc;
    1257              : 
    1258          250 :     case FMT_COLON:
    1259          250 :     case FMT_SLASH:
    1260          250 :       goto optional_comma;
    1261              : 
    1262            2 :     case FMT_END:
    1263            2 :       error = unexpected_end;
    1264            2 :       goto syntax;
    1265              : 
    1266           35 :     default:
    1267           35 :       if (mode != MODE_FORMAT)
    1268           26 :         format_locus.nextc += format_string_pos - 1;
    1269           35 :       if (!gfc_notify_std (GFC_STD_LEGACY,
    1270              :           "Missing comma in FORMAT string at %L", &format_locus))
    1271              :         return false;
    1272              :       /* If we do not actually return a failure, we need to unwind this
    1273              :          before the next round.  */
    1274           35 :       if (mode != MODE_FORMAT)
    1275           26 :         format_locus.nextc -= format_string_pos;
    1276           35 :       goto format_item_1;
    1277              :     }
    1278              : 
    1279         1464 : optional_comma:
    1280              :   /* Optional comma is a weird between state where we've just finished
    1281              :      reading a colon, slash, dollar or P descriptor.  */
    1282         1464 :   t = format_lex ();
    1283         1464 :   if (t == FMT_ERROR)
    1284            0 :     goto fail;
    1285         1464 : optional_comma_1:
    1286         1482 :   switch (t)
    1287              :     {
    1288              :     case FMT_COMMA:
    1289              :       break;
    1290              : 
    1291          244 :     case FMT_RPAREN:
    1292          244 :       level--;
    1293          244 :       if (level < 0)
    1294          110 :         goto finished;
    1295          134 :       goto between_desc;
    1296              : 
    1297          855 :     default:
    1298              :       /* Assume that we have another format item.  */
    1299          855 :       saved_token = t;
    1300          855 :       break;
    1301              :     }
    1302              : 
    1303         1238 :   goto format_item;
    1304              : 
    1305         2276 : extension_optional_comma:
    1306              :   /* As a GNU extension, permit a missing comma after a string literal.  */
    1307         2276 :   t = format_lex ();
    1308         2276 :   if (t == FMT_ERROR)
    1309            0 :     goto fail;
    1310         2276 :   switch (t)
    1311              :     {
    1312              :     case FMT_COMMA:
    1313              :       break;
    1314              : 
    1315         1056 :     case FMT_RPAREN:
    1316         1056 :       level--;
    1317         1056 :       if (level < 0)
    1318          930 :         goto finished;
    1319          126 :       goto between_desc;
    1320              : 
    1321           43 :     case FMT_COLON:
    1322           43 :     case FMT_SLASH:
    1323           43 :       goto optional_comma;
    1324              : 
    1325            0 :     case FMT_END:
    1326            0 :       error = unexpected_end;
    1327            0 :       goto syntax;
    1328              : 
    1329           24 :     default:
    1330           24 :       if (mode != MODE_FORMAT)
    1331           12 :         format_locus.nextc += format_string_pos;
    1332           24 :       if (!gfc_notify_std (GFC_STD_LEGACY,
    1333              :           "Missing comma in FORMAT string at %L", &format_locus))
    1334              :         return false;
    1335              :       /* If we do not actually return a failure, we need to unwind this
    1336              :          before the next round.  */
    1337           24 :       if (mode != MODE_FORMAT)
    1338           12 :         format_locus.nextc -= format_string_pos;
    1339           24 :       saved_token = t;
    1340           24 :       break;
    1341              :     }
    1342              : 
    1343         1177 :   goto format_item;
    1344              : 
    1345           31 : syntax:
    1346           31 :   if (mode != MODE_FORMAT)
    1347           26 :     format_locus.nextc += format_string_pos;
    1348           31 :   if (error == unexpected_element)
    1349            3 :     gfc_error (error, error_element, &format_locus);
    1350              :   else
    1351           28 :     gfc_error (error, &format_locus);
    1352              : fail:
    1353              :   rv = false;
    1354              : 
    1355              : finished:
    1356              :   return rv;
    1357              : }
    1358              : 
    1359              : 
    1360              : /* Given an expression node that is a constant string, see if it looks
    1361              :    like a format string.  */
    1362              : 
    1363              : static bool
    1364        12287 : check_format_string (gfc_expr *e, bool is_input)
    1365              : {
    1366        12287 :   bool rv;
    1367        12287 :   int i;
    1368        12287 :   if (!e || e->ts.type != BT_CHARACTER || e->expr_type != EXPR_CONSTANT)
    1369              :     return true;
    1370              : 
    1371        11216 :   mode = MODE_STRING;
    1372        11216 :   format_string = e->value.character.string;
    1373              : 
    1374              :   /* More elaborate measures are needed to show where a problem is within a
    1375              :      format string that has been calculated, but that's probably not worth the
    1376              :      effort.  */
    1377        11216 :   format_locus = e->where;
    1378        11216 :   rv = check_format (is_input);
    1379              :   /* check for extraneous characters at the end of an otherwise valid format
    1380              :      string, like '(A10,I3)F5'
    1381              :      start at the end and move back to the last character processed,
    1382              :      spaces are OK */
    1383        11216 :   if (rv && e->value.character.length > format_string_pos)
    1384           75 :     for (i=e->value.character.length-1;i>format_string_pos-1;i--)
    1385           72 :       if (e->value.character.string[i] != ' ')
    1386              :         {
    1387            1 :           format_locus.nextc += format_length + 1;
    1388            1 :           gfc_warning (0,
    1389              :                        "Extraneous characters in format at %L", &format_locus);
    1390            1 :           break;
    1391              :         }
    1392              :   return rv;
    1393              : }
    1394              : 
    1395              : 
    1396              : /************ Fortran I/O statement matchers *************/
    1397              : 
    1398              : /* Match a FORMAT statement.  This amounts to actually parsing the
    1399              :    format descriptors in order to correctly locate the end of the
    1400              :    format string.  */
    1401              : 
    1402              : match
    1403         1024 : gfc_match_format (void)
    1404              : {
    1405         1024 :   gfc_expr *e;
    1406         1024 :   locus start;
    1407              : 
    1408         1024 :   if (gfc_current_ns->proc_name
    1409          997 :       && gfc_current_ns->proc_name->attr.flavor == FL_MODULE)
    1410              :     {
    1411            1 :       gfc_error ("Format statement in module main block at %C");
    1412            1 :       return MATCH_ERROR;
    1413              :     }
    1414              : 
    1415              :   /* Before parsing the rest of a FORMAT statement, check F2008:c1206.  */
    1416         1023 :   if ((gfc_current_state () == COMP_FUNCTION
    1417         1023 :        || gfc_current_state () == COMP_SUBROUTINE)
    1418          171 :       && gfc_state_stack->previous->state == COMP_INTERFACE)
    1419              :     {
    1420            1 :       gfc_error ("FORMAT statement at %C cannot appear within an INTERFACE");
    1421            1 :       return MATCH_ERROR;
    1422              :     }
    1423              : 
    1424         1022 :   if (gfc_statement_label == NULL)
    1425              :     {
    1426            0 :       gfc_error ("Missing format label at %C");
    1427            0 :       return MATCH_ERROR;
    1428              :     }
    1429         1022 :   gfc_gobble_whitespace ();
    1430              : 
    1431         1022 :   mode = MODE_FORMAT;
    1432         1022 :   format_length = 0;
    1433              : 
    1434         1022 :   start = gfc_current_locus;
    1435              : 
    1436         1022 :   if (!check_format (false))
    1437              :     return MATCH_ERROR;
    1438              : 
    1439         1017 :   if (gfc_match_eos () != MATCH_YES)
    1440              :     {
    1441            0 :       gfc_syntax_error (ST_FORMAT);
    1442            0 :       return MATCH_ERROR;
    1443              :     }
    1444              : 
    1445              :   /* The label doesn't get created until after the statement is done
    1446              :      being matched, so we have to leave the string for later.  */
    1447              : 
    1448         1017 :   gfc_current_locus = start;    /* Back to the beginning */
    1449              : 
    1450         1017 :   new_st.loc = start;
    1451         1017 :   new_st.op = EXEC_NOP;
    1452              : 
    1453         1017 :   e = gfc_get_character_expr (gfc_default_character_kind, &start,
    1454              :                               NULL, format_length);
    1455         1017 :   format_string = e->value.character.string;
    1456         1017 :   gfc_statement_label->format = e;
    1457              : 
    1458         1017 :   mode = MODE_COPY;
    1459         1017 :   check_format (false);         /* Guaranteed to succeed */
    1460         1017 :   gfc_match_eos ();             /* Guaranteed to succeed */
    1461              : 
    1462         1017 :   return MATCH_YES;
    1463              : }
    1464              : 
    1465              : 
    1466              : /* Match an expression I/O tag of some sort.  */
    1467              : 
    1468              : static match
    1469       671617 : match_etag (const io_tag *tag, gfc_expr **v)
    1470              : {
    1471       671617 :   gfc_expr *result;
    1472       671617 :   match m;
    1473              : 
    1474       671617 :   m = gfc_match (tag->spec);
    1475       671617 :   if (m != MATCH_YES)
    1476              :     return m;
    1477              : 
    1478        12791 :   m = gfc_match (tag->value, &result);
    1479        12791 :   if (m != MATCH_YES)
    1480              :     {
    1481            0 :       gfc_error ("Invalid value for %s specification at %C", tag->name);
    1482            0 :       return MATCH_ERROR;
    1483              :     }
    1484              : 
    1485        12791 :   if (*v != NULL)
    1486              :     {
    1487            2 :       gfc_error ("Duplicate %s specification at %C", tag->name);
    1488            2 :       gfc_free_expr (result);
    1489            2 :       return MATCH_ERROR;
    1490              :     }
    1491              : 
    1492        12789 :   *v = result;
    1493        12789 :   return MATCH_YES;
    1494              : }
    1495              : 
    1496              : 
    1497              : /* Match a variable I/O tag of some sort.  */
    1498              : 
    1499              : static match
    1500       196569 : match_vtag (const io_tag *tag, gfc_expr **v)
    1501              : {
    1502       196569 :   gfc_expr *result;
    1503       196569 :   match m;
    1504              : 
    1505       196569 :   m = gfc_match (tag->spec);
    1506       196569 :   if (m != MATCH_YES)
    1507              :     return m;
    1508              : 
    1509         4045 :   m = gfc_match (tag->value, &result);
    1510         4045 :   if (m != MATCH_YES)
    1511              :     {
    1512            1 :       gfc_error ("Invalid value for %s specification at %C", tag->name);
    1513            1 :       return MATCH_ERROR;
    1514              :     }
    1515              : 
    1516         4044 :   if (*v != NULL)
    1517              :     {
    1518            0 :       gfc_error ("Duplicate %s specification at %C", tag->name);
    1519            0 :       gfc_free_expr (result);
    1520            0 :       return MATCH_ERROR;
    1521              :     }
    1522              : 
    1523         4044 :   if (result->symtree)
    1524              :     {
    1525         4040 :       bool impure;
    1526              : 
    1527         4040 :       if (result->symtree->n.sym->attr.intent == INTENT_IN)
    1528              :         {
    1529            0 :           gfc_error ("Variable %s cannot be INTENT(IN) at %C", tag->name);
    1530            0 :           gfc_free_expr (result);
    1531            0 :           return MATCH_ERROR;
    1532              :         }
    1533              : 
    1534         4040 :       impure = gfc_impure_variable (result->symtree->n.sym);
    1535         4040 :       if (impure && gfc_pure (NULL))
    1536              :         {
    1537            0 :           gfc_error ("Variable %s cannot be assigned in PURE procedure at %C",
    1538            0 :                      tag->name);
    1539            0 :           gfc_free_expr (result);
    1540            0 :           return MATCH_ERROR;
    1541              :         }
    1542              : 
    1543         4040 :       if (impure)
    1544           28 :         gfc_unset_implicit_pure (NULL);
    1545              :     }
    1546              : 
    1547         4044 :   *v = result;
    1548         4044 :   return MATCH_YES;
    1549              : }
    1550              : 
    1551              : 
    1552              : /* Match I/O tags that cause variables to become redefined.  */
    1553              : 
    1554              : static match
    1555       168786 : match_out_tag (const io_tag *tag, gfc_expr **result)
    1556              : {
    1557       168786 :   match m;
    1558              : 
    1559       168786 :   m = match_vtag (tag, result);
    1560       168786 :   if (m == MATCH_YES)
    1561              :     {
    1562         2827 :       if ((*result)->symtree)
    1563         2823 :         gfc_check_do_variable ((*result)->symtree);
    1564              : 
    1565         2827 :       if ((*result)->expr_type == EXPR_CONSTANT)
    1566              :         {
    1567            4 :           gfc_error ("Expecting a variable at %L", &(*result)->where);
    1568            4 :           return MATCH_ERROR;
    1569              :         }
    1570              :     }
    1571              : 
    1572              :   return m;
    1573              : }
    1574              : 
    1575              : 
    1576              : /* Match a label I/O tag.  */
    1577              : 
    1578              : static match
    1579       147256 : match_ltag (const io_tag *tag, gfc_st_label ** label)
    1580              : {
    1581       147256 :   match m;
    1582       147256 :   gfc_st_label *old;
    1583              : 
    1584       147256 :   old = *label;
    1585       147256 :   m = gfc_match (tag->spec);
    1586       147256 :   if (m != MATCH_YES)
    1587              :     return m;
    1588              : 
    1589         1017 :   m = gfc_match (tag->value, label);
    1590         1017 :   if (m != MATCH_YES)
    1591              :     {
    1592            4 :       gfc_error ("Invalid value for %s specification at %C", tag->name);
    1593            4 :       return MATCH_ERROR;
    1594              :     }
    1595              : 
    1596         1013 :   if (old)
    1597              :     {
    1598            0 :       gfc_error ("Duplicate %s label specification at %C", tag->name);
    1599            0 :       return MATCH_ERROR;
    1600              :     }
    1601              : 
    1602         1013 :   if (!gfc_reference_st_label (*label, ST_LABEL_TARGET))
    1603              :     return MATCH_ERROR;
    1604              : 
    1605              :   return m;
    1606              : }
    1607              : 
    1608              : 
    1609              : /* Match a tag using match_etag, but only if -fdec is enabled.  */
    1610              : static match
    1611         5832 : match_dec_etag (const io_tag *tag, gfc_expr **e)
    1612              : {
    1613         5832 :   match m = match_etag (tag, e);
    1614         5832 :   if (flag_dec && m != MATCH_NO)
    1615              :     return m;
    1616         5669 :   else if (m != MATCH_NO)
    1617              :     {
    1618            7 :       gfc_error ("%s at %C is a DEC extension, enable with "
    1619            7 :                  "%<-fdec%>", tag->name);
    1620            7 :       return MATCH_ERROR;
    1621              :     }
    1622              :   return m;
    1623              : }
    1624              : 
    1625              : 
    1626              : /* Match a tag using match_vtag, but only if -fdec is enabled.  */
    1627              : static match
    1628          625 : match_dec_vtag (const io_tag *tag, gfc_expr **e)
    1629              : {
    1630          625 :   match m = match_vtag(tag, e);
    1631          625 :   if (flag_dec && m != MATCH_NO)
    1632              :     return m;
    1633          607 :   else if (m != MATCH_NO)
    1634              :     {
    1635            2 :       gfc_error ("%s at %C is a DEC extension, enable with "
    1636            2 :                  "%<-fdec%>", tag->name);
    1637            2 :       return MATCH_ERROR;
    1638              :     }
    1639              :   return m;
    1640              : }
    1641              : 
    1642              : 
    1643              : /* Match a DEC I/O flag tag - a tag with no expression such as READONLY.  */
    1644              : 
    1645              : static match
    1646         8569 : match_dec_ftag (const io_tag *tag, gfc_open *o)
    1647              : {
    1648         8569 :   match m;
    1649              : 
    1650         8569 :   m = gfc_match (tag->spec);
    1651         8569 :   if (m != MATCH_YES)
    1652              :     return m;
    1653              : 
    1654           44 :   if (!flag_dec)
    1655              :     {
    1656            6 :       gfc_error ("%s at %C is a DEC extension, enable with "
    1657            6 :                  "%<-fdec%>", tag->name);
    1658            6 :       return MATCH_ERROR;
    1659              :     }
    1660              : 
    1661              :   /* Just set the READONLY flag, which we use at runtime to avoid delete on
    1662              :      close.  */
    1663           38 :   if (tag == &tag_readonly)
    1664              :     {
    1665           22 :       o->readonly |= 1;
    1666           22 :       return MATCH_YES;
    1667              :     }
    1668              : 
    1669              :   /* Interpret SHARED as SHARE='DENYNONE' (read lock).  */
    1670           16 :   else if (tag == &tag_shared)
    1671              :     {
    1672            9 :       if (o->share != NULL)
    1673              :         {
    1674            2 :           gfc_error ("Duplicate %s specification at %C", tag->name);
    1675            2 :           return MATCH_ERROR;
    1676              :         }
    1677            7 :       o->share = gfc_get_character_expr (gfc_default_character_kind,
    1678              :           &gfc_current_locus, "denynone", 8);
    1679            7 :       return MATCH_YES;
    1680              :     }
    1681              : 
    1682              :   /* Interpret NOSHARED as SHARE='DENYRW' (exclusive lock).  */
    1683            7 :   else if (tag == &tag_noshared)
    1684              :     {
    1685            7 :       if (o->share != NULL)
    1686              :         {
    1687            0 :           gfc_error ("Duplicate %s specification at %C", tag->name);
    1688            0 :           return MATCH_ERROR;
    1689              :         }
    1690            7 :       o->share = gfc_get_character_expr (gfc_default_character_kind,
    1691              :           &gfc_current_locus, "denyrw", 6);
    1692            7 :       return MATCH_YES;
    1693              :     }
    1694              : 
    1695              :   /* We handle all DEC tags above.  */
    1696            0 :   gcc_unreachable ();
    1697              : }
    1698              : 
    1699              : 
    1700              : /* Resolution of the FORMAT tag, to be called from resolve_tag.  */
    1701              : 
    1702              : static bool
    1703        12248 : resolve_tag_format (gfc_expr *e)
    1704              : {
    1705        12248 :   if (e->expr_type == EXPR_CONSTANT
    1706        11185 :       && (e->ts.type != BT_CHARACTER
    1707        11181 :           || e->ts.kind != gfc_default_character_kind))
    1708              :     {
    1709            4 :       gfc_error ("Constant expression in FORMAT tag at %L must be "
    1710              :                  "of type default CHARACTER", &e->where);
    1711            4 :       return false;
    1712              :     }
    1713              : 
    1714              :   /* Concatenate a constant character array into a single character
    1715              :      expression.  */
    1716              : 
    1717        12222 :   if ((e->expr_type == EXPR_ARRAY || e->rank > 0)
    1718          111 :       && e->ts.type == BT_CHARACTER
    1719        12317 :       && gfc_is_constant_expr (e))
    1720              :     {
    1721            2 :       if (e->expr_type == EXPR_VARIABLE
    1722            0 :           && e->symtree->n.sym->attr.flavor == FL_PARAMETER)
    1723            0 :         gfc_simplify_expr (e, 1);
    1724              : 
    1725            2 :       if (e->expr_type == EXPR_ARRAY)
    1726              :         {
    1727            2 :           gfc_constructor *c;
    1728            2 :           gfc_charlen_t n, len;
    1729            2 :           gfc_expr *r;
    1730            2 :           gfc_char_t *dest, *src;
    1731              : 
    1732            2 :           if (e->value.constructor == NULL)
    1733              :            {
    1734            1 :              gfc_error ("FORMAT tag at %L cannot be a zero-sized array",
    1735              :                         &e->where);
    1736            1 :              return false;
    1737              :            }
    1738              : 
    1739            1 :           n = 0;
    1740            1 :           c = gfc_constructor_first (e->value.constructor);
    1741            1 :           len = c->expr->value.character.length;
    1742              : 
    1743           10 :           for ( ; c; c = gfc_constructor_next (c))
    1744            9 :             n += len;
    1745              : 
    1746            1 :           r = gfc_get_character_expr (e->ts.kind, &e->where, NULL, n);
    1747            1 :           dest = r->value.character.string;
    1748              : 
    1749            1 :           for (c = gfc_constructor_first (e->value.constructor);
    1750           10 :              c; c = gfc_constructor_next (c))
    1751              :             {
    1752            9 :               src = c->expr->value.character.string;
    1753           27 :               for (gfc_charlen_t i = 0 ; i < len; i++)
    1754           18 :                 *dest++ = *src++;
    1755              :             }
    1756              : 
    1757            1 :           gfc_replace_expr (e, r);
    1758            1 :           return true;
    1759              :         }
    1760              :     }
    1761              : 
    1762              :   /* If e's rank is zero and e is not an element of an array, it should be
    1763              :      of integer or character type.  The integer variable should be
    1764              :      ASSIGNED.  */
    1765        12242 :   if (e->rank == 0
    1766        12133 :       && (e->expr_type != EXPR_VARIABLE
    1767          922 :           || e->symtree == NULL
    1768          922 :           || e->symtree->n.sym->as == NULL
    1769           79 :           || e->symtree->n.sym->as->rank == 0))
    1770              :     {
    1771        12054 :       if ((e->ts.type != BT_CHARACTER
    1772        12045 :            || e->ts.kind != gfc_default_character_kind)
    1773           11 :           && e->ts.type != BT_INTEGER)
    1774              :         {
    1775            5 :           gfc_error ("FORMAT tag at %L must be of type default-kind CHARACTER "
    1776              :                      "or of INTEGER", &e->where);
    1777            5 :           return false;
    1778              :         }
    1779        12049 :       else if (e->ts.type == BT_INTEGER && e->expr_type == EXPR_VARIABLE)
    1780              :         {
    1781            3 :           if (!gfc_notify_std (GFC_STD_F95_DEL, "ASSIGNED variable in "
    1782              :                                "FORMAT tag at %L", &e->where))
    1783              :             return false;
    1784            3 :           if (e->symtree->n.sym->attr.assign != 1)
    1785              :             {
    1786            1 :               gfc_error ("Variable %qs at %L has not been assigned a "
    1787              :                          "format label", e->symtree->n.sym->name, &e->where);
    1788            1 :               return false;
    1789              :             }
    1790              :         }
    1791        12046 :       else if (e->ts.type == BT_INTEGER)
    1792              :         {
    1793            3 :           gfc_error ("Scalar %qs in FORMAT tag at %L is not an ASSIGNED "
    1794              :                      "variable", gfc_basic_typename (e->ts.type), &e->where);
    1795            3 :           return false;
    1796              :         }
    1797              : 
    1798        12045 :       gfc_value_used_expr (e, VALUE_USED);
    1799        12045 :       return true;
    1800              :     }
    1801              : 
    1802              :   /* If rank is nonzero and type is not character, we allow it under GFC_STD_LEGACY.
    1803              :      It may be assigned an Hollerith constant.  */
    1804          188 :   if (e->ts.type != BT_CHARACTER)
    1805              :     {
    1806              :       if (e->ts.type == BT_DERIVED || e->ts.type == BT_CLASS
    1807              :           || e->ts.type == BT_VOID || e->ts.type == BT_UNKNOWN)
    1808              :         {
    1809            5 :           gfc_error ("Non-character non-Hollerith in FORMAT tag at %L",
    1810              :                      &e->where);
    1811            5 :           return false;
    1812              :         }
    1813           62 :       if (!gfc_notify_std (GFC_STD_LEGACY, "Non-character in FORMAT tag "
    1814              :                            "at %L", &e->where))
    1815              :         return false;
    1816              : 
    1817           60 :       if (e->rank == 0 && e->symtree->n.sym->as->type == AS_ASSUMED_SHAPE)
    1818              :         {
    1819            1 :           gfc_error ("Non-character assumed shape array element in FORMAT"
    1820              :                      " tag at %L", &e->where);
    1821            1 :           return false;
    1822              :         }
    1823              : 
    1824           59 :       if (e->rank == 0 && e->symtree->n.sym->as->type == AS_ASSUMED_SIZE)
    1825              :         {
    1826            1 :           gfc_error ("Non-character assumed size array element in FORMAT"
    1827              :                      " tag at %L", &e->where);
    1828            1 :           return false;
    1829              :         }
    1830              : 
    1831           58 :       if (e->rank == 0 && e->symtree->n.sym->attr.pointer)
    1832              :         {
    1833            1 :           gfc_error ("Non-character pointer array element in FORMAT tag at %L",
    1834              :                      &e->where);
    1835            1 :           return false;
    1836              :         }
    1837              :     }
    1838              : 
    1839          178 :   gfc_value_used_expr (e, VALUE_USED);
    1840          178 :   return true;
    1841              : }
    1842              : 
    1843              : 
    1844              : /* Do expression resolution and type-checking on an expression tag.  */
    1845              : 
    1846              : static bool
    1847       639056 : resolve_tag (const io_tag *tag, gfc_expr *e)
    1848              : {
    1849       639056 :   if (e == NULL)
    1850              :     return true;
    1851              : 
    1852        37807 :   if (!gfc_resolve_expr (e))
    1853              :     return false;
    1854              : 
    1855        37803 :   if (tag == &tag_format)
    1856        12248 :     return resolve_tag_format (e);
    1857              : 
    1858        25555 :   if (e->ts.type != tag->type)
    1859              :     {
    1860          348 :       gfc_error ("%s tag at %L must be of type %s", tag->name,
    1861              :                  &e->where, gfc_basic_typename (tag->type));
    1862          348 :       return false;
    1863              :     }
    1864              : 
    1865        25207 :   if (e->ts.type == BT_CHARACTER && e->ts.kind != gfc_default_character_kind)
    1866              :     {
    1867           68 :       gfc_error ("%s tag at %L must be a character string of default kind",
    1868           68 :                  tag->name, &e->where);
    1869           68 :       return false;
    1870              :     }
    1871              : 
    1872        25139 :   if (e->rank != 0)
    1873              :     {
    1874           52 :       gfc_error ("%s tag at %L must be scalar", tag->name, &e->where);
    1875           52 :       return false;
    1876              :     }
    1877              : 
    1878        25087 :   if (tag == &tag_iomsg)
    1879              :     {
    1880          566 :       if (!gfc_notify_std (GFC_STD_F2003, "IOMSG tag at %L", &e->where))
    1881              :         return false;
    1882              :     }
    1883              : 
    1884        25087 :   if ((tag == &tag_iostat || tag == &tag_size || tag == &tag_iolength
    1885        22756 :        || tag == &tag_number || tag == &tag_nextrec || tag == &tag_s_recl)
    1886         2539 :       && e->ts.kind != gfc_default_integer_kind)
    1887              :     {
    1888          105 :       if (!gfc_notify_std (GFC_STD_F2003, "Fortran 95 requires default "
    1889          105 :                            "INTEGER in %s tag at %L", tag->name, &e->where))
    1890              :         return false;
    1891              :     }
    1892              : 
    1893        25071 :   if (e->ts.kind != gfc_default_logical_kind &&
    1894        10981 :       (tag == &tag_exist || tag == &tag_named || tag == &tag_opened
    1895        10975 :        || tag == &tag_pending))
    1896              :     {
    1897           39 :       if (!gfc_notify_std (GFC_STD_F2008, "Non-default LOGICAL kind "
    1898           39 :                            "in %s tag at %L", tag->name, &e->where))
    1899              :         return false;
    1900              :     }
    1901              : 
    1902        25063 :   if (tag == &tag_newunit)
    1903              :     {
    1904          146 :       if (!gfc_notify_std (GFC_STD_F2008, "NEWUNIT specifier at %L",
    1905              :                            &e->where))
    1906              :         return false;
    1907              :     }
    1908              : 
    1909        25062 :   if (tag == &tag_convert)
    1910              :     {
    1911           84 :       if (!gfc_notify_std (GFC_STD_GNU, "CONVERT tag at %L", &e->where))
    1912              :         return false;
    1913              :     }
    1914              : 
    1915              :   /* NEWUNIT, IOSTAT, SIZE and IOMSG are variable definition contexts.  */
    1916        25062 :   if (tag == &tag_newunit || tag == &tag_iostat
    1917        22793 :       || tag == &tag_size || tag == &tag_iomsg)
    1918              :     {
    1919         2939 :       char context[64];
    1920              : 
    1921         2939 :       sprintf (context, _("%s tag"), tag->name);
    1922         2939 :       if (!gfc_check_vardef_context (e, false, false, false, context))
    1923           32 :         return false;
    1924              : 
    1925         2907 :       gfc_expr_set_at (e, &e->where, VALUE_VARDEF);
    1926         2907 :     }
    1927              :   else
    1928        22123 :     gfc_value_used_expr (e, VALUE_USED);
    1929              : 
    1930              :   return true;
    1931              : }
    1932              : 
    1933              : 
    1934              : /* Match a single tag of an OPEN statement.  */
    1935              : 
    1936              : static match
    1937        11144 : match_open_element (gfc_open *open)
    1938              : {
    1939        11144 :   match m;
    1940              : 
    1941        11144 :   m = match_etag (&tag_e_async, &open->asynchronous);
    1942        11144 :   if (m != MATCH_NO)
    1943              :     return m;
    1944        11028 :   m = match_etag (&tag_unit, &open->unit);
    1945        11028 :   if (m != MATCH_NO)
    1946              :     return m;
    1947        10086 :   m = match_etag (&tag_iomsg, &open->iomsg);
    1948        10086 :   if (m != MATCH_NO)
    1949              :     return m;
    1950        10028 :   m = match_out_tag (&tag_iostat, &open->iostat);
    1951        10028 :   if (m != MATCH_NO)
    1952              :     return m;
    1953         9853 :   m = match_etag (&tag_file, &open->file);
    1954         9853 :   if (m != MATCH_NO)
    1955              :     return m;
    1956         8347 :   m = match_etag (&tag_status, &open->status);
    1957         8347 :   if (m != MATCH_NO)
    1958              :     return m;
    1959         6201 :   m = match_etag (&tag_e_access, &open->access);
    1960         6201 :   if (m != MATCH_NO)
    1961              :     return m;
    1962         5420 :   m = match_etag (&tag_e_form, &open->form);
    1963         5420 :   if (m != MATCH_NO)
    1964              :     return m;
    1965         4321 :   m = match_etag (&tag_e_recl, &open->recl);
    1966         4321 :   if (m != MATCH_NO)
    1967              :     return m;
    1968         4067 :   m = match_etag (&tag_e_blank, &open->blank);
    1969         4067 :   if (m != MATCH_NO)
    1970              :     return m;
    1971         4028 :   m = match_etag (&tag_e_position, &open->position);
    1972         4028 :   if (m != MATCH_NO)
    1973              :     return m;
    1974         3892 :   m = match_etag (&tag_e_action, &open->action);
    1975         3892 :   if (m != MATCH_NO)
    1976              :     return m;
    1977         3630 :   m = match_etag (&tag_e_delim, &open->delim);
    1978         3630 :   if (m != MATCH_NO)
    1979              :     return m;
    1980         3487 :   m = match_etag (&tag_e_pad, &open->pad);
    1981         3487 :   if (m != MATCH_NO)
    1982              :     return m;
    1983         3432 :   m = match_etag (&tag_e_decimal, &open->decimal);
    1984         3432 :   if (m != MATCH_NO)
    1985              :     return m;
    1986         3382 :   m = match_etag (&tag_e_encoding, &open->encoding);
    1987         3382 :   if (m != MATCH_NO)
    1988              :     return m;
    1989         3308 :   m = match_etag (&tag_e_round, &open->round);
    1990         3308 :   if (m != MATCH_NO)
    1991              :     return m;
    1992         3294 :   m = match_etag (&tag_e_sign, &open->sign);
    1993         3294 :   if (m != MATCH_NO)
    1994              :     return m;
    1995         3262 :   m = match_ltag (&tag_err, &open->err);
    1996         3262 :   if (m != MATCH_NO)
    1997              :     return m;
    1998         3146 :   m = match_etag (&tag_convert, &open->convert);
    1999         3146 :   if (m != MATCH_NO)
    2000              :     return m;
    2001         3074 :   m = match_out_tag (&tag_newunit, &open->newunit);
    2002         3074 :   if (m != MATCH_NO)
    2003              :     return m;
    2004              : 
    2005              :   /* The following are extensions enabled with -fdec.  */
    2006         2925 :   m = match_dec_etag (&tag_e_share, &open->share);
    2007         2925 :   if (m != MATCH_NO)
    2008              :     return m;
    2009         2907 :   m = match_dec_etag (&tag_cc, &open->cc);
    2010         2907 :   if (m != MATCH_NO)
    2011              :     return m;
    2012         2876 :   m = match_dec_ftag (&tag_readonly, open);
    2013         2876 :   if (m != MATCH_NO)
    2014              :     return m;
    2015         2852 :   m = match_dec_ftag (&tag_shared, open);
    2016         2852 :   if (m != MATCH_NO)
    2017              :     return m;
    2018         2841 :   m = match_dec_ftag (&tag_noshared, open);
    2019         2841 :   if (m != MATCH_NO)
    2020              :     return m;
    2021              : 
    2022              :   return MATCH_NO;
    2023              : }
    2024              : 
    2025              : 
    2026              : /* Free the gfc_open structure and all the expressions it contains.  */
    2027              : 
    2028              : void
    2029         3924 : gfc_free_open (gfc_open *open)
    2030              : {
    2031         3924 :   if (open == NULL)
    2032              :     return;
    2033              : 
    2034         3924 :   gfc_free_expr (open->unit);
    2035         3924 :   gfc_free_expr (open->iomsg);
    2036         3924 :   gfc_free_expr (open->iostat);
    2037         3924 :   gfc_free_expr (open->file);
    2038         3924 :   gfc_free_expr (open->status);
    2039         3924 :   gfc_free_expr (open->access);
    2040         3924 :   gfc_free_expr (open->form);
    2041         3924 :   gfc_free_expr (open->recl);
    2042         3924 :   gfc_free_expr (open->blank);
    2043         3924 :   gfc_free_expr (open->position);
    2044         3924 :   gfc_free_expr (open->action);
    2045         3924 :   gfc_free_expr (open->delim);
    2046         3924 :   gfc_free_expr (open->pad);
    2047         3924 :   gfc_free_expr (open->decimal);
    2048         3924 :   gfc_free_expr (open->encoding);
    2049         3924 :   gfc_free_expr (open->round);
    2050         3924 :   gfc_free_expr (open->sign);
    2051         3924 :   gfc_free_expr (open->convert);
    2052         3924 :   gfc_free_expr (open->asynchronous);
    2053         3924 :   gfc_free_expr (open->newunit);
    2054         3924 :   gfc_free_expr (open->share);
    2055         3924 :   gfc_free_expr (open->cc);
    2056         3924 :   free (open);
    2057              : }
    2058              : 
    2059              : static bool
    2060              : check_open_constraints (gfc_open *open, locus *where);
    2061              : 
    2062              : /* Resolve everything in a gfc_open structure.  */
    2063              : 
    2064              : bool
    2065         3907 : gfc_resolve_open (gfc_open *open, locus *where)
    2066              : {
    2067         3907 :   RESOLVE_TAG (&tag_unit, open->unit);
    2068         3907 :   RESOLVE_TAG (&tag_iomsg, open->iomsg);
    2069         3891 :   RESOLVE_TAG (&tag_iostat, open->iostat);
    2070         3890 :   RESOLVE_TAG (&tag_file, open->file);
    2071         3889 :   RESOLVE_TAG (&tag_status, open->status);
    2072         3875 :   RESOLVE_TAG (&tag_e_access, open->access);
    2073         3863 :   RESOLVE_TAG (&tag_e_form, open->form);
    2074         3852 :   RESOLVE_TAG (&tag_e_recl, open->recl);
    2075         3846 :   RESOLVE_TAG (&tag_e_blank, open->blank);
    2076         3834 :   RESOLVE_TAG (&tag_e_position, open->position);
    2077         3823 :   RESOLVE_TAG (&tag_e_action, open->action);
    2078         3812 :   RESOLVE_TAG (&tag_e_delim, open->delim);
    2079         3801 :   RESOLVE_TAG (&tag_e_pad, open->pad);
    2080         3790 :   RESOLVE_TAG (&tag_e_decimal, open->decimal);
    2081         3778 :   RESOLVE_TAG (&tag_e_encoding, open->encoding);
    2082         3766 :   RESOLVE_TAG (&tag_e_async, open->asynchronous);
    2083         3755 :   RESOLVE_TAG (&tag_e_round, open->round);
    2084         3743 :   RESOLVE_TAG (&tag_e_sign, open->sign);
    2085         3731 :   RESOLVE_TAG (&tag_convert, open->convert);
    2086         3731 :   RESOLVE_TAG (&tag_newunit, open->newunit);
    2087         3729 :   RESOLVE_TAG (&tag_e_share, open->share);
    2088         3728 :   RESOLVE_TAG (&tag_cc, open->cc);
    2089              : 
    2090         3727 :   if (!gfc_reference_st_label (open->err, ST_LABEL_TARGET))
    2091              :     return false;
    2092              : 
    2093         3727 :   return check_open_constraints (open, where);
    2094              : }
    2095              : 
    2096              : 
    2097              : /* Check if a given value for a SPECIFIER is either in the list of values
    2098              :    allowed in F95 or F2003, issuing an error message and returning a zero
    2099              :    value if it is not allowed.  */
    2100              : 
    2101              : 
    2102              : static bool
    2103         6943 : compare_to_allowed_values (const char *specifier, const char *allowed[],
    2104              :                            const char *allowed_f2003[],
    2105              :                            const char *allowed_gnu[], gfc_char_t *value,
    2106              :                            const char *statement, bool warn, locus *where,
    2107              :                            int *num = NULL)
    2108              : {
    2109         6943 :   int i;
    2110         6943 :   unsigned int len;
    2111              : 
    2112         6943 :   len = gfc_wide_strlen (value);
    2113         6943 :   if (len > 0)
    2114              :   {
    2115         6930 :     for (len--; len > 0; len--)
    2116         6930 :       if (value[len] != ' ')
    2117              :         break;
    2118         6912 :     len++;
    2119              :   }
    2120              : 
    2121        15548 :   for (i = 0; allowed[i]; i++)
    2122        15015 :     if (len == strlen (allowed[i])
    2123        15015 :         && gfc_wide_strncasecmp (value, allowed[i], strlen (allowed[i])) == 0)
    2124              :       {
    2125         6410 :         if (num)
    2126          199 :           *num = i;
    2127         6410 :       return 1;
    2128              :       }
    2129              : 
    2130          533 :   if (!where)
    2131            0 :     where = &gfc_current_locus;
    2132              : 
    2133          562 :   for (i = 0; allowed_f2003 && allowed_f2003[i]; i++)
    2134          443 :     if (len == strlen (allowed_f2003[i])
    2135          443 :         && gfc_wide_strncasecmp (value, allowed_f2003[i],
    2136              :                                  strlen (allowed_f2003[i])) == 0)
    2137              :       {
    2138          414 :         notification n = gfc_notification_std (GFC_STD_F2003);
    2139              : 
    2140          414 :         if (n == WARNING || (warn && n == ERROR))
    2141              :           {
    2142            0 :             gfc_warning (0, "Fortran 2003: %s specifier in %s statement at %L "
    2143              :                          "has value %qs", specifier, statement, where,
    2144              :                          allowed_f2003[i]);
    2145            0 :             return 1;
    2146              :           }
    2147              :         else
    2148          414 :           if (n == ERROR)
    2149              :             {
    2150            0 :               gfc_notify_std (GFC_STD_F2003, "%s specifier in "
    2151              :                               "%s statement at %L has value %qs", specifier,
    2152              :                               statement, where, allowed_f2003[i]);
    2153            0 :               return 0;
    2154              :             }
    2155              : 
    2156              :         /* n == SILENT */
    2157              :         return 1;
    2158              :       }
    2159              : 
    2160          127 :   for (i = 0; allowed_gnu && allowed_gnu[i]; i++)
    2161           29 :     if (len == strlen (allowed_gnu[i])
    2162           29 :         && gfc_wide_strncasecmp (value, allowed_gnu[i],
    2163              :                                  strlen (allowed_gnu[i])) == 0)
    2164              :       {
    2165           21 :         notification n = gfc_notification_std (GFC_STD_GNU);
    2166              : 
    2167           21 :         if (n == WARNING || (warn && n == ERROR))
    2168              :           {
    2169           21 :             gfc_warning (0, "Extension: %s specifier in %s statement at %L "
    2170              :                          "has value %qs", specifier, statement, where,
    2171              :                          allowed_gnu[i]);
    2172           21 :             return 1;
    2173              :           }
    2174              :         else
    2175            0 :           if (n == ERROR)
    2176              :             {
    2177            0 :               gfc_notify_std (GFC_STD_GNU, "%s specifier in "
    2178              :                               "%s statement at %L has value %qs", specifier,
    2179              :                               statement, where, allowed_gnu[i]);
    2180            0 :               return 0;
    2181              :             }
    2182              : 
    2183              :         /* n == SILENT */
    2184              :         return 1;
    2185              :       }
    2186              : 
    2187           98 :   if (warn)
    2188              :     {
    2189           38 :       char *s = gfc_widechar_to_char (value, -1);
    2190           38 :       gfc_warning (0,
    2191              :                    "%s specifier in %s statement at %L has invalid value %qs",
    2192              :                    specifier, statement, where, s);
    2193           38 :       free (s);
    2194           38 :       return 1;
    2195              :     }
    2196              :   else
    2197              :     {
    2198           60 :       char *s = gfc_widechar_to_char (value, -1);
    2199           60 :       gfc_error ("%s specifier in %s statement at %L has invalid value %qs",
    2200              :                  specifier, statement, where, s);
    2201           60 :       free (s);
    2202           60 :       return 0;
    2203              :     }
    2204              : }
    2205              : 
    2206              : 
    2207              : /* Check constraints on the OPEN statement.
    2208              :    Similar to check_io_constraints for data transfer statements.
    2209              :    At this point all tags have already been resolved via resolve_tag, which,
    2210              :    among other things, verifies that BT_CHARACTER tags are of default kind.  */
    2211              : 
    2212              : static bool
    2213         3727 : check_open_constraints (gfc_open *open, locus *where)
    2214              : {
    2215              : #define warn_or_error(...) \
    2216              : { \
    2217              :   if (warn) \
    2218              :     gfc_warning (0, __VA_ARGS__); \
    2219              :   else \
    2220              :     { \
    2221              :       gfc_error (__VA_ARGS__); \
    2222              :       return false; \
    2223              :     } \
    2224              : }
    2225              : 
    2226         3727 :   bool warn = (open->err || open->iostat) ? true : false;
    2227              : 
    2228              :   /* Checks on the ACCESS specifier.  */
    2229         3727 :   if (open->access && open->access->expr_type == EXPR_CONSTANT)
    2230              :     {
    2231          769 :       static const char *access_f95[] = { "SEQUENTIAL", "DIRECT", NULL };
    2232          769 :       static const char *access_f2003[] = { "STREAM", NULL };
    2233          769 :       static const char *access_gnu[] = { "APPEND", NULL };
    2234              : 
    2235          769 :       if (!compare_to_allowed_values ("ACCESS", access_f95, access_f2003,
    2236              :                                       access_gnu,
    2237              :                                       open->access->value.character.string,
    2238              :                                       "OPEN", warn, &open->access->where))
    2239              :         return false;
    2240              :     }
    2241              : 
    2242              :   /* Checks on the ACTION specifier.  */
    2243         3723 :   if (open->action && open->action->expr_type == EXPR_CONSTANT)
    2244              :     {
    2245          238 :       gfc_char_t *str = open->action->value.character.string;
    2246          238 :       static const char *action[] = { "READ", "WRITE", "READWRITE", NULL };
    2247              : 
    2248          238 :       if (!compare_to_allowed_values ("ACTION", action, NULL, NULL,
    2249              :                                       str, "OPEN", warn, &open->action->where))
    2250              :         return false;
    2251              : 
    2252              :       /* With READONLY, only allow ACTION='READ'.  */
    2253          235 :       if (open->readonly && (gfc_wide_strlen (str) != 4
    2254            8 :                              || gfc_wide_strncasecmp (str, "READ", 4) != 0))
    2255              :         {
    2256            2 :           gfc_error ("ACTION type conflicts with READONLY specifier at %L",
    2257            2 :                      &open->action->where);
    2258            2 :           return false;
    2259              :         }
    2260              :     }
    2261              : 
    2262              :   /* If we see READONLY and no ACTION, set ACTION='READ'.  */
    2263         3485 :   else if (open->readonly && open->action == NULL)
    2264              :     {
    2265            6 :       open->action = gfc_get_character_expr (gfc_default_character_kind,
    2266              :                                              &gfc_current_locus, "read", 4);
    2267              :     }
    2268              : 
    2269              :   /* Checks on the ASYNCHRONOUS specifier.  */
    2270         3718 :   if (open->asynchronous)
    2271              :     {
    2272          105 :       if (!gfc_notify_std (GFC_STD_F2003, "ASYNCHRONOUS= at %L "
    2273              :                            "not allowed in Fortran 95",
    2274              :                            &open->asynchronous->where))
    2275              :         return false;
    2276              : 
    2277          105 :       if (open->asynchronous->expr_type == EXPR_CONSTANT)
    2278              :         {
    2279          103 :           static const char * asynchronous[] = { "YES", "NO", NULL };
    2280              : 
    2281          103 :           if (!compare_to_allowed_values ("ASYNCHRONOUS", asynchronous,
    2282              :                         NULL, NULL, open->asynchronous->value.character.string,
    2283              :                         "OPEN", warn, &open->asynchronous->where))
    2284              :             return false;
    2285              :         }
    2286              :     }
    2287              : 
    2288              :   /* Checks on the BLANK specifier.  */
    2289         3717 :   if (open->blank)
    2290              :     {
    2291           27 :       if (open->blank->expr_type == EXPR_CONSTANT)
    2292              :         {
    2293           27 :           static const char *blank[] = { "ZERO", "NULL", NULL };
    2294              : 
    2295           27 :           if (!compare_to_allowed_values ("BLANK", blank, NULL, NULL,
    2296              :                                           open->blank->value.character.string,
    2297              :                                           "OPEN", warn, &open->blank->where))
    2298              :             return false;
    2299              :         }
    2300              :     }
    2301              : 
    2302              :   /* Checks on the CARRIAGECONTROL specifier.  */
    2303         3714 :   if (open->cc && open->cc->expr_type == EXPR_CONSTANT)
    2304              :     {
    2305           18 :       static const char *cc[] = { "LIST", "FORTRAN", "NONE", NULL };
    2306           18 :       if (!compare_to_allowed_values ("CARRIAGECONTROL", cc, NULL, NULL,
    2307              :                                       open->cc->value.character.string,
    2308              :                                       "OPEN", warn, &open->cc->where))
    2309              :         return false;
    2310              :     }
    2311              : 
    2312              :   /* Checks on the DECIMAL specifier.  */
    2313         3714 :   if (open->decimal)
    2314              :     {
    2315           38 :       if (!gfc_notify_std (GFC_STD_F2003, "DECIMAL= at %L "
    2316              :                            "not allowed in Fortran 95", &open->decimal->where))
    2317              :         return false;
    2318              : 
    2319           38 :       if (open->decimal->expr_type == EXPR_CONSTANT)
    2320              :         {
    2321           38 :           static const char * decimal[] = { "COMMA", "POINT", NULL };
    2322              : 
    2323           38 :           if (!compare_to_allowed_values ("DECIMAL", decimal, NULL, NULL,
    2324              :                                           open->decimal->value.character.string,
    2325              :                                           "OPEN", warn, &open->decimal->where))
    2326              :             return false;
    2327              :         }
    2328              :     }
    2329              : 
    2330              :   /* Checks on the DELIM specifier.  */
    2331         3712 :   if (open->delim)
    2332              :     {
    2333          132 :       if (open->delim->expr_type == EXPR_CONSTANT)
    2334              :         {
    2335          132 :           static const char *delim[] = { "APOSTROPHE", "QUOTE", "NONE", NULL };
    2336              : 
    2337          132 :           if (!compare_to_allowed_values ("DELIM", delim, NULL, NULL,
    2338              :                                           open->delim->value.character.string,
    2339              :                                           "OPEN", warn, &open->delim->where))
    2340              :             return false;
    2341              :         }
    2342              :     }
    2343              : 
    2344              :   /* Checks on the ENCODING specifier.  */
    2345         3709 :   if (open->encoding)
    2346              :     {
    2347           62 :       if (!gfc_notify_std (GFC_STD_F2003, "ENCODING= at %L "
    2348              :                            "not allowed in Fortran 95", &open->encoding->where))
    2349              :         return false;
    2350              : 
    2351           62 :       if (open->encoding->expr_type == EXPR_CONSTANT)
    2352              :         {
    2353           62 :           static const char * encoding[] = { "DEFAULT", "UTF-8", NULL };
    2354              : 
    2355           62 :           if (!compare_to_allowed_values ("ENCODING", encoding, NULL, NULL,
    2356              :                                           open->encoding->value.character.string,
    2357              :                                           "OPEN", warn, &open->encoding->where))
    2358              :             return false;
    2359              :         }
    2360              :     }
    2361              : 
    2362              :   /* Checks on the FORM specifier.  */
    2363         3707 :   if (open->form && open->form->expr_type == EXPR_CONSTANT)
    2364              :     {
    2365         1082 :       static const char *form[] = { "FORMATTED", "UNFORMATTED", NULL };
    2366              : 
    2367         1082 :       if (!compare_to_allowed_values ("FORM", form, NULL, NULL,
    2368              :                                       open->form->value.character.string,
    2369              :                                       "OPEN", warn, &open->form->where))
    2370              :         return false;
    2371              :     }
    2372              : 
    2373              :   /* Checks on the PAD specifier.  */
    2374         3704 :   if (open->pad && open->pad->expr_type == EXPR_CONSTANT)
    2375              :     {
    2376           44 :       static const char *pad[] = { "YES", "NO", NULL };
    2377              : 
    2378           44 :       if (!compare_to_allowed_values ("PAD", pad, NULL, NULL,
    2379              :                                       open->pad->value.character.string,
    2380              :                                       "OPEN", warn, &open->pad->where))
    2381              :         return false;
    2382              :     }
    2383              : 
    2384              :   /* Checks on the POSITION specifier.  */
    2385         3702 :   if (open->position && open->position->expr_type == EXPR_CONSTANT)
    2386              :     {
    2387          125 :       static const char *position[] = { "ASIS", "REWIND", "APPEND", NULL };
    2388              : 
    2389          125 :       if (!compare_to_allowed_values ("POSITION", position, NULL, NULL,
    2390              :                                       open->position->value.character.string,
    2391              :                                       "OPEN", warn, &open->position->where))
    2392              :         return false;
    2393              :     }
    2394              : 
    2395              :   /* Checks on the ROUND specifier.  */
    2396         3699 :   if (open->round)
    2397              :     {
    2398            2 :       if (!gfc_notify_std (GFC_STD_F2003, "ROUND= at %L "
    2399              :                            "not allowed in Fortran 95", &open->round->where))
    2400              :         return false;
    2401              : 
    2402            2 :       if (open->round->expr_type == EXPR_CONSTANT)
    2403              :         {
    2404            2 :           static const char * round[] = { "UP", "DOWN", "ZERO", "NEAREST",
    2405              :                                           "COMPATIBLE", "PROCESSOR_DEFINED",
    2406              :                                            NULL };
    2407              : 
    2408            2 :           if (!compare_to_allowed_values ("ROUND", round, NULL, NULL,
    2409              :                                           open->round->value.character.string,
    2410              :                                           "OPEN", warn, &open->round->where))
    2411              :             return false;
    2412              :         }
    2413              :     }
    2414              : 
    2415              :   /* Checks on the SHARE specifier.  */
    2416         3697 :   if (open->share && open->share->expr_type == EXPR_CONSTANT)
    2417              :     {
    2418           24 :       static const char *share[] = { "DENYNONE", "DENYRW", NULL };
    2419           24 :       if (!compare_to_allowed_values ("SHARE", share, NULL, NULL,
    2420              :                                       open->share->value.character.string,
    2421              :                                       "OPEN", warn, &open->share->where))
    2422              :         return false;
    2423              :     }
    2424              : 
    2425              :   /* Checks on the SIGN specifier.  */
    2426         3697 :   if (open->sign)
    2427              :     {
    2428           20 :       if (!gfc_notify_std (GFC_STD_F2003, "SIGN= at %L "
    2429              :                            "not allowed in Fortran 95", &open->sign->where))
    2430              :         return false;
    2431              : 
    2432           20 :       if (open->sign->expr_type == EXPR_CONSTANT)
    2433              :         {
    2434           20 :           static const char * sign[] = { "PLUS", "SUPPRESS", "PROCESSOR_DEFINED",
    2435              :                                           NULL };
    2436              : 
    2437           20 :           if (!compare_to_allowed_values ("SIGN", sign, NULL, NULL,
    2438              :                                           open->sign->value.character.string,
    2439              :                                           "OPEN", warn, &open->sign->where))
    2440              :             return false;
    2441              :         }
    2442              :     }
    2443              : 
    2444              :   /* Checks on the RECL specifier.  */
    2445         3695 :   if (open->recl && open->recl->expr_type == EXPR_CONSTANT
    2446          212 :       && open->recl->ts.type == BT_INTEGER
    2447          212 :       && mpz_sgn (open->recl->value.integer) != 1)
    2448              :     {
    2449            6 :       warn_or_error (G_("RECL in OPEN statement at %L must be positive"),
    2450            4 :                      &open->recl->where);
    2451              :     }
    2452              : 
    2453              :   /* Checks on the STATUS specifier.  */
    2454         3693 :   if (open->status && open->status->expr_type == EXPR_CONSTANT)
    2455              :     {
    2456         2124 :       static const char *status[] = { "OLD", "NEW", "SCRATCH",
    2457              :         "REPLACE", "UNKNOWN", NULL };
    2458              : 
    2459         2124 :       if (!compare_to_allowed_values ("STATUS", status, NULL, NULL,
    2460              :                                       open->status->value.character.string,
    2461              :                                       "OPEN", warn, &open->status->where))
    2462              :         return false;
    2463              : 
    2464              :       /* F2003, 9.4.5: If the STATUS= specifier has the value NEW or REPLACE,
    2465              :          the FILE= specifier shall appear.  */
    2466         2121 :       if (open->file == NULL
    2467         2121 :           && (gfc_wide_strncasecmp (open->status->value.character.string,
    2468              :                                     "replace", 7) == 0
    2469         1610 :               || gfc_wide_strncasecmp (open->status->value.character.string,
    2470              :                                        "new", 3) == 0))
    2471              :         {
    2472            6 :           char *s = gfc_widechar_to_char (open->status->value.character.string,
    2473              :                                           -1);
    2474            6 :           warn_or_error (G_("The STATUS specified in OPEN statement at %L is "
    2475              :                          "%qs and no FILE specifier is present"),
    2476            4 :                          &open->status->where, s);
    2477            4 :           free (s);
    2478              :         }
    2479              : 
    2480              :       /* F2003, 9.4.5: If the STATUS= specifier has the value SCRATCH,
    2481              :          the FILE= specifier shall not appear.  */
    2482         2119 :       if (gfc_wide_strncasecmp (open->status->value.character.string,
    2483         2119 :                                 "scratch", 7) == 0 && open->file)
    2484              :         {
    2485            3 :           warn_or_error (G_("The STATUS specified in OPEN statement at %L "
    2486              :                          "cannot have the value SCRATCH if a FILE specifier "
    2487            2 :                          "is present"), &open->status->where);
    2488              :         }
    2489              :     }
    2490              : 
    2491              :   /* Checks on NEWUNIT specifier.  */
    2492         3687 :   if (open->newunit)
    2493              :     {
    2494          144 :       if (open->unit)
    2495              :         {
    2496            0 :           gfc_error ("UNIT specifier not allowed with NEWUNIT at %L",
    2497              :                      &open->newunit->where);
    2498            0 :           return false;
    2499              :         }
    2500              : 
    2501          144 :       if (!open->file &&
    2502           27 :           (!open->status ||
    2503           26 :            (open->status->expr_type == EXPR_CONSTANT
    2504           25 :              && gfc_wide_strncasecmp (open->status->value.character.string,
    2505              :                                       "scratch", 7) != 0)))
    2506              :         {
    2507            1 :              gfc_error ("NEWUNIT specifier must have FILE= "
    2508            1 :                         "or STATUS='scratch' at %L", &open->newunit->where);
    2509            1 :              return false;
    2510              :         }
    2511              :     }
    2512         3543 :   else if (!open->unit)
    2513              :     {
    2514            2 :       gfc_error ("OPEN statement at %L must have UNIT or NEWUNIT specified",
    2515              :                  where);
    2516            2 :       return false;
    2517              :     }
    2518              : 
    2519              :   /* Things that are not allowed for unformatted I/O.  */
    2520         1085 :   if (open->form && open->form->expr_type == EXPR_CONSTANT
    2521         1079 :       && (open->delim || open->decimal || open->encoding || open->round
    2522         1064 :           || open->sign || open->pad || open->blank)
    2523         3705 :       && gfc_wide_strncasecmp (open->form->value.character.string,
    2524              :                                "unformatted", 11) == 0)
    2525              :     {
    2526            9 :       locus *loc;
    2527            9 :       const char *spec;
    2528            9 :       if (open->delim)
    2529              :         {
    2530            3 :           loc = &open->delim->where;
    2531            3 :           spec = "DELIM ";
    2532              :         }
    2533            6 :       else if (open->pad)
    2534              :         {
    2535            3 :           loc = &open->pad->where;
    2536            3 :           spec = "PAD ";
    2537              :         }
    2538            3 :       else if (open->blank)
    2539              :         {
    2540            3 :           loc = &open->blank->where;
    2541            3 :           spec = "BLANK ";
    2542              :         }
    2543              :       else
    2544              :         {
    2545              :           loc = where;
    2546              :           spec = "";
    2547              :         }
    2548              : 
    2549            9 :       warn_or_error (G_("%sspecifier at %L not allowed in OPEN statement for "
    2550            6 :                      "unformatted I/O"), spec, loc);
    2551              :     }
    2552              : 
    2553          246 :   if (open->recl && open->access && open->access->expr_type == EXPR_CONSTANT
    2554         3905 :       && gfc_wide_strncasecmp (open->access->value.character.string,
    2555              :                                "stream", 6) == 0)
    2556              :     {
    2557            0 :       warn_or_error (G_("RECL specifier not allowed in OPEN statement at %L for "
    2558            0 :                      "stream I/O"), &open->recl->where);
    2559              :     }
    2560              : 
    2561         3681 :   if (open->position
    2562          122 :       && open->access && open->access->expr_type == EXPR_CONSTANT
    2563         3729 :       && !(gfc_wide_strncasecmp (open->access->value.character.string,
    2564              :                                  "sequential", 10) == 0
    2565           39 :            || gfc_wide_strncasecmp (open->access->value.character.string,
    2566              :                                     "stream", 6) == 0
    2567            9 :            || gfc_wide_strncasecmp (open->access->value.character.string,
    2568              :                                     "append", 6) == 0))
    2569              :     {
    2570            3 :       warn_or_error (G_("POSITION specifier in OPEN statement at %L only allowed "
    2571            2 :                      "for stream or sequential ACCESS"), &open->position->where);
    2572              :     }
    2573              : 
    2574              :   return true;
    2575              : #undef warn_or_error
    2576              : }
    2577              : 
    2578              : 
    2579              : /* Match an OPEN statement.  */
    2580              : 
    2581              : match
    2582         3924 : gfc_match_open (void)
    2583              : {
    2584         3924 :   gfc_open *open;
    2585         3924 :   match m;
    2586              : 
    2587         3924 :   m = gfc_match_char ('(');
    2588         3924 :   if (m == MATCH_NO)
    2589              :     return m;
    2590              : 
    2591         3924 :   open = XCNEW (gfc_open);
    2592              : 
    2593         3924 :   m = match_open_element (open);
    2594              : 
    2595         3924 :   if (m == MATCH_ERROR)
    2596            0 :     goto cleanup;
    2597         3924 :   if (m == MATCH_NO)
    2598              :     {
    2599         2832 :       m = gfc_match_expr (&open->unit);
    2600         2832 :       if (m == MATCH_ERROR)
    2601            0 :         goto cleanup;
    2602              :     }
    2603              : 
    2604        11127 :   for (;;)
    2605              :     {
    2606        11127 :       if (gfc_match_char (')') == MATCH_YES)
    2607              :         break;
    2608         7220 :       if (gfc_match_char (',') != MATCH_YES)
    2609            0 :         goto syntax;
    2610              : 
    2611         7220 :       m = match_open_element (open);
    2612         7220 :       if (m == MATCH_ERROR)
    2613           17 :         goto cleanup;
    2614         7203 :       if (m == MATCH_NO)
    2615            0 :         goto syntax;
    2616              :     }
    2617              : 
    2618         3907 :   if (gfc_match_eos () == MATCH_NO)
    2619            0 :     goto syntax;
    2620              : 
    2621         3907 :   if (gfc_pure (NULL))
    2622              :     {
    2623            0 :       gfc_error ("OPEN statement not allowed in PURE procedure at %C");
    2624            0 :       goto cleanup;
    2625              :     }
    2626              : 
    2627         3907 :   gfc_unset_implicit_pure (NULL);
    2628              : 
    2629         3907 :   new_st.op = EXEC_OPEN;
    2630         3907 :   new_st.ext.open = open;
    2631         3907 :   return MATCH_YES;
    2632              : 
    2633            0 : syntax:
    2634            0 :   gfc_syntax_error (ST_OPEN);
    2635              : 
    2636           17 : cleanup:
    2637           17 :   gfc_free_open (open);
    2638           17 :   return MATCH_ERROR;
    2639              : }
    2640              : 
    2641              : 
    2642              : /* Free a gfc_close structure an all its expressions.  */
    2643              : 
    2644              : void
    2645         3094 : gfc_free_close (gfc_close *close)
    2646              : {
    2647         3094 :   if (close == NULL)
    2648              :     return;
    2649              : 
    2650         3094 :   gfc_free_expr (close->unit);
    2651         3094 :   gfc_free_expr (close->iomsg);
    2652         3094 :   gfc_free_expr (close->iostat);
    2653         3094 :   gfc_free_expr (close->status);
    2654         3094 :   free (close);
    2655              : }
    2656              : 
    2657              : 
    2658              : /* Match elements of a CLOSE statement.  */
    2659              : 
    2660              : static match
    2661         4566 : match_close_element (gfc_close *close)
    2662              : {
    2663         4566 :   match m;
    2664              : 
    2665         4566 :   m = match_etag (&tag_unit, &close->unit);
    2666         4566 :   if (m != MATCH_NO)
    2667              :     return m;
    2668         4255 :   m = match_etag (&tag_status, &close->status);
    2669         4255 :   if (m != MATCH_NO)
    2670              :     return m;
    2671         2848 :   m = match_etag (&tag_iomsg, &close->iomsg);
    2672         2848 :   if (m != MATCH_NO)
    2673              :     return m;
    2674         2819 :   m = match_out_tag (&tag_iostat, &close->iostat);
    2675         2819 :   if (m != MATCH_NO)
    2676              :     return m;
    2677         2792 :   m = match_ltag (&tag_err, &close->err);
    2678         2792 :   if (m != MATCH_NO)
    2679              :     return m;
    2680              : 
    2681              :   return MATCH_NO;
    2682              : }
    2683              : 
    2684              : 
    2685              : /* Match a CLOSE statement.  */
    2686              : 
    2687              : match
    2688         3094 : gfc_match_close (void)
    2689              : {
    2690         3094 :   gfc_close *close;
    2691         3094 :   match m;
    2692              : 
    2693         3094 :   m = gfc_match_char ('(');
    2694         3094 :   if (m == MATCH_NO)
    2695              :     return m;
    2696              : 
    2697         3094 :   close = XCNEW (gfc_close);
    2698              : 
    2699         3094 :   m = match_close_element (close);
    2700              : 
    2701         3094 :   if (m == MATCH_ERROR)
    2702            0 :     goto cleanup;
    2703         3094 :   if (m == MATCH_NO)
    2704              :     {
    2705         2782 :       m = gfc_match_expr (&close->unit);
    2706         2782 :       if (m == MATCH_NO)
    2707            0 :         goto syntax;
    2708         2782 :       if (m == MATCH_ERROR)
    2709            0 :         goto cleanup;
    2710              :     }
    2711              : 
    2712         4566 :   for (;;)
    2713              :     {
    2714         4566 :       if (gfc_match_char (')') == MATCH_YES)
    2715              :         break;
    2716         1472 :       if (gfc_match_char (',') != MATCH_YES)
    2717            0 :         goto syntax;
    2718              : 
    2719         1472 :       m = match_close_element (close);
    2720         1472 :       if (m == MATCH_ERROR)
    2721            0 :         goto cleanup;
    2722         1472 :       if (m == MATCH_NO)
    2723            0 :         goto syntax;
    2724              :     }
    2725              : 
    2726         3094 :   if (gfc_match_eos () == MATCH_NO)
    2727            0 :     goto syntax;
    2728              : 
    2729         3094 :   if (gfc_pure (NULL))
    2730              :     {
    2731            0 :       gfc_error ("CLOSE statement not allowed in PURE procedure at %C");
    2732            0 :       goto cleanup;
    2733              :     }
    2734              : 
    2735         3094 :   gfc_unset_implicit_pure (NULL);
    2736              : 
    2737         3094 :   new_st.op = EXEC_CLOSE;
    2738         3094 :   new_st.ext.close = close;
    2739         3094 :   return MATCH_YES;
    2740              : 
    2741            0 : syntax:
    2742            0 :   gfc_syntax_error (ST_CLOSE);
    2743              : 
    2744            0 : cleanup:
    2745            0 :   gfc_free_close (close);
    2746            0 :   return MATCH_ERROR;
    2747              : }
    2748              : 
    2749              : 
    2750              : static bool
    2751         3064 : check_close_constraints (gfc_close *close, locus *where)
    2752              : {
    2753         3064 :   bool warn = (close->iostat || close->err) ? true : false;
    2754              : 
    2755         3064 :   if (close->unit == NULL)
    2756              :     {
    2757            1 :       gfc_error ("CLOSE statement at %L requires a UNIT number", where);
    2758            1 :       return false;
    2759              :     }
    2760              : 
    2761         3063 :   if (close->unit->expr_type == EXPR_CONSTANT
    2762         2792 :       && close->unit->ts.type == BT_INTEGER
    2763         2792 :       && mpz_sgn (close->unit->value.integer) < 0)
    2764              :     {
    2765            0 :       gfc_error ("UNIT number in CLOSE statement at %L must be non-negative",
    2766              :                  &close->unit->where);
    2767              :     }
    2768              : 
    2769              :   /* Checks on the STATUS specifier.  */
    2770         3063 :   if (close->status && close->status->expr_type == EXPR_CONSTANT)
    2771              :     {
    2772         1381 :       static const char *status[] = { "KEEP", "DELETE", NULL };
    2773              : 
    2774         1381 :       if (!compare_to_allowed_values ("STATUS", status, NULL, NULL,
    2775              :                                       close->status->value.character.string,
    2776              :                                       "CLOSE", warn, &close->status->where))
    2777              :         return false;
    2778              :     }
    2779              : 
    2780              :   return true;
    2781              : }
    2782              : 
    2783              : /* Resolve everything in a gfc_close structure.  */
    2784              : 
    2785              : bool
    2786         3094 : gfc_resolve_close (gfc_close *close, locus *where)
    2787              : {
    2788         3094 :   RESOLVE_TAG (&tag_unit, close->unit);
    2789         3094 :   RESOLVE_TAG (&tag_iomsg, close->iomsg);
    2790         3077 :   RESOLVE_TAG (&tag_iostat, close->iostat);
    2791         3075 :   RESOLVE_TAG (&tag_status, close->status);
    2792              : 
    2793         3064 :   if (!gfc_reference_st_label (close->err, ST_LABEL_TARGET))
    2794              :     return false;
    2795              : 
    2796         3064 :   return check_close_constraints (close, where);
    2797              : }
    2798              : 
    2799              : 
    2800              : /* Free a gfc_filepos structure.  */
    2801              : 
    2802              : void
    2803         2825 : gfc_free_filepos (gfc_filepos *fp)
    2804              : {
    2805         2825 :   gfc_free_expr (fp->unit);
    2806         2825 :   gfc_free_expr (fp->iomsg);
    2807         2825 :   gfc_free_expr (fp->iostat);
    2808         2825 :   free (fp);
    2809         2825 : }
    2810              : 
    2811              : 
    2812              : /* Match elements of a REWIND, BACKSPACE, ENDFILE, or FLUSH statement.  */
    2813              : 
    2814              : static match
    2815         2522 : match_file_element (gfc_filepos *fp)
    2816              : {
    2817         2522 :   match m;
    2818              : 
    2819         2522 :   m = match_etag (&tag_unit, &fp->unit);
    2820         2522 :   if (m != MATCH_NO)
    2821              :     return m;
    2822         2489 :   m = match_etag (&tag_iomsg, &fp->iomsg);
    2823         2489 :   if (m != MATCH_NO)
    2824              :     return m;
    2825         2401 :   m = match_out_tag (&tag_iostat, &fp->iostat);
    2826         2401 :   if (m != MATCH_NO)
    2827              :     return m;
    2828         2323 :   m = match_ltag (&tag_err, &fp->err);
    2829         2323 :   if (m != MATCH_NO)
    2830              :     return m;
    2831              : 
    2832              :   return MATCH_NO;
    2833              : }
    2834              : 
    2835              : 
    2836              : /* Match the second half of the file-positioning statements, REWIND,
    2837              :    BACKSPACE, ENDFILE, or the FLUSH statement.  */
    2838              : 
    2839              : static match
    2840         2825 : match_filepos (gfc_statement st, gfc_exec_op op)
    2841              : {
    2842         2825 :   gfc_filepos *fp;
    2843         2825 :   match m;
    2844              : 
    2845         2825 :   fp = XCNEW (gfc_filepos);
    2846              : 
    2847         2825 :   if (gfc_match_char ('(') == MATCH_NO)
    2848              :     {
    2849          480 :       m = gfc_match_expr (&fp->unit);
    2850          480 :       if (m == MATCH_ERROR)
    2851            0 :         goto cleanup;
    2852          480 :       if (m == MATCH_NO)
    2853            0 :         goto syntax;
    2854              : 
    2855          480 :       goto done;
    2856              :     }
    2857              : 
    2858         2345 :   m = match_file_element (fp);
    2859         2345 :   if (m == MATCH_ERROR)
    2860            8 :     goto cleanup;
    2861         2337 :   if (m == MATCH_NO)
    2862              :     {
    2863         2299 :       m = gfc_match_expr (&fp->unit);
    2864         2299 :       if (m == MATCH_ERROR || m == MATCH_NO)
    2865            8 :         goto syntax;
    2866              :     }
    2867              : 
    2868         2506 :   for (;;)
    2869              :     {
    2870         2506 :       if (gfc_match_char (')') == MATCH_YES)
    2871              :         break;
    2872          177 :       if (gfc_match_char (',') != MATCH_YES)
    2873            0 :         goto syntax;
    2874              : 
    2875          177 :       m = match_file_element (fp);
    2876          177 :       if (m == MATCH_ERROR)
    2877            0 :         goto cleanup;
    2878          177 :       if (m == MATCH_NO)
    2879            0 :         goto syntax;
    2880              :     }
    2881              : 
    2882         2329 : done:
    2883         2809 :   if (gfc_match_eos () != MATCH_YES)
    2884            0 :     goto syntax;
    2885              : 
    2886         2809 :   if (gfc_pure (NULL))
    2887              :     {
    2888            0 :       gfc_error ("%s statement not allowed in PURE procedure at %C",
    2889              :                  gfc_ascii_statement (st));
    2890              : 
    2891            0 :       goto cleanup;
    2892              :     }
    2893              : 
    2894         2809 :   gfc_unset_implicit_pure (NULL);
    2895              : 
    2896         2809 :   new_st.op = op;
    2897         2809 :   new_st.ext.filepos = fp;
    2898         2809 :   return MATCH_YES;
    2899              : 
    2900            8 : syntax:
    2901            8 :   gfc_syntax_error (st);
    2902              : 
    2903           16 : cleanup:
    2904           16 :   gfc_free_filepos (fp);
    2905           16 :   return MATCH_ERROR;
    2906              : }
    2907              : 
    2908              : 
    2909              : bool
    2910         2809 : gfc_resolve_filepos (gfc_filepos *fp, locus *where)
    2911              : {
    2912         2809 :   RESOLVE_TAG (&tag_unit, fp->unit);
    2913         2809 :   RESOLVE_TAG (&tag_iostat, fp->iostat);
    2914         2806 :   RESOLVE_TAG (&tag_iomsg, fp->iomsg);
    2915              : 
    2916         2748 :   if (!fp->unit && (fp->iostat || fp->iomsg || fp->err))
    2917              :     {
    2918            5 :       gfc_error ("UNIT number missing in statement at %L", where);
    2919            5 :       return false;
    2920              :     }
    2921              : 
    2922         2743 :   if (!gfc_reference_st_label (fp->err, ST_LABEL_TARGET))
    2923              :     return false;
    2924              : 
    2925         2743 :   if (fp->unit->expr_type == EXPR_CONSTANT
    2926         2554 :       && fp->unit->ts.type == BT_INTEGER
    2927         2554 :       && mpz_sgn (fp->unit->value.integer) < 0)
    2928              :     {
    2929            0 :       gfc_error ("UNIT number in statement at %L must be non-negative",
    2930              :                  &fp->unit->where);
    2931            0 :       return false;
    2932              :     }
    2933              : 
    2934              :   return true;
    2935              : }
    2936              : 
    2937              : 
    2938              : /* Match the file positioning statements: ENDFILE, BACKSPACE, REWIND,
    2939              :    and the FLUSH statement.  */
    2940              : 
    2941              : match
    2942           75 : gfc_match_endfile (void)
    2943              : {
    2944           75 :   return match_filepos (ST_END_FILE, EXEC_ENDFILE);
    2945              : }
    2946              : 
    2947              : match
    2948          412 : gfc_match_backspace (void)
    2949              : {
    2950          412 :   return match_filepos (ST_BACKSPACE, EXEC_BACKSPACE);
    2951              : }
    2952              : 
    2953              : match
    2954         2239 : gfc_match_rewind (void)
    2955              : {
    2956         2239 :   return match_filepos (ST_REWIND, EXEC_REWIND);
    2957              : }
    2958              : 
    2959              : match
    2960           99 : gfc_match_flush (void)
    2961              : {
    2962           99 :   if (!gfc_notify_std (GFC_STD_F2003, "FLUSH statement at %C"))
    2963              :     return MATCH_ERROR;
    2964              : 
    2965           99 :   return match_filepos (ST_FLUSH, EXEC_FLUSH);
    2966              : }
    2967              : 
    2968              : /******************** Data Transfer Statements *********************/
    2969              : 
    2970              : /* Return a default unit number.  */
    2971              : 
    2972              : static gfc_expr *
    2973        11716 : default_unit (io_kind k)
    2974              : {
    2975        11716 :   int unit;
    2976              : 
    2977        11716 :   if (k == M_READ)
    2978              :     unit = 5;
    2979              :   else
    2980        11638 :     unit = 6;
    2981              : 
    2982        11716 :   return gfc_get_int_expr (gfc_default_integer_kind, NULL, unit);
    2983              : }
    2984              : 
    2985              : 
    2986              : /* Match a unit specification for a data transfer statement.  */
    2987              : 
    2988              : static match
    2989        25691 : match_dt_unit (io_kind k, gfc_dt *dt)
    2990              : {
    2991        25691 :   gfc_expr *e;
    2992        25691 :   char c;
    2993              : 
    2994        25691 :   if (gfc_match_char ('*') == MATCH_YES)
    2995              :     {
    2996         3962 :       if (dt->io_unit != NULL)
    2997            0 :         goto conflict;
    2998              : 
    2999         3962 :       dt->io_unit = default_unit (k);
    3000              : 
    3001         3962 :       c = gfc_peek_ascii_char ();
    3002         3962 :       if (c == ')')
    3003            0 :         gfc_error_now ("Missing format with default unit at %C");
    3004              : 
    3005         3962 :       return MATCH_YES;
    3006              :     }
    3007              : 
    3008        21729 :   if (gfc_match_expr (&e) == MATCH_YES)
    3009              :     {
    3010        21729 :       if (dt->io_unit != NULL)
    3011              :         {
    3012            0 :           gfc_free_expr (e);
    3013            0 :           goto conflict;
    3014              :         }
    3015              : 
    3016        21729 :       dt->io_unit = e;
    3017        21729 :       return MATCH_YES;
    3018              :     }
    3019              : 
    3020              :   return MATCH_NO;
    3021              : 
    3022            0 : conflict:
    3023            0 :   gfc_error ("Duplicate UNIT specification at %C");
    3024            0 :   return MATCH_ERROR;
    3025              : }
    3026              : 
    3027              : 
    3028              : /* Match a format specification.  */
    3029              : 
    3030              : static match
    3031        30094 : match_dt_format (gfc_dt *dt)
    3032              : {
    3033        30094 :   locus where;
    3034        30094 :   gfc_expr *e;
    3035        30094 :   gfc_st_label *label;
    3036        30094 :   match m;
    3037              : 
    3038        30094 :   where = gfc_current_locus;
    3039              : 
    3040        30094 :   if (gfc_match_char ('*') == MATCH_YES)
    3041              :     {
    3042        15608 :       if (dt->format_expr != NULL || dt->format_label != NULL)
    3043            0 :         goto conflict;
    3044              : 
    3045        15608 :       dt->format_label = &format_asterisk;
    3046        15608 :       return MATCH_YES;
    3047              :     }
    3048              : 
    3049        14486 :   if ((m = gfc_match_st_label (&label)) == MATCH_YES)
    3050              :     {
    3051         1772 :       char c;
    3052              : 
    3053              :       /* Need to check if the format label is actually either an operand
    3054              :          to a user-defined operator or is a kind type parameter.  That is,
    3055              :          print 2.ip.8      ! .ip. is a user-defined operator return CHARACTER.
    3056              :          print 1_'(I0)', i ! 1_'(I0)' is a default character string.  */
    3057              : 
    3058         1772 :       gfc_gobble_whitespace ();
    3059         1772 :       c = gfc_peek_ascii_char ();
    3060         1772 :       if (c == '.' || c == '_')
    3061            2 :         gfc_current_locus = where;
    3062              :       else
    3063              :         {
    3064         1770 :           if (dt->format_expr != NULL || dt->format_label != NULL)
    3065              :             {
    3066            0 :               gfc_free_st_label (label);
    3067            0 :               goto conflict;
    3068              :             }
    3069              : 
    3070         1770 :           if (!gfc_reference_st_label (label, ST_LABEL_FORMAT))
    3071              :             return MATCH_ERROR;
    3072              : 
    3073         1765 :           dt->format_label = label;
    3074         1765 :           return MATCH_YES;
    3075              :         }
    3076              :     }
    3077        12714 :   else if (m == MATCH_ERROR)
    3078              :     /* The label was zero or too large.  Emit the correct diagnosis.  */
    3079              :     return MATCH_ERROR;
    3080              : 
    3081        12714 :   if (gfc_match_expr (&e) == MATCH_YES)
    3082              :     {
    3083        12287 :       if (dt->format_expr != NULL || dt->format_label != NULL)
    3084              :         {
    3085            0 :           gfc_free_expr (e);
    3086            0 :           goto conflict;
    3087              :         }
    3088        12287 :       dt->format_expr = e;
    3089        12287 :       return MATCH_YES;
    3090              :     }
    3091              : 
    3092          427 :   gfc_current_locus = where;    /* The only case where we have to restore */
    3093              : 
    3094          427 :   return MATCH_NO;
    3095              : 
    3096            0 : conflict:
    3097            0 :   gfc_error ("Duplicate format specification at %C");
    3098            0 :   return MATCH_ERROR;
    3099              : }
    3100              : 
    3101              : /* Check for formatted read and write DTIO procedures.  */
    3102              : 
    3103              : static bool
    3104         3020 : dtio_procs_present (gfc_symbol *sym, io_kind k)
    3105              : {
    3106         3020 :   gfc_symbol *derived;
    3107              : 
    3108         3020 :   if (sym && sym->ts.u.derived)
    3109              :     {
    3110         1563 :       if (sym->ts.type == BT_CLASS && CLASS_DATA (sym))
    3111           22 :         derived = CLASS_DATA (sym)->ts.u.derived;
    3112         1541 :       else if (sym->ts.type == BT_DERIVED)
    3113              :         derived = sym->ts.u.derived;
    3114              :       else
    3115              :         return false;
    3116         1150 :       if ((k == M_WRITE || k == M_PRINT) &&
    3117          345 :           (gfc_find_specific_dtio_proc (derived, true, true) != NULL))
    3118              :         return true;
    3119         1210 :       if ((k == M_READ) &&
    3120          460 :           (gfc_find_specific_dtio_proc (derived, false, true) != NULL))
    3121              :         return true;
    3122              :     }
    3123              :   return false;
    3124              : }
    3125              : 
    3126              : /* Traverse a namelist that is part of a READ statement to make sure
    3127              :    that none of the variables in the namelist are INTENT(IN).  Returns
    3128              :    nonzero if we find such a variable.  */
    3129              : 
    3130              : static int
    3131          867 : check_namelist (gfc_symbol *sym)
    3132              : {
    3133          867 :   gfc_namelist *p;
    3134              : 
    3135         2903 :   for (p = sym->namelist; p; p = p->next)
    3136         2037 :     if (p->sym->attr.intent == INTENT_IN)
    3137              :       {
    3138            1 :         gfc_error ("Symbol %qs in namelist %qs is INTENT(IN) at %C",
    3139              :                    p->sym->name, sym->name);
    3140            1 :         return 1;
    3141              :       }
    3142              : 
    3143              :   return 0;
    3144              : }
    3145              : 
    3146              : 
    3147              : /* Match a single data transfer element.  */
    3148              : 
    3149              : static match
    3150        53988 : match_dt_element (io_kind k, gfc_dt *dt)
    3151              : {
    3152        53988 :   char name[GFC_MAX_SYMBOL_LEN + 1];
    3153        53988 :   gfc_symbol *sym;
    3154        53988 :   match m;
    3155              : 
    3156        53988 :   if (gfc_match (" unit =") == MATCH_YES)
    3157              :     {
    3158         1211 :       m = match_dt_unit (k, dt);
    3159         1211 :       if (m != MATCH_NO)
    3160              :         return m;
    3161              :     }
    3162              : 
    3163        52777 :   if (gfc_match (" fmt =") == MATCH_YES)
    3164              :     {
    3165         2006 :       m = match_dt_format (dt);
    3166         2006 :       if (m != MATCH_NO)
    3167              :         return m;
    3168              :     }
    3169              : 
    3170        50771 :   if (gfc_match (" nml = %n", name) == MATCH_YES)
    3171              :     {
    3172          770 :       if (dt->namelist != NULL)
    3173              :         {
    3174            0 :           gfc_error ("Duplicate NML specification at %C");
    3175            0 :           return MATCH_ERROR;
    3176              :         }
    3177              : 
    3178          770 :       if (gfc_find_symbol (name, NULL, 1, &sym))
    3179              :         return MATCH_ERROR;
    3180              : 
    3181          770 :       if (sym == NULL || sym->attr.flavor != FL_NAMELIST)
    3182              :         {
    3183            0 :           gfc_error ("Symbol %qs at %C must be a NAMELIST group name",
    3184              :                      sym != NULL ? sym->name : name);
    3185            0 :           return MATCH_ERROR;
    3186              :         }
    3187              : 
    3188          770 :       dt->namelist = sym;
    3189          770 :       if (k == M_READ && check_namelist (sym))
    3190              :         return MATCH_ERROR;
    3191              : 
    3192          770 :       return MATCH_YES;
    3193              :     }
    3194              : 
    3195        50001 :   m = match_etag (&tag_e_async, &dt->asynchronous);
    3196        50001 :   if (m != MATCH_NO)
    3197              :     return m;
    3198        49772 :   m = match_etag (&tag_e_blank, &dt->blank);
    3199        49772 :   if (m != MATCH_NO)
    3200              :     return m;
    3201        49731 :   m = match_etag (&tag_e_delim, &dt->delim);
    3202        49731 :   if (m != MATCH_NO)
    3203              :     return m;
    3204        49702 :   m = match_etag (&tag_e_pad, &dt->pad);
    3205        49702 :   if (m != MATCH_NO)
    3206              :     return m;
    3207        49597 :   m = match_etag (&tag_e_sign, &dt->sign);
    3208        49597 :   if (m != MATCH_NO)
    3209              :     return m;
    3210        49558 :   m = match_etag (&tag_e_round, &dt->round);
    3211        49558 :   if (m != MATCH_NO)
    3212              :     return m;
    3213        49219 :   m = match_out_tag (&tag_id, &dt->id);
    3214        49219 :   if (m != MATCH_NO)
    3215              :     return m;
    3216        49198 :   m = match_etag (&tag_e_decimal, &dt->decimal);
    3217        49198 :   if (m != MATCH_NO)
    3218              :     return m;
    3219        49030 :   m = match_etag (&tag_rec, &dt->rec);
    3220        49030 :   if (m != MATCH_NO)
    3221              :     return m;
    3222        48530 :   m = match_etag (&tag_spos, &dt->pos);
    3223        48530 :   if (m != MATCH_NO)
    3224              :     return m;
    3225        48358 :   m = match_etag (&tag_iomsg, &dt->iomsg);
    3226        48358 :   if (m != MATCH_NO)
    3227              :     return m;
    3228              : 
    3229        47903 :   m = match_out_tag (&tag_iostat, &dt->iostat);
    3230        47903 :   if (m != MATCH_NO)
    3231              :     return m;
    3232        46112 :   m = match_ltag (&tag_err, &dt->err);
    3233        46112 :   if (m == MATCH_YES)
    3234          250 :     dt->err_where = gfc_current_locus;
    3235        46112 :   if (m != MATCH_NO)
    3236              :     return m;
    3237        45862 :   m = match_etag (&tag_advance, &dt->advance);
    3238        45862 :   if (m != MATCH_NO)
    3239              :     return m;
    3240        45479 :   m = match_out_tag (&tag_size, &dt->size);
    3241        45479 :   if (m != MATCH_NO)
    3242              :     return m;
    3243              : 
    3244        45414 :   m = match_ltag (&tag_end, &dt->end);
    3245        45414 :   if (m == MATCH_YES)
    3246              :     {
    3247          562 :       if (k == M_WRITE)
    3248              :        {
    3249            4 :          gfc_error ("END tag at %C not allowed in output statement");
    3250            4 :          return MATCH_ERROR;
    3251              :        }
    3252          558 :       dt->end_where = gfc_current_locus;
    3253              :     }
    3254        45410 :   if (m != MATCH_NO)
    3255              :     return m;
    3256              : 
    3257        44852 :   m = match_ltag (&tag_eor, &dt->eor);
    3258        44852 :   if (m == MATCH_YES)
    3259           34 :     dt->eor_where = gfc_current_locus;
    3260        44852 :   if (m != MATCH_NO)
    3261              :     return m;
    3262              : 
    3263              :   return MATCH_NO;
    3264              : }
    3265              : 
    3266              : 
    3267              : /* Free a data transfer structure and everything below it.  */
    3268              : 
    3269              : void
    3270        66575 : gfc_free_dt (gfc_dt *dt)
    3271              : {
    3272        66575 :   if (dt == NULL)
    3273              :     return;
    3274              : 
    3275        33356 :   gfc_free_expr (dt->io_unit);
    3276        33356 :   gfc_free_expr (dt->format_expr);
    3277        33356 :   gfc_free_expr (dt->rec);
    3278        33356 :   gfc_free_expr (dt->advance);
    3279        33356 :   gfc_free_expr (dt->iomsg);
    3280        33356 :   gfc_free_expr (dt->iostat);
    3281        33356 :   gfc_free_expr (dt->size);
    3282        33356 :   gfc_free_expr (dt->pad);
    3283        33356 :   gfc_free_expr (dt->delim);
    3284        33356 :   gfc_free_expr (dt->sign);
    3285        33356 :   gfc_free_expr (dt->round);
    3286        33356 :   gfc_free_expr (dt->blank);
    3287        33356 :   gfc_free_expr (dt->decimal);
    3288        33356 :   gfc_free_expr (dt->pos);
    3289        33356 :   gfc_free_expr (dt->dt_io_kind);
    3290              :   /* dt->extra_comma is a link to dt_io_kind if it is set.  */
    3291        33356 :   free (dt);
    3292              : }
    3293              : 
    3294              : 
    3295              : static const char *
    3296              : io_kind_name (io_kind k);
    3297              : 
    3298              : static bool
    3299              : check_io_constraints (io_kind k, gfc_dt *dt, gfc_code *io_code,
    3300              :                       locus *spec_end);
    3301              : 
    3302              : /* Resolve everything in a gfc_dt structure.  */
    3303              : 
    3304              : bool
    3305        33285 : gfc_resolve_dt (gfc_code *dt_code, gfc_dt *dt, locus *loc)
    3306              : {
    3307        33285 :   gfc_expr *e;
    3308        33285 :   io_kind k;
    3309        33285 :   bool internal_unit;
    3310              : 
    3311              :   /* This is set in any case.  */
    3312        33285 :   gcc_assert (dt->dt_io_kind);
    3313        33285 :   k = dt->dt_io_kind->value.iokind;
    3314              : 
    3315        33285 :   RESOLVE_TAG (&tag_format, dt->format_expr);
    3316        33257 :   RESOLVE_TAG (&tag_rec, dt->rec);
    3317        33257 :   RESOLVE_TAG (&tag_spos, dt->pos);
    3318        33257 :   RESOLVE_TAG (&tag_advance, dt->advance);
    3319        33254 :   RESOLVE_TAG (&tag_id, dt->id);
    3320        33254 :   RESOLVE_TAG (&tag_iomsg, dt->iomsg);
    3321        33225 :   RESOLVE_TAG (&tag_iostat, dt->iostat);
    3322        33222 :   RESOLVE_TAG (&tag_size, dt->size);
    3323        33218 :   RESOLVE_TAG (&tag_e_pad, dt->pad);
    3324        33196 :   RESOLVE_TAG (&tag_e_delim, dt->delim);
    3325        33174 :   RESOLVE_TAG (&tag_e_sign, dt->sign);
    3326        33152 :   RESOLVE_TAG (&tag_e_round, dt->round);
    3327        33130 :   RESOLVE_TAG (&tag_e_blank, dt->blank);
    3328        33108 :   RESOLVE_TAG (&tag_e_decimal, dt->decimal);
    3329        33088 :   RESOLVE_TAG (&tag_e_async, dt->asynchronous);
    3330              : 
    3331              :   /* Check I/O constraints.
    3332              :      To validate NAMELIST we need to check if we were also given an I/O list,
    3333              :      which is stored in code->block->next with op EXEC_TRANSFER.
    3334              :      Note that the I/O list was already resolved from resolve_transfer.  */
    3335        33065 :   gfc_code *io_code = NULL;
    3336        33065 :   if (dt_code && dt_code->block && dt_code->block->next
    3337        33065 :       && dt_code->block->next->op == EXEC_TRANSFER)
    3338        33065 :     io_code = dt_code->block->next;
    3339              : 
    3340        33065 :   if (!check_io_constraints (k, dt, io_code, loc))
    3341              :     return false;
    3342              : 
    3343        33006 :   e = dt->io_unit;
    3344        33006 :   if (e == NULL)
    3345              :     {
    3346            2 :       gfc_error ("UNIT not specified at %L", loc);
    3347            2 :       return false;
    3348              :     }
    3349              : 
    3350        33004 :   if (e->symtree && e->symtree->n.sym->attr.flavor == FL_PARAMETER
    3351          365 :       && e->ts.type == BT_CHARACTER)
    3352              :     {
    3353            4 :       gfc_error ("UNIT specification at %L must "
    3354              :       "not be a character PARAMETER", &e->where);
    3355            4 :       return false;
    3356              :     }
    3357              : 
    3358        33000 :   internal_unit = false;
    3359        33000 :   if (gfc_resolve_expr (e)
    3360        33000 :       && (e->ts.type != BT_INTEGER
    3361         9993 :           && (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_VARIABLE)))
    3362              :     {
    3363              :       /* If there is no extra comma signifying the "format" form of the IO
    3364              :          statement, then this must be an error.  */
    3365            2 :       if (!dt->extra_comma)
    3366              :         {
    3367            1 :           gfc_error ("UNIT specification at %L must be an INTEGER expression "
    3368              :                      "or a CHARACTER variable", &e->where);
    3369            1 :           return false;
    3370              :         }
    3371              :       else
    3372              :         {
    3373              :           /* At this point, we have an extra comma.  If io_unit has arrived as
    3374              :              type character, we assume its really the "format" form of the I/O
    3375              :              statement.  We set the io_unit to the default unit and format to
    3376              :              the character expression.  See F95 Standard section 9.4.  */
    3377            1 :           if (e->ts.type == BT_CHARACTER && (k == M_READ || k == M_PRINT))
    3378              :             {
    3379            0 :               dt->format_expr = dt->io_unit;
    3380            0 :               dt->io_unit = default_unit (k);
    3381              : 
    3382              :               /* Nullify this pointer now so that a warning/error is not
    3383              :                  triggered below for the "Extension".  */
    3384            0 :               dt->extra_comma = NULL;
    3385              :             }
    3386              : 
    3387            1 :           if (k == M_WRITE)
    3388              :             {
    3389            1 :               gfc_error ("Invalid form of WRITE statement at %L, UNIT required",
    3390            1 :                          &dt->extra_comma->where);
    3391            1 :               return false;
    3392              :             }
    3393              :         }
    3394              :     }
    3395              : 
    3396        32998 :   if (e->ts.type == BT_CHARACTER)
    3397              :     {
    3398         9991 :       internal_unit = true;
    3399         9991 :       if (gfc_has_vector_index (e))
    3400              :         {
    3401            3 :           gfc_error ("Internal unit with vector subscript at %L", &e->where);
    3402            3 :           return false;
    3403              :         }
    3404              : 
    3405              :       /* If we are writing, make sure the internal unit can be changed.  */
    3406         9988 :       gcc_assert (k != M_PRINT);
    3407         9988 :       if (k == M_WRITE)
    3408              :         {
    3409         8088 :           if (!gfc_check_vardef_context (e, false, false, false,
    3410         8088 :                                         _("internal unit in WRITE")))
    3411              :             return false;
    3412              : 
    3413         8087 :           gfc_expr_set_at (e, &e->where, VALUE_VARDEF);
    3414              :         }
    3415              :     }
    3416              : 
    3417        32994 :   if (e->rank && e->ts.type != BT_CHARACTER)
    3418              :     {
    3419            1 :       gfc_error ("External IO UNIT cannot be an array at %L", &e->where);
    3420            1 :       return false;
    3421              :     }
    3422              : 
    3423        32993 :   if (e->expr_type == EXPR_CONSTANT && e->ts.type == BT_INTEGER
    3424        21485 :       && mpz_sgn (e->value.integer) < 0)
    3425              :     {
    3426            0 :       gfc_error ("UNIT number in statement at %L must be non-negative",
    3427              :                  &e->where);
    3428            0 :       return false;
    3429              :     }
    3430              : 
    3431        32993 :   if (!internal_unit)
    3432        23006 :     gfc_value_used_expr (e, VALUE_USED);
    3433              : 
    3434              :   /* If we are reading and have a namelist, check that all namelist symbols
    3435              :      can appear in a variable definition context.  */
    3436        32993 :   if (dt->namelist)
    3437              :     {
    3438         1193 :       gfc_namelist* n;
    3439         4208 :       for (n = dt->namelist->namelist; n; n = n->next)
    3440              :         {
    3441         3021 :           gfc_expr* e;
    3442         3021 :           bool t;
    3443              : 
    3444         3021 :           if (k == M_READ)
    3445              :             {
    3446         2035 :               e = gfc_get_variable_expr (gfc_find_sym_in_symtree (n->sym));
    3447         2035 :               t = gfc_check_vardef_context (e, false, false, false, NULL);
    3448         2035 :               gfc_free_expr (e);
    3449              : 
    3450         2035 :               if (!t)
    3451              :                 {
    3452            1 :                   gfc_error ("NAMELIST %qs in READ statement at %L contains"
    3453              :                              " the symbol %qs which may not appear in a"
    3454              :                              " variable definition context",
    3455            1 :                              dt->namelist->name, loc, n->sym->name);
    3456            1 :                   return false;
    3457              :                 }
    3458         2034 :               gfc_value_set_at (n->sym, NULL, VALUE_VARDEF);
    3459              :             }
    3460              : 
    3461         3020 :           t = dtio_procs_present (n->sym, k);
    3462              : 
    3463         3020 :           if (n->sym->ts.type == BT_CLASS && !t)
    3464              :             {
    3465            3 :               gfc_error ("NAMELIST object %qs in namelist %qs at %L is "
    3466              :                          "polymorphic and requires a defined input/output "
    3467            3 :                          "procedure", n->sym->name, dt->namelist->name, loc);
    3468            3 :               return false;
    3469              :             }
    3470              : 
    3471         3017 :           if ((n->sym->ts.type == BT_DERIVED)
    3472          783 :               && (n->sym->ts.u.derived->attr.alloc_comp
    3473          781 :                   || n->sym->ts.u.derived->attr.pointer_comp))
    3474              :             {
    3475            2 :               if (!gfc_notify_std (GFC_STD_F2003, "NAMELIST object %qs in "
    3476              :                                    "namelist %qs at %L with ALLOCATABLE "
    3477              :                                    "or POINTER components", n->sym->name,
    3478            2 :                                    dt->namelist->name, loc))
    3479              :                 return false;
    3480              : 
    3481            2 :               if (!t)
    3482              :                 {
    3483            2 :                   gfc_error ("NAMELIST object %qs in namelist %qs at %L has "
    3484              :                              "ALLOCATABLE or POINTER components and thus requires "
    3485            2 :                              "a defined input/output procedure", n->sym->name,
    3486            2 :                              dt->namelist->name, loc);
    3487            2 :                   return false;
    3488              :                 }
    3489              :             }
    3490              :         }
    3491              :     }
    3492              : 
    3493        32987 :   if (dt->extra_comma
    3494        32987 :       && !gfc_notify_std (GFC_STD_LEGACY, "Comma before i/o item list at %L",
    3495              :                           &dt->extra_comma->where))
    3496              :     return false;
    3497              : 
    3498        32987 :   if (dt->err)
    3499              :     {
    3500          250 :       if (!gfc_reference_st_label (dt->err, ST_LABEL_TARGET))
    3501              :         return false;
    3502          250 :       if (dt->err->defined == ST_LABEL_UNKNOWN)
    3503              :         {
    3504            1 :           gfc_error ("ERR tag label %d at %L not defined",
    3505              :                       dt->err->value, &dt->err_where);
    3506            1 :           return false;
    3507              :         }
    3508              :     }
    3509              : 
    3510        32986 :   if (dt->end)
    3511              :     {
    3512          557 :       if (!gfc_reference_st_label (dt->end, ST_LABEL_TARGET))
    3513              :         return false;
    3514          557 :       if (dt->end->defined == ST_LABEL_UNKNOWN)
    3515              :         {
    3516            1 :           gfc_error ("END tag label %d at %L not defined",
    3517              :                       dt->end->value, &dt->end_where);
    3518            1 :           return false;
    3519              :         }
    3520              :     }
    3521              : 
    3522        32985 :   if (dt->eor)
    3523              :     {
    3524           31 :       if (!gfc_reference_st_label (dt->eor, ST_LABEL_TARGET))
    3525              :         return false;
    3526           31 :       if (dt->eor->defined == ST_LABEL_UNKNOWN)
    3527              :         {
    3528            1 :           gfc_error ("EOR tag label %d at %L not defined",
    3529              :                       dt->eor->value, &dt->eor_where);
    3530            1 :           return false;
    3531              :         }
    3532              :     }
    3533              : 
    3534              :   /* Check the format label actually exists.  */
    3535        32984 :   if (dt->format_label && dt->format_label != &format_asterisk
    3536         1767 :       && dt->format_label->defined == ST_LABEL_UNKNOWN)
    3537              :     {
    3538            7 :       gfc_error ("FORMAT label %d at %L not defined", dt->format_label->value,
    3539              :                  loc);
    3540            7 :       return false;
    3541              :     }
    3542              : 
    3543              :   return true;
    3544              : }
    3545              : 
    3546              : 
    3547              : /* Given an io_kind, return its name.  */
    3548              : 
    3549              : static const char *
    3550          811 : io_kind_name (io_kind k)
    3551              : {
    3552          811 :   const char *name;
    3553              : 
    3554          811 :   switch (k)
    3555              :     {
    3556              :     case M_READ:
    3557              :       name = "READ";
    3558              :       break;
    3559          499 :     case M_WRITE:
    3560          499 :       name = "WRITE";
    3561          499 :       break;
    3562           26 :     case M_PRINT:
    3563           26 :       name = "PRINT";
    3564           26 :       break;
    3565            0 :     case M_INQUIRE:
    3566            0 :       name = "INQUIRE";
    3567            0 :       break;
    3568            0 :     default:
    3569            0 :       gfc_internal_error ("io_kind_name(): bad I/O-kind");
    3570              :     }
    3571              : 
    3572          811 :   return name;
    3573              : }
    3574              : 
    3575              : 
    3576              : /* Match an IO iteration statement of the form:
    3577              : 
    3578              :    ( [<IO element> ,] <IO element>, I = <expr>, <expr> [, <expr> ] )
    3579              : 
    3580              :    which is equivalent to a single IO element.  This function is
    3581              :    mutually recursive with match_io_element().  */
    3582              : 
    3583              : static match match_io_element (io_kind, gfc_code **);
    3584              : 
    3585              : static match
    3586        48300 : match_io_iterator (io_kind k, gfc_code **result)
    3587              : {
    3588        48300 :   gfc_code *head, *tail, *new_code;
    3589        48300 :   gfc_iterator *iter;
    3590        48300 :   locus old_loc;
    3591        48300 :   match m;
    3592        48300 :   int n;
    3593              : 
    3594        48300 :   iter = NULL;
    3595        48300 :   head = NULL;
    3596        48300 :   old_loc = gfc_current_locus;
    3597              : 
    3598        48300 :   if (gfc_match_char ('(') != MATCH_YES)
    3599              :     return MATCH_NO;
    3600              : 
    3601          763 :   m = match_io_element (k, &head);
    3602          763 :   tail = head;
    3603              : 
    3604          763 :   if (m != MATCH_YES || gfc_match_char (',') != MATCH_YES)
    3605              :     {
    3606           92 :       m = MATCH_NO;
    3607           92 :       goto cleanup;
    3608              :     }
    3609              : 
    3610              :   /* Can't be anything but an IO iterator.  Build a list.  */
    3611          671 :   iter = gfc_get_iterator ();
    3612              : 
    3613          671 :   for (n = 1;; n++)
    3614              :     {
    3615          723 :       m = gfc_match_iterator (iter, 0);
    3616          723 :       if (m == MATCH_ERROR)
    3617            0 :         goto cleanup;
    3618          723 :       if (m == MATCH_YES)
    3619              :         {
    3620          654 :           gfc_check_do_variable (iter->var->symtree);
    3621          654 :           break;
    3622              :         }
    3623              : 
    3624           69 :       m = match_io_element (k, &new_code);
    3625           69 :       if (m == MATCH_ERROR)
    3626            0 :         goto cleanup;
    3627           69 :       if (m == MATCH_NO)
    3628              :         {
    3629              :           if (n > 2)
    3630              :             goto syntax;
    3631              :           goto cleanup;
    3632              :         }
    3633              : 
    3634           69 :       tail = gfc_append_code (tail, new_code);
    3635              : 
    3636           69 :       if (gfc_match_char (',') != MATCH_YES)
    3637              :         {
    3638           17 :           if (n > 2)
    3639            0 :             goto syntax;
    3640           17 :           m = MATCH_NO;
    3641           17 :           goto cleanup;
    3642              :         }
    3643              :     }
    3644              : 
    3645          654 :   if (gfc_match_char (')') != MATCH_YES)
    3646            1 :     goto syntax;
    3647              : 
    3648          653 :   new_code = gfc_get_code (EXEC_DO);
    3649          653 :   new_code->ext.iterator = iter;
    3650              : 
    3651          653 :   new_code->block = gfc_get_code (EXEC_DO);
    3652          653 :   new_code->block->next = head;
    3653              : 
    3654          653 :   *result = new_code;
    3655          653 :   return MATCH_YES;
    3656              : 
    3657            1 : syntax:
    3658            1 :   gfc_error ("Syntax error in I/O iterator at %C");
    3659            1 :   m = MATCH_ERROR;
    3660              : 
    3661          110 : cleanup:
    3662          110 :   gfc_free_iterator (iter, 1);
    3663          110 :   gfc_free_statements (head);
    3664          110 :   gfc_current_locus = old_loc;
    3665          110 :   return m;
    3666              : }
    3667              : 
    3668              : 
    3669              : /* Match a single element of an IO list, which is either a single
    3670              :    expression or an IO Iterator.  */
    3671              : 
    3672              : static match
    3673        48300 : match_io_element (io_kind k, gfc_code **cpp)
    3674              : {
    3675        48300 :   gfc_expr *expr;
    3676        48300 :   gfc_code *cp;
    3677        48300 :   match m;
    3678              : 
    3679        48300 :   expr = NULL;
    3680              : 
    3681        48300 :   m = match_io_iterator (k, cpp);
    3682        48300 :   if (m == MATCH_YES)
    3683              :     return MATCH_YES;
    3684              : 
    3685        47647 :   if (k == M_READ)
    3686              :     {
    3687         7488 :       m = gfc_match_variable (&expr, 0);
    3688         7488 :       if (m == MATCH_NO)
    3689              :         {
    3690            0 :           gfc_error ("Expecting variable in READ statement at %C");
    3691            0 :           m = MATCH_ERROR;
    3692              :         }
    3693              : 
    3694         7488 :       if (m == MATCH_YES && expr->expr_type == EXPR_CONSTANT)
    3695              :         {
    3696            1 :           gfc_error ("Expecting variable or io-implied-do in READ statement "
    3697              :                    "at %L", &expr->where);
    3698            1 :           m = MATCH_ERROR;
    3699              :         }
    3700              : 
    3701         7488 :       if (m == MATCH_YES
    3702         7487 :           && expr->expr_type == EXPR_VARIABLE
    3703         7487 :           && expr->symtree->n.sym->attr.external)
    3704              :         {
    3705            2 :           gfc_error ("Expecting variable or io-implied-do at %L",
    3706              :                      &expr->where);
    3707            2 :           m = MATCH_ERROR;
    3708              :         }
    3709              :     }
    3710              :   else
    3711              :     {
    3712        40159 :       m = gfc_match_expr (&expr);
    3713        40159 :       if (m == MATCH_NO)
    3714           41 :         gfc_error ("Expected expression in %s statement at %C",
    3715              :                    io_kind_name (k));
    3716              : 
    3717        40159 :       if (m == MATCH_YES && expr->ts.type == BT_BOZ)
    3718              :         {
    3719            6 :           if (gfc_invalid_boz (G_("BOZ literal constant at %L cannot appear in"
    3720              :                                 " an output IO list"), &gfc_current_locus))
    3721              :             return MATCH_ERROR;
    3722            3 :           if (!gfc_boz2int (expr, gfc_max_integer_kind))
    3723              :             return MATCH_ERROR;
    3724        47644 :         };
    3725              :     }
    3726              : 
    3727        47644 :   if (m == MATCH_YES && k == M_READ && gfc_check_do_variable (expr->symtree))
    3728              :     m = MATCH_ERROR;
    3729              : 
    3730        47643 :   if (m != MATCH_YES)
    3731              :     {
    3732          142 :       gfc_free_expr (expr);
    3733          142 :       return MATCH_ERROR;
    3734              :     }
    3735              : 
    3736        47502 :   cp = gfc_get_code (EXEC_TRANSFER);
    3737        47502 :   cp->expr1 = expr;
    3738        47502 :   if (k != M_INQUIRE)
    3739        47348 :     cp->ext.dt = current_dt;
    3740              : 
    3741        47502 :   *cpp = cp;
    3742        47502 :   return MATCH_YES;
    3743              : }
    3744              : 
    3745              : 
    3746              : /* Match an I/O list, building gfc_code structures as we go.  */
    3747              : 
    3748              : static match
    3749        31360 : match_io_list (io_kind k, gfc_code **head_p)
    3750              : {
    3751        31360 :   gfc_code *head, *tail, *new_code;
    3752        31360 :   match m;
    3753              : 
    3754        31360 :   *head_p = head = tail = NULL;
    3755        31360 :   if (gfc_match_eos () == MATCH_YES)
    3756              :     return MATCH_YES;
    3757              : 
    3758        47468 :   for (;;)
    3759              :     {
    3760        47468 :       m = match_io_element (k, &new_code);
    3761        47468 :       if (m == MATCH_ERROR)
    3762          104 :         goto cleanup;
    3763        47364 :       if (m == MATCH_NO)
    3764              :         goto syntax;
    3765              : 
    3766        47364 :       tail = gfc_append_code (tail, new_code);
    3767        47364 :       if (head == NULL)
    3768        31262 :         head = new_code;
    3769              : 
    3770        47364 :       if (gfc_match_eos () == MATCH_YES)
    3771              :         break;
    3772        16117 :       if (gfc_match_char (',') != MATCH_YES)
    3773            9 :         goto syntax;
    3774              :     }
    3775              : 
    3776        31247 :   *head_p = head;
    3777        31247 :   return MATCH_YES;
    3778              : 
    3779            9 : syntax:
    3780            9 :   gfc_error ("Syntax error in %s statement at %C", io_kind_name (k));
    3781              : 
    3782          113 : cleanup:
    3783          113 :   gfc_free_statements (head);
    3784          113 :   return MATCH_ERROR;
    3785              : }
    3786              : 
    3787              : 
    3788              : /* Attach the data transfer end node.  */
    3789              : 
    3790              : static void
    3791        33379 : terminate_io (gfc_code *io_code)
    3792              : {
    3793        33379 :   gfc_code *c;
    3794              : 
    3795        33379 :   if (io_code == NULL)
    3796         2167 :     io_code = new_st.block;
    3797              : 
    3798        33379 :   c = gfc_get_code (EXEC_DT_END);
    3799              : 
    3800              :   /* Point to structure that is already there */
    3801        33379 :   c->ext.dt = new_st.ext.dt;
    3802        33379 :   gfc_append_code (io_code, c);
    3803        33379 : }
    3804              : 
    3805              : 
    3806              : /* Check the constraints for a data transfer statement.  The majority of the
    3807              :    constraints appearing in 9.4 of the standard appear here.
    3808              : 
    3809              :    Tag expressions are already resolved by resolve_tag, which includes
    3810              :    verifying the type, that they are scalar, and verifying that BT_CHARACTER
    3811              :    tags are of default kind.  */
    3812              : 
    3813              : static bool
    3814        33065 : check_io_constraints (io_kind k, gfc_dt *dt, gfc_code *io_code,
    3815              :                       locus *spec_end)
    3816              : {
    3817              : #define io_constraint(condition, msg, where)\
    3818              : if (condition) \
    3819              :   {\
    3820              :     if (GFC_LOCUS_IS_SET (*where))\
    3821              :       gfc_error ((msg), (where));\
    3822              :     else\
    3823              :       gfc_error ((msg), spec_end);\
    3824              :     return false;\
    3825              :   }
    3826              : 
    3827        33065 :   gfc_expr *expr;
    3828        33065 :   gfc_symbol *sym = NULL;
    3829        33065 :   bool warn, unformatted;
    3830              : 
    3831        33065 :   warn = (dt->err || dt->iostat) ? true : false;
    3832        20849 :   unformatted = dt->format_expr == NULL && dt->format_label == NULL
    3833        36668 :                 && dt->namelist == NULL;
    3834              : 
    3835        33065 :   expr = dt->io_unit;
    3836        33065 :   if (expr && expr->expr_type == EXPR_VARIABLE
    3837        11522 :       && expr->ts.type == BT_CHARACTER)
    3838              :     {
    3839         9998 :       sym = expr->symtree->n.sym;
    3840              : 
    3841         9998 :       io_constraint (k == M_WRITE && sym->attr.intent == INTENT_IN,
    3842              :                      "Internal file at %L must not be INTENT(IN)",
    3843         9998 :                      &expr->where);
    3844              : 
    3845         9998 :       io_constraint (gfc_has_vector_index (dt->io_unit),
    3846              :                      "Internal file incompatible with vector subscript at %L",
    3847         9998 :                      &expr->where);
    3848              : 
    3849         9998 :       io_constraint (dt->rec != NULL,
    3850              :                      "REC tag at %L is incompatible with internal file",
    3851         9997 :                      &dt->rec->where);
    3852              : 
    3853         9997 :       io_constraint (dt->pos != NULL,
    3854              :                      "POS tag at %L is incompatible with internal file",
    3855         9996 :                      &dt->pos->where);
    3856              : 
    3857         9996 :       io_constraint (unformatted,
    3858              :                      "Unformatted I/O not allowed with internal unit at %L",
    3859         9995 :                      &dt->io_unit->where);
    3860              : 
    3861         9995 :       io_constraint (dt->asynchronous != NULL,
    3862              :                      "ASYNCHRONOUS tag at %L not allowed with internal file",
    3863         9995 :                      &dt->asynchronous->where);
    3864              : 
    3865         9995 :       if (dt->namelist != NULL)
    3866              :         {
    3867          254 :           if (!gfc_notify_std (GFC_STD_F2003, "Internal file at %L with "
    3868              :                                "namelist", &expr->where))
    3869              :             return false;
    3870              :         }
    3871              : 
    3872         9994 :       io_constraint (dt->advance != NULL,
    3873              :                      "ADVANCE tag at %L is incompatible with internal file",
    3874              :                      &dt->advance->where);
    3875              :     }
    3876              : 
    3877        33058 :   if (expr && expr->ts.type != BT_CHARACTER)
    3878              :     {
    3879              : 
    3880        23062 :       if (gfc_pure (NULL) && (k == M_READ || k == M_WRITE))
    3881              :         {
    3882            0 :           gfc_error ("IO UNIT in %s statement at %L must be "
    3883              :                      "an internal file in a PURE procedure",
    3884              :                      io_kind_name (k), &expr->where);
    3885            0 :           return false;
    3886              :         }
    3887              : 
    3888        23062 :       if (k == M_READ || k == M_WRITE)
    3889        15455 :         gfc_unset_implicit_pure (NULL);
    3890              :     }
    3891              : 
    3892        33060 :   if (dt->asynchronous)
    3893              :     {
    3894          206 :       int num = -1;
    3895          206 :       static const char * asynchronous[] = { "YES", "NO", NULL };
    3896              : 
    3897              :       /* Note: gfc_reduce_init_expr reports an error if not init-expr.  */
    3898          206 :       if (!gfc_reduce_init_expr (dt->asynchronous))
    3899            7 :         return false;
    3900              : 
    3901          201 :       if (!compare_to_allowed_values
    3902          201 :                 ("ASYNCHRONOUS", asynchronous, NULL, NULL,
    3903              :                  dt->asynchronous->value.character.string,
    3904          201 :                  io_kind_name (k), warn, &dt->asynchronous->where, &num))
    3905              :         return false;
    3906              : 
    3907          199 :       gcc_checking_assert (num != -1);
    3908              : 
    3909              :       /* For "YES", mark related symbols as asynchronous.  */
    3910          199 :       if (num == 0)
    3911              :         {
    3912              :           /* SIZE variable.  */
    3913          195 :           if (dt->size)
    3914            0 :             dt->size->symtree->n.sym->attr.asynchronous = 1;
    3915              : 
    3916              :           /* Variables in a NAMELIST.  */
    3917          195 :           if (dt->namelist)
    3918            4 :             for (gfc_namelist *nl = dt->namelist->namelist; nl; nl = nl->next)
    3919            3 :               nl->sym->attr.asynchronous = 1;
    3920              : 
    3921              :           /* Variables in an I/O list.  */
    3922          430 :           for (gfc_code *xfer = io_code; xfer && xfer->op == EXEC_TRANSFER;
    3923          235 :                xfer = xfer->next)
    3924              :             {
    3925          235 :               gfc_expr *expr = xfer->expr1;
    3926          470 :               while (expr != NULL && expr->expr_type == EXPR_OP
    3927          241 :                      && expr->value.op.op == INTRINSIC_PARENTHESES)
    3928            0 :                 expr = expr->value.op.op1;
    3929              : 
    3930          235 :               if (expr && expr->expr_type == EXPR_VARIABLE)
    3931          157 :                 expr->symtree->n.sym->attr.asynchronous = 1;
    3932              :             }
    3933              :         }
    3934              :     }
    3935              : 
    3936        33053 :   if (dt->id)
    3937              :     {
    3938           21 :       bool not_yes
    3939           21 :         = !dt->asynchronous
    3940           20 :           || gfc_wide_strlen (dt->asynchronous->value.character.string) != 3
    3941           40 :           || gfc_wide_strncasecmp (dt->asynchronous->value.character.string,
    3942        33053 :                                    "yes", 3) != 0;
    3943            2 :       io_constraint (not_yes,
    3944              :                      "ID= specifier at %L must be with ASYNCHRONOUS='yes' "
    3945              :                      "specifier", &dt->id->where);
    3946              :     }
    3947              : 
    3948        33051 :   if (dt->decimal)
    3949              :     {
    3950          145 :       if (!gfc_notify_std (GFC_STD_F2003, "DECIMAL= at %L "
    3951              :                            "not allowed in Fortran 95", &dt->decimal->where))
    3952              :         return false;
    3953              : 
    3954          145 :       if (dt->decimal->expr_type == EXPR_CONSTANT)
    3955              :         {
    3956          127 :           static const char * decimal[] = { "COMMA", "POINT", NULL };
    3957              : 
    3958          127 :           if (!compare_to_allowed_values ("DECIMAL", decimal, NULL, NULL,
    3959              :                                           dt->decimal->value.character.string,
    3960              :                                           io_kind_name (k), warn,
    3961              :                                           &dt->decimal->where))
    3962              :             return false;
    3963              : 
    3964          123 :           io_constraint (unformatted,
    3965              :                          "the DECIMAL= specifier at %L must be with an "
    3966              :                          "explicit format expression", &dt->decimal->where);
    3967              :         }
    3968              :     }
    3969              : 
    3970        33047 :   if (dt->blank)
    3971              :     {
    3972           17 :       if (!gfc_notify_std (GFC_STD_F2003, "BLANK= at %L "
    3973              :                            "not allowed in Fortran 95", &dt->blank->where))
    3974              :         return false;
    3975              : 
    3976           17 :       if (dt->blank->expr_type == EXPR_CONSTANT)
    3977              :         {
    3978           16 :           static const char * blank[] = { "NULL", "ZERO", NULL };
    3979              : 
    3980              : 
    3981           16 :           if (!compare_to_allowed_values ("BLANK", blank, NULL, NULL,
    3982              :                                           dt->blank->value.character.string,
    3983              :                                           io_kind_name (k), warn,
    3984              :                                           &dt->blank->where))
    3985              :             return false;
    3986              : 
    3987           12 :           io_constraint (unformatted,
    3988              :                          "the BLANK= specifier at %L must be with an "
    3989              :                          "explicit format expression", &dt->blank->where);
    3990              :         }
    3991              :     }
    3992              : 
    3993        33043 :   if (dt->pad)
    3994              :     {
    3995           83 :       if (!gfc_notify_std (GFC_STD_F2003, "PAD= at %L "
    3996              :                            "not allowed in Fortran 95", &dt->pad->where))
    3997              :         return false;
    3998              : 
    3999           83 :       if (dt->pad->expr_type == EXPR_CONSTANT)
    4000              :         {
    4001           83 :           static const char * pad[] = { "YES", "NO", NULL };
    4002              : 
    4003           83 :           if (!compare_to_allowed_values ("PAD", pad, NULL, NULL,
    4004              :                                           dt->pad->value.character.string,
    4005              :                                           io_kind_name (k), warn,
    4006              :                                           &dt->pad->where))
    4007              :             return false;
    4008              : 
    4009           81 :           io_constraint (unformatted,
    4010              :                          "the PAD= specifier at %L must be with an "
    4011              :                          "explicit format expression", &dt->pad->where);
    4012              :         }
    4013              :     }
    4014              : 
    4015        33039 :   if (dt->round)
    4016              :     {
    4017          317 :       if (!gfc_notify_std (GFC_STD_F2003, "ROUND= at %L "
    4018              :                            "not allowed in Fortran 95", &dt->round->where))
    4019              :         return false;
    4020              : 
    4021          317 :       if (dt->round->expr_type == EXPR_CONSTANT)
    4022              :         {
    4023          305 :           static const char * round[] = { "UP", "DOWN", "ZERO", "NEAREST",
    4024              :                                           "COMPATIBLE", "PROCESSOR_DEFINED",
    4025              :                                           NULL };
    4026              : 
    4027          305 :           if (!compare_to_allowed_values ("ROUND", round, NULL, NULL,
    4028              :                                           dt->round->value.character.string,
    4029              :                                           io_kind_name (k), warn,
    4030              :                                           &dt->round->where))
    4031              :             return false;
    4032              :         }
    4033              :     }
    4034              : 
    4035        33035 :   if (dt->sign)
    4036              :     {
    4037              :       /* When implemented, change the following to use gfc_notify_std F2003.
    4038              :       if (gfc_notify_std (GFC_STD_F2003, "SIGN= at %L "
    4039              :           "not allowed in Fortran 95", &dt->sign->where) == false)
    4040              :         return false;  */
    4041              : 
    4042           17 :       if (dt->sign->expr_type == EXPR_CONSTANT)
    4043              :         {
    4044           16 :           static const char * sign[] = { "PLUS", "SUPPRESS", "PROCESSOR_DEFINED",
    4045              :                                          NULL };
    4046              : 
    4047           16 :           if (!compare_to_allowed_values ("SIGN", sign, NULL, NULL,
    4048              :                                       dt->sign->value.character.string,
    4049              :                                       io_kind_name (k), warn, &dt->sign->where))
    4050              :             return false;
    4051              : 
    4052           12 :           io_constraint (unformatted,
    4053              :                          "SIGN= specifier at %L must be with an "
    4054           12 :                          "explicit format expression", &dt->sign->where);
    4055              : 
    4056           12 :           io_constraint (k == M_READ,
    4057              :                          "SIGN= specifier at %L not allowed in a "
    4058              :                          "READ statement", &dt->sign->where);
    4059              :         }
    4060              :     }
    4061              : 
    4062        33031 :   if (dt->delim)
    4063              :     {
    4064            7 :       if (!gfc_notify_std (GFC_STD_F2003, "DELIM= at %L "
    4065              :                            "not allowed in Fortran 95", &dt->delim->where))
    4066              :         return false;
    4067              : 
    4068            6 :       if (dt->delim->expr_type == EXPR_CONSTANT)
    4069              :         {
    4070            6 :           static const char *delim[] = { "APOSTROPHE", "QUOTE", "NONE", NULL };
    4071              : 
    4072            6 :           if (!compare_to_allowed_values ("DELIM", delim, NULL, NULL,
    4073              :                                           dt->delim->value.character.string,
    4074              :                                           io_kind_name (k), warn,
    4075              :                                           &dt->delim->where))
    4076              :             return false;
    4077              : 
    4078            2 :           io_constraint (k == M_READ,
    4079              :                          "DELIM= specifier at %L not allowed in a "
    4080            2 :                          "READ statement", &dt->delim->where);
    4081              : 
    4082            2 :           io_constraint (dt->format_label != &format_asterisk
    4083              :                          && dt->namelist == NULL,
    4084              :                          "DELIM= specifier at %L must have FMT=*",
    4085            2 :                          &dt->delim->where);
    4086              : 
    4087            2 :           io_constraint (unformatted && dt->namelist == NULL,
    4088              :                          "DELIM= specifier at %L must be with FMT=* or "
    4089              :                          "NML= specifier", &dt->delim->where);
    4090              :         }
    4091              :     }
    4092              : 
    4093        33026 :   if (dt->namelist)
    4094              :     {
    4095         1197 :       io_constraint (io_code && dt->namelist,
    4096              :                      "NAMELIST cannot be followed by IO-list at %L",
    4097         1196 :                      &io_code->loc);
    4098              : 
    4099         1196 :       io_constraint (dt->format_expr,
    4100              :                      "IO spec-list cannot contain both NAMELIST group name "
    4101              :                      "and format specification at %L",
    4102         1195 :                      &dt->format_expr->where);
    4103              : 
    4104         1195 :       io_constraint (dt->format_label,
    4105              :                      "IO spec-list cannot contain both NAMELIST group name "
    4106         1194 :                      "and format label at %L", spec_end);
    4107              : 
    4108         1194 :       io_constraint (dt->rec,
    4109              :                      "NAMELIST IO is not allowed with a REC= specifier "
    4110         1194 :                      "at %L", &dt->rec->where);
    4111              : 
    4112         1194 :       io_constraint (dt->advance,
    4113              :                      "NAMELIST IO is not allowed with a ADVANCE= specifier "
    4114              :                      "at %L", &dt->advance->where);
    4115              :     }
    4116              : 
    4117        33022 :   if (dt->rec)
    4118              :     {
    4119          499 :       io_constraint (dt->end,
    4120              :                      "An END tag is not allowed with a "
    4121          498 :                      "REC= specifier at %L", &dt->end_where);
    4122              : 
    4123          498 :       io_constraint (dt->format_label == &format_asterisk,
    4124              :                      "FMT=* is not allowed with a REC= specifier "
    4125          497 :                      "at %L", spec_end);
    4126              : 
    4127          497 :       io_constraint (dt->pos,
    4128              :                      "POS= is not allowed with REC= specifier "
    4129              :                      "at %L", &dt->pos->where);
    4130              :     }
    4131              : 
    4132        33018 :   if (dt->advance)
    4133              :     {
    4134          373 :       int not_yes, not_no;
    4135          373 :       expr = dt->advance;
    4136              : 
    4137          373 :       io_constraint (dt->format_label == &format_asterisk,
    4138              :                      "List directed format(*) is not allowed with a "
    4139          373 :                      "ADVANCE= specifier at %L.", &expr->where);
    4140              : 
    4141          373 :       io_constraint (unformatted,
    4142              :                      "the ADVANCE= specifier at %L must appear with an "
    4143          372 :                      "explicit format expression", &expr->where);
    4144              : 
    4145          372 :       if (expr->expr_type == EXPR_CONSTANT && expr->ts.type == BT_CHARACTER)
    4146              :         {
    4147          353 :           const gfc_char_t *advance = expr->value.character.string;
    4148          353 :           not_no = gfc_wide_strlen (advance) != 2
    4149          353 :                    || gfc_wide_strncasecmp (advance, "no", 2) != 0;
    4150          353 :           not_yes = gfc_wide_strlen (advance) != 3
    4151          353 :                     || gfc_wide_strncasecmp (advance, "yes", 3) != 0;
    4152          353 :         }
    4153              :       else
    4154              :         {
    4155              :           not_no = 0;
    4156              :           not_yes = 0;
    4157              :         }
    4158              : 
    4159          372 :       io_constraint (not_no && not_yes,
    4160              :                      "ADVANCE= specifier at %L must have value = "
    4161          368 :                      "YES or NO.", &expr->where);
    4162              : 
    4163          368 :       io_constraint (dt->size && not_no && k == M_READ,
    4164              :                      "SIZE tag at %L requires an ADVANCE = %<NO%>",
    4165          367 :                      &dt->size->where);
    4166              : 
    4167          367 :       io_constraint (dt->eor && not_no && k == M_READ,
    4168              :                      "EOR tag at %L requires an ADVANCE = %<NO%>",
    4169              :                      &dt->eor_where);
    4170              :     }
    4171              : 
    4172        33011 :   if (k != M_READ)
    4173              :     {
    4174        26709 :       io_constraint (dt->end, "END tag not allowed with output at %L",
    4175        26708 :                      &dt->end_where);
    4176              : 
    4177        26708 :       io_constraint (dt->eor, "EOR tag not allowed with output at %L",
    4178        26706 :                      &dt->eor_where);
    4179              : 
    4180        26706 :       io_constraint (dt->blank,
    4181              :                      "BLANK= specifier not allowed with output at %L",
    4182        26706 :                      &dt->blank->where);
    4183              : 
    4184        26706 :       io_constraint (dt->pad, "PAD= specifier not allowed with output at %L",
    4185        26706 :                      &dt->pad->where);
    4186              : 
    4187        26706 :       io_constraint (dt->size, "SIZE= specifier not allowed with output at %L",
    4188              :                      &dt->size->where);
    4189              :     }
    4190              :   else
    4191              :     {
    4192         6302 :       io_constraint (dt->size && dt->advance == NULL,
    4193              :                      "SIZE tag at %L requires an ADVANCE tag",
    4194         6302 :                      &dt->size->where);
    4195              : 
    4196         6302 :       io_constraint (dt->eor && dt->advance == NULL,
    4197              :                      "EOR tag at %L requires an ADVANCE tag",
    4198              :                      &dt->eor_where);
    4199              :     }
    4200              : 
    4201              :   return true;
    4202              : #undef io_constraint
    4203              : }
    4204              : 
    4205              : 
    4206              : /* Match a READ, WRITE or PRINT statement.  */
    4207              : 
    4208              : static match
    4209        33459 : match_io (io_kind k)
    4210              : {
    4211        33459 :   char name[GFC_MAX_SYMBOL_LEN + 1];
    4212        33459 :   gfc_code *io_code;
    4213        33459 :   gfc_symbol *sym;
    4214        33459 :   int comma_flag;
    4215        33459 :   locus where;
    4216        33459 :   locus control;
    4217        33459 :   gfc_dt *dt;
    4218        33459 :   match m;
    4219              : 
    4220        33459 :   where = gfc_current_locus;
    4221        33459 :   comma_flag = 0;
    4222        33459 :   current_dt = dt = XCNEW (gfc_dt);
    4223        33459 :   m = gfc_match_char ('(');
    4224        33459 :   if (m == MATCH_NO)
    4225              :     {
    4226         7753 :       where = gfc_current_locus;
    4227         7753 :       if (k == M_WRITE)
    4228            0 :         goto syntax;
    4229         7753 :       else if (k == M_PRINT)
    4230              :         {
    4231              :           /* Treat the non-standard case of PRINT namelist.  */
    4232         7459 :           if ((gfc_current_form == FORM_FIXED || gfc_peek_ascii_char () == ' ')
    4233        14962 :               && gfc_match_name (name) == MATCH_YES)
    4234              :             {
    4235          131 :               gfc_find_symbol (name, NULL, 1, &sym);
    4236          131 :               if (sym && sym->attr.flavor == FL_NAMELIST)
    4237              :                 {
    4238           11 :                   if (!gfc_notify_std (GFC_STD_GNU, "PRINT namelist at "
    4239              :                                        "%C is an extension"))
    4240              :                     {
    4241            2 :                       m = MATCH_ERROR;
    4242            2 :                       goto cleanup;
    4243              :                     }
    4244              : 
    4245            9 :                   dt->io_unit = default_unit (k);
    4246            9 :                   dt->namelist = sym;
    4247            9 :                   goto get_io_list;
    4248              :                 }
    4249              :               else
    4250          120 :                 gfc_current_locus = where;
    4251              :             }
    4252              : 
    4253         7728 :           if (gfc_match_char ('*') == MATCH_YES
    4254         7728 :               && gfc_match_char(',') == MATCH_YES)
    4255              :             {
    4256         6933 :               locus where2 = gfc_current_locus;
    4257         6933 :               if (gfc_match_eos () == MATCH_YES)
    4258              :                 {
    4259            1 :                   gfc_current_locus = where2;
    4260            1 :                   gfc_error ("Comma after * at %C not allowed without I/O list");
    4261            1 :                   m = MATCH_ERROR;
    4262            1 :                   goto cleanup;
    4263              :                 }
    4264              :               else
    4265         6932 :                 gfc_current_locus = where;
    4266              :             }
    4267              :           else
    4268          795 :             gfc_current_locus = where;
    4269              :         }
    4270              : 
    4271         7741 :       if (gfc_current_form == FORM_FREE)
    4272              :         {
    4273         7463 :           char c = gfc_peek_ascii_char ();
    4274              : 
    4275              :           /* Issue a warning for an invalid tab in 'print<tab>*'.  After
    4276              :              the warning is issued, consume any other whitespace and check
    4277              :              that the next char is an *, ', or ".  */
    4278         7463 :           if (c == '\t')
    4279              :             {
    4280            2 :               gfc_gobble_whitespace ();
    4281            2 :               c = gfc_peek_ascii_char ();
    4282            2 :               if (c != '*' && c != '\'' && c != '"')
    4283              :                 {
    4284            0 :                   m = MATCH_NO;
    4285            0 :                   goto cleanup;
    4286              :                 }
    4287              :             }
    4288         7461 :           else if (c != ' ' && c != '*' && c != '\'' && c != '"')
    4289              :             {
    4290            2 :               m = MATCH_NO;
    4291            2 :               goto cleanup;
    4292              :             }
    4293              :         }
    4294              : 
    4295         7739 :       m = match_dt_format (dt);
    4296         7739 :       if (m == MATCH_ERROR)
    4297            0 :         goto cleanup;
    4298         7739 :       if (m == MATCH_NO)
    4299            4 :         goto syntax;
    4300              : 
    4301         7735 :       comma_flag = 1;
    4302         7735 :       dt->io_unit = default_unit (k);
    4303         7735 :       goto get_io_list;
    4304              :     }
    4305              :   else
    4306              :     {
    4307              :       /* Before issuing an error for a malformed 'print (1,*)' type of
    4308              :          error, check for a default-char-expr of the form ('(I0)').  */
    4309        25706 :       if (m == MATCH_YES)
    4310              :         {
    4311        25706 :           control = gfc_current_locus;
    4312        25706 :           if (k == M_PRINT)
    4313              :             {
    4314              :               /* Reset current locus to get the initial '(' in an expression.  */
    4315           10 :               gfc_current_locus = where;
    4316           10 :               dt->format_expr = NULL;
    4317           10 :               m = match_dt_format (dt);
    4318              : 
    4319           10 :               if (m == MATCH_ERROR)
    4320            0 :                 goto cleanup;
    4321           10 :               if (m == MATCH_NO || dt->format_expr == NULL)
    4322            3 :                 goto syntax;
    4323              : 
    4324            7 :               comma_flag = 1;
    4325            7 :               dt->io_unit = default_unit (k);
    4326            7 :               goto get_io_list;
    4327              :             }
    4328        25696 :           if (k == M_READ)
    4329              :             {
    4330              :               /* Commit any pending symbols now so that when we undo
    4331              :                  symbols later we wont lose them.  */
    4332         6421 :               gfc_commit_symbols ();
    4333              :               /* Reset current locus to get the initial '(' in an expression.  */
    4334         6421 :               gfc_current_locus = where;
    4335         6421 :               dt->format_expr = NULL;
    4336         6421 :               m = gfc_match_expr (&dt->format_expr);
    4337         6421 :               if (m == MATCH_YES)
    4338              :                 {
    4339          545 :                   if (dt->format_expr
    4340          545 :                       && dt->format_expr->ts.type == BT_CHARACTER)
    4341              :                     {
    4342            3 :                       comma_flag = 1;
    4343            3 :                       dt->io_unit = default_unit (k);
    4344            3 :                       goto get_io_list;
    4345              :                     }
    4346              :                   else
    4347              :                     {
    4348          542 :                       gfc_free_expr (dt->format_expr);
    4349          542 :                       dt->format_expr = NULL;
    4350          542 :                       gfc_current_locus = control;
    4351              :                     }
    4352              :                 }
    4353              :               else
    4354              :                 {
    4355         5876 :                   gfc_clear_error ();
    4356         5876 :                   gfc_undo_symbols ();
    4357         5876 :                   gfc_free_expr (dt->format_expr);
    4358         5876 :                   dt->format_expr = NULL;
    4359         5876 :                   gfc_current_locus = control;
    4360              :                 }
    4361              :             }
    4362              :         }
    4363              :     }
    4364              : 
    4365              :   /* Match a control list */
    4366        25693 :   if (match_dt_element (k, dt) == MATCH_YES)
    4367         1213 :     goto next;
    4368        24480 :   if (match_dt_unit (k, dt) != MATCH_YES)
    4369            0 :     goto loop;
    4370              : 
    4371        24480 :   if (gfc_match_char (')') == MATCH_YES)
    4372         1481 :     goto get_io_list;
    4373        22999 :   if (gfc_match_char (',') != MATCH_YES)
    4374            0 :     goto syntax;
    4375              : 
    4376        22999 :   m = match_dt_element (k, dt);
    4377        22999 :   if (m == MATCH_YES)
    4378         2660 :     goto next;
    4379        20339 :   if (m == MATCH_ERROR)
    4380            0 :     goto cleanup;
    4381              : 
    4382        20339 :   m = match_dt_format (dt);
    4383        20339 :   if (m == MATCH_YES)
    4384        19912 :     goto next;
    4385          427 :   if (m == MATCH_ERROR)
    4386            7 :     goto cleanup;
    4387              : 
    4388          420 :   where = gfc_current_locus;
    4389              : 
    4390          420 :   m = gfc_match_name (name);
    4391          420 :   if (m == MATCH_YES)
    4392              :     {
    4393          420 :       gfc_find_symbol (name, NULL, 1, &sym);
    4394          420 :       if (sym && sym->attr.flavor == FL_NAMELIST)
    4395              :         {
    4396          420 :           dt->namelist = sym;
    4397          420 :           if (k == M_READ && check_namelist (sym))
    4398              :             {
    4399            1 :               m = MATCH_ERROR;
    4400            1 :               goto cleanup;
    4401              :             }
    4402          419 :           goto next;
    4403              :         }
    4404              :     }
    4405              : 
    4406            0 :   gfc_current_locus = where;
    4407              : 
    4408            0 :   goto loop;                    /* No matches, try regular elements */
    4409              : 
    4410        24204 : next:
    4411        24204 :   if (gfc_match_char (')') == MATCH_YES)
    4412        20016 :     goto get_io_list;
    4413         4188 :   if (gfc_match_char (',') != MATCH_YES)
    4414            0 :     goto syntax;
    4415              : 
    4416         4188 : loop:
    4417         5296 :   for (;;)
    4418              :     {
    4419         5296 :       m = match_dt_element (k, dt);
    4420         5296 :       if (m == MATCH_NO)
    4421            0 :         goto syntax;
    4422         5296 :       if (m == MATCH_ERROR)
    4423            4 :         goto cleanup;
    4424              : 
    4425         5292 :       if (gfc_match_char (')') == MATCH_YES)
    4426              :         break;
    4427         1108 :       if (gfc_match_char (',') != MATCH_YES)
    4428            0 :         goto syntax;
    4429              :     }
    4430              : 
    4431         4184 : get_io_list:
    4432              : 
    4433              :   /* Save the IO kind for later use.  */
    4434        33435 :   dt->dt_io_kind = gfc_get_iokind_expr (&gfc_current_locus, k);
    4435              : 
    4436              :   /* Optional leading comma (non-standard).  We use a gfc_expr structure here
    4437              :      to save the locus.  This is used later when resolving transfer statements
    4438              :      that might have a format expression without unit number.  */
    4439        33435 :   if (!comma_flag && gfc_match_char (',') == MATCH_YES)
    4440           87 :     dt->extra_comma = dt->dt_io_kind;
    4441              : 
    4442        33435 :   io_code = NULL;
    4443        33435 :   if (gfc_match_eos () != MATCH_YES)
    4444              :     {
    4445        31267 :       if (comma_flag && gfc_match_char (',') != MATCH_YES)
    4446              :         {
    4447            0 :           gfc_error ("Expected comma in I/O list at %C");
    4448            0 :           m = MATCH_ERROR;
    4449            0 :           goto cleanup;
    4450              :         }
    4451              : 
    4452        31267 :       m = match_io_list (k, &io_code);
    4453        31267 :       if (m == MATCH_ERROR)
    4454          113 :         goto cleanup;
    4455              :       if (m == MATCH_NO)
    4456              :         goto syntax;
    4457              :     }
    4458              : 
    4459              :   /* See if we want to use defaults for missing exponents in real transfers
    4460              :      and other DEC runtime extensions. */
    4461        33322 :   if (flag_dec_format_defaults)
    4462          484 :     dt->dec_ext = 1;
    4463              : 
    4464              :   /* Check the format string now.  */
    4465        33322 :   if (dt->format_expr
    4466        33322 :       && (!gfc_simplify_expr (dt->format_expr, 0)
    4467        12287 :           || !check_format_string (dt->format_expr, k == M_READ)))
    4468           35 :     return MATCH_ERROR;
    4469              : 
    4470        33287 :   new_st.op = (k == M_READ) ? EXEC_READ : EXEC_WRITE;
    4471        33287 :   new_st.ext.dt = dt;
    4472        33287 :   new_st.block = gfc_get_code (new_st.op);
    4473        33287 :   new_st.block->next = io_code;
    4474              : 
    4475        33287 :   terminate_io (io_code);
    4476              : 
    4477        33287 :   return MATCH_YES;
    4478              : 
    4479            7 : syntax:
    4480            7 :   gfc_error ("Syntax error in %s statement at %C", io_kind_name (k));
    4481            7 :   m = MATCH_ERROR;
    4482              : 
    4483          137 : cleanup:
    4484          137 :   gfc_free_dt (dt);
    4485          137 :   return m;
    4486              : }
    4487              : 
    4488              : 
    4489              : match
    4490         6435 : gfc_match_read (void)
    4491              : {
    4492         6435 :   return match_io (M_READ);
    4493              : }
    4494              : 
    4495              : 
    4496              : match
    4497        19275 : gfc_match_write (void)
    4498              : {
    4499        19275 :   return match_io (M_WRITE);
    4500              : }
    4501              : 
    4502              : 
    4503              : match
    4504         7749 : gfc_match_print (void)
    4505              : {
    4506         7749 :   match m;
    4507              : 
    4508         7749 :   m = match_io (M_PRINT);
    4509         7749 :   if (m != MATCH_YES)
    4510              :     return m;
    4511              : 
    4512         7624 :   if (gfc_pure (NULL))
    4513              :     {
    4514            0 :       gfc_error ("PRINT statement at %C not allowed within PURE procedure");
    4515            0 :       return MATCH_ERROR;
    4516              :     }
    4517              : 
    4518         7624 :   gfc_unset_implicit_pure (NULL);
    4519              : 
    4520         7624 :   return MATCH_YES;
    4521              : }
    4522              : 
    4523              : 
    4524              : /* Free a gfc_inquire structure.  */
    4525              : 
    4526              : void
    4527          846 : gfc_free_inquire (gfc_inquire *inquire)
    4528              : {
    4529              : 
    4530          846 :   if (inquire == NULL)
    4531              :     return;
    4532              : 
    4533          846 :   gfc_free_expr (inquire->unit);
    4534          846 :   gfc_free_expr (inquire->file);
    4535          846 :   gfc_free_expr (inquire->iomsg);
    4536          846 :   gfc_free_expr (inquire->iostat);
    4537          846 :   gfc_free_expr (inquire->exist);
    4538          846 :   gfc_free_expr (inquire->opened);
    4539          846 :   gfc_free_expr (inquire->number);
    4540          846 :   gfc_free_expr (inquire->named);
    4541          846 :   gfc_free_expr (inquire->name);
    4542          846 :   gfc_free_expr (inquire->access);
    4543          846 :   gfc_free_expr (inquire->sequential);
    4544          846 :   gfc_free_expr (inquire->direct);
    4545          846 :   gfc_free_expr (inquire->form);
    4546          846 :   gfc_free_expr (inquire->formatted);
    4547          846 :   gfc_free_expr (inquire->unformatted);
    4548          846 :   gfc_free_expr (inquire->recl);
    4549          846 :   gfc_free_expr (inquire->nextrec);
    4550          846 :   gfc_free_expr (inquire->blank);
    4551          846 :   gfc_free_expr (inquire->position);
    4552          846 :   gfc_free_expr (inquire->action);
    4553          846 :   gfc_free_expr (inquire->read);
    4554          846 :   gfc_free_expr (inquire->write);
    4555          846 :   gfc_free_expr (inquire->readwrite);
    4556          846 :   gfc_free_expr (inquire->delim);
    4557          846 :   gfc_free_expr (inquire->encoding);
    4558          846 :   gfc_free_expr (inquire->pad);
    4559          846 :   gfc_free_expr (inquire->iolength);
    4560          846 :   gfc_free_expr (inquire->convert);
    4561          846 :   gfc_free_expr (inquire->strm_pos);
    4562          846 :   gfc_free_expr (inquire->asynchronous);
    4563          846 :   gfc_free_expr (inquire->decimal);
    4564          846 :   gfc_free_expr (inquire->pending);
    4565          846 :   gfc_free_expr (inquire->id);
    4566          846 :   gfc_free_expr (inquire->sign);
    4567          846 :   gfc_free_expr (inquire->size);
    4568          846 :   gfc_free_expr (inquire->round);
    4569          846 :   gfc_free_expr (inquire->share);
    4570          846 :   gfc_free_expr (inquire->cc);
    4571          846 :   free (inquire);
    4572              : }
    4573              : 
    4574              : 
    4575              : /* Match an element of an INQUIRE statement.  */
    4576              : 
    4577              : #define RETM   if (m != MATCH_NO) return m;
    4578              : 
    4579              : static match
    4580         2607 : match_inquire_element (gfc_inquire *inquire)
    4581              : {
    4582         2607 :   match m;
    4583              : 
    4584         2607 :   m = match_etag (&tag_unit, &inquire->unit);
    4585         2607 :   RETM m = match_etag (&tag_file, &inquire->file);
    4586         2274 :   RETM m = match_ltag (&tag_err, &inquire->err);
    4587         2063 :   RETM m = match_etag (&tag_iomsg, &inquire->iomsg);
    4588         2056 :   RETM m = match_out_tag (&tag_iostat, &inquire->iostat);
    4589         2031 :   RETM m = match_vtag (&tag_exist, &inquire->exist);
    4590         1982 :   RETM m = match_vtag (&tag_opened, &inquire->opened);
    4591         1840 :   RETM m = match_vtag (&tag_named, &inquire->named);
    4592         1688 :   RETM m = match_vtag (&tag_name, &inquire->name);
    4593         1665 :   RETM m = match_out_tag (&tag_number, &inquire->number);
    4594         1638 :   RETM m = match_vtag (&tag_s_access, &inquire->access);
    4595         1551 :   RETM m = match_vtag (&tag_sequential, &inquire->sequential);
    4596         1401 :   RETM m = match_vtag (&tag_direct, &inquire->direct);
    4597         1362 :   RETM m = match_vtag (&tag_s_form, &inquire->form);
    4598         1251 :   RETM m = match_vtag (&tag_formatted, &inquire->formatted);
    4599         1236 :   RETM m = match_vtag (&tag_unformatted, &inquire->unformatted);
    4600         1190 :   RETM m = match_out_tag (&tag_s_recl, &inquire->recl);
    4601         1151 :   RETM m = match_out_tag (&tag_nextrec, &inquire->nextrec);
    4602         1092 :   RETM m = match_vtag (&tag_s_blank, &inquire->blank);
    4603         1030 :   RETM m = match_vtag (&tag_s_position, &inquire->position);
    4604         1006 :   RETM m = match_vtag (&tag_s_action, &inquire->action);
    4605          949 :   RETM m = match_vtag (&tag_read, &inquire->read);
    4606          927 :   RETM m = match_vtag (&tag_write, &inquire->write);
    4607          894 :   RETM m = match_vtag (&tag_readwrite, &inquire->readwrite);
    4608          861 :   RETM m = match_vtag (&tag_s_async, &inquire->asynchronous);
    4609          828 :   RETM m = match_vtag (&tag_s_delim, &inquire->delim);
    4610          801 :   RETM m = match_vtag (&tag_s_decimal, &inquire->decimal);
    4611          761 :   RETM m = match_out_tag (&tag_size, &inquire->size);
    4612          742 :   RETM m = match_vtag (&tag_s_encoding, &inquire->encoding);
    4613          699 :   RETM m = match_vtag (&tag_s_round, &inquire->round);
    4614          679 :   RETM m = match_vtag (&tag_s_sign, &inquire->sign);
    4615          660 :   RETM m = match_vtag (&tag_s_pad, &inquire->pad);
    4616          641 :   RETM m = match_out_tag (&tag_iolength, &inquire->iolength);
    4617          602 :   RETM m = match_vtag (&tag_convert, &inquire->convert);
    4618          509 :   RETM m = match_out_tag (&tag_strm_out, &inquire->strm_pos);
    4619          497 :   RETM m = match_vtag (&tag_pending, &inquire->pending);
    4620          389 :   RETM m = match_etag (&tag_id, &inquire->id);
    4621          369 :   RETM m = match_vtag (&tag_s_iqstream, &inquire->iqstream);
    4622          358 :   RETM m = match_dec_vtag (&tag_v_share, &inquire->share);
    4623          316 :   RETM m = match_dec_vtag (&tag_v_cc, &inquire->cc);
    4624          309 :   RETM return MATCH_NO;
    4625              : }
    4626              : 
    4627              : #undef RETM
    4628              : 
    4629              : 
    4630              : match
    4631          938 : gfc_match_inquire (void)
    4632              : {
    4633          938 :   gfc_inquire *inquire;
    4634          938 :   gfc_code *code;
    4635          938 :   match m;
    4636          938 :   locus loc;
    4637              : 
    4638          938 :   m = gfc_match_char ('(');
    4639          938 :   if (m == MATCH_NO)
    4640              :     return m;
    4641              : 
    4642          938 :   inquire = XCNEW (gfc_inquire);
    4643              : 
    4644          938 :   loc = gfc_current_locus;
    4645              : 
    4646          938 :   m = match_inquire_element (inquire);
    4647          938 :   if (m == MATCH_ERROR)
    4648            0 :     goto cleanup;
    4649          938 :   if (m == MATCH_NO)
    4650              :     {
    4651          302 :       m = gfc_match_expr (&inquire->unit);
    4652          302 :       if (m == MATCH_ERROR)
    4653            0 :         goto cleanup;
    4654          302 :       if (m == MATCH_NO)
    4655            0 :         goto syntax;
    4656              :     }
    4657              : 
    4658              :   /* See if we have the IOLENGTH form of the inquire statement.  */
    4659          938 :   if (inquire->iolength != NULL)
    4660              :     {
    4661           93 :       if (gfc_match_char (')') != MATCH_YES)
    4662            0 :         goto syntax;
    4663              : 
    4664           93 :       m = match_io_list (M_INQUIRE, &code);
    4665           93 :       if (m == MATCH_ERROR)
    4666            0 :         goto cleanup;
    4667           93 :       if (m == MATCH_NO)
    4668              :         goto syntax;
    4669              : 
    4670          246 :       for (gfc_code *c = code; c; c = c->next)
    4671          154 :         if (c->expr1 && c->expr1->expr_type == EXPR_FUNCTION
    4672            2 :             && c->expr1->symtree && c->expr1->symtree->n.sym->attr.function
    4673            2 :             && !c->expr1->symtree->n.sym->attr.external
    4674            1 :             && strcmp (c->expr1->symtree->name, "null") == 0)
    4675              :           {
    4676            1 :             gfc_error ("NULL() near %L cannot appear in INQUIRE statement",
    4677              :                        &c->expr1->where);
    4678            1 :             goto cleanup;
    4679              :           }
    4680              : 
    4681           92 :       new_st.op = EXEC_IOLENGTH;
    4682           92 :       new_st.expr1 = inquire->iolength;
    4683           92 :       new_st.ext.inquire = inquire;
    4684              : 
    4685           92 :       if (gfc_pure (NULL))
    4686              :         {
    4687            0 :           gfc_free_statements (code);
    4688            0 :           gfc_error ("INQUIRE statement not allowed in PURE procedure at %C");
    4689            0 :           return MATCH_ERROR;
    4690              :         }
    4691              : 
    4692           92 :       gfc_unset_implicit_pure (NULL);
    4693              : 
    4694           92 :       new_st.block = gfc_get_code (EXEC_IOLENGTH);
    4695           92 :       terminate_io (code);
    4696           92 :       new_st.block->next = code;
    4697           92 :       return MATCH_YES;
    4698              :     }
    4699              : 
    4700              :   /* At this point, we have the non-IOLENGTH inquire statement.  */
    4701         2512 :   for (;;)
    4702              :     {
    4703         2512 :       if (gfc_match_char (')') == MATCH_YES)
    4704              :         break;
    4705         1669 :       if (gfc_match_char (',') != MATCH_YES)
    4706            0 :         goto syntax;
    4707              : 
    4708         1669 :       m = match_inquire_element (inquire);
    4709         1669 :       if (m == MATCH_ERROR)
    4710            2 :         goto cleanup;
    4711         1667 :       if (m == MATCH_NO)
    4712            0 :         goto syntax;
    4713              : 
    4714         1667 :       if (inquire->iolength != NULL)
    4715              :         {
    4716            0 :           gfc_error ("IOLENGTH tag invalid in INQUIRE statement at %C");
    4717            0 :           goto cleanup;
    4718              :         }
    4719              :     }
    4720              : 
    4721          843 :   if (gfc_match_eos () != MATCH_YES)
    4722            0 :     goto syntax;
    4723              : 
    4724          843 :   if (inquire->unit != NULL && inquire->file != NULL)
    4725              :     {
    4726            2 :       gfc_error ("INQUIRE statement at %L cannot contain both FILE and "
    4727              :                  "UNIT specifiers", &loc);
    4728            2 :       goto cleanup;
    4729              :     }
    4730              : 
    4731          841 :   if (inquire->unit == NULL && inquire->file == NULL)
    4732              :     {
    4733            1 :       gfc_error ("INQUIRE statement at %L requires either FILE or "
    4734              :                  "UNIT specifier", &loc);
    4735            1 :       goto cleanup;
    4736              :     }
    4737              : 
    4738          840 :   if (inquire->unit != NULL && inquire->unit->expr_type == EXPR_CONSTANT
    4739          524 :       && inquire->unit->ts.type == BT_INTEGER
    4740          524 :       && ((mpz_get_si (inquire->unit->value.integer) == GFC_INTERNAL_UNIT4)
    4741          523 :       || (mpz_get_si (inquire->unit->value.integer) == GFC_INTERNAL_UNIT)))
    4742              :     {
    4743            2 :       gfc_error ("UNIT number in INQUIRE statement at %L cannot "
    4744              :                  "be %d", &loc, (int) mpz_get_si (inquire->unit->value.integer));
    4745            2 :       goto cleanup;
    4746              :     }
    4747              : 
    4748          838 :   if (gfc_pure (NULL))
    4749              :     {
    4750            0 :       gfc_error ("INQUIRE statement not allowed in PURE procedure at %C");
    4751            0 :       goto cleanup;
    4752              :     }
    4753              : 
    4754          838 :   gfc_unset_implicit_pure (NULL);
    4755              : 
    4756          838 :   if (inquire->id != NULL && inquire->pending == NULL)
    4757              :     {
    4758            0 :       gfc_error ("INQUIRE statement at %L requires a PENDING= specifier with "
    4759              :                  "the ID= specifier", &loc);
    4760            0 :       goto cleanup;
    4761              :     }
    4762              : 
    4763          838 :   new_st.op = EXEC_INQUIRE;
    4764          838 :   new_st.ext.inquire = inquire;
    4765          838 :   return MATCH_YES;
    4766              : 
    4767            0 : syntax:
    4768            0 :   gfc_syntax_error (ST_INQUIRE);
    4769              : 
    4770            8 : cleanup:
    4771            8 :   gfc_free_inquire (inquire);
    4772            8 :   return MATCH_ERROR;
    4773              : }
    4774              : 
    4775              : 
    4776              : /* Resolve everything in a gfc_inquire structure.  */
    4777              : 
    4778              : bool
    4779          930 : gfc_resolve_inquire (gfc_inquire *inquire)
    4780              : {
    4781          930 :   RESOLVE_TAG (&tag_unit, inquire->unit);
    4782          930 :   RESOLVE_TAG (&tag_file, inquire->file);
    4783          929 :   RESOLVE_TAG (&tag_id, inquire->id);
    4784              : 
    4785              :   /* For INQUIRE, all tags except FILE, ID and UNIT are variable definition
    4786              :      contexts.  Thus, use an extended RESOLVE_TAG macro for that.  */
    4787              : #define INQUIRE_RESOLVE_TAG(tag, expr) \
    4788              :   RESOLVE_TAG (tag, expr); \
    4789              :   if (expr) \
    4790              :     { \
    4791              :       char context[64]; \
    4792              :       sprintf (context, _("%s tag with INQUIRE"), (tag)->name); \
    4793              :       if (gfc_check_vardef_context ((expr), false, false, false, \
    4794              :                                     context) == false) \
    4795              :         return false; \
    4796              :       gfc_expr_set_at (expr, &expr->where, VALUE_VARDEF);        \
    4797              :     }
    4798          929 :   INQUIRE_RESOLVE_TAG (&tag_iomsg, inquire->iomsg);
    4799          917 :   INQUIRE_RESOLVE_TAG (&tag_iostat, inquire->iostat);
    4800          916 :   INQUIRE_RESOLVE_TAG (&tag_exist, inquire->exist);
    4801          914 :   INQUIRE_RESOLVE_TAG (&tag_opened, inquire->opened);
    4802          912 :   INQUIRE_RESOLVE_TAG (&tag_number, inquire->number);
    4803          910 :   INQUIRE_RESOLVE_TAG (&tag_named, inquire->named);
    4804          908 :   INQUIRE_RESOLVE_TAG (&tag_name, inquire->name);
    4805          907 :   INQUIRE_RESOLVE_TAG (&tag_s_access, inquire->access);
    4806          906 :   INQUIRE_RESOLVE_TAG (&tag_sequential, inquire->sequential);
    4807          905 :   INQUIRE_RESOLVE_TAG (&tag_direct, inquire->direct);
    4808          904 :   INQUIRE_RESOLVE_TAG (&tag_s_form, inquire->form);
    4809          903 :   INQUIRE_RESOLVE_TAG (&tag_formatted, inquire->formatted);
    4810          901 :   INQUIRE_RESOLVE_TAG (&tag_unformatted, inquire->unformatted);
    4811          900 :   INQUIRE_RESOLVE_TAG (&tag_s_recl, inquire->recl);
    4812          899 :   INQUIRE_RESOLVE_TAG (&tag_nextrec, inquire->nextrec);
    4813          898 :   INQUIRE_RESOLVE_TAG (&tag_s_blank, inquire->blank);
    4814          897 :   INQUIRE_RESOLVE_TAG (&tag_s_position, inquire->position);
    4815          896 :   INQUIRE_RESOLVE_TAG (&tag_s_action, inquire->action);
    4816          895 :   INQUIRE_RESOLVE_TAG (&tag_read, inquire->read);
    4817          894 :   INQUIRE_RESOLVE_TAG (&tag_write, inquire->write);
    4818          893 :   INQUIRE_RESOLVE_TAG (&tag_readwrite, inquire->readwrite);
    4819          892 :   INQUIRE_RESOLVE_TAG (&tag_s_delim, inquire->delim);
    4820          891 :   INQUIRE_RESOLVE_TAG (&tag_s_pad, inquire->pad);
    4821          890 :   INQUIRE_RESOLVE_TAG (&tag_s_encoding, inquire->encoding);
    4822          888 :   INQUIRE_RESOLVE_TAG (&tag_s_round, inquire->round);
    4823          887 :   INQUIRE_RESOLVE_TAG (&tag_iolength, inquire->iolength);
    4824          885 :   INQUIRE_RESOLVE_TAG (&tag_convert, inquire->convert);
    4825          885 :   INQUIRE_RESOLVE_TAG (&tag_strm_out, inquire->strm_pos);
    4826          885 :   INQUIRE_RESOLVE_TAG (&tag_s_async, inquire->asynchronous);
    4827          884 :   INQUIRE_RESOLVE_TAG (&tag_s_sign, inquire->sign);
    4828          883 :   INQUIRE_RESOLVE_TAG (&tag_s_round, inquire->round);
    4829          883 :   INQUIRE_RESOLVE_TAG (&tag_pending, inquire->pending);
    4830          881 :   INQUIRE_RESOLVE_TAG (&tag_size, inquire->size);
    4831          881 :   INQUIRE_RESOLVE_TAG (&tag_s_decimal, inquire->decimal);
    4832          880 :   INQUIRE_RESOLVE_TAG (&tag_s_iqstream, inquire->iqstream);
    4833          880 :   INQUIRE_RESOLVE_TAG (&tag_v_share, inquire->share);
    4834          880 :   INQUIRE_RESOLVE_TAG (&tag_v_cc, inquire->cc);
    4835              : #undef INQUIRE_RESOLVE_TAG
    4836              : 
    4837          880 :   if (!gfc_reference_st_label (inquire->err, ST_LABEL_TARGET))
    4838              :     return false;
    4839              : 
    4840              :   return true;
    4841              : }
    4842              : 
    4843              : 
    4844              : void
    4845           89 : gfc_free_wait (gfc_wait *wait)
    4846              : {
    4847           89 :   if (wait == NULL)
    4848              :     return;
    4849              : 
    4850           89 :   gfc_free_expr (wait->unit);
    4851           89 :   gfc_free_expr (wait->iostat);
    4852           89 :   gfc_free_expr (wait->iomsg);
    4853           89 :   gfc_free_expr (wait->id);
    4854           89 :   free (wait);
    4855              : }
    4856              : 
    4857              : 
    4858              : bool
    4859           89 : gfc_resolve_wait (gfc_wait *wait)
    4860              : {
    4861           89 :   RESOLVE_TAG (&tag_unit, wait->unit);
    4862           89 :   RESOLVE_TAG (&tag_iomsg, wait->iomsg);
    4863           74 :   RESOLVE_TAG (&tag_iostat, wait->iostat);
    4864           74 :   RESOLVE_TAG (&tag_id, wait->id);
    4865              : 
    4866           74 :   if (!gfc_reference_st_label (wait->err, ST_LABEL_TARGET))
    4867              :     return false;
    4868              : 
    4869           74 :   if (!gfc_reference_st_label (wait->end, ST_LABEL_TARGET))
    4870              :     return false;
    4871              : 
    4872              :   return true;
    4873              : }
    4874              : 
    4875              : /* Match an element of a WAIT statement.  */
    4876              : 
    4877              : #define RETM   if (m != MATCH_NO) return m;
    4878              : 
    4879              : static match
    4880          166 : match_wait_element (gfc_wait *wait)
    4881              : {
    4882          166 :   match m;
    4883              : 
    4884          166 :   m = match_etag (&tag_unit, &wait->unit);
    4885          166 :   RETM m = match_ltag (&tag_err, &wait->err);
    4886          153 :   RETM m = match_ltag (&tag_end, &wait->end);
    4887          146 :   RETM m = match_ltag (&tag_eor, &wait->eor);
    4888          139 :   RETM m = match_etag (&tag_iomsg, &wait->iomsg);
    4889          139 :   RETM m = match_out_tag (&tag_iostat, &wait->iostat);
    4890          110 :   RETM m = match_etag (&tag_id, &wait->id);
    4891           89 :   RETM return MATCH_NO;
    4892              : }
    4893              : 
    4894              : #undef RETM
    4895              : 
    4896              : 
    4897              : match
    4898           89 : gfc_match_wait (void)
    4899              : {
    4900           89 :   gfc_wait *wait;
    4901           89 :   match m;
    4902              : 
    4903           89 :   m = gfc_match_char ('(');
    4904           89 :   if (m == MATCH_NO)
    4905              :     return m;
    4906              : 
    4907           89 :   wait = XCNEW (gfc_wait);
    4908              : 
    4909           89 :   m = match_wait_element (wait);
    4910           89 :   if (m == MATCH_ERROR)
    4911            0 :     goto cleanup;
    4912           89 :   if (m == MATCH_NO)
    4913              :     {
    4914           76 :       m = gfc_match_expr (&wait->unit);
    4915           76 :       if (m == MATCH_ERROR)
    4916            0 :         goto cleanup;
    4917           76 :       if (m == MATCH_NO)
    4918            0 :         goto syntax;
    4919              :     }
    4920              : 
    4921          166 :   for (;;)
    4922              :     {
    4923          166 :       if (gfc_match_char (')') == MATCH_YES)
    4924              :         break;
    4925           77 :       if (gfc_match_char (',') != MATCH_YES)
    4926            0 :         goto syntax;
    4927              : 
    4928           77 :       m = match_wait_element (wait);
    4929           77 :       if (m == MATCH_ERROR)
    4930            0 :         goto cleanup;
    4931           77 :       if (m == MATCH_NO)
    4932            0 :         goto syntax;
    4933              :     }
    4934              : 
    4935           89 :   if (!gfc_notify_std (GFC_STD_F2003, "WAIT at %C "
    4936              :                        "not allowed in Fortran 95"))
    4937            0 :     goto cleanup;
    4938              : 
    4939           89 :   if (gfc_pure (NULL))
    4940              :     {
    4941            0 :       gfc_error ("WAIT statement not allowed in PURE procedure at %C");
    4942            0 :       goto cleanup;
    4943              :     }
    4944              : 
    4945           89 :   gfc_unset_implicit_pure (NULL);
    4946              : 
    4947           89 :   new_st.op = EXEC_WAIT;
    4948           89 :   new_st.ext.wait = wait;
    4949              : 
    4950           89 :   return MATCH_YES;
    4951              : 
    4952            0 : syntax:
    4953            0 :   gfc_syntax_error (ST_WAIT);
    4954              : 
    4955            0 : cleanup:
    4956            0 :   gfc_free_wait (wait);
    4957            0 :   return MATCH_ERROR;
    4958              : }
        

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.