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