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 167676 : next_char (gfc_instring in_string)
148 : {
149 167676 : static gfc_char_t c;
150 :
151 167676 : if (use_last_char)
152 : {
153 28727 : use_last_char = 0;
154 28727 : return c;
155 : }
156 :
157 138949 : format_length++;
158 :
159 138949 : if (mode == MODE_STRING)
160 81147 : c = *format_string++;
161 : else
162 : {
163 57802 : c = gfc_next_char_literal (in_string);
164 57802 : if (c == '\n')
165 0 : c = '\0';
166 : }
167 :
168 138949 : 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 138949 : if (mode == MODE_COPY)
180 28841 : *format_string++ = c;
181 :
182 138949 : if (mode != MODE_STRING)
183 57802 : format_locus = gfc_current_locus;
184 :
185 138949 : format_string_pos++;
186 :
187 138949 : c = gfc_wide_toupper (c);
188 138949 : return c;
189 : }
190 :
191 :
192 : /* Back up one character position. Only works once. */
193 :
194 : static void
195 28733 : unget_char (void)
196 : {
197 28733 : use_last_char = 1;
198 2640 : }
199 :
200 : /* Eat up the spaces and return a character. */
201 :
202 : static char
203 127893 : next_char_not_space ()
204 : {
205 136448 : char c;
206 136448 : do
207 : {
208 136448 : error_element = c = next_char (NONSTRING);
209 136448 : if (c == '\t')
210 4 : gfc_warning (OPT_Wtabs, "Nonconforming tab character in format at %C");
211 : }
212 136448 : while (gfc_is_whitespace (c));
213 127893 : 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 122575 : format_lex (void)
223 : {
224 122575 : format_token token;
225 122575 : char c, delim;
226 122575 : int zflag;
227 122575 : int negative_flag;
228 :
229 122575 : if (saved_token != FMT_NONE)
230 : {
231 27982 : token = saved_token;
232 27982 : saved_token = FMT_NONE;
233 27982 : return token;
234 : }
235 :
236 94593 : c = next_char_not_space ();
237 :
238 94593 : negative_flag = 0;
239 94593 : 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 23523 : case '0':
272 23523 : case '1':
273 23523 : case '2':
274 23523 : case '3':
275 23523 : case '4':
276 23523 : case '5':
277 23523 : case '6':
278 23523 : case '7':
279 23523 : case '8':
280 23523 : case '9':
281 23523 : zflag = (c == '0');
282 :
283 23523 : value = c - '0';
284 :
285 28465 : do
286 : {
287 28465 : c = next_char_not_space ();
288 28465 : if (ISDIGIT (c))
289 : {
290 4942 : value = 10 * value + (c - '0');
291 4942 : if (c != '0')
292 28465 : zflag = 0;
293 : }
294 : }
295 28465 : while (ISDIGIT (c));
296 :
297 23523 : unget_char ();
298 23523 : token = zflag ? FMT_ZERO : FMT_POSINT;
299 : break;
300 :
301 : case '.':
302 : token = FMT_PERIOD;
303 : break;
304 :
305 11126 : case ',':
306 11126 : token = FMT_COMMA;
307 11126 : 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 1046 : case 'T':
322 1046 : c = next_char_not_space ();
323 1046 : switch (c)
324 : {
325 : case 'L':
326 : token = FMT_TL;
327 : break;
328 204 : case 'R':
329 204 : token = FMT_TR;
330 204 : break;
331 629 : default:
332 629 : token = FMT_T;
333 629 : unget_char ();
334 : }
335 : break;
336 :
337 14491 : case '(':
338 14491 : token = FMT_LPAREN;
339 14491 : break;
340 :
341 14461 : case ')':
342 14461 : token = FMT_RPAREN;
343 14461 : 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 2438 : case '\'':
370 2438 : case '"':
371 2438 : delim = c;
372 :
373 2438 : value = 0;
374 :
375 51332 : for (;;)
376 : {
377 26885 : c = next_char (INSTRING_WARN);
378 26885 : if (c == '\0')
379 : {
380 : token = FMT_END;
381 : break;
382 : }
383 :
384 26885 : if (c == delim)
385 : {
386 2612 : c = next_char (NONSTRING);
387 :
388 2612 : if (c == '\0')
389 : {
390 : token = FMT_END;
391 : break;
392 : }
393 :
394 2612 : if (c != delim)
395 : {
396 2438 : unget_char ();
397 2438 : token = FMT_CHAR;
398 2438 : break;
399 : }
400 : }
401 24447 : 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 4815 : 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 8001 : case 'A':
479 8001 : token = FMT_A;
480 8001 : 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 140 : case '*':
588 140 : token = FMT_STAR;
589 140 : 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 13375 : check_format (bool is_input)
627 : {
628 13375 : const char *posint_required
629 : = G_("Positive width required in format string at %L");
630 13375 : const char *nonneg_required
631 : = G_("Nonnegative width required in format string at %L");
632 13375 : const char *unexpected_element
633 : = G_("Unexpected element %qc in format string at %L");
634 13375 : const char *unexpected_end
635 : = G_("Unexpected end of format string in format string at %L");
636 13375 : const char *zero_width
637 : = G_("Zero width in format descriptor in format string at %L");
638 :
639 13375 : const char *error = NULL;
640 13375 : format_token t, u;
641 13375 : int level;
642 13375 : int repeat;
643 13375 : bool rv;
644 :
645 13375 : use_last_char = 0;
646 13375 : saved_token = FMT_NONE;
647 13375 : level = 0;
648 13375 : repeat = 0;
649 13375 : rv = true;
650 13375 : format_string_pos = 0;
651 :
652 13375 : t = format_lex ();
653 13375 : if (t == FMT_ERROR)
654 0 : goto fail;
655 13375 : 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 13369 : t = format_lex ();
662 13369 : if (t == FMT_ERROR)
663 0 : goto fail;
664 13369 : if (t == FMT_RPAREN)
665 52 : goto finished; /* Empty format is legal */
666 13317 : saved_token = t;
667 :
668 26366 : format_item:
669 : /* In this state, the next thing has to be a format item. */
670 26366 : t = format_lex ();
671 26366 : if (t == FMT_ERROR)
672 0 : goto fail;
673 26366 : format_item_1:
674 26407 : switch (t)
675 : {
676 140 : case FMT_STAR:
677 140 : repeat = -1;
678 140 : t = format_lex ();
679 140 : if (t == FMT_ERROR)
680 0 : goto fail;
681 140 : if (t == FMT_LPAREN)
682 : {
683 140 : level++;
684 140 : goto format_item;
685 : }
686 0 : error = G_("Left parenthesis required after %<*%> in format string "
687 : "at %L");
688 0 : goto syntax;
689 :
690 5932 : case FMT_POSINT:
691 5932 : repeat = value;
692 5932 : t = format_lex ();
693 5932 : if (t == FMT_ERROR)
694 0 : goto fail;
695 5932 : if (t == FMT_LPAREN)
696 : {
697 794 : level++;
698 794 : 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 2438 : case FMT_CHAR:
752 2438 : 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 16474 : case FMT_T:
775 16474 : case FMT_TL:
776 16474 : case FMT_TR:
777 16474 : case FMT_IBOZ:
778 16474 : case FMT_F:
779 16474 : case FMT_E:
780 16474 : case FMT_EN:
781 16474 : case FMT_ES:
782 16474 : case FMT_EX:
783 16474 : case FMT_G:
784 16474 : case FMT_L:
785 16474 : case FMT_A:
786 16474 : case FMT_D:
787 16474 : case FMT_H:
788 16474 : case FMT_DT:
789 16474 : 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 21635 : data_desc:
810 : /* In this state, t must currently be a data descriptor.
811 : Deal with things that can/must follow the descriptor. */
812 21635 : 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 1045 : case FMT_T:
856 1045 : case FMT_TL:
857 1045 : case FMT_TR:
858 1045 : t = format_lex ();
859 1045 : 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 7995 : case FMT_A:
902 7995 : t = format_lex ();
903 7995 : if (t == FMT_ERROR)
904 0 : goto fail;
905 7995 : if (t == FMT_ZERO)
906 : {
907 0 : error = zero_width;
908 0 : goto syntax;
909 : }
910 7995 : if (t != FMT_POSINT)
911 6422 : 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 4815 : case FMT_IBOZ:
1194 4815 : t = format_lex ();
1195 4815 : if (t == FMT_ERROR)
1196 0 : goto fail;
1197 4815 : 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 4748 : else if (is_input && t == FMT_ZERO)
1212 : {
1213 2 : error = posint_required;
1214 2 : goto syntax;
1215 : }
1216 :
1217 4806 : t = format_lex ();
1218 4806 : if (t == FMT_ERROR)
1219 0 : goto fail;
1220 4806 : if (t != FMT_PERIOD)
1221 4362 : 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 22455 : t = format_lex ();
1244 22455 : if (t == FMT_ERROR)
1245 0 : goto fail;
1246 22455 : switch (t)
1247 : {
1248 :
1249 9410 : case FMT_COMMA:
1250 9410 : goto format_item;
1251 :
1252 12758 : case FMT_RPAREN:
1253 12758 : level--;
1254 12758 : if (level < 0)
1255 11950 : 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 2438 : extension_optional_comma:
1306 : /* As a GNU extension, permit a missing comma after a string literal. */
1307 2438 : t = format_lex ();
1308 2438 : if (t == FMT_ERROR)
1309 0 : goto fail;
1310 2438 : switch (t)
1311 : {
1312 : case FMT_COMMA:
1313 : break;
1314 :
1315 1128 : case FMT_RPAREN:
1316 1128 : level--;
1317 1128 : if (level < 0)
1318 978 : goto finished;
1319 150 : 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 1267 : 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 12383 : check_format_string (gfc_expr *e, bool is_input)
1365 : {
1366 12383 : bool rv;
1367 12383 : int i;
1368 12383 : if (!e || e->ts.type != BT_CHARACTER || e->expr_type != EXPR_CONSTANT)
1369 : return true;
1370 :
1371 11312 : mode = MODE_STRING;
1372 11312 : 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 11312 : format_locus = e->where;
1378 11312 : 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 11312 : 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 1036 : gfc_match_format (void)
1404 : {
1405 1036 : gfc_expr *e;
1406 1036 : locus start;
1407 :
1408 1036 : if (gfc_current_ns->proc_name
1409 1009 : && 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 1035 : if ((gfc_current_state () == COMP_FUNCTION
1417 1035 : || gfc_current_state () == COMP_SUBROUTINE)
1418 183 : && 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 1034 : if (gfc_statement_label == NULL)
1425 : {
1426 0 : gfc_error ("Missing format label at %C");
1427 0 : return MATCH_ERROR;
1428 : }
1429 1034 : gfc_gobble_whitespace ();
1430 :
1431 1034 : mode = MODE_FORMAT;
1432 1034 : format_length = 0;
1433 :
1434 1034 : start = gfc_current_locus;
1435 :
1436 1034 : if (!check_format (false))
1437 : return MATCH_ERROR;
1438 :
1439 1029 : 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 1029 : gfc_current_locus = start; /* Back to the beginning */
1449 :
1450 1029 : new_st.loc = start;
1451 1029 : new_st.op = EXEC_NOP;
1452 :
1453 1029 : e = gfc_get_character_expr (gfc_default_character_kind, &start,
1454 : NULL, format_length);
1455 1029 : format_string = e->value.character.string;
1456 1029 : gfc_statement_label->format = e;
1457 :
1458 1029 : mode = MODE_COPY;
1459 1029 : check_format (false); /* Guaranteed to succeed */
1460 1029 : gfc_match_eos (); /* Guaranteed to succeed */
1461 :
1462 1029 : return MATCH_YES;
1463 : }
1464 :
1465 :
1466 : /* Match an expression I/O tag of some sort. */
1467 :
1468 : static match
1469 676958 : match_etag (const io_tag *tag, gfc_expr **v)
1470 : {
1471 676958 : gfc_expr *result;
1472 676958 : match m;
1473 :
1474 676958 : m = gfc_match (tag->spec);
1475 676958 : if (m != MATCH_YES)
1476 : return m;
1477 :
1478 12899 : m = gfc_match (tag->value, &result);
1479 12899 : 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 12899 : 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 12897 : *v = result;
1493 12897 : return MATCH_YES;
1494 : }
1495 :
1496 :
1497 : /* Match a variable I/O tag of some sort. */
1498 :
1499 : static match
1500 197838 : match_vtag (const io_tag *tag, gfc_expr **v)
1501 : {
1502 197838 : gfc_expr *result;
1503 197838 : match m;
1504 :
1505 197838 : m = gfc_match (tag->spec);
1506 197838 : if (m != MATCH_YES)
1507 : return m;
1508 :
1509 4087 : m = gfc_match (tag->value, &result);
1510 4087 : 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 4086 : 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 4086 : if (result->symtree)
1524 : {
1525 4082 : bool impure;
1526 :
1527 4082 : 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 4082 : impure = gfc_impure_variable (result->symtree->n.sym);
1535 4082 : 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 4082 : if (impure)
1544 28 : gfc_unset_implicit_pure (NULL);
1545 : }
1546 :
1547 4086 : *v = result;
1548 4086 : return MATCH_YES;
1549 : }
1550 :
1551 :
1552 : /* Match I/O tags that cause variables to become redefined. */
1553 :
1554 : static match
1555 170055 : match_out_tag (const io_tag *tag, gfc_expr **result)
1556 : {
1557 170055 : match m;
1558 :
1559 170055 : m = match_vtag (tag, result);
1560 170055 : if (m == MATCH_YES)
1561 : {
1562 2869 : if ((*result)->symtree)
1563 2865 : gfc_check_do_variable ((*result)->symtree);
1564 :
1565 2869 : 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 148369 : match_ltag (const io_tag *tag, gfc_st_label ** label)
1580 : {
1581 148369 : match m;
1582 148369 : gfc_st_label *old;
1583 :
1584 148369 : old = *label;
1585 148369 : m = gfc_match (tag->spec);
1586 148369 : 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 5844 : match_dec_etag (const io_tag *tag, gfc_expr **e)
1612 : {
1613 5844 : match m = match_etag (tag, e);
1614 5844 : if (flag_dec && m != MATCH_NO)
1615 : return m;
1616 5681 : 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 8587 : match_dec_ftag (const io_tag *tag, gfc_open *o)
1647 : {
1648 8587 : match m;
1649 :
1650 8587 : m = gfc_match (tag->spec);
1651 8587 : 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 12344 : resolve_tag_format (gfc_expr *e)
1704 : {
1705 12344 : if (e->expr_type == EXPR_CONSTANT
1706 11281 : && (e->ts.type != BT_CHARACTER
1707 11277 : || 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 12318 : if ((e->expr_type == EXPR_ARRAY || e->rank > 0)
1718 111 : && e->ts.type == BT_CHARACTER
1719 12413 : && 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 12338 : if (e->rank == 0
1766 12229 : && (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 12150 : if ((e->ts.type != BT_CHARACTER
1772 12141 : || 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 12145 : 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 12142 : 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 12141 : gfc_value_used_expr (e, VALUE_USED);
1799 12141 : 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 643019 : resolve_tag (const io_tag *tag, gfc_expr *e)
1848 : {
1849 643019 : if (e == NULL)
1850 : return true;
1851 :
1852 38155 : if (!gfc_resolve_expr (e))
1853 : return false;
1854 :
1855 38151 : if (tag == &tag_format)
1856 12344 : return resolve_tag_format (e);
1857 :
1858 25807 : 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 25459 : 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 25391 : 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 25339 : 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 25339 : if ((tag == &tag_iostat || tag == &tag_size || tag == &tag_iolength
1885 23008 : || 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 25323 : if (e->ts.kind != gfc_default_logical_kind &&
1894 11089 : (tag == &tag_exist || tag == &tag_named || tag == &tag_opened
1895 11083 : || 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 25315 : if (tag == &tag_newunit)
1903 : {
1904 188 : if (!gfc_notify_std (GFC_STD_F2008, "NEWUNIT specifier at %L",
1905 : &e->where))
1906 : return false;
1907 : }
1908 :
1909 25314 : 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 25314 : if (tag == &tag_newunit || tag == &tag_iostat
1917 23003 : || tag == &tag_size || tag == &tag_iomsg)
1918 : {
1919 2981 : char context[64];
1920 :
1921 2981 : sprintf (context, _("%s tag"), tag->name);
1922 2981 : if (!gfc_check_vardef_context (e, false, false, false, context))
1923 32 : return false;
1924 :
1925 2949 : gfc_expr_set_at (e, &e->where, VALUE_VARDEF);
1926 2949 : }
1927 : else
1928 22333 : 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 11300 : match_open_element (gfc_open *open)
1938 : {
1939 11300 : match m;
1940 :
1941 11300 : m = match_etag (&tag_e_async, &open->asynchronous);
1942 11300 : if (m != MATCH_NO)
1943 : return m;
1944 11184 : m = match_etag (&tag_unit, &open->unit);
1945 11184 : if (m != MATCH_NO)
1946 : return m;
1947 10242 : m = match_etag (&tag_iomsg, &open->iomsg);
1948 10242 : if (m != MATCH_NO)
1949 : return m;
1950 10184 : m = match_out_tag (&tag_iostat, &open->iostat);
1951 10184 : if (m != MATCH_NO)
1952 : return m;
1953 10009 : m = match_etag (&tag_file, &open->file);
1954 10009 : if (m != MATCH_NO)
1955 : return m;
1956 8497 : m = match_etag (&tag_status, &open->status);
1957 8497 : if (m != MATCH_NO)
1958 : return m;
1959 6309 : m = match_etag (&tag_e_access, &open->access);
1960 6309 : if (m != MATCH_NO)
1961 : return m;
1962 5510 : m = match_etag (&tag_e_form, &open->form);
1963 5510 : if (m != MATCH_NO)
1964 : return m;
1965 4375 : m = match_etag (&tag_e_recl, &open->recl);
1966 4375 : if (m != MATCH_NO)
1967 : return m;
1968 4121 : m = match_etag (&tag_e_blank, &open->blank);
1969 4121 : if (m != MATCH_NO)
1970 : return m;
1971 4082 : m = match_etag (&tag_e_position, &open->position);
1972 4082 : if (m != MATCH_NO)
1973 : return m;
1974 3946 : m = match_etag (&tag_e_action, &open->action);
1975 3946 : if (m != MATCH_NO)
1976 : return m;
1977 3684 : m = match_etag (&tag_e_delim, &open->delim);
1978 3684 : if (m != MATCH_NO)
1979 : return m;
1980 3535 : m = match_etag (&tag_e_pad, &open->pad);
1981 3535 : if (m != MATCH_NO)
1982 : return m;
1983 3480 : m = match_etag (&tag_e_decimal, &open->decimal);
1984 3480 : if (m != MATCH_NO)
1985 : return m;
1986 3430 : m = match_etag (&tag_e_encoding, &open->encoding);
1987 3430 : if (m != MATCH_NO)
1988 : return m;
1989 3356 : m = match_etag (&tag_e_round, &open->round);
1990 3356 : if (m != MATCH_NO)
1991 : return m;
1992 3342 : m = match_etag (&tag_e_sign, &open->sign);
1993 3342 : if (m != MATCH_NO)
1994 : return m;
1995 3310 : m = match_ltag (&tag_err, &open->err);
1996 3310 : if (m != MATCH_NO)
1997 : return m;
1998 3194 : m = match_etag (&tag_convert, &open->convert);
1999 3194 : if (m != MATCH_NO)
2000 : return m;
2001 3122 : m = match_out_tag (&tag_newunit, &open->newunit);
2002 3122 : if (m != MATCH_NO)
2003 : return m;
2004 :
2005 : /* The following are extensions enabled with -fdec. */
2006 2931 : m = match_dec_etag (&tag_e_share, &open->share);
2007 2931 : if (m != MATCH_NO)
2008 : return m;
2009 2913 : m = match_dec_etag (&tag_cc, &open->cc);
2010 2913 : if (m != MATCH_NO)
2011 : return m;
2012 2882 : m = match_dec_ftag (&tag_readonly, open);
2013 2882 : if (m != MATCH_NO)
2014 : return m;
2015 2858 : m = match_dec_ftag (&tag_shared, open);
2016 2858 : if (m != MATCH_NO)
2017 : return m;
2018 2847 : m = match_dec_ftag (&tag_noshared, open);
2019 2847 : 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 3972 : gfc_free_open (gfc_open *open)
2030 : {
2031 3972 : if (open == NULL)
2032 : return;
2033 :
2034 3972 : gfc_free_expr (open->unit);
2035 3972 : gfc_free_expr (open->iomsg);
2036 3972 : gfc_free_expr (open->iostat);
2037 3972 : gfc_free_expr (open->file);
2038 3972 : gfc_free_expr (open->status);
2039 3972 : gfc_free_expr (open->access);
2040 3972 : gfc_free_expr (open->form);
2041 3972 : gfc_free_expr (open->recl);
2042 3972 : gfc_free_expr (open->blank);
2043 3972 : gfc_free_expr (open->position);
2044 3972 : gfc_free_expr (open->action);
2045 3972 : gfc_free_expr (open->delim);
2046 3972 : gfc_free_expr (open->pad);
2047 3972 : gfc_free_expr (open->decimal);
2048 3972 : gfc_free_expr (open->encoding);
2049 3972 : gfc_free_expr (open->round);
2050 3972 : gfc_free_expr (open->sign);
2051 3972 : gfc_free_expr (open->convert);
2052 3972 : gfc_free_expr (open->asynchronous);
2053 3972 : gfc_free_expr (open->newunit);
2054 3972 : gfc_free_expr (open->share);
2055 3972 : gfc_free_expr (open->cc);
2056 3972 : 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 3955 : gfc_resolve_open (gfc_open *open, locus *where)
2066 : {
2067 3955 : RESOLVE_TAG (&tag_unit, open->unit);
2068 3955 : RESOLVE_TAG (&tag_iomsg, open->iomsg);
2069 3939 : RESOLVE_TAG (&tag_iostat, open->iostat);
2070 3938 : RESOLVE_TAG (&tag_file, open->file);
2071 3937 : RESOLVE_TAG (&tag_status, open->status);
2072 3923 : RESOLVE_TAG (&tag_e_access, open->access);
2073 3911 : RESOLVE_TAG (&tag_e_form, open->form);
2074 3900 : RESOLVE_TAG (&tag_e_recl, open->recl);
2075 3894 : RESOLVE_TAG (&tag_e_blank, open->blank);
2076 3882 : RESOLVE_TAG (&tag_e_position, open->position);
2077 3871 : RESOLVE_TAG (&tag_e_action, open->action);
2078 3860 : RESOLVE_TAG (&tag_e_delim, open->delim);
2079 3849 : RESOLVE_TAG (&tag_e_pad, open->pad);
2080 3838 : RESOLVE_TAG (&tag_e_decimal, open->decimal);
2081 3826 : RESOLVE_TAG (&tag_e_encoding, open->encoding);
2082 3814 : RESOLVE_TAG (&tag_e_async, open->asynchronous);
2083 3803 : RESOLVE_TAG (&tag_e_round, open->round);
2084 3791 : RESOLVE_TAG (&tag_e_sign, open->sign);
2085 3779 : RESOLVE_TAG (&tag_convert, open->convert);
2086 3779 : RESOLVE_TAG (&tag_newunit, open->newunit);
2087 3777 : RESOLVE_TAG (&tag_e_share, open->share);
2088 3776 : RESOLVE_TAG (&tag_cc, open->cc);
2089 :
2090 3775 : if (!gfc_reference_st_label (open->err, ST_LABEL_TARGET))
2091 : return false;
2092 :
2093 3775 : 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 7045 : 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 7045 : int i;
2110 7045 : unsigned int len;
2111 :
2112 7045 : len = gfc_wide_strlen (value);
2113 7045 : if (len > 0)
2114 : {
2115 7032 : for (len--; len > 0; len--)
2116 7032 : if (value[len] != ' ')
2117 : break;
2118 7014 : len++;
2119 : }
2120 :
2121 15770 : for (i = 0; allowed[i]; i++)
2122 15219 : if (len == strlen (allowed[i])
2123 15219 : && gfc_wide_strncasecmp (value, allowed[i], strlen (allowed[i])) == 0)
2124 : {
2125 6494 : if (num)
2126 199 : *num = i;
2127 6494 : return 1;
2128 : }
2129 :
2130 551 : if (!where)
2131 0 : where = &gfc_current_locus;
2132 :
2133 580 : for (i = 0; allowed_f2003 && allowed_f2003[i]; i++)
2134 461 : if (len == strlen (allowed_f2003[i])
2135 461 : && gfc_wide_strncasecmp (value, allowed_f2003[i],
2136 : strlen (allowed_f2003[i])) == 0)
2137 : {
2138 432 : notification n = gfc_notification_std (GFC_STD_F2003);
2139 :
2140 432 : 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 432 : 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 3775 : 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 3775 : bool warn = (open->err || open->iostat) ? true : false;
2227 :
2228 : /* Checks on the ACCESS specifier. */
2229 3775 : if (open->access && open->access->expr_type == EXPR_CONSTANT)
2230 : {
2231 787 : static const char *access_f95[] = { "SEQUENTIAL", "DIRECT", NULL };
2232 787 : static const char *access_f2003[] = { "STREAM", NULL };
2233 787 : static const char *access_gnu[] = { "APPEND", NULL };
2234 :
2235 787 : 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 3771 : 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 3533 : 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 3766 : 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 3765 : 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 3762 : 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 3762 : 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 3760 : if (open->delim)
2332 : {
2333 138 : if (open->delim->expr_type == EXPR_CONSTANT)
2334 : {
2335 138 : static const char *delim[] = { "APOSTROPHE", "QUOTE", "NONE", NULL };
2336 :
2337 138 : 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 3757 : 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 3755 : if (open->form && open->form->expr_type == EXPR_CONSTANT)
2364 : {
2365 1118 : static const char *form[] = { "FORMATTED", "UNFORMATTED", NULL };
2366 :
2367 1118 : 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 3752 : 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 3750 : 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 3747 : 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 3745 : 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 3745 : 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 3743 : 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 3741 : if (open->status && open->status->expr_type == EXPR_CONSTANT)
2455 : {
2456 2166 : static const char *status[] = { "OLD", "NEW", "SCRATCH",
2457 : "REPLACE", "UNKNOWN", NULL };
2458 :
2459 2166 : 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 2163 : if (open->file == NULL
2467 2163 : && (gfc_wide_strncasecmp (open->status->value.character.string,
2468 : "replace", 7) == 0
2469 1652 : || 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 2161 : if (gfc_wide_strncasecmp (open->status->value.character.string,
2483 2161 : "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 3735 : if (open->newunit)
2493 : {
2494 186 : 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 186 : if (!open->file &&
2502 63 : (!open->status ||
2503 62 : (open->status->expr_type == EXPR_CONSTANT
2504 61 : && 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 3549 : 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 1121 : if (open->form && open->form->expr_type == EXPR_CONSTANT
2521 1115 : && (open->delim || open->decimal || open->encoding || open->round
2522 1100 : || open->sign || open->pad || open->blank)
2523 3753 : && 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 3953 : && 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 3729 : if (open->position
2562 122 : && open->access && open->access->expr_type == EXPR_CONSTANT
2563 3777 : && !(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 3972 : gfc_match_open (void)
2583 : {
2584 3972 : gfc_open *open;
2585 3972 : match m;
2586 :
2587 3972 : m = gfc_match_char ('(');
2588 3972 : if (m == MATCH_NO)
2589 : return m;
2590 :
2591 3972 : open = XCNEW (gfc_open);
2592 :
2593 3972 : m = match_open_element (open);
2594 :
2595 3972 : if (m == MATCH_ERROR)
2596 0 : goto cleanup;
2597 3972 : if (m == MATCH_NO)
2598 : {
2599 2838 : m = gfc_match_expr (&open->unit);
2600 2838 : if (m == MATCH_ERROR)
2601 0 : goto cleanup;
2602 : }
2603 :
2604 11283 : for (;;)
2605 : {
2606 11283 : if (gfc_match_char (')') == MATCH_YES)
2607 : break;
2608 7328 : if (gfc_match_char (',') != MATCH_YES)
2609 0 : goto syntax;
2610 :
2611 7328 : m = match_open_element (open);
2612 7328 : if (m == MATCH_ERROR)
2613 17 : goto cleanup;
2614 7311 : if (m == MATCH_NO)
2615 0 : goto syntax;
2616 : }
2617 :
2618 3955 : if (gfc_match_eos () == MATCH_NO)
2619 0 : goto syntax;
2620 :
2621 3955 : 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 3955 : gfc_unset_implicit_pure (NULL);
2628 :
2629 3955 : new_st.op = EXEC_OPEN;
2630 3955 : new_st.ext.open = open;
2631 3955 : 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 3148 : gfc_free_close (gfc_close *close)
2646 : {
2647 3148 : if (close == NULL)
2648 : return;
2649 :
2650 3148 : gfc_free_expr (close->unit);
2651 3148 : gfc_free_expr (close->iomsg);
2652 3148 : gfc_free_expr (close->iostat);
2653 3148 : gfc_free_expr (close->status);
2654 3148 : free (close);
2655 : }
2656 :
2657 :
2658 : /* Match elements of a CLOSE statement. */
2659 :
2660 : static match
2661 4620 : match_close_element (gfc_close *close)
2662 : {
2663 4620 : match m;
2664 :
2665 4620 : m = match_etag (&tag_unit, &close->unit);
2666 4620 : if (m != MATCH_NO)
2667 : return m;
2668 4309 : m = match_etag (&tag_status, &close->status);
2669 4309 : if (m != MATCH_NO)
2670 : return m;
2671 2902 : m = match_etag (&tag_iomsg, &close->iomsg);
2672 2902 : if (m != MATCH_NO)
2673 : return m;
2674 2873 : m = match_out_tag (&tag_iostat, &close->iostat);
2675 2873 : if (m != MATCH_NO)
2676 : return m;
2677 2846 : m = match_ltag (&tag_err, &close->err);
2678 2846 : if (m != MATCH_NO)
2679 : return m;
2680 :
2681 : return MATCH_NO;
2682 : }
2683 :
2684 :
2685 : /* Match a CLOSE statement. */
2686 :
2687 : match
2688 3148 : gfc_match_close (void)
2689 : {
2690 3148 : gfc_close *close;
2691 3148 : match m;
2692 :
2693 3148 : m = gfc_match_char ('(');
2694 3148 : if (m == MATCH_NO)
2695 : return m;
2696 :
2697 3148 : close = XCNEW (gfc_close);
2698 :
2699 3148 : m = match_close_element (close);
2700 :
2701 3148 : if (m == MATCH_ERROR)
2702 0 : goto cleanup;
2703 3148 : if (m == MATCH_NO)
2704 : {
2705 2836 : m = gfc_match_expr (&close->unit);
2706 2836 : if (m == MATCH_NO)
2707 0 : goto syntax;
2708 2836 : if (m == MATCH_ERROR)
2709 0 : goto cleanup;
2710 : }
2711 :
2712 4620 : for (;;)
2713 : {
2714 4620 : 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 3148 : if (gfc_match_eos () == MATCH_NO)
2727 0 : goto syntax;
2728 :
2729 3148 : 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 3148 : gfc_unset_implicit_pure (NULL);
2736 :
2737 3148 : new_st.op = EXEC_CLOSE;
2738 3148 : new_st.ext.close = close;
2739 3148 : 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 3118 : check_close_constraints (gfc_close *close, locus *where)
2752 : {
2753 3118 : bool warn = (close->iostat || close->err) ? true : false;
2754 :
2755 3118 : 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 3117 : if (close->unit->expr_type == EXPR_CONSTANT
2762 2798 : && close->unit->ts.type == BT_INTEGER
2763 2798 : && 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 3117 : 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 3148 : gfc_resolve_close (gfc_close *close, locus *where)
2787 : {
2788 3148 : RESOLVE_TAG (&tag_unit, close->unit);
2789 3148 : RESOLVE_TAG (&tag_iomsg, close->iomsg);
2790 3131 : RESOLVE_TAG (&tag_iostat, close->iostat);
2791 3129 : RESOLVE_TAG (&tag_status, close->status);
2792 :
2793 3118 : if (!gfc_reference_st_label (close->err, ST_LABEL_TARGET))
2794 : return false;
2795 :
2796 3118 : return check_close_constraints (close, where);
2797 : }
2798 :
2799 :
2800 : /* Free a gfc_filepos structure. */
2801 :
2802 : void
2803 2867 : gfc_free_filepos (gfc_filepos *fp)
2804 : {
2805 2867 : gfc_free_expr (fp->unit);
2806 2867 : gfc_free_expr (fp->iomsg);
2807 2867 : gfc_free_expr (fp->iostat);
2808 2867 : free (fp);
2809 2867 : }
2810 :
2811 :
2812 : /* Match elements of a REWIND, BACKSPACE, ENDFILE, or FLUSH statement. */
2813 :
2814 : static match
2815 2564 : match_file_element (gfc_filepos *fp)
2816 : {
2817 2564 : match m;
2818 :
2819 2564 : m = match_etag (&tag_unit, &fp->unit);
2820 2564 : if (m != MATCH_NO)
2821 : return m;
2822 2531 : m = match_etag (&tag_iomsg, &fp->iomsg);
2823 2531 : if (m != MATCH_NO)
2824 : return m;
2825 2443 : m = match_out_tag (&tag_iostat, &fp->iostat);
2826 2443 : if (m != MATCH_NO)
2827 : return m;
2828 2365 : m = match_ltag (&tag_err, &fp->err);
2829 2365 : 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 2867 : match_filepos (gfc_statement st, gfc_exec_op op)
2841 : {
2842 2867 : gfc_filepos *fp;
2843 2867 : match m;
2844 :
2845 2867 : fp = XCNEW (gfc_filepos);
2846 :
2847 2867 : 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 2387 : m = match_file_element (fp);
2859 2387 : if (m == MATCH_ERROR)
2860 8 : goto cleanup;
2861 2379 : if (m == MATCH_NO)
2862 : {
2863 2341 : m = gfc_match_expr (&fp->unit);
2864 2341 : if (m == MATCH_ERROR || m == MATCH_NO)
2865 8 : goto syntax;
2866 : }
2867 :
2868 2548 : for (;;)
2869 : {
2870 2548 : 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 2371 : done:
2883 2851 : if (gfc_match_eos () != MATCH_YES)
2884 0 : goto syntax;
2885 :
2886 2851 : 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 2851 : gfc_unset_implicit_pure (NULL);
2895 :
2896 2851 : new_st.op = op;
2897 2851 : new_st.ext.filepos = fp;
2898 2851 : 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 2851 : gfc_resolve_filepos (gfc_filepos *fp, locus *where)
2911 : {
2912 2851 : RESOLVE_TAG (&tag_unit, fp->unit);
2913 2851 : RESOLVE_TAG (&tag_iostat, fp->iostat);
2914 2848 : RESOLVE_TAG (&tag_iomsg, fp->iomsg);
2915 :
2916 2790 : 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 2785 : if (!gfc_reference_st_label (fp->err, ST_LABEL_TARGET))
2923 : return false;
2924 :
2925 2785 : if (fp->unit->expr_type == EXPR_CONSTANT
2926 2560 : && fp->unit->ts.type == BT_INTEGER
2927 2560 : && 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 2281 : gfc_match_rewind (void)
2955 : {
2956 2281 : 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 11724 : default_unit (io_kind k)
2974 : {
2975 11724 : int unit;
2976 :
2977 11724 : if (k == M_READ)
2978 : unit = 5;
2979 : else
2980 11646 : unit = 6;
2981 :
2982 11724 : 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 25856 : match_dt_unit (io_kind k, gfc_dt *dt)
2990 : {
2991 25856 : gfc_expr *e;
2992 25856 : char c;
2993 :
2994 25856 : if (gfc_match_char ('*') == MATCH_YES)
2995 : {
2996 3964 : if (dt->io_unit != NULL)
2997 0 : goto conflict;
2998 :
2999 3964 : dt->io_unit = default_unit (k);
3000 :
3001 3964 : c = gfc_peek_ascii_char ();
3002 3964 : if (c == ')')
3003 0 : gfc_error_now ("Missing format with default unit at %C");
3004 :
3005 3964 : return MATCH_YES;
3006 : }
3007 :
3008 21892 : if (gfc_match_expr (&e) == MATCH_YES)
3009 : {
3010 21892 : if (dt->io_unit != NULL)
3011 : {
3012 0 : gfc_free_expr (e);
3013 0 : goto conflict;
3014 : }
3015 :
3016 21892 : dt->io_unit = e;
3017 21892 : 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 30258 : match_dt_format (gfc_dt *dt)
3032 : {
3033 30258 : locus where;
3034 30258 : gfc_expr *e;
3035 30258 : gfc_st_label *label;
3036 30258 : match m;
3037 :
3038 30258 : where = gfc_current_locus;
3039 :
3040 30258 : if (gfc_match_char ('*') == MATCH_YES)
3041 : {
3042 15645 : if (dt->format_expr != NULL || dt->format_label != NULL)
3043 0 : goto conflict;
3044 :
3045 15645 : dt->format_label = &format_asterisk;
3046 15645 : return MATCH_YES;
3047 : }
3048 :
3049 14613 : if ((m = gfc_match_st_label (&label)) == MATCH_YES)
3050 : {
3051 1802 : 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 1802 : gfc_gobble_whitespace ();
3059 1802 : c = gfc_peek_ascii_char ();
3060 1802 : if (c == '.' || c == '_')
3061 2 : gfc_current_locus = where;
3062 : else
3063 : {
3064 1800 : if (dt->format_expr != NULL || dt->format_label != NULL)
3065 : {
3066 0 : gfc_free_st_label (label);
3067 0 : goto conflict;
3068 : }
3069 :
3070 1800 : if (!gfc_reference_st_label (label, ST_LABEL_FORMAT))
3071 : return MATCH_ERROR;
3072 :
3073 1795 : dt->format_label = label;
3074 1795 : return MATCH_YES;
3075 : }
3076 : }
3077 12811 : else if (m == MATCH_ERROR)
3078 : /* The label was zero or too large. Emit the correct diagnosis. */
3079 : return MATCH_ERROR;
3080 :
3081 12811 : if (gfc_match_expr (&e) == MATCH_YES)
3082 : {
3083 12383 : if (dt->format_expr != NULL || dt->format_label != NULL)
3084 : {
3085 0 : gfc_free_expr (e);
3086 0 : goto conflict;
3087 : }
3088 12383 : dt->format_expr = e;
3089 12383 : return MATCH_YES;
3090 : }
3091 :
3092 428 : gfc_current_locus = where; /* The only case where we have to restore */
3093 :
3094 428 : 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 3028 : dtio_procs_present (gfc_symbol *sym, io_kind k)
3105 : {
3106 3028 : gfc_symbol *derived;
3107 :
3108 3028 : if (sym && sym->ts.u.derived)
3109 : {
3110 1569 : if (sym->ts.type == BT_CLASS && CLASS_DATA (sym))
3111 22 : derived = CLASS_DATA (sym)->ts.u.derived;
3112 1547 : else if (sym->ts.type == BT_DERIVED)
3113 : derived = sym->ts.u.derived;
3114 : else
3115 : return false;
3116 1156 : if ((k == M_WRITE || k == M_PRINT) &&
3117 345 : (gfc_find_specific_dtio_proc (derived, true, true) != NULL))
3118 : return true;
3119 1222 : if ((k == M_READ) &&
3120 466 : (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 873 : check_namelist (gfc_symbol *sym)
3132 : {
3133 873 : gfc_namelist *p;
3134 :
3135 2915 : for (p = sym->namelist; p; p = p->next)
3136 2043 : 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 54318 : match_dt_element (io_kind k, gfc_dt *dt)
3151 : {
3152 54318 : char name[GFC_MAX_SYMBOL_LEN + 1];
3153 54318 : gfc_symbol *sym;
3154 54318 : match m;
3155 54318 : locus where;
3156 :
3157 54318 : if (gfc_match (" unit =") == MATCH_YES)
3158 : {
3159 1211 : m = match_dt_unit (k, dt);
3160 1211 : if (m != MATCH_NO)
3161 : return m;
3162 : }
3163 :
3164 53107 : if (gfc_match (" fmt =") == MATCH_YES)
3165 : {
3166 2006 : m = match_dt_format (dt);
3167 2006 : if (m != MATCH_NO)
3168 : return m;
3169 : }
3170 :
3171 51101 : where = gfc_current_locus;
3172 51101 : if (gfc_match (" nml = %n", name) == MATCH_YES)
3173 : {
3174 777 : if (dt->namelist != NULL)
3175 : {
3176 0 : gfc_error ("Duplicate NML specification at %C");
3177 0 : return MATCH_ERROR;
3178 : }
3179 :
3180 777 : if (gfc_find_symbol (name, NULL, 1, &sym))
3181 : return MATCH_ERROR;
3182 :
3183 777 : if (sym == NULL || sym->attr.flavor != FL_NAMELIST)
3184 : {
3185 0 : gfc_error ("Symbol %qs at %C must be a NAMELIST group name",
3186 : sym != NULL ? sym->name : name);
3187 0 : return MATCH_ERROR;
3188 : }
3189 :
3190 777 : dt->namelist = sym;
3191 777 : dt->nml_where = where;
3192 777 : if (k == M_READ && check_namelist (sym))
3193 : return MATCH_ERROR;
3194 :
3195 777 : return MATCH_YES;
3196 : }
3197 :
3198 50324 : m = match_etag (&tag_e_async, &dt->asynchronous);
3199 50324 : if (m != MATCH_NO)
3200 : return m;
3201 50095 : m = match_etag (&tag_e_blank, &dt->blank);
3202 50095 : if (m != MATCH_NO)
3203 : return m;
3204 50054 : m = match_etag (&tag_e_delim, &dt->delim);
3205 50054 : if (m != MATCH_NO)
3206 : return m;
3207 50025 : m = match_etag (&tag_e_pad, &dt->pad);
3208 50025 : if (m != MATCH_NO)
3209 : return m;
3210 49920 : m = match_etag (&tag_e_sign, &dt->sign);
3211 49920 : if (m != MATCH_NO)
3212 : return m;
3213 49881 : m = match_etag (&tag_e_round, &dt->round);
3214 49881 : if (m != MATCH_NO)
3215 : return m;
3216 49542 : m = match_out_tag (&tag_id, &dt->id);
3217 49542 : if (m != MATCH_NO)
3218 : return m;
3219 49521 : m = match_etag (&tag_e_decimal, &dt->decimal);
3220 49521 : if (m != MATCH_NO)
3221 : return m;
3222 49353 : m = match_etag (&tag_rec, &dt->rec);
3223 49353 : if (m != MATCH_NO)
3224 : return m;
3225 48853 : m = match_etag (&tag_spos, &dt->pos);
3226 48853 : if (m != MATCH_NO)
3227 : return m;
3228 48681 : m = match_etag (&tag_iomsg, &dt->iomsg);
3229 48681 : if (m != MATCH_NO)
3230 : return m;
3231 :
3232 48226 : m = match_out_tag (&tag_iostat, &dt->iostat);
3233 48226 : if (m != MATCH_NO)
3234 : return m;
3235 46435 : m = match_ltag (&tag_err, &dt->err);
3236 46435 : if (m == MATCH_YES)
3237 250 : dt->err_where = gfc_current_locus;
3238 46435 : if (m != MATCH_NO)
3239 : return m;
3240 46185 : m = match_etag (&tag_advance, &dt->advance);
3241 46185 : if (m != MATCH_NO)
3242 : return m;
3243 45802 : m = match_out_tag (&tag_size, &dt->size);
3244 45802 : if (m != MATCH_NO)
3245 : return m;
3246 :
3247 45737 : m = match_ltag (&tag_end, &dt->end);
3248 45737 : if (m == MATCH_YES)
3249 : {
3250 562 : if (k == M_WRITE)
3251 : {
3252 4 : gfc_error ("END tag at %C not allowed in output statement");
3253 4 : return MATCH_ERROR;
3254 : }
3255 558 : dt->end_where = gfc_current_locus;
3256 : }
3257 45733 : if (m != MATCH_NO)
3258 : return m;
3259 :
3260 45175 : m = match_ltag (&tag_eor, &dt->eor);
3261 45175 : if (m == MATCH_YES)
3262 34 : dt->eor_where = gfc_current_locus;
3263 45175 : if (m != MATCH_NO)
3264 : return m;
3265 :
3266 : return MATCH_NO;
3267 : }
3268 :
3269 :
3270 : /* Free a data transfer structure and everything below it. */
3271 :
3272 : void
3273 66917 : gfc_free_dt (gfc_dt *dt)
3274 : {
3275 66917 : if (dt == NULL)
3276 : return;
3277 :
3278 33527 : gfc_free_expr (dt->io_unit);
3279 33527 : gfc_free_expr (dt->format_expr);
3280 33527 : gfc_free_expr (dt->rec);
3281 33527 : gfc_free_expr (dt->advance);
3282 33527 : gfc_free_expr (dt->iomsg);
3283 33527 : gfc_free_expr (dt->iostat);
3284 33527 : gfc_free_expr (dt->size);
3285 33527 : gfc_free_expr (dt->pad);
3286 33527 : gfc_free_expr (dt->delim);
3287 33527 : gfc_free_expr (dt->sign);
3288 33527 : gfc_free_expr (dt->round);
3289 33527 : gfc_free_expr (dt->blank);
3290 33527 : gfc_free_expr (dt->decimal);
3291 33527 : gfc_free_expr (dt->pos);
3292 33527 : gfc_free_expr (dt->dt_io_kind);
3293 : /* dt->extra_comma is a link to dt_io_kind if it is set. */
3294 33527 : free (dt);
3295 : }
3296 :
3297 :
3298 : static const char *
3299 : io_kind_name (io_kind k);
3300 :
3301 : static bool
3302 : check_io_constraints (io_kind k, gfc_dt *dt, gfc_code *io_code,
3303 : locus *spec_end);
3304 :
3305 : /* Resolve everything in a gfc_dt structure. */
3306 :
3307 : bool
3308 33456 : gfc_resolve_dt (gfc_code *dt_code, gfc_dt *dt, locus *loc)
3309 : {
3310 33456 : gfc_expr *e;
3311 33456 : io_kind k;
3312 33456 : bool internal_unit;
3313 :
3314 : /* This is set in any case. */
3315 33456 : gcc_assert (dt->dt_io_kind);
3316 33456 : k = dt->dt_io_kind->value.iokind;
3317 :
3318 33456 : RESOLVE_TAG (&tag_format, dt->format_expr);
3319 33428 : RESOLVE_TAG (&tag_rec, dt->rec);
3320 33428 : RESOLVE_TAG (&tag_spos, dt->pos);
3321 33428 : RESOLVE_TAG (&tag_advance, dt->advance);
3322 33425 : RESOLVE_TAG (&tag_id, dt->id);
3323 33425 : RESOLVE_TAG (&tag_iomsg, dt->iomsg);
3324 33396 : RESOLVE_TAG (&tag_iostat, dt->iostat);
3325 33393 : RESOLVE_TAG (&tag_size, dt->size);
3326 33389 : RESOLVE_TAG (&tag_e_pad, dt->pad);
3327 33367 : RESOLVE_TAG (&tag_e_delim, dt->delim);
3328 33345 : RESOLVE_TAG (&tag_e_sign, dt->sign);
3329 33323 : RESOLVE_TAG (&tag_e_round, dt->round);
3330 33301 : RESOLVE_TAG (&tag_e_blank, dt->blank);
3331 33279 : RESOLVE_TAG (&tag_e_decimal, dt->decimal);
3332 33259 : RESOLVE_TAG (&tag_e_async, dt->asynchronous);
3333 :
3334 : /* Check I/O constraints.
3335 : To validate NAMELIST we need to check if we were also given an I/O list,
3336 : which is stored in code->block->next with op EXEC_TRANSFER.
3337 : Note that the I/O list was already resolved from resolve_transfer. */
3338 33236 : gfc_code *io_code = NULL;
3339 33236 : if (dt_code && dt_code->block && dt_code->block->next
3340 33236 : && dt_code->block->next->op == EXEC_TRANSFER)
3341 33236 : io_code = dt_code->block->next;
3342 :
3343 33236 : if (!check_io_constraints (k, dt, io_code, loc))
3344 : return false;
3345 :
3346 33177 : e = dt->io_unit;
3347 33177 : if (e == NULL)
3348 : {
3349 2 : gfc_error ("UNIT not specified at %L", loc);
3350 2 : return false;
3351 : }
3352 :
3353 33175 : if (e->symtree && e->symtree->n.sym->attr.flavor == FL_PARAMETER
3354 365 : && e->ts.type == BT_CHARACTER)
3355 : {
3356 4 : gfc_error ("UNIT specification at %L must "
3357 : "not be a character PARAMETER", &e->where);
3358 4 : return false;
3359 : }
3360 :
3361 33171 : internal_unit = false;
3362 33171 : if (gfc_resolve_expr (e)
3363 33171 : && (e->ts.type != BT_INTEGER
3364 10006 : && (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_VARIABLE)))
3365 : {
3366 : /* If there is no extra comma signifying the "format" form of the IO
3367 : statement, then this must be an error. */
3368 2 : if (!dt->extra_comma)
3369 : {
3370 1 : gfc_error ("UNIT specification at %L must be an INTEGER expression "
3371 : "or a CHARACTER variable", &e->where);
3372 1 : return false;
3373 : }
3374 : else
3375 : {
3376 : /* At this point, we have an extra comma. If io_unit has arrived as
3377 : type character, we assume its really the "format" form of the I/O
3378 : statement. We set the io_unit to the default unit and format to
3379 : the character expression. See F95 Standard section 9.4. */
3380 1 : if (e->ts.type == BT_CHARACTER && (k == M_READ || k == M_PRINT))
3381 : {
3382 0 : dt->format_expr = dt->io_unit;
3383 0 : dt->io_unit = default_unit (k);
3384 :
3385 : /* Nullify this pointer now so that a warning/error is not
3386 : triggered below for the "Extension". */
3387 0 : dt->extra_comma = NULL;
3388 : }
3389 :
3390 1 : if (k == M_WRITE)
3391 : {
3392 1 : gfc_error ("Invalid form of WRITE statement at %L, UNIT required",
3393 1 : &dt->extra_comma->where);
3394 1 : return false;
3395 : }
3396 : }
3397 : }
3398 :
3399 33169 : if (e->ts.type == BT_CHARACTER)
3400 : {
3401 10004 : internal_unit = true;
3402 10004 : if (gfc_has_vector_index (e))
3403 : {
3404 3 : gfc_error ("Internal unit with vector subscript at %L", &e->where);
3405 3 : return false;
3406 : }
3407 :
3408 : /* If we are writing, make sure the internal unit can be changed. */
3409 10001 : gcc_assert (k != M_PRINT);
3410 10001 : if (k == M_WRITE)
3411 : {
3412 8100 : if (!gfc_check_vardef_context (e, false, false, false,
3413 8100 : _("internal unit in WRITE")))
3414 : return false;
3415 :
3416 8099 : gfc_expr_set_at (e, &e->where, VALUE_VARDEF);
3417 : }
3418 : else
3419 1901 : gfc_value_used_expr (e, VALUE_USED);
3420 : }
3421 :
3422 33165 : if (e->rank && e->ts.type != BT_CHARACTER)
3423 : {
3424 1 : gfc_error ("External IO UNIT cannot be an array at %L", &e->where);
3425 1 : return false;
3426 : }
3427 :
3428 33164 : if (e->expr_type == EXPR_CONSTANT && e->ts.type == BT_INTEGER
3429 21571 : && mpz_sgn (e->value.integer) < 0)
3430 : {
3431 0 : gfc_error ("UNIT number in statement at %L must be non-negative",
3432 : &e->where);
3433 0 : return false;
3434 : }
3435 :
3436 33164 : if (!internal_unit)
3437 23164 : gfc_value_used_expr (e, VALUE_USED);
3438 :
3439 : /* If we are reading and have a namelist, check that all namelist symbols
3440 : can appear in a variable definition context. */
3441 33164 : if (dt->namelist)
3442 : {
3443 1201 : gfc_namelist* n;
3444 4224 : for (n = dt->namelist->namelist; n; n = n->next)
3445 : {
3446 3029 : gfc_expr* e;
3447 3029 : bool t;
3448 :
3449 3029 : e = gfc_get_variable_expr (gfc_find_sym_in_symtree (n->sym));
3450 :
3451 3029 : if (k == M_READ)
3452 : {
3453 2041 : t = gfc_check_vardef_context (e, false, false, false, NULL);
3454 2041 : gfc_free_expr (e);
3455 :
3456 2041 : if (!t)
3457 : {
3458 1 : gfc_error ("NAMELIST %qs in READ statement at %L contains"
3459 : " the symbol %qs which may not appear in a"
3460 : " variable definition context",
3461 1 : dt->namelist->name, loc, n->sym->name);
3462 1 : return false;
3463 : }
3464 2040 : gfc_value_set_at (n->sym, &dt->nml_where, VALUE_READ);
3465 : }
3466 988 : else if (k == M_WRITE || k == M_PRINT)
3467 : {
3468 988 : e->where = dt->nml_where;
3469 988 : gfc_value_used_expr (e, VALUE_USED);
3470 988 : gfc_free_expr (e);
3471 : }
3472 :
3473 3028 : n->sym->attr.referenced = 1;
3474 :
3475 3028 : t = dtio_procs_present (n->sym, k);
3476 :
3477 3028 : if (n->sym->ts.type == BT_CLASS && !t)
3478 : {
3479 3 : gfc_error ("NAMELIST object %qs in namelist %qs at %L is "
3480 : "polymorphic and requires a defined input/output "
3481 3 : "procedure", n->sym->name, dt->namelist->name, loc);
3482 3 : return false;
3483 : }
3484 :
3485 3025 : if ((n->sym->ts.type == BT_DERIVED)
3486 789 : && (n->sym->ts.u.derived->attr.alloc_comp
3487 787 : || n->sym->ts.u.derived->attr.pointer_comp))
3488 : {
3489 2 : if (!gfc_notify_std (GFC_STD_F2003, "NAMELIST object %qs in "
3490 : "namelist %qs at %L with ALLOCATABLE "
3491 : "or POINTER components", n->sym->name,
3492 2 : dt->namelist->name, loc))
3493 : return false;
3494 :
3495 2 : if (!t)
3496 : {
3497 2 : gfc_error ("NAMELIST object %qs in namelist %qs at %L has "
3498 : "ALLOCATABLE or POINTER components and thus requires "
3499 2 : "a defined input/output procedure", n->sym->name,
3500 2 : dt->namelist->name, loc);
3501 2 : return false;
3502 : }
3503 : }
3504 : }
3505 : }
3506 :
3507 33158 : if (dt->extra_comma
3508 33158 : && !gfc_notify_std (GFC_STD_LEGACY, "Comma before i/o item list at %L",
3509 : &dt->extra_comma->where))
3510 : return false;
3511 :
3512 33158 : if (dt->err)
3513 : {
3514 250 : if (!gfc_reference_st_label (dt->err, ST_LABEL_TARGET))
3515 : return false;
3516 250 : if (dt->err->defined == ST_LABEL_UNKNOWN)
3517 : {
3518 1 : gfc_error ("ERR tag label %d at %L not defined",
3519 : dt->err->value, &dt->err_where);
3520 1 : return false;
3521 : }
3522 : }
3523 :
3524 33157 : if (dt->end)
3525 : {
3526 557 : if (!gfc_reference_st_label (dt->end, ST_LABEL_TARGET))
3527 : return false;
3528 557 : if (dt->end->defined == ST_LABEL_UNKNOWN)
3529 : {
3530 1 : gfc_error ("END tag label %d at %L not defined",
3531 : dt->end->value, &dt->end_where);
3532 1 : return false;
3533 : }
3534 : }
3535 :
3536 33156 : if (dt->eor)
3537 : {
3538 31 : if (!gfc_reference_st_label (dt->eor, ST_LABEL_TARGET))
3539 : return false;
3540 31 : if (dt->eor->defined == ST_LABEL_UNKNOWN)
3541 : {
3542 1 : gfc_error ("EOR tag label %d at %L not defined",
3543 : dt->eor->value, &dt->eor_where);
3544 1 : return false;
3545 : }
3546 : }
3547 :
3548 : /* Check the format label actually exists. */
3549 33155 : if (dt->format_label && dt->format_label != &format_asterisk
3550 1797 : && dt->format_label->defined == ST_LABEL_UNKNOWN)
3551 : {
3552 7 : gfc_error ("FORMAT label %d at %L not defined", dt->format_label->value,
3553 : loc);
3554 7 : return false;
3555 : }
3556 :
3557 : return true;
3558 : }
3559 :
3560 :
3561 : /* Given an io_kind, return its name. */
3562 :
3563 : static const char *
3564 811 : io_kind_name (io_kind k)
3565 : {
3566 811 : const char *name;
3567 :
3568 811 : switch (k)
3569 : {
3570 : case M_READ:
3571 : name = "READ";
3572 : break;
3573 499 : case M_WRITE:
3574 499 : name = "WRITE";
3575 499 : break;
3576 26 : case M_PRINT:
3577 26 : name = "PRINT";
3578 26 : break;
3579 0 : case M_INQUIRE:
3580 0 : name = "INQUIRE";
3581 0 : break;
3582 0 : default:
3583 0 : gfc_internal_error ("io_kind_name(): bad I/O-kind");
3584 : }
3585 :
3586 811 : return name;
3587 : }
3588 :
3589 :
3590 : /* Match an IO iteration statement of the form:
3591 :
3592 : ( [<IO element> ,] <IO element>, I = <expr>, <expr> [, <expr> ] )
3593 :
3594 : which is equivalent to a single IO element. This function is
3595 : mutually recursive with match_io_element(). */
3596 :
3597 : static match match_io_element (io_kind, gfc_code **);
3598 :
3599 : static match
3600 48453 : match_io_iterator (io_kind k, gfc_code **result)
3601 : {
3602 48453 : gfc_code *head, *tail, *new_code;
3603 48453 : gfc_iterator *iter;
3604 48453 : locus old_loc;
3605 48453 : match m;
3606 48453 : int n;
3607 :
3608 48453 : iter = NULL;
3609 48453 : head = NULL;
3610 48453 : old_loc = gfc_current_locus;
3611 :
3612 48453 : if (gfc_match_char ('(') != MATCH_YES)
3613 : return MATCH_NO;
3614 :
3615 764 : m = match_io_element (k, &head);
3616 764 : tail = head;
3617 :
3618 764 : if (m != MATCH_YES || gfc_match_char (',') != MATCH_YES)
3619 : {
3620 93 : m = MATCH_NO;
3621 93 : goto cleanup;
3622 : }
3623 :
3624 : /* Can't be anything but an IO iterator. Build a list. */
3625 671 : iter = gfc_get_iterator ();
3626 :
3627 671 : for (n = 1;; n++)
3628 : {
3629 723 : m = gfc_match_iterator (iter, 0);
3630 723 : if (m == MATCH_ERROR)
3631 0 : goto cleanup;
3632 723 : if (m == MATCH_YES)
3633 : {
3634 654 : gfc_check_do_variable (iter->var->symtree);
3635 654 : break;
3636 : }
3637 :
3638 69 : m = match_io_element (k, &new_code);
3639 69 : if (m == MATCH_ERROR)
3640 0 : goto cleanup;
3641 69 : if (m == MATCH_NO)
3642 : {
3643 : if (n > 2)
3644 : goto syntax;
3645 : goto cleanup;
3646 : }
3647 :
3648 69 : tail = gfc_append_code (tail, new_code);
3649 :
3650 69 : if (gfc_match_char (',') != MATCH_YES)
3651 : {
3652 17 : if (n > 2)
3653 0 : goto syntax;
3654 17 : m = MATCH_NO;
3655 17 : goto cleanup;
3656 : }
3657 : }
3658 :
3659 654 : if (gfc_match_char (')') != MATCH_YES)
3660 1 : goto syntax;
3661 :
3662 653 : new_code = gfc_get_code (EXEC_DO);
3663 653 : new_code->ext.iterator = iter;
3664 :
3665 653 : new_code->block = gfc_get_code (EXEC_DO);
3666 653 : new_code->block->next = head;
3667 :
3668 653 : *result = new_code;
3669 653 : return MATCH_YES;
3670 :
3671 1 : syntax:
3672 1 : gfc_error ("Syntax error in I/O iterator at %C");
3673 1 : m = MATCH_ERROR;
3674 :
3675 111 : cleanup:
3676 111 : gfc_free_iterator (iter, 1);
3677 111 : gfc_free_statements (head);
3678 111 : gfc_current_locus = old_loc;
3679 111 : return m;
3680 : }
3681 :
3682 :
3683 : /* Match a single element of an IO list, which is either a single
3684 : expression or an IO Iterator. */
3685 :
3686 : static match
3687 48453 : match_io_element (io_kind k, gfc_code **cpp)
3688 : {
3689 48453 : gfc_expr *expr;
3690 48453 : gfc_code *cp;
3691 48453 : match m;
3692 :
3693 48453 : expr = NULL;
3694 :
3695 48453 : m = match_io_iterator (k, cpp);
3696 48453 : if (m == MATCH_YES)
3697 : return MATCH_YES;
3698 :
3699 47800 : if (k == M_READ)
3700 : {
3701 7525 : m = gfc_match_variable (&expr, 0);
3702 7525 : if (m == MATCH_NO)
3703 : {
3704 0 : gfc_error ("Expecting variable in READ statement at %C");
3705 0 : m = MATCH_ERROR;
3706 : }
3707 :
3708 7525 : if (m == MATCH_YES && expr->expr_type == EXPR_CONSTANT)
3709 : {
3710 1 : gfc_error ("Expecting variable or io-implied-do in READ statement "
3711 : "at %L", &expr->where);
3712 1 : m = MATCH_ERROR;
3713 : }
3714 :
3715 7525 : if (m == MATCH_YES
3716 7524 : && expr->expr_type == EXPR_VARIABLE
3717 7524 : && expr->symtree->n.sym->attr.external)
3718 : {
3719 2 : gfc_error ("Expecting variable or io-implied-do at %L",
3720 : &expr->where);
3721 2 : m = MATCH_ERROR;
3722 : }
3723 : }
3724 : else
3725 : {
3726 40275 : m = gfc_match_expr (&expr);
3727 40275 : if (m == MATCH_NO)
3728 41 : gfc_error ("Expected expression in %s statement at %C",
3729 : io_kind_name (k));
3730 :
3731 40275 : if (m == MATCH_YES && expr->ts.type == BT_BOZ)
3732 : {
3733 6 : if (gfc_invalid_boz (G_("BOZ literal constant at %L cannot appear in"
3734 : " an output IO list"), &gfc_current_locus))
3735 : return MATCH_ERROR;
3736 3 : if (!gfc_boz2int (expr, gfc_max_integer_kind))
3737 : return MATCH_ERROR;
3738 47797 : };
3739 : }
3740 :
3741 47797 : if (m == MATCH_YES && k == M_READ && gfc_check_do_variable (expr->symtree))
3742 : m = MATCH_ERROR;
3743 :
3744 47796 : if (m != MATCH_YES)
3745 : {
3746 142 : gfc_free_expr (expr);
3747 142 : return MATCH_ERROR;
3748 : }
3749 :
3750 47655 : cp = gfc_get_code (EXEC_TRANSFER);
3751 47655 : cp->expr1 = expr;
3752 47655 : if (k != M_INQUIRE)
3753 47501 : cp->ext.dt = current_dt;
3754 :
3755 47655 : *cpp = cp;
3756 47655 : return MATCH_YES;
3757 : }
3758 :
3759 :
3760 : /* Match an I/O list, building gfc_code structures as we go. */
3761 :
3762 : static match
3763 31487 : match_io_list (io_kind k, gfc_code **head_p)
3764 : {
3765 31487 : gfc_code *head, *tail, *new_code;
3766 31487 : match m;
3767 :
3768 31487 : *head_p = head = tail = NULL;
3769 31487 : if (gfc_match_eos () == MATCH_YES)
3770 : return MATCH_YES;
3771 :
3772 47620 : for (;;)
3773 : {
3774 47620 : m = match_io_element (k, &new_code);
3775 47620 : if (m == MATCH_ERROR)
3776 104 : goto cleanup;
3777 47516 : if (m == MATCH_NO)
3778 : goto syntax;
3779 :
3780 47516 : tail = gfc_append_code (tail, new_code);
3781 47516 : if (head == NULL)
3782 31389 : head = new_code;
3783 :
3784 47516 : if (gfc_match_eos () == MATCH_YES)
3785 : break;
3786 16142 : if (gfc_match_char (',') != MATCH_YES)
3787 9 : goto syntax;
3788 : }
3789 :
3790 31374 : *head_p = head;
3791 31374 : return MATCH_YES;
3792 :
3793 9 : syntax:
3794 9 : gfc_error ("Syntax error in %s statement at %C", io_kind_name (k));
3795 :
3796 113 : cleanup:
3797 113 : gfc_free_statements (head);
3798 113 : return MATCH_ERROR;
3799 : }
3800 :
3801 :
3802 : /* Attach the data transfer end node. */
3803 :
3804 : static void
3805 33550 : terminate_io (gfc_code *io_code)
3806 : {
3807 33550 : gfc_code *c;
3808 :
3809 33550 : if (io_code == NULL)
3810 2211 : io_code = new_st.block;
3811 :
3812 33550 : c = gfc_get_code (EXEC_DT_END);
3813 :
3814 : /* Point to structure that is already there */
3815 33550 : c->ext.dt = new_st.ext.dt;
3816 33550 : gfc_append_code (io_code, c);
3817 33550 : }
3818 :
3819 :
3820 : /* Check the constraints for a data transfer statement. The majority of the
3821 : constraints appearing in 9.4 of the standard appear here.
3822 :
3823 : Tag expressions are already resolved by resolve_tag, which includes
3824 : verifying the type, that they are scalar, and verifying that BT_CHARACTER
3825 : tags are of default kind. */
3826 :
3827 : static bool
3828 33236 : check_io_constraints (io_kind k, gfc_dt *dt, gfc_code *io_code,
3829 : locus *spec_end)
3830 : {
3831 : #define io_constraint(condition, msg, where)\
3832 : if (condition) \
3833 : {\
3834 : if (GFC_LOCUS_IS_SET (*where))\
3835 : gfc_error ((msg), (where));\
3836 : else\
3837 : gfc_error ((msg), spec_end);\
3838 : return false;\
3839 : }
3840 :
3841 33236 : gfc_expr *expr;
3842 33236 : gfc_symbol *sym = NULL;
3843 33236 : bool warn, unformatted;
3844 :
3845 33236 : warn = (dt->err || dt->iostat) ? true : false;
3846 20924 : unformatted = dt->format_expr == NULL && dt->format_label == NULL
3847 36847 : && dt->namelist == NULL;
3848 :
3849 33236 : expr = dt->io_unit;
3850 33236 : if (expr && expr->expr_type == EXPR_VARIABLE
3851 11607 : && expr->ts.type == BT_CHARACTER)
3852 : {
3853 10011 : sym = expr->symtree->n.sym;
3854 :
3855 10011 : io_constraint (k == M_WRITE && sym->attr.intent == INTENT_IN,
3856 : "Internal file at %L must not be INTENT(IN)",
3857 10011 : &expr->where);
3858 :
3859 10011 : io_constraint (gfc_has_vector_index (dt->io_unit),
3860 : "Internal file incompatible with vector subscript at %L",
3861 10011 : &expr->where);
3862 :
3863 10011 : io_constraint (dt->rec != NULL,
3864 : "REC tag at %L is incompatible with internal file",
3865 10010 : &dt->rec->where);
3866 :
3867 10010 : io_constraint (dt->pos != NULL,
3868 : "POS tag at %L is incompatible with internal file",
3869 10009 : &dt->pos->where);
3870 :
3871 10009 : io_constraint (unformatted,
3872 : "Unformatted I/O not allowed with internal unit at %L",
3873 10008 : &dt->io_unit->where);
3874 :
3875 10008 : io_constraint (dt->asynchronous != NULL,
3876 : "ASYNCHRONOUS tag at %L not allowed with internal file",
3877 10008 : &dt->asynchronous->where);
3878 :
3879 10008 : if (dt->namelist != NULL)
3880 : {
3881 254 : if (!gfc_notify_std (GFC_STD_F2003, "Internal file at %L with "
3882 : "namelist", &expr->where))
3883 : return false;
3884 : }
3885 :
3886 10007 : io_constraint (dt->advance != NULL,
3887 : "ADVANCE tag at %L is incompatible with internal file",
3888 : &dt->advance->where);
3889 : }
3890 :
3891 33229 : if (expr && expr->ts.type != BT_CHARACTER)
3892 : {
3893 :
3894 23220 : if (gfc_pure (NULL) && (k == M_READ || k == M_WRITE))
3895 : {
3896 0 : gfc_error ("IO UNIT in %s statement at %L must be "
3897 : "an internal file in a PURE procedure",
3898 : io_kind_name (k), &expr->where);
3899 0 : return false;
3900 : }
3901 :
3902 23220 : if (k == M_READ || k == M_WRITE)
3903 15607 : gfc_unset_implicit_pure (NULL);
3904 : }
3905 :
3906 33231 : if (dt->asynchronous)
3907 : {
3908 206 : int num = -1;
3909 206 : static const char * asynchronous[] = { "YES", "NO", NULL };
3910 :
3911 : /* Note: gfc_reduce_init_expr reports an error if not init-expr. */
3912 206 : if (!gfc_reduce_init_expr (dt->asynchronous))
3913 7 : return false;
3914 :
3915 201 : if (!compare_to_allowed_values
3916 201 : ("ASYNCHRONOUS", asynchronous, NULL, NULL,
3917 : dt->asynchronous->value.character.string,
3918 201 : io_kind_name (k), warn, &dt->asynchronous->where, &num))
3919 : return false;
3920 :
3921 199 : gcc_checking_assert (num != -1);
3922 :
3923 : /* For "YES", mark related symbols as asynchronous. */
3924 199 : if (num == 0)
3925 : {
3926 : /* SIZE variable. */
3927 195 : if (dt->size)
3928 0 : dt->size->symtree->n.sym->attr.asynchronous = 1;
3929 :
3930 : /* Variables in a NAMELIST. */
3931 195 : if (dt->namelist)
3932 4 : for (gfc_namelist *nl = dt->namelist->namelist; nl; nl = nl->next)
3933 3 : nl->sym->attr.asynchronous = 1;
3934 :
3935 : /* Variables in an I/O list. */
3936 430 : for (gfc_code *xfer = io_code; xfer && xfer->op == EXEC_TRANSFER;
3937 235 : xfer = xfer->next)
3938 : {
3939 235 : gfc_expr *expr = xfer->expr1;
3940 470 : while (expr != NULL && expr->expr_type == EXPR_OP
3941 241 : && expr->value.op.op == INTRINSIC_PARENTHESES)
3942 0 : expr = expr->value.op.op1;
3943 :
3944 235 : if (expr && expr->expr_type == EXPR_VARIABLE)
3945 157 : expr->symtree->n.sym->attr.asynchronous = 1;
3946 : }
3947 : }
3948 : }
3949 :
3950 33224 : if (dt->id)
3951 : {
3952 21 : bool not_yes
3953 21 : = !dt->asynchronous
3954 20 : || gfc_wide_strlen (dt->asynchronous->value.character.string) != 3
3955 40 : || gfc_wide_strncasecmp (dt->asynchronous->value.character.string,
3956 33224 : "yes", 3) != 0;
3957 2 : io_constraint (not_yes,
3958 : "ID= specifier at %L must be with ASYNCHRONOUS='yes' "
3959 : "specifier", &dt->id->where);
3960 : }
3961 :
3962 33222 : if (dt->decimal)
3963 : {
3964 145 : if (!gfc_notify_std (GFC_STD_F2003, "DECIMAL= at %L "
3965 : "not allowed in Fortran 95", &dt->decimal->where))
3966 : return false;
3967 :
3968 145 : if (dt->decimal->expr_type == EXPR_CONSTANT)
3969 : {
3970 127 : static const char * decimal[] = { "COMMA", "POINT", NULL };
3971 :
3972 127 : if (!compare_to_allowed_values ("DECIMAL", decimal, NULL, NULL,
3973 : dt->decimal->value.character.string,
3974 : io_kind_name (k), warn,
3975 : &dt->decimal->where))
3976 : return false;
3977 :
3978 123 : io_constraint (unformatted,
3979 : "the DECIMAL= specifier at %L must be with an "
3980 : "explicit format expression", &dt->decimal->where);
3981 : }
3982 : }
3983 :
3984 33218 : if (dt->blank)
3985 : {
3986 17 : if (!gfc_notify_std (GFC_STD_F2003, "BLANK= at %L "
3987 : "not allowed in Fortran 95", &dt->blank->where))
3988 : return false;
3989 :
3990 17 : if (dt->blank->expr_type == EXPR_CONSTANT)
3991 : {
3992 16 : static const char * blank[] = { "NULL", "ZERO", NULL };
3993 :
3994 :
3995 16 : if (!compare_to_allowed_values ("BLANK", blank, NULL, NULL,
3996 : dt->blank->value.character.string,
3997 : io_kind_name (k), warn,
3998 : &dt->blank->where))
3999 : return false;
4000 :
4001 12 : io_constraint (unformatted,
4002 : "the BLANK= specifier at %L must be with an "
4003 : "explicit format expression", &dt->blank->where);
4004 : }
4005 : }
4006 :
4007 33214 : if (dt->pad)
4008 : {
4009 83 : if (!gfc_notify_std (GFC_STD_F2003, "PAD= at %L "
4010 : "not allowed in Fortran 95", &dt->pad->where))
4011 : return false;
4012 :
4013 83 : if (dt->pad->expr_type == EXPR_CONSTANT)
4014 : {
4015 83 : static const char * pad[] = { "YES", "NO", NULL };
4016 :
4017 83 : if (!compare_to_allowed_values ("PAD", pad, NULL, NULL,
4018 : dt->pad->value.character.string,
4019 : io_kind_name (k), warn,
4020 : &dt->pad->where))
4021 : return false;
4022 :
4023 81 : io_constraint (unformatted,
4024 : "the PAD= specifier at %L must be with an "
4025 : "explicit format expression", &dt->pad->where);
4026 : }
4027 : }
4028 :
4029 33210 : if (dt->round)
4030 : {
4031 317 : if (!gfc_notify_std (GFC_STD_F2003, "ROUND= at %L "
4032 : "not allowed in Fortran 95", &dt->round->where))
4033 : return false;
4034 :
4035 317 : if (dt->round->expr_type == EXPR_CONSTANT)
4036 : {
4037 305 : static const char * round[] = { "UP", "DOWN", "ZERO", "NEAREST",
4038 : "COMPATIBLE", "PROCESSOR_DEFINED",
4039 : NULL };
4040 :
4041 305 : if (!compare_to_allowed_values ("ROUND", round, NULL, NULL,
4042 : dt->round->value.character.string,
4043 : io_kind_name (k), warn,
4044 : &dt->round->where))
4045 : return false;
4046 : }
4047 : }
4048 :
4049 33206 : if (dt->sign)
4050 : {
4051 : /* When implemented, change the following to use gfc_notify_std F2003.
4052 : if (gfc_notify_std (GFC_STD_F2003, "SIGN= at %L "
4053 : "not allowed in Fortran 95", &dt->sign->where) == false)
4054 : return false; */
4055 :
4056 17 : if (dt->sign->expr_type == EXPR_CONSTANT)
4057 : {
4058 16 : static const char * sign[] = { "PLUS", "SUPPRESS", "PROCESSOR_DEFINED",
4059 : NULL };
4060 :
4061 16 : if (!compare_to_allowed_values ("SIGN", sign, NULL, NULL,
4062 : dt->sign->value.character.string,
4063 : io_kind_name (k), warn, &dt->sign->where))
4064 : return false;
4065 :
4066 12 : io_constraint (unformatted,
4067 : "SIGN= specifier at %L must be with an "
4068 12 : "explicit format expression", &dt->sign->where);
4069 :
4070 12 : io_constraint (k == M_READ,
4071 : "SIGN= specifier at %L not allowed in a "
4072 : "READ statement", &dt->sign->where);
4073 : }
4074 : }
4075 :
4076 33202 : if (dt->delim)
4077 : {
4078 7 : if (!gfc_notify_std (GFC_STD_F2003, "DELIM= at %L "
4079 : "not allowed in Fortran 95", &dt->delim->where))
4080 : return false;
4081 :
4082 6 : if (dt->delim->expr_type == EXPR_CONSTANT)
4083 : {
4084 6 : static const char *delim[] = { "APOSTROPHE", "QUOTE", "NONE", NULL };
4085 :
4086 6 : if (!compare_to_allowed_values ("DELIM", delim, NULL, NULL,
4087 : dt->delim->value.character.string,
4088 : io_kind_name (k), warn,
4089 : &dt->delim->where))
4090 : return false;
4091 :
4092 2 : io_constraint (k == M_READ,
4093 : "DELIM= specifier at %L not allowed in a "
4094 2 : "READ statement", &dt->delim->where);
4095 :
4096 2 : io_constraint (dt->format_label != &format_asterisk
4097 : && dt->namelist == NULL,
4098 : "DELIM= specifier at %L must have FMT=*",
4099 2 : &dt->delim->where);
4100 :
4101 2 : io_constraint (unformatted && dt->namelist == NULL,
4102 : "DELIM= specifier at %L must be with FMT=* or "
4103 : "NML= specifier", &dt->delim->where);
4104 : }
4105 : }
4106 :
4107 33197 : if (dt->namelist)
4108 : {
4109 1205 : io_constraint (io_code && dt->namelist,
4110 : "NAMELIST cannot be followed by IO-list at %L",
4111 1204 : &io_code->loc);
4112 :
4113 1204 : io_constraint (dt->format_expr,
4114 : "IO spec-list cannot contain both NAMELIST group name "
4115 : "and format specification at %L",
4116 1203 : &dt->format_expr->where);
4117 :
4118 1203 : io_constraint (dt->format_label,
4119 : "IO spec-list cannot contain both NAMELIST group name "
4120 1202 : "and format label at %L", spec_end);
4121 :
4122 1202 : io_constraint (dt->rec,
4123 : "NAMELIST IO is not allowed with a REC= specifier "
4124 1202 : "at %L", &dt->rec->where);
4125 :
4126 1202 : io_constraint (dt->advance,
4127 : "NAMELIST IO is not allowed with a ADVANCE= specifier "
4128 : "at %L", &dt->advance->where);
4129 : }
4130 :
4131 33193 : if (dt->rec)
4132 : {
4133 499 : io_constraint (dt->end,
4134 : "An END tag is not allowed with a "
4135 498 : "REC= specifier at %L", &dt->end_where);
4136 :
4137 498 : io_constraint (dt->format_label == &format_asterisk,
4138 : "FMT=* is not allowed with a REC= specifier "
4139 497 : "at %L", spec_end);
4140 :
4141 497 : io_constraint (dt->pos,
4142 : "POS= is not allowed with REC= specifier "
4143 : "at %L", &dt->pos->where);
4144 : }
4145 :
4146 33189 : if (dt->advance)
4147 : {
4148 373 : int not_yes, not_no;
4149 373 : expr = dt->advance;
4150 :
4151 373 : io_constraint (dt->format_label == &format_asterisk,
4152 : "List directed format(*) is not allowed with a "
4153 373 : "ADVANCE= specifier at %L.", &expr->where);
4154 :
4155 373 : io_constraint (unformatted,
4156 : "the ADVANCE= specifier at %L must appear with an "
4157 372 : "explicit format expression", &expr->where);
4158 :
4159 372 : if (expr->expr_type == EXPR_CONSTANT && expr->ts.type == BT_CHARACTER)
4160 : {
4161 353 : const gfc_char_t *advance = expr->value.character.string;
4162 353 : not_no = gfc_wide_strlen (advance) != 2
4163 353 : || gfc_wide_strncasecmp (advance, "no", 2) != 0;
4164 353 : not_yes = gfc_wide_strlen (advance) != 3
4165 353 : || gfc_wide_strncasecmp (advance, "yes", 3) != 0;
4166 353 : }
4167 : else
4168 : {
4169 : not_no = 0;
4170 : not_yes = 0;
4171 : }
4172 :
4173 372 : io_constraint (not_no && not_yes,
4174 : "ADVANCE= specifier at %L must have value = "
4175 368 : "YES or NO.", &expr->where);
4176 :
4177 368 : io_constraint (dt->size && not_no && k == M_READ,
4178 : "SIZE tag at %L requires an ADVANCE = %<NO%>",
4179 367 : &dt->size->where);
4180 :
4181 367 : io_constraint (dt->eor && not_no && k == M_READ,
4182 : "EOR tag at %L requires an ADVANCE = %<NO%>",
4183 : &dt->eor_where);
4184 : }
4185 :
4186 33182 : if (k != M_READ)
4187 : {
4188 26837 : io_constraint (dt->end, "END tag not allowed with output at %L",
4189 26836 : &dt->end_where);
4190 :
4191 26836 : io_constraint (dt->eor, "EOR tag not allowed with output at %L",
4192 26834 : &dt->eor_where);
4193 :
4194 26834 : io_constraint (dt->blank,
4195 : "BLANK= specifier not allowed with output at %L",
4196 26834 : &dt->blank->where);
4197 :
4198 26834 : io_constraint (dt->pad, "PAD= specifier not allowed with output at %L",
4199 26834 : &dt->pad->where);
4200 :
4201 26834 : io_constraint (dt->size, "SIZE= specifier not allowed with output at %L",
4202 : &dt->size->where);
4203 : }
4204 : else
4205 : {
4206 6345 : io_constraint (dt->size && dt->advance == NULL,
4207 : "SIZE tag at %L requires an ADVANCE tag",
4208 6345 : &dt->size->where);
4209 :
4210 6345 : io_constraint (dt->eor && dt->advance == NULL,
4211 : "EOR tag at %L requires an ADVANCE tag",
4212 : &dt->eor_where);
4213 : }
4214 :
4215 : return true;
4216 : #undef io_constraint
4217 : }
4218 :
4219 :
4220 : /* Match a READ, WRITE or PRINT statement. */
4221 :
4222 : static match
4223 33630 : match_io (io_kind k)
4224 : {
4225 33630 : char name[GFC_MAX_SYMBOL_LEN + 1];
4226 33630 : gfc_code *io_code;
4227 33630 : gfc_symbol *sym;
4228 33630 : int comma_flag;
4229 33630 : locus where;
4230 33630 : locus control;
4231 33630 : gfc_dt *dt;
4232 33630 : match m;
4233 :
4234 33630 : where = gfc_current_locus;
4235 33630 : comma_flag = 0;
4236 33630 : current_dt = dt = XCNEW (gfc_dt);
4237 33630 : m = gfc_match_char ('(');
4238 33630 : if (m == MATCH_NO)
4239 : {
4240 7759 : where = gfc_current_locus;
4241 7759 : if (k == M_WRITE)
4242 0 : goto syntax;
4243 7759 : else if (k == M_PRINT)
4244 : {
4245 : /* Treat the non-standard case of PRINT namelist. */
4246 7465 : if ((gfc_current_form == FORM_FIXED || gfc_peek_ascii_char () == ' ')
4247 14972 : && gfc_match_name (name) == MATCH_YES)
4248 : {
4249 131 : gfc_find_symbol (name, NULL, 1, &sym);
4250 131 : if (sym && sym->attr.flavor == FL_NAMELIST)
4251 : {
4252 11 : if (!gfc_notify_std (GFC_STD_GNU, "PRINT namelist at "
4253 : "%C is an extension"))
4254 : {
4255 2 : m = MATCH_ERROR;
4256 2 : goto cleanup;
4257 : }
4258 :
4259 9 : dt->io_unit = default_unit (k);
4260 9 : dt->namelist = sym;
4261 9 : goto get_io_list;
4262 : }
4263 : else
4264 120 : gfc_current_locus = where;
4265 : }
4266 :
4267 7734 : if (gfc_match_char ('*') == MATCH_YES
4268 7734 : && gfc_match_char(',') == MATCH_YES)
4269 : {
4270 6939 : locus where2 = gfc_current_locus;
4271 6939 : if (gfc_match_eos () == MATCH_YES)
4272 : {
4273 1 : gfc_current_locus = where2;
4274 1 : gfc_error ("Comma after * at %C not allowed without I/O list");
4275 1 : m = MATCH_ERROR;
4276 1 : goto cleanup;
4277 : }
4278 : else
4279 6938 : gfc_current_locus = where;
4280 : }
4281 : else
4282 795 : gfc_current_locus = where;
4283 : }
4284 :
4285 7747 : if (gfc_current_form == FORM_FREE)
4286 : {
4287 7469 : char c = gfc_peek_ascii_char ();
4288 :
4289 : /* Issue a warning for an invalid tab in 'print<tab>*'. After
4290 : the warning is issued, consume any other whitespace and check
4291 : that the next char is an *, ', or ". */
4292 7469 : if (c == '\t')
4293 : {
4294 2 : gfc_gobble_whitespace ();
4295 2 : c = gfc_peek_ascii_char ();
4296 2 : if (c != '*' && c != '\'' && c != '"')
4297 : {
4298 0 : m = MATCH_NO;
4299 0 : goto cleanup;
4300 : }
4301 : }
4302 7467 : else if (c != ' ' && c != '*' && c != '\'' && c != '"')
4303 : {
4304 2 : m = MATCH_NO;
4305 2 : goto cleanup;
4306 : }
4307 : }
4308 :
4309 7745 : m = match_dt_format (dt);
4310 7745 : if (m == MATCH_ERROR)
4311 0 : goto cleanup;
4312 7745 : if (m == MATCH_NO)
4313 4 : goto syntax;
4314 :
4315 7741 : comma_flag = 1;
4316 7741 : dt->io_unit = default_unit (k);
4317 7741 : goto get_io_list;
4318 : }
4319 : else
4320 : {
4321 : /* Before issuing an error for a malformed 'print (1,*)' type of
4322 : error, check for a default-char-expr of the form ('(I0)'). */
4323 25871 : if (m == MATCH_YES)
4324 : {
4325 25871 : control = gfc_current_locus;
4326 25871 : if (k == M_PRINT)
4327 : {
4328 : /* Reset current locus to get the initial '(' in an expression. */
4329 10 : gfc_current_locus = where;
4330 10 : dt->format_expr = NULL;
4331 10 : m = match_dt_format (dt);
4332 :
4333 10 : if (m == MATCH_ERROR)
4334 0 : goto cleanup;
4335 10 : if (m == MATCH_NO || dt->format_expr == NULL)
4336 3 : goto syntax;
4337 :
4338 7 : comma_flag = 1;
4339 7 : dt->io_unit = default_unit (k);
4340 7 : goto get_io_list;
4341 : }
4342 25861 : if (k == M_READ)
4343 : {
4344 : /* Commit any pending symbols now so that when we undo
4345 : symbols later we wont lose them. */
4346 6464 : gfc_commit_symbols ();
4347 : /* Reset current locus to get the initial '(' in an expression. */
4348 6464 : gfc_current_locus = where;
4349 6464 : dt->format_expr = NULL;
4350 6464 : m = gfc_match_expr (&dt->format_expr);
4351 6464 : if (m == MATCH_YES)
4352 : {
4353 545 : if (dt->format_expr
4354 545 : && dt->format_expr->ts.type == BT_CHARACTER)
4355 : {
4356 3 : comma_flag = 1;
4357 3 : dt->io_unit = default_unit (k);
4358 3 : goto get_io_list;
4359 : }
4360 : else
4361 : {
4362 542 : gfc_free_expr (dt->format_expr);
4363 542 : dt->format_expr = NULL;
4364 542 : gfc_current_locus = control;
4365 : }
4366 : }
4367 : else
4368 : {
4369 5919 : gfc_clear_error ();
4370 5919 : gfc_undo_symbols ();
4371 5919 : gfc_free_expr (dt->format_expr);
4372 5919 : dt->format_expr = NULL;
4373 5919 : gfc_current_locus = control;
4374 : }
4375 : }
4376 : }
4377 : }
4378 :
4379 : /* Match a control list */
4380 25858 : if (match_dt_element (k, dt) == MATCH_YES)
4381 1213 : goto next;
4382 24645 : if (match_dt_unit (k, dt) != MATCH_YES)
4383 0 : goto loop;
4384 :
4385 24645 : if (gfc_match_char (')') == MATCH_YES)
4386 1481 : goto get_io_list;
4387 23164 : if (gfc_match_char (',') != MATCH_YES)
4388 0 : goto syntax;
4389 :
4390 23164 : m = match_dt_element (k, dt);
4391 23164 : if (m == MATCH_YES)
4392 2667 : goto next;
4393 20497 : if (m == MATCH_ERROR)
4394 0 : goto cleanup;
4395 :
4396 20497 : m = match_dt_format (dt);
4397 20497 : if (m == MATCH_YES)
4398 20069 : goto next;
4399 428 : if (m == MATCH_ERROR)
4400 7 : goto cleanup;
4401 :
4402 421 : where = gfc_current_locus;
4403 :
4404 421 : m = gfc_match_name (name);
4405 421 : if (m == MATCH_YES)
4406 : {
4407 421 : gfc_find_symbol (name, NULL, 1, &sym);
4408 421 : if (sym && sym->attr.flavor == FL_NAMELIST)
4409 : {
4410 421 : dt->namelist = sym;
4411 421 : if (k == M_READ && check_namelist (sym))
4412 : {
4413 1 : m = MATCH_ERROR;
4414 1 : goto cleanup;
4415 : }
4416 420 : dt->nml_where = where;
4417 420 : goto next;
4418 : }
4419 : }
4420 :
4421 0 : gfc_current_locus = where;
4422 :
4423 0 : goto loop; /* No matches, try regular elements */
4424 :
4425 24369 : next:
4426 24369 : if (gfc_match_char (')') == MATCH_YES)
4427 20181 : goto get_io_list;
4428 4188 : if (gfc_match_char (',') != MATCH_YES)
4429 0 : goto syntax;
4430 :
4431 4188 : loop:
4432 5296 : for (;;)
4433 : {
4434 5296 : m = match_dt_element (k, dt);
4435 5296 : if (m == MATCH_NO)
4436 0 : goto syntax;
4437 5296 : if (m == MATCH_ERROR)
4438 4 : goto cleanup;
4439 :
4440 5292 : if (gfc_match_char (')') == MATCH_YES)
4441 : break;
4442 1108 : if (gfc_match_char (',') != MATCH_YES)
4443 0 : goto syntax;
4444 : }
4445 :
4446 4184 : get_io_list:
4447 :
4448 : /* Save the IO kind for later use. */
4449 33606 : dt->dt_io_kind = gfc_get_iokind_expr (&gfc_current_locus, k);
4450 :
4451 : /* Optional leading comma (non-standard). We use a gfc_expr structure here
4452 : to save the locus. This is used later when resolving transfer statements
4453 : that might have a format expression without unit number. */
4454 33606 : if (!comma_flag && gfc_match_char (',') == MATCH_YES)
4455 87 : dt->extra_comma = dt->dt_io_kind;
4456 :
4457 33606 : io_code = NULL;
4458 33606 : if (gfc_match_eos () != MATCH_YES)
4459 : {
4460 31394 : if (comma_flag && gfc_match_char (',') != MATCH_YES)
4461 : {
4462 0 : gfc_error ("Expected comma in I/O list at %C");
4463 0 : m = MATCH_ERROR;
4464 0 : goto cleanup;
4465 : }
4466 :
4467 31394 : m = match_io_list (k, &io_code);
4468 31394 : if (m == MATCH_ERROR)
4469 113 : goto cleanup;
4470 : if (m == MATCH_NO)
4471 : goto syntax;
4472 : }
4473 :
4474 : /* See if we want to use defaults for missing exponents in real transfers
4475 : and other DEC runtime extensions. */
4476 33493 : if (flag_dec_format_defaults)
4477 484 : dt->dec_ext = 1;
4478 :
4479 : /* Check the format string now. */
4480 33493 : if (dt->format_expr
4481 33493 : && (!gfc_simplify_expr (dt->format_expr, 0)
4482 12383 : || !check_format_string (dt->format_expr, k == M_READ)))
4483 35 : return MATCH_ERROR;
4484 :
4485 33458 : new_st.op = (k == M_READ) ? EXEC_READ : EXEC_WRITE;
4486 33458 : new_st.ext.dt = dt;
4487 33458 : new_st.block = gfc_get_code (new_st.op);
4488 33458 : new_st.block->next = io_code;
4489 :
4490 33458 : terminate_io (io_code);
4491 :
4492 33458 : return MATCH_YES;
4493 :
4494 7 : syntax:
4495 7 : gfc_error ("Syntax error in %s statement at %C", io_kind_name (k));
4496 7 : m = MATCH_ERROR;
4497 :
4498 137 : cleanup:
4499 137 : gfc_free_dt (dt);
4500 137 : return m;
4501 : }
4502 :
4503 :
4504 : match
4505 6478 : gfc_match_read (void)
4506 : {
4507 6478 : return match_io (M_READ);
4508 : }
4509 :
4510 :
4511 : match
4512 19397 : gfc_match_write (void)
4513 : {
4514 19397 : return match_io (M_WRITE);
4515 : }
4516 :
4517 :
4518 : match
4519 7755 : gfc_match_print (void)
4520 : {
4521 7755 : match m;
4522 :
4523 7755 : m = match_io (M_PRINT);
4524 7755 : if (m != MATCH_YES)
4525 : return m;
4526 :
4527 7630 : if (gfc_pure (NULL))
4528 : {
4529 0 : gfc_error ("PRINT statement at %C not allowed within PURE procedure");
4530 0 : return MATCH_ERROR;
4531 : }
4532 :
4533 7630 : gfc_unset_implicit_pure (NULL);
4534 :
4535 7630 : return MATCH_YES;
4536 : }
4537 :
4538 :
4539 : /* Free a gfc_inquire structure. */
4540 :
4541 : void
4542 846 : gfc_free_inquire (gfc_inquire *inquire)
4543 : {
4544 :
4545 846 : if (inquire == NULL)
4546 : return;
4547 :
4548 846 : gfc_free_expr (inquire->unit);
4549 846 : gfc_free_expr (inquire->file);
4550 846 : gfc_free_expr (inquire->iomsg);
4551 846 : gfc_free_expr (inquire->iostat);
4552 846 : gfc_free_expr (inquire->exist);
4553 846 : gfc_free_expr (inquire->opened);
4554 846 : gfc_free_expr (inquire->number);
4555 846 : gfc_free_expr (inquire->named);
4556 846 : gfc_free_expr (inquire->name);
4557 846 : gfc_free_expr (inquire->access);
4558 846 : gfc_free_expr (inquire->sequential);
4559 846 : gfc_free_expr (inquire->direct);
4560 846 : gfc_free_expr (inquire->form);
4561 846 : gfc_free_expr (inquire->formatted);
4562 846 : gfc_free_expr (inquire->unformatted);
4563 846 : gfc_free_expr (inquire->recl);
4564 846 : gfc_free_expr (inquire->nextrec);
4565 846 : gfc_free_expr (inquire->blank);
4566 846 : gfc_free_expr (inquire->position);
4567 846 : gfc_free_expr (inquire->action);
4568 846 : gfc_free_expr (inquire->read);
4569 846 : gfc_free_expr (inquire->write);
4570 846 : gfc_free_expr (inquire->readwrite);
4571 846 : gfc_free_expr (inquire->delim);
4572 846 : gfc_free_expr (inquire->encoding);
4573 846 : gfc_free_expr (inquire->pad);
4574 846 : gfc_free_expr (inquire->iolength);
4575 846 : gfc_free_expr (inquire->convert);
4576 846 : gfc_free_expr (inquire->strm_pos);
4577 846 : gfc_free_expr (inquire->asynchronous);
4578 846 : gfc_free_expr (inquire->decimal);
4579 846 : gfc_free_expr (inquire->pending);
4580 846 : gfc_free_expr (inquire->id);
4581 846 : gfc_free_expr (inquire->sign);
4582 846 : gfc_free_expr (inquire->size);
4583 846 : gfc_free_expr (inquire->round);
4584 846 : gfc_free_expr (inquire->share);
4585 846 : gfc_free_expr (inquire->cc);
4586 846 : free (inquire);
4587 : }
4588 :
4589 :
4590 : /* Match an element of an INQUIRE statement. */
4591 :
4592 : #define RETM if (m != MATCH_NO) return m;
4593 :
4594 : static match
4595 2607 : match_inquire_element (gfc_inquire *inquire)
4596 : {
4597 2607 : match m;
4598 :
4599 2607 : m = match_etag (&tag_unit, &inquire->unit);
4600 2607 : RETM m = match_etag (&tag_file, &inquire->file);
4601 2274 : RETM m = match_ltag (&tag_err, &inquire->err);
4602 2063 : RETM m = match_etag (&tag_iomsg, &inquire->iomsg);
4603 2056 : RETM m = match_out_tag (&tag_iostat, &inquire->iostat);
4604 2031 : RETM m = match_vtag (&tag_exist, &inquire->exist);
4605 1982 : RETM m = match_vtag (&tag_opened, &inquire->opened);
4606 1840 : RETM m = match_vtag (&tag_named, &inquire->named);
4607 1688 : RETM m = match_vtag (&tag_name, &inquire->name);
4608 1665 : RETM m = match_out_tag (&tag_number, &inquire->number);
4609 1638 : RETM m = match_vtag (&tag_s_access, &inquire->access);
4610 1551 : RETM m = match_vtag (&tag_sequential, &inquire->sequential);
4611 1401 : RETM m = match_vtag (&tag_direct, &inquire->direct);
4612 1362 : RETM m = match_vtag (&tag_s_form, &inquire->form);
4613 1251 : RETM m = match_vtag (&tag_formatted, &inquire->formatted);
4614 1236 : RETM m = match_vtag (&tag_unformatted, &inquire->unformatted);
4615 1190 : RETM m = match_out_tag (&tag_s_recl, &inquire->recl);
4616 1151 : RETM m = match_out_tag (&tag_nextrec, &inquire->nextrec);
4617 1092 : RETM m = match_vtag (&tag_s_blank, &inquire->blank);
4618 1030 : RETM m = match_vtag (&tag_s_position, &inquire->position);
4619 1006 : RETM m = match_vtag (&tag_s_action, &inquire->action);
4620 949 : RETM m = match_vtag (&tag_read, &inquire->read);
4621 927 : RETM m = match_vtag (&tag_write, &inquire->write);
4622 894 : RETM m = match_vtag (&tag_readwrite, &inquire->readwrite);
4623 861 : RETM m = match_vtag (&tag_s_async, &inquire->asynchronous);
4624 828 : RETM m = match_vtag (&tag_s_delim, &inquire->delim);
4625 801 : RETM m = match_vtag (&tag_s_decimal, &inquire->decimal);
4626 761 : RETM m = match_out_tag (&tag_size, &inquire->size);
4627 742 : RETM m = match_vtag (&tag_s_encoding, &inquire->encoding);
4628 699 : RETM m = match_vtag (&tag_s_round, &inquire->round);
4629 679 : RETM m = match_vtag (&tag_s_sign, &inquire->sign);
4630 660 : RETM m = match_vtag (&tag_s_pad, &inquire->pad);
4631 641 : RETM m = match_out_tag (&tag_iolength, &inquire->iolength);
4632 602 : RETM m = match_vtag (&tag_convert, &inquire->convert);
4633 509 : RETM m = match_out_tag (&tag_strm_out, &inquire->strm_pos);
4634 497 : RETM m = match_vtag (&tag_pending, &inquire->pending);
4635 389 : RETM m = match_etag (&tag_id, &inquire->id);
4636 369 : RETM m = match_vtag (&tag_s_iqstream, &inquire->iqstream);
4637 358 : RETM m = match_dec_vtag (&tag_v_share, &inquire->share);
4638 316 : RETM m = match_dec_vtag (&tag_v_cc, &inquire->cc);
4639 309 : RETM return MATCH_NO;
4640 : }
4641 :
4642 : #undef RETM
4643 :
4644 :
4645 : match
4646 938 : gfc_match_inquire (void)
4647 : {
4648 938 : gfc_inquire *inquire;
4649 938 : gfc_code *code;
4650 938 : match m;
4651 938 : locus loc;
4652 :
4653 938 : m = gfc_match_char ('(');
4654 938 : if (m == MATCH_NO)
4655 : return m;
4656 :
4657 938 : inquire = XCNEW (gfc_inquire);
4658 :
4659 938 : loc = gfc_current_locus;
4660 :
4661 938 : m = match_inquire_element (inquire);
4662 938 : if (m == MATCH_ERROR)
4663 0 : goto cleanup;
4664 938 : if (m == MATCH_NO)
4665 : {
4666 302 : m = gfc_match_expr (&inquire->unit);
4667 302 : if (m == MATCH_ERROR)
4668 0 : goto cleanup;
4669 302 : if (m == MATCH_NO)
4670 0 : goto syntax;
4671 : }
4672 :
4673 : /* See if we have the IOLENGTH form of the inquire statement. */
4674 938 : if (inquire->iolength != NULL)
4675 : {
4676 93 : if (gfc_match_char (')') != MATCH_YES)
4677 0 : goto syntax;
4678 :
4679 93 : m = match_io_list (M_INQUIRE, &code);
4680 93 : if (m == MATCH_ERROR)
4681 0 : goto cleanup;
4682 93 : if (m == MATCH_NO)
4683 : goto syntax;
4684 :
4685 246 : for (gfc_code *c = code; c; c = c->next)
4686 154 : if (c->expr1 && c->expr1->expr_type == EXPR_FUNCTION
4687 2 : && c->expr1->symtree && c->expr1->symtree->n.sym->attr.function
4688 2 : && !c->expr1->symtree->n.sym->attr.external
4689 1 : && strcmp (c->expr1->symtree->name, "null") == 0)
4690 : {
4691 1 : gfc_error ("NULL() near %L cannot appear in INQUIRE statement",
4692 : &c->expr1->where);
4693 1 : goto cleanup;
4694 : }
4695 :
4696 92 : new_st.op = EXEC_IOLENGTH;
4697 92 : new_st.expr1 = inquire->iolength;
4698 92 : new_st.ext.inquire = inquire;
4699 :
4700 92 : if (gfc_pure (NULL))
4701 : {
4702 0 : gfc_free_statements (code);
4703 0 : gfc_error ("INQUIRE statement not allowed in PURE procedure at %C");
4704 0 : return MATCH_ERROR;
4705 : }
4706 :
4707 92 : gfc_unset_implicit_pure (NULL);
4708 :
4709 92 : new_st.block = gfc_get_code (EXEC_IOLENGTH);
4710 92 : terminate_io (code);
4711 92 : new_st.block->next = code;
4712 92 : return MATCH_YES;
4713 : }
4714 :
4715 : /* At this point, we have the non-IOLENGTH inquire statement. */
4716 2512 : for (;;)
4717 : {
4718 2512 : if (gfc_match_char (')') == MATCH_YES)
4719 : break;
4720 1669 : if (gfc_match_char (',') != MATCH_YES)
4721 0 : goto syntax;
4722 :
4723 1669 : m = match_inquire_element (inquire);
4724 1669 : if (m == MATCH_ERROR)
4725 2 : goto cleanup;
4726 1667 : if (m == MATCH_NO)
4727 0 : goto syntax;
4728 :
4729 1667 : if (inquire->iolength != NULL)
4730 : {
4731 0 : gfc_error ("IOLENGTH tag invalid in INQUIRE statement at %C");
4732 0 : goto cleanup;
4733 : }
4734 : }
4735 :
4736 843 : if (gfc_match_eos () != MATCH_YES)
4737 0 : goto syntax;
4738 :
4739 843 : if (inquire->unit != NULL && inquire->file != NULL)
4740 : {
4741 2 : gfc_error ("INQUIRE statement at %L cannot contain both FILE and "
4742 : "UNIT specifiers", &loc);
4743 2 : goto cleanup;
4744 : }
4745 :
4746 841 : if (inquire->unit == NULL && inquire->file == NULL)
4747 : {
4748 1 : gfc_error ("INQUIRE statement at %L requires either FILE or "
4749 : "UNIT specifier", &loc);
4750 1 : goto cleanup;
4751 : }
4752 :
4753 840 : if (inquire->unit != NULL && inquire->unit->expr_type == EXPR_CONSTANT
4754 524 : && inquire->unit->ts.type == BT_INTEGER
4755 524 : && ((mpz_get_si (inquire->unit->value.integer) == GFC_INTERNAL_UNIT4)
4756 523 : || (mpz_get_si (inquire->unit->value.integer) == GFC_INTERNAL_UNIT)))
4757 : {
4758 2 : gfc_error ("UNIT number in INQUIRE statement at %L cannot "
4759 : "be %d", &loc, (int) mpz_get_si (inquire->unit->value.integer));
4760 2 : goto cleanup;
4761 : }
4762 :
4763 838 : if (gfc_pure (NULL))
4764 : {
4765 0 : gfc_error ("INQUIRE statement not allowed in PURE procedure at %C");
4766 0 : goto cleanup;
4767 : }
4768 :
4769 838 : gfc_unset_implicit_pure (NULL);
4770 :
4771 838 : if (inquire->id != NULL && inquire->pending == NULL)
4772 : {
4773 0 : gfc_error ("INQUIRE statement at %L requires a PENDING= specifier with "
4774 : "the ID= specifier", &loc);
4775 0 : goto cleanup;
4776 : }
4777 :
4778 838 : new_st.op = EXEC_INQUIRE;
4779 838 : new_st.ext.inquire = inquire;
4780 838 : return MATCH_YES;
4781 :
4782 0 : syntax:
4783 0 : gfc_syntax_error (ST_INQUIRE);
4784 :
4785 8 : cleanup:
4786 8 : gfc_free_inquire (inquire);
4787 8 : return MATCH_ERROR;
4788 : }
4789 :
4790 :
4791 : /* Resolve everything in a gfc_inquire structure. */
4792 :
4793 : bool
4794 930 : gfc_resolve_inquire (gfc_inquire *inquire)
4795 : {
4796 930 : RESOLVE_TAG (&tag_unit, inquire->unit);
4797 930 : RESOLVE_TAG (&tag_file, inquire->file);
4798 929 : RESOLVE_TAG (&tag_id, inquire->id);
4799 :
4800 : /* For INQUIRE, all tags except FILE, ID and UNIT are variable definition
4801 : contexts. Thus, use an extended RESOLVE_TAG macro for that. */
4802 : #define INQUIRE_RESOLVE_TAG(tag, expr) \
4803 : RESOLVE_TAG (tag, expr); \
4804 : if (expr) \
4805 : { \
4806 : char context[64]; \
4807 : sprintf (context, _("%s tag with INQUIRE"), (tag)->name); \
4808 : if (gfc_check_vardef_context ((expr), false, false, false, \
4809 : context) == false) \
4810 : return false; \
4811 : gfc_expr_set_at (expr, &expr->where, VALUE_VARDEF); \
4812 : }
4813 929 : INQUIRE_RESOLVE_TAG (&tag_iomsg, inquire->iomsg);
4814 917 : INQUIRE_RESOLVE_TAG (&tag_iostat, inquire->iostat);
4815 916 : INQUIRE_RESOLVE_TAG (&tag_exist, inquire->exist);
4816 914 : INQUIRE_RESOLVE_TAG (&tag_opened, inquire->opened);
4817 912 : INQUIRE_RESOLVE_TAG (&tag_number, inquire->number);
4818 910 : INQUIRE_RESOLVE_TAG (&tag_named, inquire->named);
4819 908 : INQUIRE_RESOLVE_TAG (&tag_name, inquire->name);
4820 907 : INQUIRE_RESOLVE_TAG (&tag_s_access, inquire->access);
4821 906 : INQUIRE_RESOLVE_TAG (&tag_sequential, inquire->sequential);
4822 905 : INQUIRE_RESOLVE_TAG (&tag_direct, inquire->direct);
4823 904 : INQUIRE_RESOLVE_TAG (&tag_s_form, inquire->form);
4824 903 : INQUIRE_RESOLVE_TAG (&tag_formatted, inquire->formatted);
4825 901 : INQUIRE_RESOLVE_TAG (&tag_unformatted, inquire->unformatted);
4826 900 : INQUIRE_RESOLVE_TAG (&tag_s_recl, inquire->recl);
4827 899 : INQUIRE_RESOLVE_TAG (&tag_nextrec, inquire->nextrec);
4828 898 : INQUIRE_RESOLVE_TAG (&tag_s_blank, inquire->blank);
4829 897 : INQUIRE_RESOLVE_TAG (&tag_s_position, inquire->position);
4830 896 : INQUIRE_RESOLVE_TAG (&tag_s_action, inquire->action);
4831 895 : INQUIRE_RESOLVE_TAG (&tag_read, inquire->read);
4832 894 : INQUIRE_RESOLVE_TAG (&tag_write, inquire->write);
4833 893 : INQUIRE_RESOLVE_TAG (&tag_readwrite, inquire->readwrite);
4834 892 : INQUIRE_RESOLVE_TAG (&tag_s_delim, inquire->delim);
4835 891 : INQUIRE_RESOLVE_TAG (&tag_s_pad, inquire->pad);
4836 890 : INQUIRE_RESOLVE_TAG (&tag_s_encoding, inquire->encoding);
4837 888 : INQUIRE_RESOLVE_TAG (&tag_s_round, inquire->round);
4838 887 : INQUIRE_RESOLVE_TAG (&tag_iolength, inquire->iolength);
4839 885 : INQUIRE_RESOLVE_TAG (&tag_convert, inquire->convert);
4840 885 : INQUIRE_RESOLVE_TAG (&tag_strm_out, inquire->strm_pos);
4841 885 : INQUIRE_RESOLVE_TAG (&tag_s_async, inquire->asynchronous);
4842 884 : INQUIRE_RESOLVE_TAG (&tag_s_sign, inquire->sign);
4843 883 : INQUIRE_RESOLVE_TAG (&tag_s_round, inquire->round);
4844 883 : INQUIRE_RESOLVE_TAG (&tag_pending, inquire->pending);
4845 881 : INQUIRE_RESOLVE_TAG (&tag_size, inquire->size);
4846 881 : INQUIRE_RESOLVE_TAG (&tag_s_decimal, inquire->decimal);
4847 880 : INQUIRE_RESOLVE_TAG (&tag_s_iqstream, inquire->iqstream);
4848 880 : INQUIRE_RESOLVE_TAG (&tag_v_share, inquire->share);
4849 880 : INQUIRE_RESOLVE_TAG (&tag_v_cc, inquire->cc);
4850 : #undef INQUIRE_RESOLVE_TAG
4851 :
4852 880 : if (!gfc_reference_st_label (inquire->err, ST_LABEL_TARGET))
4853 : return false;
4854 :
4855 : return true;
4856 : }
4857 :
4858 :
4859 : void
4860 89 : gfc_free_wait (gfc_wait *wait)
4861 : {
4862 89 : if (wait == NULL)
4863 : return;
4864 :
4865 89 : gfc_free_expr (wait->unit);
4866 89 : gfc_free_expr (wait->iostat);
4867 89 : gfc_free_expr (wait->iomsg);
4868 89 : gfc_free_expr (wait->id);
4869 89 : free (wait);
4870 : }
4871 :
4872 :
4873 : bool
4874 89 : gfc_resolve_wait (gfc_wait *wait)
4875 : {
4876 89 : RESOLVE_TAG (&tag_unit, wait->unit);
4877 89 : RESOLVE_TAG (&tag_iomsg, wait->iomsg);
4878 74 : RESOLVE_TAG (&tag_iostat, wait->iostat);
4879 74 : RESOLVE_TAG (&tag_id, wait->id);
4880 :
4881 74 : if (!gfc_reference_st_label (wait->err, ST_LABEL_TARGET))
4882 : return false;
4883 :
4884 74 : if (!gfc_reference_st_label (wait->end, ST_LABEL_TARGET))
4885 : return false;
4886 :
4887 : return true;
4888 : }
4889 :
4890 : /* Match an element of a WAIT statement. */
4891 :
4892 : #define RETM if (m != MATCH_NO) return m;
4893 :
4894 : static match
4895 166 : match_wait_element (gfc_wait *wait)
4896 : {
4897 166 : match m;
4898 :
4899 166 : m = match_etag (&tag_unit, &wait->unit);
4900 166 : RETM m = match_ltag (&tag_err, &wait->err);
4901 153 : RETM m = match_ltag (&tag_end, &wait->end);
4902 146 : RETM m = match_ltag (&tag_eor, &wait->eor);
4903 139 : RETM m = match_etag (&tag_iomsg, &wait->iomsg);
4904 139 : RETM m = match_out_tag (&tag_iostat, &wait->iostat);
4905 110 : RETM m = match_etag (&tag_id, &wait->id);
4906 89 : RETM return MATCH_NO;
4907 : }
4908 :
4909 : #undef RETM
4910 :
4911 :
4912 : match
4913 89 : gfc_match_wait (void)
4914 : {
4915 89 : gfc_wait *wait;
4916 89 : match m;
4917 :
4918 89 : m = gfc_match_char ('(');
4919 89 : if (m == MATCH_NO)
4920 : return m;
4921 :
4922 89 : wait = XCNEW (gfc_wait);
4923 :
4924 89 : m = match_wait_element (wait);
4925 89 : if (m == MATCH_ERROR)
4926 0 : goto cleanup;
4927 89 : if (m == MATCH_NO)
4928 : {
4929 76 : m = gfc_match_expr (&wait->unit);
4930 76 : if (m == MATCH_ERROR)
4931 0 : goto cleanup;
4932 76 : if (m == MATCH_NO)
4933 0 : goto syntax;
4934 : }
4935 :
4936 166 : for (;;)
4937 : {
4938 166 : if (gfc_match_char (')') == MATCH_YES)
4939 : break;
4940 77 : if (gfc_match_char (',') != MATCH_YES)
4941 0 : goto syntax;
4942 :
4943 77 : m = match_wait_element (wait);
4944 77 : if (m == MATCH_ERROR)
4945 0 : goto cleanup;
4946 77 : if (m == MATCH_NO)
4947 0 : goto syntax;
4948 : }
4949 :
4950 89 : if (!gfc_notify_std (GFC_STD_F2003, "WAIT at %C "
4951 : "not allowed in Fortran 95"))
4952 0 : goto cleanup;
4953 :
4954 89 : if (gfc_pure (NULL))
4955 : {
4956 0 : gfc_error ("WAIT statement not allowed in PURE procedure at %C");
4957 0 : goto cleanup;
4958 : }
4959 :
4960 89 : gfc_unset_implicit_pure (NULL);
4961 :
4962 89 : new_st.op = EXEC_WAIT;
4963 89 : new_st.ext.wait = wait;
4964 :
4965 89 : return MATCH_YES;
4966 :
4967 0 : syntax:
4968 0 : gfc_syntax_error (ST_WAIT);
4969 :
4970 0 : cleanup:
4971 0 : gfc_free_wait (wait);
4972 0 : return MATCH_ERROR;
4973 : }
|