Line data Source code
1 : /* Matching subroutines in all sizes, shapes and colors.
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 :
29 : int gfc_matching_ptr_assignment = 0;
30 : int gfc_matching_procptr_assignment = 0;
31 : bool gfc_matching_prefix = false;
32 :
33 : /* Stack of SELECT TYPE statements. */
34 : gfc_select_type_stack *select_type_stack = NULL;
35 :
36 : /* List of type parameter expressions. */
37 : gfc_actual_arglist *type_param_spec_list;
38 :
39 : /* For debugging and diagnostic purposes. Return the textual representation
40 : of the intrinsic operator OP. */
41 : const char *
42 9199284 : gfc_op2string (gfc_intrinsic_op op)
43 : {
44 9199284 : switch (op)
45 : {
46 : case INTRINSIC_UPLUS:
47 : case INTRINSIC_PLUS:
48 : return "+";
49 :
50 707463 : case INTRINSIC_UMINUS:
51 707463 : case INTRINSIC_MINUS:
52 707463 : return "-";
53 :
54 353612 : case INTRINSIC_POWER:
55 353612 : return "**";
56 353611 : case INTRINSIC_CONCAT:
57 353611 : return "//";
58 354081 : case INTRINSIC_TIMES:
59 354081 : return "*";
60 353612 : case INTRINSIC_DIVIDE:
61 353612 : return "/";
62 :
63 353740 : case INTRINSIC_AND:
64 353740 : return ".and.";
65 354437 : case INTRINSIC_OR:
66 354437 : return ".or.";
67 353729 : case INTRINSIC_EQV:
68 353729 : return ".eqv.";
69 353726 : case INTRINSIC_NEQV:
70 353726 : return ".neqv.";
71 :
72 353632 : case INTRINSIC_EQ_OS:
73 353632 : return ".eq.";
74 353634 : case INTRINSIC_EQ:
75 353634 : return "==";
76 353632 : case INTRINSIC_NE_OS:
77 353632 : return ".ne.";
78 353620 : case INTRINSIC_NE:
79 353620 : return "/=";
80 353623 : case INTRINSIC_GE_OS:
81 353623 : return ".ge.";
82 353617 : case INTRINSIC_GE:
83 353617 : return ">=";
84 353624 : case INTRINSIC_LE_OS:
85 353624 : return ".le.";
86 353617 : case INTRINSIC_LE:
87 353617 : return "<=";
88 353669 : case INTRINSIC_LT_OS:
89 353669 : return ".lt.";
90 353641 : case INTRINSIC_LT:
91 353641 : return "<";
92 353632 : case INTRINSIC_GT_OS:
93 353632 : return ".gt.";
94 353617 : case INTRINSIC_GT:
95 353617 : return ">";
96 353610 : case INTRINSIC_NOT:
97 353610 : return ".not.";
98 :
99 877 : case INTRINSIC_ASSIGN:
100 877 : return "=";
101 :
102 353610 : case INTRINSIC_PARENTHESES:
103 353610 : return "parens";
104 :
105 1 : case INTRINSIC_NONE:
106 1 : return "none";
107 :
108 : /* DTIO */
109 0 : case INTRINSIC_FORMATTED:
110 0 : return "formatted";
111 0 : case INTRINSIC_UNFORMATTED:
112 0 : return "unformatted";
113 :
114 0 : default:
115 0 : break;
116 : }
117 :
118 0 : gfc_internal_error ("gfc_op2string(): Bad code");
119 : /* Not reached. */
120 : }
121 :
122 :
123 : /******************** Generic matching subroutines ************************/
124 :
125 : /* Matches a member separator. With standard FORTRAN this is '%', but with
126 : DEC structures we must carefully match dot ('.').
127 : Because operators are spelled ".op.", a dotted string such as "x.y.z..."
128 : can be either a component reference chain or a combination of binary
129 : operations.
130 : There is no real way to win because the string may be grammatically
131 : ambiguous. The following rules help avoid ambiguities - they match
132 : some behavior of other (older) compilers. If the rules here are changed
133 : the test cases should be updated. If the user has problems with these rules
134 : they probably deserve the consequences. Consider "x.y.z":
135 : (1) If any user defined operator ".y." exists, this is always y(x,z)
136 : (even if ".y." is the wrong type and/or x has a member y).
137 : (2) Otherwise if x has a member y, and y is itself a derived type,
138 : this is (x->y)->z, even if an intrinsic operator exists which
139 : can handle (x,z).
140 : (3) If x has no member y or (x->y) is not a derived type but ".y."
141 : is an intrinsic operator (such as ".eq."), this is y(x,z).
142 : (4) Lastly if there is no operator ".y." and x has no member "y", it is an
143 : error.
144 : It is worth noting that the logic here does not support mixed use of member
145 : accessors within a single string. That is, even if x has component y and y
146 : has component z, the following are all syntax errors:
147 : "x%y.z" "x.y%z" "(x.y).z" "(x%y)%z"
148 : */
149 :
150 : match
151 8289846 : gfc_match_member_sep(gfc_symbol *sym)
152 : {
153 8289846 : char name[GFC_MAX_SYMBOL_LEN + 1];
154 8289846 : locus dot_loc, start_loc;
155 8289846 : gfc_intrinsic_op iop;
156 8289846 : match m;
157 8289846 : gfc_symbol *tsym;
158 8289846 : gfc_component *c = NULL;
159 :
160 : /* What a relief: '%' is an unambiguous member separator. */
161 8289846 : if (gfc_match_char ('%') == MATCH_YES)
162 : return MATCH_YES;
163 :
164 : /* Beware ye who enter here. */
165 8105949 : if (!flag_dec_structure || !sym)
166 : return MATCH_NO;
167 :
168 66707 : tsym = NULL;
169 :
170 : /* We may be given either a derived type variable or the derived type
171 : declaration itself (which actually contains the components);
172 : we need the latter to search for components. */
173 66707 : if (gfc_fl_struct (sym->attr.flavor))
174 : tsym = sym;
175 66307 : else if (gfc_bt_struct (sym->ts.type))
176 2726 : tsym = sym->ts.u.derived;
177 :
178 66707 : iop = INTRINSIC_NONE;
179 66707 : name[0] = '\0';
180 66707 : m = MATCH_NO;
181 :
182 : /* If we have to reject come back here later. */
183 66707 : start_loc = gfc_current_locus;
184 :
185 : /* Look for a component access next. */
186 66707 : if (gfc_match_char ('.') != MATCH_YES)
187 : return MATCH_NO;
188 :
189 : /* If we accept, come back here. */
190 7865 : dot_loc = gfc_current_locus;
191 :
192 : /* Try to match a symbol name following the dot. */
193 7865 : if (gfc_match_name (name) != MATCH_YES)
194 : {
195 1 : gfc_error ("Expected structure component or operator name "
196 : "after %<.%> at %C");
197 1 : goto error;
198 : }
199 :
200 : /* If no dot follows we have "x.y" which should be a component access. */
201 7864 : if (gfc_match_char ('.') != MATCH_YES)
202 1658 : goto yes;
203 :
204 : /* Now we have a string "x.y.z" which could be a nested member access
205 : (x->y)->z or a binary operation y on x and z. */
206 :
207 : /* First use any user-defined operators ".y." */
208 6206 : if (gfc_find_uop (name, sym->ns) != NULL)
209 6 : goto no;
210 :
211 : /* Match accesses to existing derived-type components for
212 : derived-type vars: "x.y.z" = (x->y)->z */
213 6200 : c = gfc_find_component(tsym, name, false, true, NULL);
214 6200 : if (c && (gfc_bt_struct (c->ts.type) || c->ts.type == BT_CLASS))
215 314 : goto yes;
216 :
217 : /* If y is not a component or has no members, try intrinsic operators. */
218 5886 : gfc_current_locus = start_loc;
219 5886 : if (gfc_match_intrinsic_op (&iop) != MATCH_YES)
220 : {
221 : /* If ".y." is not an intrinsic operator but y was a valid non-
222 : structure component, match and leave the trailing dot to be
223 : dealt with later. */
224 877 : if (c)
225 877 : goto yes;
226 :
227 0 : gfc_error ("%qs is neither a defined operator nor a "
228 : "structure component in dotted string at %C", name);
229 0 : goto error;
230 : }
231 :
232 : /* .y. is an intrinsic operator, overriding any possible member access. */
233 5009 : goto no;
234 :
235 : /* Return keeping the current locus consistent with the match result. */
236 : error:
237 : m = MATCH_ERROR;
238 5016 : no:
239 5016 : gfc_current_locus = start_loc;
240 5016 : return m;
241 2849 : yes:
242 2849 : gfc_current_locus = dot_loc;
243 2849 : return MATCH_YES;
244 : }
245 :
246 :
247 : /* This function scans the current statement counting the opened and closed
248 : parenthesis to make sure they are balanced. */
249 :
250 : match
251 383812 : gfc_match_parens (void)
252 : {
253 383812 : locus old_loc, where;
254 383812 : int count;
255 383812 : gfc_instring instring;
256 383812 : gfc_char_t c, quote;
257 :
258 383812 : old_loc = gfc_current_locus;
259 383812 : count = 0;
260 383812 : instring = NONSTRING;
261 383812 : quote = ' ';
262 :
263 14742359 : for (;;)
264 : {
265 14742359 : if (count > 0)
266 8246486 : where = gfc_current_locus;
267 14742359 : c = gfc_next_char_literal (instring);
268 14742359 : if (c == '\n')
269 : break;
270 14358547 : if (quote == ' ' && ((c == '\'') || (c == '"')))
271 : {
272 58371 : quote = c;
273 58371 : instring = INSTRING_WARN;
274 58371 : continue;
275 : }
276 14300176 : if (quote != ' ' && c == quote)
277 : {
278 58371 : quote = ' ';
279 58371 : instring = NONSTRING;
280 58371 : continue;
281 : }
282 :
283 14241805 : if (c == '(' && quote == ' ')
284 : {
285 687090 : count++;
286 : }
287 14241805 : if (c == ')' && quote == ' ')
288 : {
289 687084 : count--;
290 687084 : where = gfc_current_locus;
291 : }
292 : }
293 :
294 383812 : gfc_current_locus = old_loc;
295 :
296 383812 : if (count != 0)
297 : {
298 10 : gfc_error ("Missing %qs in statement at or before %L",
299 : count > 0? ")":"(", &where);
300 10 : return MATCH_ERROR;
301 : }
302 :
303 : return MATCH_YES;
304 : }
305 :
306 :
307 : /* See if the next character is a special character that has
308 : escaped by a \ via the -fbackslash option. */
309 :
310 : match
311 12228 : gfc_match_special_char (gfc_char_t *res)
312 : {
313 12228 : int len, i;
314 12228 : gfc_char_t c, n;
315 12228 : match m;
316 :
317 12228 : m = MATCH_YES;
318 :
319 12228 : switch ((c = gfc_next_char_literal (INSTRING_WARN)))
320 : {
321 0 : case 'a':
322 0 : *res = '\a';
323 0 : break;
324 372 : case 'b':
325 372 : *res = '\b';
326 372 : break;
327 96 : case 't':
328 96 : *res = '\t';
329 96 : break;
330 0 : case 'f':
331 0 : *res = '\f';
332 0 : break;
333 36 : case 'n':
334 36 : *res = '\n';
335 36 : break;
336 96 : case 'r':
337 96 : *res = '\r';
338 96 : break;
339 0 : case 'v':
340 0 : *res = '\v';
341 0 : break;
342 48 : case '\\':
343 48 : *res = '\\';
344 48 : break;
345 2644 : case '0':
346 2644 : *res = '\0';
347 2644 : break;
348 :
349 8936 : case 'x':
350 8936 : case 'u':
351 8936 : case 'U':
352 : /* Hexadecimal form of wide characters. */
353 8936 : len = (c == 'x' ? 2 : (c == 'u' ? 4 : 8));
354 8936 : n = 0;
355 34168 : for (i = 0; i < len; i++)
356 : {
357 25232 : char buf[2] = { '\0', '\0' };
358 :
359 25232 : c = gfc_next_char_literal (INSTRING_WARN);
360 25232 : if (!gfc_wide_fits_in_byte (c)
361 25232 : || !gfc_check_digit ((unsigned char) c, 16))
362 0 : return MATCH_NO;
363 :
364 25232 : buf[0] = (unsigned char) c;
365 25232 : n = n << 4;
366 25232 : n += strtol (buf, NULL, 16);
367 : }
368 8936 : *res = n;
369 8936 : break;
370 :
371 : default:
372 : /* Unknown backslash codes are simply not expanded. */
373 : m = MATCH_NO;
374 : break;
375 : }
376 :
377 : return m;
378 : }
379 :
380 :
381 : /* In free form, match at least one space. Always matches in fixed
382 : form. */
383 :
384 : match
385 453725 : gfc_match_space (void)
386 : {
387 453725 : locus old_loc;
388 453725 : char c;
389 :
390 453725 : if (gfc_current_form == FORM_FIXED)
391 : return MATCH_YES;
392 :
393 431651 : old_loc = gfc_current_locus;
394 :
395 431651 : c = gfc_next_ascii_char ();
396 431651 : if (!gfc_is_whitespace (c))
397 : {
398 13675 : gfc_current_locus = old_loc;
399 13675 : return MATCH_NO;
400 : }
401 :
402 417976 : gfc_gobble_whitespace ();
403 :
404 417976 : return MATCH_YES;
405 : }
406 :
407 :
408 : /* Match an end of statement. End of statement is optional
409 : whitespace, followed by a ';' or '\n' or comment '!'. If a
410 : semicolon is found, we continue to eat whitespace and semicolons. */
411 :
412 : match
413 3616978 : gfc_match_eos (void)
414 : {
415 3616978 : locus old_loc;
416 3616978 : int flag;
417 3616978 : char c;
418 :
419 3616978 : flag = 0;
420 :
421 3683194 : for (;;)
422 : {
423 3650086 : old_loc = gfc_current_locus;
424 3650086 : gfc_gobble_whitespace ();
425 :
426 3650086 : c = gfc_next_ascii_char ();
427 3650086 : switch (c)
428 : {
429 0 : case '!':
430 0 : do
431 : {
432 0 : c = gfc_next_ascii_char ();
433 : }
434 0 : while (c != '\n');
435 :
436 : /* Fall through. */
437 :
438 : case '\n':
439 : return MATCH_YES;
440 :
441 33108 : case ';':
442 33108 : flag = 1;
443 33108 : continue;
444 : }
445 :
446 2273818 : break;
447 : }
448 :
449 2273818 : gfc_current_locus = old_loc;
450 2273818 : return (flag) ? MATCH_YES : MATCH_NO;
451 : }
452 :
453 :
454 : /* Match a literal integer on the input, setting the value on
455 : MATCH_YES. Literal ints occur in kind-parameters as well as
456 : old-style character length specifications. If cnt is non-NULL it
457 : will be set to the number of digits.
458 : When gobble_ws is false, do not skip over leading blanks. */
459 :
460 : match
461 794407 : gfc_match_small_literal_int (int *value, int *cnt, bool gobble_ws)
462 : {
463 794407 : locus old_loc;
464 794407 : char c;
465 794407 : int i, j;
466 :
467 794407 : old_loc = gfc_current_locus;
468 :
469 794407 : *value = -1;
470 794407 : if (gobble_ws)
471 320540 : gfc_gobble_whitespace ();
472 794407 : c = gfc_next_ascii_char ();
473 794407 : if (cnt)
474 316749 : *cnt = 0;
475 :
476 794407 : if (!ISDIGIT (c))
477 : {
478 401135 : gfc_current_locus = old_loc;
479 401135 : return MATCH_NO;
480 : }
481 :
482 393272 : i = c - '0';
483 393272 : j = 1;
484 :
485 483983 : for (;;)
486 : {
487 483983 : old_loc = gfc_current_locus;
488 483983 : c = gfc_next_ascii_char ();
489 :
490 483983 : if (!ISDIGIT (c))
491 : break;
492 :
493 90711 : i = 10 * i + c - '0';
494 90711 : j++;
495 :
496 90711 : if (i > 99999999)
497 : {
498 0 : gfc_error ("Integer too large at %C");
499 0 : return MATCH_ERROR;
500 : }
501 : }
502 :
503 393272 : gfc_current_locus = old_loc;
504 :
505 393272 : *value = i;
506 393272 : if (cnt)
507 11166 : *cnt = j;
508 : return MATCH_YES;
509 : }
510 :
511 :
512 : /* Match a small, constant integer expression, like in a kind
513 : statement. On MATCH_YES, 'value' is set. */
514 :
515 : match
516 198341 : gfc_match_small_int (int *value)
517 : {
518 198341 : gfc_expr *expr;
519 198341 : match m;
520 198341 : int i;
521 :
522 198341 : m = gfc_match_expr (&expr);
523 198341 : if (m != MATCH_YES)
524 : return m;
525 :
526 198341 : if (gfc_extract_int (expr, &i, 1))
527 1412 : m = MATCH_ERROR;
528 198341 : gfc_free_expr (expr);
529 :
530 198341 : *value = i;
531 198341 : return m;
532 : }
533 :
534 :
535 : /* Matches a statement label. Uses gfc_match_small_literal_int() to
536 : do most of the work. */
537 :
538 : match
539 316745 : gfc_match_st_label (gfc_st_label **label)
540 : {
541 316745 : locus old_loc;
542 316745 : match m;
543 316745 : int i, cnt;
544 :
545 316745 : old_loc = gfc_current_locus;
546 :
547 316745 : m = gfc_match_small_literal_int (&i, &cnt);
548 316745 : if (m != MATCH_YES)
549 : return m;
550 :
551 11164 : if (cnt > 5)
552 : {
553 2 : gfc_error ("Too many digits in statement label at %C");
554 2 : goto cleanup;
555 : }
556 :
557 11162 : if (i == 0)
558 : {
559 2 : gfc_error ("Statement label at %C is zero");
560 2 : goto cleanup;
561 : }
562 :
563 11160 : *label = gfc_get_st_label (i);
564 11160 : return MATCH_YES;
565 :
566 4 : cleanup:
567 :
568 4 : gfc_current_locus = old_loc;
569 4 : return MATCH_ERROR;
570 : }
571 :
572 :
573 : /* Match and validate a label associated with a named IF, DO or SELECT
574 : statement. If the symbol does not have the label attribute, we add
575 : it. We also make sure the symbol does not refer to another
576 : (active) block. A matched label is pointed to by gfc_new_block. */
577 :
578 : static match
579 5861386 : gfc_match_label (void)
580 : {
581 5861386 : char name[GFC_MAX_SYMBOL_LEN + 1];
582 5861386 : match m;
583 :
584 5861386 : gfc_new_block = NULL;
585 :
586 5861386 : m = gfc_match (" %n :", name);
587 5861386 : if (m != MATCH_YES)
588 : return m;
589 :
590 126472 : if (gfc_get_symbol (name, NULL, &gfc_new_block))
591 : {
592 0 : gfc_error ("Label name %qs at %C is ambiguous", name);
593 0 : return MATCH_ERROR;
594 : }
595 :
596 126472 : if (gfc_new_block->attr.flavor == FL_LABEL)
597 : {
598 77 : gfc_error ("Duplicate construct label %qs at %C", name);
599 77 : return MATCH_ERROR;
600 : }
601 :
602 126395 : if (!gfc_add_flavor (&gfc_new_block->attr, FL_LABEL,
603 : gfc_new_block->name, NULL))
604 : return MATCH_ERROR;
605 :
606 : return MATCH_YES;
607 : }
608 :
609 :
610 : /* See if the current input looks like a name of some sort. Modifies
611 : the passed buffer which must be GFC_MAX_SYMBOL_LEN+1 bytes long.
612 : Note that options.cc restricts max_identifier_length to not more
613 : than GFC_MAX_SYMBOL_LEN.
614 : When gobble_ws is false, do not skip over leading blanks. */
615 :
616 : match
617 28578953 : gfc_match_name (char *buffer, bool gobble_ws)
618 : {
619 28578953 : locus old_loc;
620 28578953 : int i;
621 28578953 : char c;
622 :
623 28578953 : old_loc = gfc_current_locus;
624 28578953 : if (gobble_ws)
625 28483905 : gfc_gobble_whitespace ();
626 :
627 28578953 : c = gfc_next_ascii_char ();
628 28578953 : if (!(ISALPHA (c) || (c == '_' && flag_allow_leading_underscore)))
629 : {
630 : /* Special cases for unary minus and plus, which allows for a sensible
631 : error message for code of the form 'c = exp(-a*b) )' where an
632 : extra ')' appears at the end of statement. */
633 1658906 : if (!gfc_error_flag_test () && c != '(' && c != '-' && c != '+')
634 430416 : gfc_error ("Invalid character in name at %C");
635 1658906 : gfc_current_locus = old_loc;
636 1658906 : return MATCH_NO;
637 : }
638 :
639 : i = 0;
640 :
641 123559007 : do
642 : {
643 123559007 : buffer[i++] = c;
644 :
645 123559007 : if (i > gfc_option.max_identifier_length)
646 : {
647 0 : gfc_error ("Name at %C is too long");
648 0 : return MATCH_ERROR;
649 : }
650 :
651 123559007 : old_loc = gfc_current_locus;
652 123559007 : c = gfc_next_ascii_char ();
653 : }
654 123559007 : while (ISALNUM (c) || c == '_' || (flag_dollar_ok && c == '$'));
655 :
656 26920047 : if (c == '$' && !flag_dollar_ok)
657 : {
658 2 : gfc_fatal_error ("Invalid character %<$%> at %L. Use %<-fdollar-ok%> to "
659 : "allow it as an extension", &old_loc);
660 : return MATCH_ERROR;
661 : }
662 :
663 26920045 : buffer[i] = '\0';
664 26920045 : gfc_current_locus = old_loc;
665 :
666 26920045 : return MATCH_YES;
667 : }
668 :
669 :
670 : /* Match a symbol on the input. Modifies the pointer to the symbol
671 : pointer if successful. */
672 :
673 : match
674 4368131 : gfc_match_sym_tree (gfc_symtree **matched_symbol, int host_assoc)
675 : {
676 4368131 : char buffer[GFC_MAX_SYMBOL_LEN + 1];
677 4368131 : match m;
678 4368131 : int ret;
679 :
680 4368131 : locus loc = gfc_current_locus;
681 4368131 : m = gfc_match_name (buffer);
682 4368130 : if (m != MATCH_YES)
683 : return m;
684 4367932 : loc = gfc_get_location_range (NULL, 0, &loc, 1, &gfc_current_locus);
685 4367932 : if (host_assoc)
686 : {
687 2672235 : ret = gfc_get_ha_sym_tree (buffer, matched_symbol, &loc);
688 5344468 : return ret ? MATCH_ERROR : MATCH_YES;
689 : }
690 :
691 1695697 : ret = gfc_get_sym_tree (buffer, NULL, matched_symbol, false, &loc);
692 1695697 : if (ret)
693 30 : return MATCH_ERROR;
694 :
695 : return MATCH_YES;
696 : }
697 :
698 :
699 : match
700 1496793 : gfc_match_symbol (gfc_symbol **matched_symbol, int host_assoc)
701 : {
702 1496793 : gfc_symtree *st;
703 1496793 : match m;
704 :
705 1496793 : m = gfc_match_sym_tree (&st, host_assoc);
706 :
707 1496793 : if (m == MATCH_YES)
708 : {
709 1496592 : if (st)
710 1496592 : *matched_symbol = st->n.sym;
711 : else
712 0 : *matched_symbol = NULL;
713 : }
714 : else
715 201 : *matched_symbol = NULL;
716 1496793 : return m;
717 : }
718 :
719 :
720 : /* Match an intrinsic operator. Returns an INTRINSIC enum. While matching,
721 : we always find INTRINSIC_PLUS before INTRINSIC_UPLUS. We work around this
722 : in matchexp.cc. */
723 :
724 : match
725 82517778 : gfc_match_intrinsic_op (gfc_intrinsic_op *result)
726 : {
727 82517778 : locus orig_loc = gfc_current_locus;
728 82517778 : char ch;
729 :
730 82517778 : gfc_gobble_whitespace ();
731 82517778 : ch = gfc_next_ascii_char ();
732 82517778 : switch (ch)
733 : {
734 350055 : case '+':
735 : /* Matched "+". */
736 350055 : *result = INTRINSIC_PLUS;
737 350055 : return MATCH_YES;
738 :
739 530179 : case '-':
740 : /* Matched "-". */
741 530179 : *result = INTRINSIC_MINUS;
742 530179 : return MATCH_YES;
743 :
744 275136 : case '=':
745 275136 : if (gfc_next_ascii_char () == '=')
746 : {
747 : /* Matched "==". */
748 156039 : *result = INTRINSIC_EQ;
749 156039 : return MATCH_YES;
750 : }
751 : break;
752 :
753 78955 : case '<':
754 78955 : if (gfc_peek_ascii_char () == '=')
755 : {
756 : /* Matched "<=". */
757 33833 : gfc_next_ascii_char ();
758 33833 : *result = INTRINSIC_LE;
759 33833 : return MATCH_YES;
760 : }
761 : /* Matched "<". */
762 45122 : *result = INTRINSIC_LT;
763 45122 : return MATCH_YES;
764 :
765 282638 : case '>':
766 282638 : if (gfc_peek_ascii_char () == '=')
767 : {
768 : /* Matched ">=". */
769 13127 : gfc_next_ascii_char ();
770 13127 : *result = INTRINSIC_GE;
771 13127 : return MATCH_YES;
772 : }
773 : /* Matched ">". */
774 269511 : *result = INTRINSIC_GT;
775 269511 : return MATCH_YES;
776 :
777 275859 : case '*':
778 275859 : if (gfc_peek_ascii_char () == '*')
779 : {
780 : /* Matched "**". */
781 68713 : gfc_next_ascii_char ();
782 68713 : *result = INTRINSIC_POWER;
783 68713 : return MATCH_YES;
784 : }
785 : /* Matched "*". */
786 207146 : *result = INTRINSIC_TIMES;
787 207146 : return MATCH_YES;
788 :
789 5227157 : case '/':
790 5227157 : ch = gfc_peek_ascii_char ();
791 5227157 : if (ch == '=')
792 : {
793 : /* Matched "/=". */
794 4507443 : gfc_next_ascii_char ();
795 4507443 : *result = INTRINSIC_NE;
796 4507443 : return MATCH_YES;
797 : }
798 719714 : else if (ch == '/')
799 : {
800 : /* Matched "//". */
801 33411 : gfc_next_ascii_char ();
802 33411 : *result = INTRINSIC_CONCAT;
803 33411 : return MATCH_YES;
804 : }
805 : /* Matched "/". */
806 686303 : *result = INTRINSIC_DIVIDE;
807 686303 : return MATCH_YES;
808 :
809 4003315 : case '.':
810 4003315 : ch = gfc_next_ascii_char ();
811 4003315 : switch (ch)
812 : {
813 129906 : case 'a':
814 129906 : if (gfc_next_ascii_char () == 'n'
815 128996 : && gfc_next_ascii_char () == 'd'
816 258902 : && gfc_next_ascii_char () == '.')
817 : {
818 : /* Matched ".and.". */
819 128996 : *result = INTRINSIC_AND;
820 128996 : return MATCH_YES;
821 : }
822 : break;
823 :
824 99890 : case 'e':
825 99890 : if (gfc_next_ascii_char () == 'q')
826 : {
827 99806 : ch = gfc_next_ascii_char ();
828 99806 : if (ch == '.')
829 : {
830 : /* Matched ".eq.". */
831 79867 : *result = INTRINSIC_EQ_OS;
832 79867 : return MATCH_YES;
833 : }
834 19939 : else if (ch == 'v')
835 : {
836 19937 : if (gfc_next_ascii_char () == '.')
837 : {
838 : /* Matched ".eqv.". */
839 19937 : *result = INTRINSIC_EQV;
840 19937 : return MATCH_YES;
841 : }
842 : }
843 : }
844 : break;
845 :
846 78013 : case 'g':
847 78013 : ch = gfc_next_ascii_char ();
848 78013 : if (ch == 'e')
849 : {
850 20232 : if (gfc_next_ascii_char () == '.')
851 : {
852 : /* Matched ".ge.". */
853 20154 : *result = INTRINSIC_GE_OS;
854 20154 : return MATCH_YES;
855 : }
856 : }
857 57781 : else if (ch == 't')
858 : {
859 57735 : if (gfc_next_ascii_char () == '.')
860 : {
861 : /* Matched ".gt.". */
862 57735 : *result = INTRINSIC_GT_OS;
863 57735 : return MATCH_YES;
864 : }
865 : }
866 : break;
867 :
868 52626 : case 'l':
869 52626 : ch = gfc_next_ascii_char ();
870 52626 : if (ch == 'e')
871 : {
872 18288 : if (gfc_next_ascii_char () == '.')
873 : {
874 : /* Matched ".le.". */
875 18288 : *result = INTRINSIC_LE_OS;
876 18288 : return MATCH_YES;
877 : }
878 : }
879 34338 : else if (ch == 't')
880 : {
881 34128 : if (gfc_next_ascii_char () == '.')
882 : {
883 : /* Matched ".lt.". */
884 34128 : *result = INTRINSIC_LT_OS;
885 34128 : return MATCH_YES;
886 : }
887 : }
888 : break;
889 :
890 1823169 : case 'n':
891 1823169 : ch = gfc_next_ascii_char ();
892 1823169 : if (ch == 'e')
893 : {
894 1744965 : ch = gfc_next_ascii_char ();
895 1744965 : if (ch == '.')
896 : {
897 : /* Matched ".ne.". */
898 1499740 : *result = INTRINSIC_NE_OS;
899 1499740 : return MATCH_YES;
900 : }
901 245225 : else if (ch == 'q')
902 : {
903 245225 : if (gfc_next_ascii_char () == 'v'
904 245225 : && gfc_next_ascii_char () == '.')
905 : {
906 : /* Matched ".neqv.". */
907 245225 : *result = INTRINSIC_NEQV;
908 245225 : return MATCH_YES;
909 : }
910 : }
911 : }
912 78204 : else if (ch == 'o')
913 : {
914 78201 : if (gfc_next_ascii_char () == 't'
915 78201 : && gfc_next_ascii_char () == '.')
916 : {
917 : /* Matched ".not.". */
918 78156 : *result = INTRINSIC_NOT;
919 78156 : return MATCH_YES;
920 : }
921 : }
922 : break;
923 :
924 1641520 : case 'o':
925 1641520 : if (gfc_next_ascii_char () == 'r'
926 1641520 : && gfc_next_ascii_char () == '.')
927 : {
928 : /* Matched ".or.". */
929 1641291 : *result = INTRINSIC_OR;
930 1641291 : return MATCH_YES;
931 : }
932 : break;
933 :
934 449 : case 'x':
935 449 : if (gfc_next_ascii_char () == 'o'
936 327 : && gfc_next_ascii_char () == 'r'
937 776 : && gfc_next_ascii_char () == '.')
938 : {
939 327 : if (!gfc_notify_std (GFC_STD_LEGACY, ".XOR. operator at %C"))
940 : return MATCH_ERROR;
941 : /* Matched ".xor." - equivalent to ".neqv.". */
942 320 : *result = INTRINSIC_NEQV;
943 320 : return MATCH_YES;
944 : }
945 : break;
946 :
947 : default:
948 : break;
949 : }
950 : break;
951 :
952 : default:
953 : break;
954 : }
955 :
956 71793052 : gfc_current_locus = orig_loc;
957 71793052 : return MATCH_NO;
958 : }
959 :
960 :
961 : /* Match a loop control phrase:
962 :
963 : <LVALUE> = <EXPR>, <EXPR> [, <EXPR> ]
964 :
965 : If the final integer expression is not present, a constant unity
966 : expression is returned. We don't return MATCH_ERROR until after
967 : the equals sign is seen. */
968 :
969 : match
970 43348 : gfc_match_iterator (gfc_iterator *iter, int init_flag)
971 : {
972 43348 : char name[GFC_MAX_SYMBOL_LEN + 1];
973 43348 : gfc_expr *var, *e1, *e2, *e3;
974 43348 : locus start;
975 43348 : match m;
976 :
977 43348 : e1 = e2 = e3 = NULL;
978 :
979 : /* Match the start of an iterator without affecting the symbol table. */
980 :
981 43348 : start = gfc_current_locus;
982 43348 : m = gfc_match (" %n =", name);
983 43348 : gfc_current_locus = start;
984 :
985 43348 : if (m != MATCH_YES)
986 : return MATCH_NO;
987 :
988 41532 : m = gfc_match_variable (&var, 0);
989 41532 : if (m != MATCH_YES)
990 : return MATCH_NO;
991 :
992 41532 : if (var->symtree->n.sym->attr.dimension)
993 : {
994 4 : gfc_error ("Loop variable at %C cannot be an array");
995 4 : goto cleanup;
996 : }
997 :
998 : /* F2008, C617 & C565. */
999 41528 : if (var->symtree->n.sym->attr.codimension)
1000 : {
1001 1 : gfc_error ("Loop variable at %C cannot be a coarray");
1002 1 : goto cleanup;
1003 : }
1004 :
1005 41527 : if (var->ref != NULL)
1006 : {
1007 0 : gfc_error ("Loop variable at %C cannot be a sub-component");
1008 0 : goto cleanup;
1009 : }
1010 :
1011 41527 : gfc_match_char ('=');
1012 :
1013 41527 : var->symtree->n.sym->attr.implied_index = 1;
1014 :
1015 41527 : m = init_flag ? gfc_match_init_expr (&e1) : gfc_match_expr (&e1);
1016 41527 : if (m == MATCH_NO)
1017 0 : goto syntax;
1018 41527 : if (m == MATCH_ERROR)
1019 0 : goto cleanup;
1020 :
1021 41527 : if (gfc_match_char (',') != MATCH_YES)
1022 1 : goto syntax;
1023 :
1024 41526 : m = init_flag ? gfc_match_init_expr (&e2) : gfc_match_expr (&e2);
1025 41526 : if (m == MATCH_NO)
1026 0 : goto syntax;
1027 41526 : if (m == MATCH_ERROR)
1028 0 : goto cleanup;
1029 :
1030 41526 : if (gfc_match_char (',') != MATCH_YES)
1031 : {
1032 37939 : e3 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
1033 37939 : goto done;
1034 : }
1035 :
1036 3587 : m = init_flag ? gfc_match_init_expr (&e3) : gfc_match_expr (&e3);
1037 3587 : if (m == MATCH_ERROR)
1038 0 : goto cleanup;
1039 3587 : if (m == MATCH_NO)
1040 : {
1041 0 : gfc_error ("Expected a step value in iterator at %C");
1042 0 : goto cleanup;
1043 : }
1044 :
1045 3587 : done:
1046 41526 : iter->var = var;
1047 41526 : iter->start = e1;
1048 41526 : iter->end = e2;
1049 41526 : iter->step = e3;
1050 41526 : return MATCH_YES;
1051 :
1052 1 : syntax:
1053 1 : gfc_error ("Syntax error in iterator at %C");
1054 :
1055 6 : cleanup:
1056 6 : gfc_free_expr (e1);
1057 6 : gfc_free_expr (e2);
1058 6 : gfc_free_expr (e3);
1059 :
1060 6 : return MATCH_ERROR;
1061 : }
1062 :
1063 :
1064 : /* Tries to match the next non-whitespace character on the input.
1065 : This subroutine does not return MATCH_ERROR.
1066 : When gobble_ws is false, do not skip over leading blanks. */
1067 :
1068 : match
1069 41867415 : gfc_match_char (char c, bool gobble_ws)
1070 : {
1071 41867415 : locus where;
1072 :
1073 41867415 : where = gfc_current_locus;
1074 41867415 : if (gobble_ws)
1075 37245709 : gfc_gobble_whitespace ();
1076 :
1077 41867415 : if (gfc_next_ascii_char () == c)
1078 : return MATCH_YES;
1079 :
1080 34084505 : gfc_current_locus = where;
1081 34084505 : return MATCH_NO;
1082 : }
1083 :
1084 :
1085 : /* General purpose matching subroutine. The target string is a
1086 : scanf-like format string in which spaces correspond to arbitrary
1087 : whitespace (including no whitespace), characters correspond to
1088 : themselves. The %-codes are:
1089 :
1090 : %% Literal percent sign
1091 : %e Expression, pointer to a pointer is set
1092 : %s Symbol, pointer to the symbol is set (host_assoc = 0)
1093 : %S Symbol, pointer to the symbol is set (host_assoc = 1)
1094 : %n Name, character buffer is set to name
1095 : %t Matches end of statement.
1096 : %o Matches an intrinsic operator, returned as an INTRINSIC enum.
1097 : %l Matches a statement label
1098 : %v Matches a variable expression (an lvalue, except function references
1099 : having a data pointer result)
1100 : % Matches a required space (in free form) and optional spaces. */
1101 :
1102 : match
1103 91979286 : gfc_match (const char *target, ...)
1104 : {
1105 91979286 : gfc_st_label **label;
1106 91979286 : int matches, *ip;
1107 91979286 : locus old_loc;
1108 91979286 : va_list argp;
1109 91979286 : char c, *np;
1110 91979286 : match m, n;
1111 91979286 : void **vp;
1112 91979286 : const char *p;
1113 :
1114 91979286 : old_loc = gfc_current_locus;
1115 91979286 : va_start (argp, target);
1116 91979286 : m = MATCH_NO;
1117 91979286 : matches = 0;
1118 91979286 : p = target;
1119 :
1120 390415675 : loop:
1121 390415675 : c = *p++;
1122 390415675 : switch (c)
1123 : {
1124 115088813 : case ' ':
1125 115088813 : gfc_gobble_whitespace ();
1126 115088813 : goto loop;
1127 : case '\0':
1128 : m = MATCH_YES;
1129 : break;
1130 :
1131 23391679 : case '%':
1132 23391679 : c = *p++;
1133 23391679 : switch (c)
1134 : {
1135 2027020 : case 'e':
1136 2027020 : vp = va_arg (argp, void **);
1137 2027020 : n = gfc_match_expr ((gfc_expr **) vp);
1138 2027019 : if (n != MATCH_YES)
1139 : {
1140 644657 : m = n;
1141 644657 : goto not_yes;
1142 : }
1143 :
1144 1382362 : matches++;
1145 1382362 : goto loop;
1146 :
1147 2782306 : case 'v':
1148 2782306 : vp = va_arg (argp, void **);
1149 2782306 : n = gfc_match_variable ((gfc_expr **) vp, 0);
1150 2782305 : if (n != MATCH_YES)
1151 : {
1152 2970 : m = n;
1153 2970 : goto not_yes;
1154 : }
1155 :
1156 2779335 : matches++;
1157 2779335 : goto loop;
1158 :
1159 30772 : case 's':
1160 30772 : case 'S':
1161 30772 : vp = va_arg (argp, void **);
1162 30772 : n = gfc_match_symbol ((gfc_symbol **) vp, c == 'S');
1163 30772 : if (n != MATCH_YES)
1164 : {
1165 4 : m = n;
1166 4 : goto not_yes;
1167 : }
1168 :
1169 30768 : matches++;
1170 30768 : goto loop;
1171 :
1172 13321182 : case 'n':
1173 13321182 : np = va_arg (argp, char *);
1174 13321182 : n = gfc_match_name (np);
1175 13321182 : if (n != MATCH_YES)
1176 : {
1177 27059 : m = n;
1178 27059 : goto not_yes;
1179 : }
1180 :
1181 13294123 : matches++;
1182 13294123 : goto loop;
1183 :
1184 234341 : case 'l':
1185 234341 : label = va_arg (argp, gfc_st_label **);
1186 234341 : n = gfc_match_st_label (label);
1187 234341 : if (n != MATCH_YES)
1188 : {
1189 232067 : m = n;
1190 232067 : goto not_yes;
1191 : }
1192 :
1193 2274 : matches++;
1194 2274 : goto loop;
1195 :
1196 1721 : case 'o':
1197 1721 : ip = va_arg (argp, int *);
1198 1721 : n = gfc_match_intrinsic_op ((gfc_intrinsic_op *) ip);
1199 1721 : if (n != MATCH_YES)
1200 : {
1201 807 : m = n;
1202 807 : goto not_yes;
1203 : }
1204 :
1205 914 : matches++;
1206 914 : goto loop;
1207 :
1208 379154 : case 't':
1209 379154 : if (gfc_match_eos () != MATCH_YES)
1210 : {
1211 2334 : m = MATCH_NO;
1212 2334 : goto not_yes;
1213 : }
1214 376820 : goto loop;
1215 :
1216 349791 : case ' ':
1217 349791 : if (gfc_match_space () == MATCH_YES)
1218 345594 : goto loop;
1219 4197 : m = MATCH_NO;
1220 4197 : goto not_yes;
1221 :
1222 : case '%':
1223 : break; /* Fall through to character matcher. */
1224 :
1225 0 : default:
1226 0 : gfc_internal_error ("gfc_match(): Bad match code %c", c);
1227 : }
1228 : /* FALLTHRU */
1229 :
1230 237982395 : default:
1231 :
1232 : /* gfc_next_ascii_char converts characters to lower-case, so we shouldn't
1233 : expect an upper case character here! */
1234 237982395 : gcc_assert (TOLOWER (c) == c);
1235 :
1236 237982395 : if (c == gfc_next_ascii_char ())
1237 165135386 : goto loop;
1238 : break;
1239 : }
1240 :
1241 91979284 : not_yes:
1242 91979284 : va_end (argp);
1243 :
1244 91979284 : if (m != MATCH_YES)
1245 : {
1246 : /* Clean up after a failed match. */
1247 73761104 : gfc_current_locus = old_loc;
1248 73761104 : va_start (argp, target);
1249 :
1250 73761104 : p = target;
1251 82130752 : for (; matches > 0; matches--)
1252 : {
1253 17026138 : while (*p++ != '%');
1254 :
1255 8369648 : switch (*p++)
1256 : {
1257 0 : case '%':
1258 0 : matches++;
1259 0 : break; /* Skip. */
1260 :
1261 : /* Matches that don't have to be undone */
1262 5901272 : case 'o':
1263 5901272 : case 'l':
1264 5901272 : case 'n':
1265 5901272 : case 's':
1266 5901272 : (void) va_arg (argp, void **);
1267 5901272 : break;
1268 :
1269 2468376 : case 'e':
1270 2468376 : case 'v':
1271 2468376 : vp = va_arg (argp, void **);
1272 2468376 : gfc_free_expr ((struct gfc_expr *)*vp);
1273 2468376 : *vp = NULL;
1274 2468376 : break;
1275 : }
1276 : }
1277 :
1278 73761104 : va_end (argp);
1279 : }
1280 :
1281 91979284 : return m;
1282 : }
1283 :
1284 :
1285 : /*********************** Statement level matching **********************/
1286 :
1287 : /* Matches the start of a program unit, which is the program keyword
1288 : followed by an obligatory symbol. */
1289 :
1290 : match
1291 19333 : gfc_match_program (void)
1292 : {
1293 19333 : gfc_symbol *sym;
1294 19333 : match m;
1295 :
1296 19333 : m = gfc_match ("% %s%t", &sym);
1297 :
1298 19333 : if (m == MATCH_NO)
1299 : {
1300 0 : gfc_error ("Invalid form of PROGRAM statement at %C");
1301 0 : m = MATCH_ERROR;
1302 : }
1303 :
1304 19333 : if (m == MATCH_ERROR)
1305 0 : return m;
1306 :
1307 19333 : if (!gfc_add_flavor (&sym->attr, FL_PROGRAM, sym->name, NULL))
1308 : return MATCH_ERROR;
1309 :
1310 19333 : gfc_new_block = sym;
1311 :
1312 19333 : return MATCH_YES;
1313 : }
1314 :
1315 :
1316 : /* Match a simple assignment statement. */
1317 :
1318 : match
1319 1531942 : gfc_match_assignment (void)
1320 : {
1321 1531942 : gfc_expr *lvalue, *rvalue;
1322 1531942 : locus old_loc;
1323 1531942 : match m;
1324 :
1325 1531942 : old_loc = gfc_current_locus;
1326 :
1327 1531942 : lvalue = NULL;
1328 1531942 : m = gfc_match (" %v =", &lvalue);
1329 1531941 : if (m != MATCH_YES)
1330 : {
1331 1233208 : gfc_current_locus = old_loc;
1332 1233208 : gfc_free_expr (lvalue);
1333 1233208 : return MATCH_NO;
1334 : }
1335 :
1336 298733 : rvalue = NULL;
1337 298733 : m = gfc_match (" %e%t", &rvalue);
1338 :
1339 298733 : if (m == MATCH_YES
1340 287059 : && rvalue->ts.type == BT_BOZ
1341 4 : && lvalue->ts.type == BT_CLASS)
1342 : {
1343 1 : m = MATCH_ERROR;
1344 1 : gfc_error ("BOZ literal constant at %L is neither a DATA statement "
1345 : "value nor an actual argument of INT/REAL/DBLE/CMPLX "
1346 : "intrinsic subprogram", &rvalue->where);
1347 : }
1348 :
1349 298733 : if (lvalue->expr_type == EXPR_CONSTANT)
1350 : {
1351 : /* This clobbers %len and %kind. */
1352 6 : m = MATCH_ERROR;
1353 6 : gfc_error ("Assignment to a constant expression at %C");
1354 : }
1355 :
1356 298733 : if (m != MATCH_YES)
1357 : {
1358 11680 : gfc_current_locus = old_loc;
1359 11680 : gfc_free_expr (lvalue);
1360 11680 : gfc_free_expr (rvalue);
1361 11680 : return m;
1362 : }
1363 :
1364 287053 : if (!lvalue->symtree)
1365 : {
1366 0 : gfc_free_expr (lvalue);
1367 0 : gfc_free_expr (rvalue);
1368 0 : return MATCH_ERROR;
1369 : }
1370 :
1371 :
1372 287053 : gfc_set_sym_referenced (lvalue->symtree->n.sym);
1373 :
1374 287053 : new_st.op = EXEC_ASSIGN;
1375 287053 : new_st.expr1 = lvalue;
1376 287053 : new_st.expr2 = rvalue;
1377 :
1378 287053 : gfc_check_do_variable (lvalue->symtree);
1379 :
1380 287053 : return MATCH_YES;
1381 : }
1382 :
1383 :
1384 : /* Match a pointer assignment statement. */
1385 :
1386 : match
1387 1244888 : gfc_match_pointer_assignment (void)
1388 : {
1389 1244888 : gfc_expr *lvalue, *rvalue;
1390 1244888 : locus old_loc;
1391 1244888 : match m;
1392 :
1393 1244888 : old_loc = gfc_current_locus;
1394 :
1395 1244888 : lvalue = rvalue = NULL;
1396 1244888 : gfc_matching_ptr_assignment = 0;
1397 1244888 : gfc_matching_procptr_assignment = 0;
1398 :
1399 1244888 : m = gfc_match (" %v =>", &lvalue);
1400 1244888 : if (m != MATCH_YES || !lvalue->symtree)
1401 : {
1402 1235586 : m = MATCH_NO;
1403 1235586 : goto cleanup;
1404 : }
1405 :
1406 9302 : if (lvalue->symtree->n.sym->attr.proc_pointer
1407 9302 : || gfc_is_proc_ptr_comp (lvalue))
1408 1300 : gfc_matching_procptr_assignment = 1;
1409 : else
1410 8002 : gfc_matching_ptr_assignment = 1;
1411 :
1412 9302 : m = gfc_match (" %e%t", &rvalue);
1413 9302 : gfc_matching_ptr_assignment = 0;
1414 9302 : gfc_matching_procptr_assignment = 0;
1415 9302 : if (m != MATCH_YES)
1416 1 : goto cleanup;
1417 :
1418 9301 : new_st.op = EXEC_POINTER_ASSIGN;
1419 9301 : new_st.expr1 = lvalue;
1420 9301 : new_st.expr2 = rvalue;
1421 :
1422 9301 : return MATCH_YES;
1423 :
1424 1235587 : cleanup:
1425 1235587 : gfc_current_locus = old_loc;
1426 1235587 : gfc_free_expr (lvalue);
1427 1235587 : gfc_free_expr (rvalue);
1428 1235587 : return m;
1429 : }
1430 :
1431 :
1432 : /* We try to match an easy arithmetic IF statement. This only happens
1433 : when just after having encountered a simple IF statement. This code
1434 : is really duplicate with parts of the gfc_match_if code, but this is
1435 : *much* easier. */
1436 :
1437 : static match
1438 24 : match_arithmetic_if (void)
1439 : {
1440 24 : gfc_st_label *l1, *l2, *l3;
1441 24 : gfc_expr *expr;
1442 24 : match m;
1443 :
1444 24 : m = gfc_match (" ( %e ) %l , %l , %l%t", &expr, &l1, &l2, &l3);
1445 24 : if (m != MATCH_YES)
1446 : return m;
1447 :
1448 24 : if (!gfc_reference_st_label (l1, ST_LABEL_TARGET)
1449 24 : || !gfc_reference_st_label (l2, ST_LABEL_TARGET)
1450 48 : || !gfc_reference_st_label (l3, ST_LABEL_TARGET))
1451 : {
1452 0 : gfc_free_expr (expr);
1453 0 : return MATCH_ERROR;
1454 : }
1455 :
1456 24 : if (!gfc_notify_std (GFC_STD_F95_OBS | GFC_STD_F2018_DEL,
1457 : "Arithmetic IF statement at %C"))
1458 : return MATCH_ERROR;
1459 :
1460 24 : new_st.op = EXEC_ARITHMETIC_IF;
1461 24 : new_st.expr1 = expr;
1462 24 : new_st.label1 = l1;
1463 24 : new_st.label2 = l2;
1464 24 : new_st.label3 = l3;
1465 :
1466 24 : return MATCH_YES;
1467 : }
1468 :
1469 :
1470 : /* The IF statement is a bit of a pain. First of all, there are three
1471 : forms of it, the simple IF, the IF that starts a block and the
1472 : arithmetic IF.
1473 :
1474 : There is a problem with the simple IF and that is the fact that we
1475 : only have a single level of undo information on symbols. What this
1476 : means is for a simple IF, we must re-match the whole IF statement
1477 : multiple times in order to guarantee that the symbol table ends up
1478 : in the proper state. */
1479 :
1480 : static match match_simple_forall (void);
1481 : static match match_simple_where (void);
1482 :
1483 : match
1484 765450 : gfc_match_if (gfc_statement *if_type)
1485 : {
1486 765450 : gfc_expr *expr;
1487 765450 : gfc_st_label *l1, *l2, *l3;
1488 765450 : locus old_loc, old_loc2;
1489 765450 : gfc_code *p;
1490 765450 : match m, n;
1491 :
1492 765450 : n = gfc_match_label ();
1493 765450 : if (n == MATCH_ERROR)
1494 : return n;
1495 :
1496 765442 : old_loc = gfc_current_locus;
1497 :
1498 765442 : m = gfc_match (" if ", &expr);
1499 765442 : if (m != MATCH_YES)
1500 : return m;
1501 :
1502 232064 : if (gfc_match_char ('(') != MATCH_YES)
1503 : {
1504 3 : gfc_error ("Missing %<(%> in IF-expression at %C");
1505 3 : return MATCH_ERROR;
1506 : }
1507 :
1508 232061 : m = gfc_match ("%e", &expr);
1509 232061 : if (m != MATCH_YES)
1510 : return m;
1511 :
1512 232037 : old_loc2 = gfc_current_locus;
1513 232037 : gfc_current_locus = old_loc;
1514 :
1515 232037 : if (gfc_match_parens () == MATCH_ERROR)
1516 : return MATCH_ERROR;
1517 :
1518 232030 : gfc_current_locus = old_loc2;
1519 :
1520 232030 : if (gfc_match_char (')') != MATCH_YES)
1521 : {
1522 2 : gfc_error ("Syntax error in IF-expression at %C");
1523 2 : gfc_free_expr (expr);
1524 2 : return MATCH_ERROR;
1525 : }
1526 :
1527 232028 : m = gfc_match (" %l , %l , %l%t", &l1, &l2, &l3);
1528 :
1529 232028 : if (m == MATCH_YES)
1530 : {
1531 48 : if (n == MATCH_YES)
1532 : {
1533 0 : gfc_error ("Block label not appropriate for arithmetic IF "
1534 : "statement at %C");
1535 0 : gfc_free_expr (expr);
1536 0 : return MATCH_ERROR;
1537 : }
1538 :
1539 48 : if (!gfc_reference_st_label (l1, ST_LABEL_TARGET)
1540 48 : || !gfc_reference_st_label (l2, ST_LABEL_TARGET)
1541 96 : || !gfc_reference_st_label (l3, ST_LABEL_TARGET))
1542 : {
1543 0 : gfc_free_expr (expr);
1544 0 : return MATCH_ERROR;
1545 : }
1546 :
1547 48 : if (!gfc_notify_std (GFC_STD_F95_OBS | GFC_STD_F2018_DEL,
1548 : "Arithmetic IF statement at %C"))
1549 : return MATCH_ERROR;
1550 :
1551 48 : new_st.op = EXEC_ARITHMETIC_IF;
1552 48 : new_st.expr1 = expr;
1553 48 : new_st.label1 = l1;
1554 48 : new_st.label2 = l2;
1555 48 : new_st.label3 = l3;
1556 :
1557 48 : *if_type = ST_ARITHMETIC_IF;
1558 48 : return MATCH_YES;
1559 : }
1560 :
1561 231980 : if (gfc_match (" then%t") == MATCH_YES)
1562 : {
1563 14854 : new_st.op = EXEC_IF;
1564 14854 : new_st.expr1 = expr;
1565 14854 : *if_type = ST_IF_BLOCK;
1566 14854 : return MATCH_YES;
1567 : }
1568 :
1569 217126 : if (n == MATCH_YES)
1570 : {
1571 0 : gfc_error ("Block label is not appropriate for IF statement at %C");
1572 0 : gfc_free_expr (expr);
1573 0 : return MATCH_ERROR;
1574 : }
1575 :
1576 : /* At this point the only thing left is a simple IF statement. At
1577 : this point, n has to be MATCH_NO, so we don't have to worry about
1578 : re-matching a block label. From what we've got so far, try
1579 : matching an assignment. */
1580 :
1581 217126 : *if_type = ST_SIMPLE_IF;
1582 :
1583 217126 : m = gfc_match_assignment ();
1584 217126 : if (m == MATCH_YES)
1585 4793 : goto got_match;
1586 :
1587 212333 : gfc_free_expr (expr);
1588 212333 : gfc_undo_symbols ();
1589 212333 : gfc_current_locus = old_loc;
1590 :
1591 : /* m can be MATCH_NO or MATCH_ERROR, here. For MATCH_ERROR, a mangled
1592 : assignment was found. For MATCH_NO, continue to call the various
1593 : matchers. */
1594 212333 : if (m == MATCH_ERROR)
1595 : return MATCH_ERROR;
1596 :
1597 212333 : gfc_match (" if ( %e ) ", &expr); /* Guaranteed to match. */
1598 :
1599 212333 : m = gfc_match_pointer_assignment ();
1600 212333 : if (m == MATCH_YES)
1601 68 : goto got_match;
1602 :
1603 212265 : gfc_free_expr (expr);
1604 212265 : gfc_undo_symbols ();
1605 212265 : gfc_current_locus = old_loc;
1606 :
1607 212265 : gfc_match (" if ( %e ) ", &expr); /* Guaranteed to match. */
1608 :
1609 : /* Look at the next keyword to see which matcher to call. Matching
1610 : the keyword doesn't affect the symbol table, so we don't have to
1611 : restore between tries. */
1612 :
1613 : #define match(string, subr, statement) \
1614 : if (gfc_match (string) == MATCH_YES) { m = subr(); goto got_match; }
1615 :
1616 212265 : gfc_clear_error ();
1617 :
1618 212265 : match ("allocate", gfc_match_allocate, ST_ALLOCATE)
1619 212189 : match ("assign", gfc_match_assign, ST_LABEL_ASSIGNMENT)
1620 212187 : match ("backspace", gfc_match_backspace, ST_BACKSPACE)
1621 212181 : match ("call", gfc_match_call, ST_CALL)
1622 211500 : match ("change% team", gfc_match_change_team, ST_CHANGE_TEAM)
1623 211500 : match ("close", gfc_match_close, ST_CLOSE)
1624 211500 : match ("continue", gfc_match_continue, ST_CONTINUE)
1625 211500 : match ("cycle", gfc_match_cycle, ST_CYCLE)
1626 211394 : match ("deallocate", gfc_match_deallocate, ST_DEALLOCATE)
1627 210903 : match ("end file", gfc_match_endfile, ST_END_FILE)
1628 210903 : match ("end team", gfc_match_end_team, ST_END_TEAM)
1629 210903 : match ("error% stop", gfc_match_error_stop, ST_ERROR_STOP)
1630 172736 : match ("event% post", gfc_match_event_post, ST_EVENT_POST)
1631 172736 : match ("event% wait", gfc_match_event_wait, ST_EVENT_WAIT)
1632 172733 : match ("exit", gfc_match_exit, ST_EXIT)
1633 172427 : match ("fail% image", gfc_match_fail_image, ST_FAIL_IMAGE)
1634 172420 : match ("flush", gfc_match_flush, ST_FLUSH)
1635 172420 : match ("forall", match_simple_forall, ST_FORALL)
1636 172414 : match ("form% team", gfc_match_form_team, ST_FORM_TEAM)
1637 172414 : match ("go to", gfc_match_goto, ST_GOTO)
1638 172035 : match ("if", match_arithmetic_if, ST_ARITHMETIC_IF)
1639 172011 : match ("inquire", gfc_match_inquire, ST_INQUIRE)
1640 172011 : match ("lock", gfc_match_lock, ST_LOCK)
1641 172011 : match ("nullify", gfc_match_nullify, ST_NULLIFY)
1642 172011 : match ("open", gfc_match_open, ST_OPEN)
1643 172011 : match ("pause", gfc_match_pause, ST_NONE)
1644 172011 : match ("print", gfc_match_print, ST_WRITE)
1645 171609 : match ("read", gfc_match_read, ST_READ)
1646 171607 : match ("return", gfc_match_return, ST_RETURN)
1647 171218 : match ("rewind", gfc_match_rewind, ST_REWIND)
1648 171218 : match ("stop", gfc_match_stop, ST_STOP)
1649 383 : match ("wait", gfc_match_wait, ST_WAIT)
1650 383 : match ("sync% all", gfc_match_sync_all, ST_SYNC_CALL);
1651 383 : match ("sync% images", gfc_match_sync_images, ST_SYNC_IMAGES);
1652 380 : match ("sync% memory", gfc_match_sync_memory, ST_SYNC_MEMORY);
1653 380 : match ("sync% team", gfc_match_sync_team, ST_SYNC_TEAM)
1654 380 : match ("unlock", gfc_match_unlock, ST_UNLOCK)
1655 377 : match ("where", match_simple_where, ST_WHERE)
1656 370 : match ("write", gfc_match_write, ST_WRITE)
1657 :
1658 6 : if (flag_dec)
1659 1 : match ("type", gfc_match_print, ST_WRITE)
1660 :
1661 : /* All else has failed, so give up. See if any of the matchers has
1662 : stored an error message of some sort. */
1663 5 : if (!gfc_error_check ())
1664 5 : gfc_error ("Syntax error in IF-clause after %C");
1665 :
1666 5 : gfc_free_expr (expr);
1667 5 : return MATCH_ERROR;
1668 :
1669 217121 : got_match:
1670 217121 : if (m == MATCH_NO)
1671 0 : gfc_error ("Syntax error in IF-clause after %C");
1672 217121 : if (m != MATCH_YES)
1673 : {
1674 77 : gfc_free_expr (expr);
1675 77 : return MATCH_ERROR;
1676 : }
1677 :
1678 : /* At this point, we've matched the single IF and the action clause
1679 : is in new_st. Rearrange things so that the IF statement appears
1680 : in new_st. */
1681 :
1682 217044 : p = gfc_get_code (EXEC_IF);
1683 217044 : p->next = XCNEW (gfc_code);
1684 217044 : *p->next = new_st;
1685 217044 : p->next->loc = gfc_current_locus;
1686 :
1687 217044 : p->expr1 = expr;
1688 :
1689 217044 : gfc_clear_new_st ();
1690 :
1691 217044 : new_st.op = EXEC_IF;
1692 217044 : new_st.block = p;
1693 :
1694 217044 : return MATCH_YES;
1695 : }
1696 :
1697 : #undef match
1698 :
1699 :
1700 : /* Match an ELSE statement. */
1701 :
1702 : match
1703 6384 : gfc_match_else (void)
1704 : {
1705 6384 : char name[GFC_MAX_SYMBOL_LEN + 1];
1706 :
1707 6384 : if (gfc_match_eos () == MATCH_YES)
1708 : return MATCH_YES;
1709 :
1710 2259 : if (gfc_match_name (name) != MATCH_YES
1711 2258 : || gfc_current_block () == NULL
1712 2276 : || gfc_match_eos () != MATCH_YES)
1713 : {
1714 2257 : gfc_error ("Invalid character(s) in ELSE statement after %C");
1715 2257 : return MATCH_ERROR;
1716 : }
1717 :
1718 2 : if (strcmp (name, gfc_current_block ()->name) != 0)
1719 : {
1720 1 : gfc_error ("Label %qs at %C doesn't match IF label %qs",
1721 : name, gfc_current_block ()->name);
1722 1 : return MATCH_ERROR;
1723 : }
1724 :
1725 : return MATCH_YES;
1726 : }
1727 :
1728 :
1729 : /* Match an ELSE IF statement. */
1730 :
1731 : match
1732 1942 : gfc_match_elseif (void)
1733 : {
1734 1942 : char name[GFC_MAX_SYMBOL_LEN + 1];
1735 1942 : gfc_expr *expr, *then;
1736 1942 : locus where;
1737 1942 : match m;
1738 :
1739 1942 : if (gfc_match_char ('(') != MATCH_YES)
1740 : {
1741 1 : gfc_error ("Missing %<(%> in ELSE IF expression at %C");
1742 1 : return MATCH_ERROR;
1743 : }
1744 :
1745 1941 : m = gfc_match (" %e ", &expr);
1746 1941 : if (m != MATCH_YES)
1747 : return m;
1748 :
1749 1941 : if (gfc_match_char (')') != MATCH_YES)
1750 : {
1751 1 : gfc_error ("Missing %<)%> in ELSE IF expression at %C");
1752 1 : goto cleanup;
1753 : }
1754 :
1755 1940 : m = gfc_match (" then ", &then);
1756 :
1757 1940 : where = gfc_current_locus;
1758 :
1759 1940 : if (m == MATCH_YES && (gfc_match_eos () == MATCH_YES
1760 3 : || (gfc_current_block ()
1761 2 : && gfc_match_name (name) == MATCH_YES)))
1762 1937 : goto done;
1763 :
1764 3 : if (gfc_match_eos () == MATCH_YES)
1765 : {
1766 1 : gfc_error ("Missing THEN in ELSE IF statement after %L", &where);
1767 1 : goto cleanup;
1768 : }
1769 :
1770 2 : if (gfc_match_name (name) != MATCH_YES
1771 2 : || gfc_current_block () == NULL
1772 3 : || gfc_match_eos () != MATCH_YES)
1773 : {
1774 1 : gfc_error ("Syntax error in ELSE IF statement after %L", &where);
1775 1 : goto cleanup;
1776 : }
1777 :
1778 1 : if (strcmp (name, gfc_current_block ()->name) != 0)
1779 : {
1780 1 : gfc_error ("Label %qs after %L doesn't match IF label %qs",
1781 : name, &where, gfc_current_block ()->name);
1782 1 : goto cleanup;
1783 : }
1784 :
1785 0 : if (m != MATCH_YES)
1786 : return m;
1787 :
1788 0 : done:
1789 1937 : new_st.op = EXEC_IF;
1790 1937 : new_st.expr1 = expr;
1791 1937 : return MATCH_YES;
1792 :
1793 4 : cleanup:
1794 4 : gfc_free_expr (expr);
1795 4 : return MATCH_ERROR;
1796 : }
1797 :
1798 :
1799 : /* Free a gfc_iterator structure. */
1800 :
1801 : void
1802 97983 : gfc_free_iterator (gfc_iterator *iter, int flag)
1803 : {
1804 :
1805 97983 : if (iter == NULL)
1806 : return;
1807 :
1808 55876 : gfc_free_expr (iter->var);
1809 55876 : gfc_free_expr (iter->start);
1810 55876 : gfc_free_expr (iter->end);
1811 55876 : gfc_free_expr (iter->step);
1812 :
1813 55876 : if (flag)
1814 50356 : free (iter);
1815 : }
1816 :
1817 : static match
1818 374 : match_named_arg (const char *pat, const char *name, gfc_expr **e,
1819 : gfc_statement st_code)
1820 : {
1821 374 : match m;
1822 374 : gfc_expr *tmp;
1823 :
1824 374 : m = gfc_match (pat, &tmp);
1825 374 : if (m == MATCH_ERROR)
1826 : {
1827 0 : gfc_syntax_error (st_code);
1828 0 : return m;
1829 : }
1830 374 : if (m == MATCH_YES)
1831 : {
1832 194 : if (*e)
1833 : {
1834 13 : gfc_error ("Duplicate %s attribute in %C", name);
1835 13 : gfc_free_expr (tmp);
1836 13 : return MATCH_ERROR;
1837 : }
1838 181 : *e = tmp;
1839 :
1840 181 : return MATCH_YES;
1841 : }
1842 : return MATCH_NO;
1843 : }
1844 :
1845 : static match
1846 196 : match_stat_errmsg (struct sync_stat *sync_stat, gfc_statement st_code)
1847 : {
1848 196 : match m;
1849 :
1850 196 : m = match_named_arg (" stat = %v", "STAT", &sync_stat->stat, st_code);
1851 196 : if (m != MATCH_NO)
1852 : return m;
1853 :
1854 97 : m = match_named_arg (" errmsg = %v", "ERRMSG", &sync_stat->errmsg, st_code);
1855 97 : return m;
1856 : }
1857 :
1858 : /* Match a CRITICAL statement. */
1859 : match
1860 495106 : gfc_match_critical (void)
1861 : {
1862 495106 : gfc_st_label *label = NULL;
1863 495106 : match m;
1864 :
1865 495106 : if (gfc_match_label () == MATCH_ERROR)
1866 : return MATCH_ERROR;
1867 :
1868 495098 : if (gfc_match (" critical") != MATCH_YES)
1869 : return MATCH_NO;
1870 :
1871 61 : if (gfc_match_st_label (&label) == MATCH_ERROR)
1872 : return MATCH_ERROR;
1873 :
1874 61 : if (gfc_match_eos () == MATCH_YES)
1875 43 : goto done;
1876 :
1877 18 : if (gfc_match_char ('(') != MATCH_YES)
1878 1 : goto syntax;
1879 :
1880 49 : for (;;)
1881 : {
1882 33 : m = match_stat_errmsg (&new_st.ext.sync_stat, ST_CRITICAL);
1883 33 : if (m == MATCH_ERROR)
1884 2 : goto cleanup;
1885 :
1886 31 : if (gfc_match_char (',') == MATCH_YES)
1887 16 : continue;
1888 :
1889 15 : break;
1890 : }
1891 :
1892 15 : if (gfc_match (" )%t") != MATCH_YES)
1893 0 : goto syntax;
1894 :
1895 15 : done:
1896 :
1897 58 : if (gfc_pure (NULL))
1898 : {
1899 1 : gfc_error ("Image control statement CRITICAL at %C in PURE procedure");
1900 1 : return MATCH_ERROR;
1901 : }
1902 :
1903 57 : if (gfc_find_state (COMP_DO_CONCURRENT))
1904 : {
1905 1 : gfc_error ("Image control statement CRITICAL at %C in DO CONCURRENT "
1906 : "block");
1907 1 : return MATCH_ERROR;
1908 : }
1909 :
1910 56 : gfc_unset_implicit_pure (NULL);
1911 :
1912 56 : if (!gfc_notify_std (GFC_STD_F2008, "CRITICAL statement at %C"))
1913 : return MATCH_ERROR;
1914 :
1915 55 : if (flag_coarray == GFC_FCOARRAY_NONE)
1916 : {
1917 0 : gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to "
1918 : "enable");
1919 : return MATCH_ERROR;
1920 : }
1921 :
1922 55 : if (gfc_find_state (COMP_CRITICAL))
1923 : {
1924 1 : gfc_error ("Nested CRITICAL block at %C");
1925 1 : return MATCH_ERROR;
1926 : }
1927 :
1928 54 : new_st.op = EXEC_CRITICAL;
1929 :
1930 54 : if (label != NULL && !gfc_reference_st_label (label, ST_LABEL_TARGET))
1931 0 : goto cleanup;
1932 :
1933 : return MATCH_YES;
1934 :
1935 1 : syntax:
1936 1 : gfc_syntax_error (ST_CRITICAL);
1937 :
1938 3 : cleanup:
1939 3 : gfc_free_expr (new_st.ext.sync_stat.stat);
1940 3 : gfc_free_expr (new_st.ext.sync_stat.errmsg);
1941 3 : new_st.ext.sync_stat = {NULL, NULL};
1942 :
1943 3 : return MATCH_ERROR;
1944 : }
1945 :
1946 : /* Match a BLOCK statement. */
1947 :
1948 : match
1949 498119 : gfc_match_block (void)
1950 : {
1951 498119 : match m;
1952 :
1953 498119 : if (gfc_match_label () == MATCH_ERROR)
1954 : return MATCH_ERROR;
1955 :
1956 498111 : if (gfc_match (" block") != MATCH_YES)
1957 : return MATCH_NO;
1958 :
1959 : /* For this to be a correct BLOCK statement, the line must end now. */
1960 1481 : m = gfc_match_eos ();
1961 1481 : if (m == MATCH_ERROR)
1962 : return MATCH_ERROR;
1963 1481 : if (m == MATCH_NO)
1964 : return MATCH_NO;
1965 :
1966 : return MATCH_YES;
1967 : }
1968 :
1969 : bool
1970 16 : check_coarray_assoc (const char *name, gfc_association_list *assoc)
1971 : {
1972 16 : if (assoc->target->expr_type == EXPR_VARIABLE
1973 16 : && !strcmp (assoc->target->symtree->name, name))
1974 : {
1975 3 : gfc_error ("Codimension decl name %qs in association at %L "
1976 : "must not be the same as a selector",
1977 : name, &assoc->where);
1978 3 : return false;
1979 : }
1980 : return true;
1981 : }
1982 :
1983 : /* Try to resolve an EXPR_FUNCTION operand so its return type is known.
1984 : Called during ASSOCIATE selector parsing, before type-bound operator
1985 : extension, when the operand is an unresolved generic constructor call
1986 : such as `scalar_1D_t(initializer, order=2, ...)`. Errors are suppressed
1987 : since we are still in the parsing phase. */
1988 :
1989 : static void
1990 64 : resolve_assoc_operand (gfc_expr *e)
1991 : {
1992 64 : if (!e || e->ts.type != BT_UNKNOWN || e->expr_type != EXPR_FUNCTION)
1993 : return;
1994 :
1995 : /* First, try full expression resolution (works when argument types are
1996 : already known at parse time). */
1997 0 : gfc_push_suppress_errors ();
1998 0 : gfc_resolve_expr (e);
1999 0 : gfc_pop_suppress_errors ();
2000 :
2001 0 : if (e->ts.type != BT_UNKNOWN)
2002 : return;
2003 :
2004 : /* Fallback for generic constructor interfaces such as
2005 : scalar_1D_t(initializer, order=2, cells=16, x_min=0D0, x_max=5D0)
2006 : where full argument resolution is not possible at parse time.
2007 : If the function name resolves to a generic interface that wraps a
2008 : derived type (a constructor interface), infer the return type as
2009 : that derived type. */
2010 0 : if (!e->symtree || !e->symtree->n.sym)
2011 : return;
2012 :
2013 0 : gfc_symbol *dt_sym = gfc_find_dt_in_generic (e->symtree->n.sym);
2014 0 : if (dt_sym && gfc_fl_struct (dt_sym->attr.flavor))
2015 : {
2016 0 : e->ts.type = BT_DERIVED;
2017 0 : e->ts.u.derived = dt_sym;
2018 : }
2019 : }
2020 :
2021 : /* Infer the return type of a type-bound user-defined operator without
2022 : converting the expression node or triggering gfc_resolve_symbol on the
2023 : return type. This is used during ASSOCIATE selector parsing to propagate
2024 : type information bottom-up through nested UDO expressions such as
2025 : (.div. (.grad. x)), so that the outer gfc_extend_expr can locate the
2026 : type-bound .div. once the type of (.grad. x) is known.
2027 :
2028 : Calling gfc_extend_expr for this purpose would partially resolve the
2029 : return type's derived-type symbol (setting resolve_symbol_called before
2030 : resolve_typebound_procedures has run), which prevents the subsequent
2031 : outer gfc_extend_expr from properly resolving the type-bound operator
2032 : on the return type. We avoid that by reading the return type directly
2033 : from the procedure's result variable without triggering resolution. */
2034 :
2035 : static void
2036 6 : infer_typebound_uop_type (gfc_expr *e)
2037 : {
2038 6 : if (!e || e->expr_type != EXPR_OP || e->value.op.op != INTRINSIC_USER
2039 6 : || e->ts.type != BT_UNKNOWN)
2040 0 : return;
2041 :
2042 : /* Find the operand and strip parentheses. */
2043 6 : gfc_expr *operand = e->value.op.op1;
2044 12 : while (operand && operand->expr_type == EXPR_OP
2045 6 : && operand->value.op.op == INTRINSIC_PARENTHESES)
2046 0 : operand = operand->value.op.op1;
2047 :
2048 6 : if (!operand || operand->ts.type != BT_DERIVED || !operand->ts.u.derived)
2049 : return;
2050 :
2051 : /* Look up the UDO binding in the derived type's namespace (and its
2052 : parent types, via the recursion in find_typebound_proc_uop). This
2053 : does not call resolve_symbol, so it leaves resolve_symbol_called
2054 : untouched for all types involved. */
2055 6 : bool ok = true;
2056 6 : gfc_symtree *tb_uop
2057 12 : = gfc_find_typebound_user_op (operand->ts.u.derived, &ok,
2058 6 : e->value.op.uop->name, false, NULL);
2059 6 : if (!tb_uop || !tb_uop->n.tb)
2060 : return;
2061 :
2062 6 : gfc_typebound_proc *tb = tb_uop->n.tb;
2063 6 : if (!tb->is_generic || !tb->u.generic)
2064 : return;
2065 :
2066 : /* Take the first specific binding. specific_st is set from module reading;
2067 : its n.tb is the gfc_typebound_proc for that specific binding (same as
2068 : what resolve_typebound_procedures later stores in g->specific). Follow
2069 : the chain specific_st->n.tb->u.specific->n.sym to reach the actual
2070 : implementing function symbol, whose ts holds the return type.
2071 : This mirrors what build_compcall_for_operator does via
2072 : g->specific->u.specific->n.sym->ts after resolution. */
2073 6 : gfc_tbp_generic *g = tb->u.generic;
2074 6 : if (!g->specific_st || !g->specific_st->n.tb)
2075 : return;
2076 :
2077 6 : gfc_typebound_proc *specific_tb = g->specific_st->n.tb;
2078 6 : if (specific_tb->is_generic || !specific_tb->u.specific
2079 6 : || !specific_tb->u.specific->n.sym)
2080 : return;
2081 :
2082 6 : gfc_symbol *proc = specific_tb->u.specific->n.sym;
2083 6 : if (proc->ts.type != BT_UNKNOWN)
2084 6 : e->ts = proc->ts;
2085 : }
2086 :
2087 : /* Recursively propagate type information bottom-up through a nested UDO
2088 : expression tree so that when gfc_extend_expr is called on the outermost
2089 : operator during ASSOCIATE selector parsing, the inner operands already have
2090 : their types set and the type-bound lookup can succeed. Uses
2091 : infer_typebound_uop_type rather than gfc_extend_expr to avoid triggering
2092 : resolve_symbol on the return types, which would prevent the outer
2093 : gfc_extend_expr from working correctly. */
2094 :
2095 : static void
2096 76 : extend_assoc_op (gfc_expr *e)
2097 : {
2098 76 : if (!e || e->expr_type != EXPR_OP)
2099 : return;
2100 :
2101 : /* Bottom-up: process children first. */
2102 12 : extend_assoc_op (e->value.op.op1);
2103 12 : extend_assoc_op (e->value.op.op2);
2104 :
2105 : /* Propagate the child's type upward through parentheses nodes.
2106 : gfc_extend_expr's matching_typebound_op checks ts.type BEFORE stripping
2107 : INTRINSIC_PARENTHESES wrappers, so an untyped parentheses node prevents
2108 : the outer operator from being found. */
2109 12 : if (e->value.op.op == INTRINSIC_PARENTHESES
2110 6 : && e->ts.type == BT_UNKNOWN
2111 6 : && e->value.op.op1
2112 6 : && e->value.op.op1->ts.type != BT_UNKNOWN)
2113 : {
2114 6 : e->ts = e->value.op.op1->ts;
2115 6 : return;
2116 : }
2117 :
2118 : /* Only handle unresolved user-defined operators. */
2119 6 : if (e->value.op.op != INTRINSIC_USER || e->ts.type != BT_UNKNOWN)
2120 : return;
2121 :
2122 : /* Try to infer the type of each operand if it is an unresolved constructor
2123 : call (EXPR_FUNCTION whose return type is still BT_UNKNOWN). */
2124 6 : resolve_assoc_operand (e->value.op.op1);
2125 6 : resolve_assoc_operand (e->value.op.op2);
2126 :
2127 : /* Infer this operator's return type from the type-bound procedure's result
2128 : variable, without calling gfc_resolve_symbol on the return type. */
2129 6 : infer_typebound_uop_type (e);
2130 : }
2131 :
2132 : match
2133 1588 : match_association_list (bool for_change_team = false)
2134 : {
2135 1588 : new_st.ext.block.assoc = NULL;
2136 1876 : while (true)
2137 : {
2138 1732 : gfc_association_list *newAssoc = gfc_get_association_list ();
2139 1732 : gfc_association_list *a;
2140 1732 : locus pre_name = gfc_current_locus;
2141 :
2142 : /* Match the next association. */
2143 1732 : if (gfc_match (" %n ", newAssoc->name) != MATCH_YES)
2144 : {
2145 3 : gfc_error ("Expected associate name at %C");
2146 3 : goto assocListError;
2147 : }
2148 :
2149 : /* Required for an assumed rank target. */
2150 1729 : if (!for_change_team && gfc_peek_char () == '(')
2151 : {
2152 26 : newAssoc->ar = gfc_get_array_ref ();
2153 26 : if (gfc_match_array_ref (newAssoc->ar, NULL, 0, 0) != MATCH_YES)
2154 : {
2155 0 : gfc_error ("Bad bounds remapping list at %C");
2156 0 : goto assocListError;
2157 : }
2158 : }
2159 :
2160 1729 : if (newAssoc->ar && !(gfc_option.allow_std & GFC_STD_F202Y))
2161 2 : gfc_error_now ("The bounds remapping list at %C is an experimental "
2162 : "F202y feature. Use std=f202y to enable");
2163 :
2164 1729 : if (for_change_team && gfc_peek_char () == '[')
2165 : {
2166 7 : if (!newAssoc->ar)
2167 7 : newAssoc->ar = gfc_get_array_ref ();
2168 7 : if (gfc_match_array_spec (&newAssoc->ar->as, false, true)
2169 : == MATCH_ERROR)
2170 0 : goto assocListError;
2171 : }
2172 :
2173 : /* Match the next association. */
2174 1729 : if (gfc_match (" =>", newAssoc->name) != MATCH_YES)
2175 : {
2176 16 : if (for_change_team)
2177 16 : gfc_current_locus = pre_name;
2178 :
2179 16 : free (newAssoc);
2180 36 : return MATCH_NO;
2181 : }
2182 :
2183 1713 : if (!for_change_team)
2184 : {
2185 1700 : if (gfc_match (" %e", &newAssoc->target) != MATCH_YES)
2186 : {
2187 : /* Have another go, allowing for procedure pointer selectors. */
2188 22 : gfc_matching_procptr_assignment = 1;
2189 22 : if (gfc_match (" %e", &newAssoc->target) != MATCH_YES)
2190 : {
2191 8 : gfc_matching_procptr_assignment = 0;
2192 8 : gfc_error ("Invalid association target at %C");
2193 8 : goto assocListError;
2194 : }
2195 14 : gfc_matching_procptr_assignment = 0;
2196 : }
2197 1692 : newAssoc->where = gfc_current_locus;
2198 : }
2199 : else
2200 : {
2201 13 : newAssoc->where = gfc_current_locus;
2202 : /* F2018, C1116: A selector in a coarray-association shall be a named
2203 : coarray. */
2204 13 : if (gfc_match (" %v", &newAssoc->target) != MATCH_YES)
2205 : {
2206 1 : gfc_error ("Selector in coarray association as %C shall be a "
2207 : "named coarray");
2208 1 : goto assocListError;
2209 : }
2210 : }
2211 :
2212 : /* Check that the current name is not yet in the list. */
2213 1874 : for (a = new_st.ext.block.assoc; a; a = a->next)
2214 172 : if (!strcmp (a->name, newAssoc->name))
2215 : {
2216 2 : gfc_error ("Duplicate name %qs in association at %C",
2217 : newAssoc->name);
2218 2 : goto assocListError;
2219 : }
2220 :
2221 1702 : if (for_change_team)
2222 : {
2223 : /* F2018, C1113: In a change-team-stmt, a coarray-name in a
2224 : codimension-decl shall not be the same as a selector, or another
2225 : coarray-name, in that statement.
2226 : The latter is already checked for above. So check only the
2227 : former.
2228 : */
2229 11 : if (!check_coarray_assoc (newAssoc->name, newAssoc))
2230 1 : goto assocListError;
2231 :
2232 10 : for (a = new_st.ext.block.assoc; a; a = a->next)
2233 : {
2234 3 : if (!check_coarray_assoc (newAssoc->name, a)
2235 3 : || !check_coarray_assoc (a->name, newAssoc))
2236 2 : goto assocListError;
2237 :
2238 : /* F2018, C1115: No selector shall appear more than once in a
2239 : * given change-team-stmt. */
2240 1 : if (!strcmp (newAssoc->target->symtree->name,
2241 1 : a->target->symtree->name))
2242 : {
2243 1 : gfc_error ("Selector at %L duplicates selector at %L",
2244 : &newAssoc->target->where, &a->target->where);
2245 1 : goto assocListError;
2246 : }
2247 : }
2248 : }
2249 :
2250 : /* The target expression must not be coindexed. */
2251 1698 : if (gfc_is_coindexed (newAssoc->target))
2252 : {
2253 1 : gfc_error ("Association target at %C must not be coindexed");
2254 1 : goto assocListError;
2255 : }
2256 :
2257 : /* The target expression cannot be a BOZ literal constant. */
2258 1697 : if (newAssoc->target->ts.type == BT_BOZ)
2259 : {
2260 1 : gfc_error ("Association target at %L cannot be a BOZ literal "
2261 : "constant", &newAssoc->target->where);
2262 1 : goto assocListError;
2263 : }
2264 :
2265 1696 : if (newAssoc->target->expr_type == EXPR_VARIABLE
2266 837 : && newAssoc->target->symtree->n.sym->as
2267 406 : && newAssoc->target->symtree->n.sym->as->type == AS_ASSUMED_RANK)
2268 : {
2269 14 : bool bounds_remapping_list = true;
2270 14 : if (!newAssoc->ar)
2271 : bounds_remapping_list = false;
2272 : else
2273 35 : for (int dim = 0; dim < newAssoc->ar->dimen; dim++)
2274 21 : if (!newAssoc->ar->start[dim] || !newAssoc->ar->end[dim]
2275 21 : || newAssoc->ar->stride[dim] != NULL)
2276 0 : bounds_remapping_list = false;
2277 :
2278 14 : if (!bounds_remapping_list)
2279 : {
2280 0 : gfc_error ("The associate name %s with an assumed rank "
2281 : "target at %L must have a bounds remapping list "
2282 : "(list of lbound:ubound for each dimension)",
2283 : newAssoc->name, &newAssoc->target->where);
2284 0 : goto assocListError;
2285 : }
2286 :
2287 14 : if (!newAssoc->target->symtree->n.sym->attr.contiguous)
2288 : {
2289 0 : gfc_error ("The assumed rank target at %C must be contiguous");
2290 0 : goto assocListError;
2291 : }
2292 : }
2293 1682 : else if (newAssoc->target->ts.type == BT_UNKNOWN
2294 585 : && newAssoc->target->expr_type == EXPR_OP
2295 79 : && newAssoc->target->value.op.op == INTRINSIC_USER)
2296 : {
2297 : /* If the selector is an unresolved type-bound user-defined operator
2298 : expression, try to extend it now so the associate name gets a usable
2299 : type. For nested operators such as
2300 : (.div. (.grad. x))
2301 : first propagate types bottom-up through the inner operands
2302 : (extend_assoc_op). For a direct operator applied to a constructor
2303 : call such as
2304 : (.div. vector_t(init_fn, n=8))
2305 : additionally resolve the direct operands as constructor calls
2306 : (resolve_assoc_operand). Then call gfc_extend_expr on the
2307 : outermost operator. Only handle INTRINSIC_USER here; arithmetic
2308 : operators are left to the normal resolution pass. */
2309 26 : gfc_expr *tmp = gfc_copy_expr (newAssoc->target);
2310 26 : extend_assoc_op (tmp->value.op.op1);
2311 26 : extend_assoc_op (tmp->value.op.op2);
2312 26 : resolve_assoc_operand (tmp->value.op.op1);
2313 26 : resolve_assoc_operand (tmp->value.op.op2);
2314 : /* Suppress errors from gfc_extend_expr: during parsing the full
2315 : resolution has not run yet, so gfc_resolve_expr(COMPCALL) may
2316 : fail even when the type-bound operator was found and the node
2317 : was correctly converted to EXPR_COMPCALL. Accept the conversion
2318 : in that case and let the normal resolution pass finish it. */
2319 26 : gfc_push_suppress_errors ();
2320 26 : match ext_m = gfc_extend_expr (tmp);
2321 26 : gfc_pop_suppress_errors ();
2322 26 : if (ext_m == MATCH_YES
2323 0 : || (tmp->expr_type == EXPR_COMPCALL
2324 0 : && tmp->ts.type != BT_UNKNOWN))
2325 26 : gfc_replace_expr (newAssoc->target, tmp);
2326 : else
2327 0 : gfc_free_expr (tmp);
2328 : }
2329 1656 : else if (newAssoc->target->ts.type == BT_UNKNOWN
2330 559 : && newAssoc->target->expr_type == EXPR_OP)
2331 : {
2332 : /* The selector is an unresolved expression involving an overloaded
2333 : intrinsic operator (e.g. a `+' bound via an explicit interface
2334 : to a function returning CHARACTER). Try to extend it now, the
2335 : same way the type-bound user-defined operator case above does
2336 : for INTRINSIC_USER, so the associate name gets a usable type
2337 : before the body of the ASSOCIATE construct is parsed. */
2338 53 : gfc_expr *tmp = gfc_copy_expr (newAssoc->target);
2339 53 : if (gfc_extend_expr (tmp) == MATCH_YES)
2340 12 : gfc_replace_expr (newAssoc->target, tmp);
2341 : else
2342 41 : gfc_free_expr (tmp);
2343 : }
2344 :
2345 : /* The `variable' field is left blank for now; because the target is not
2346 : yet resolved, we can't use gfc_has_vector_subscript to determine it
2347 : for now. This is set during resolution. */
2348 :
2349 : /* Put it into the list. */
2350 1696 : newAssoc->next = new_st.ext.block.assoc;
2351 1696 : new_st.ext.block.assoc = newAssoc;
2352 :
2353 : /* Try next one or end if closing parenthesis is found. */
2354 1696 : gfc_gobble_whitespace ();
2355 1696 : if (gfc_peek_char () == ')')
2356 : break;
2357 144 : if (gfc_match_char (',') != MATCH_YES)
2358 : {
2359 0 : gfc_error ("Expected %<)%> or %<,%> at %C");
2360 0 : return MATCH_ERROR;
2361 : }
2362 :
2363 144 : continue;
2364 :
2365 20 : assocListError:
2366 20 : free (newAssoc);
2367 20 : return MATCH_ERROR;
2368 144 : }
2369 :
2370 1552 : return MATCH_YES;
2371 : }
2372 :
2373 : /* Match an ASSOCIATE statement. */
2374 :
2375 : match
2376 496727 : gfc_match_associate (void)
2377 : {
2378 496727 : match m;
2379 496727 : if (gfc_match_label () == MATCH_ERROR)
2380 : return MATCH_ERROR;
2381 :
2382 496719 : if (gfc_match (" associate") != MATCH_YES)
2383 : return MATCH_NO;
2384 :
2385 : /* Match the association list. */
2386 1564 : if (gfc_match_char ('(') != MATCH_YES)
2387 : {
2388 1 : gfc_error ("Expected association list at %C");
2389 1 : return MATCH_ERROR;
2390 : }
2391 :
2392 1563 : m = match_association_list ();
2393 1563 : if (m == MATCH_ERROR)
2394 14 : goto error;
2395 1549 : else if (m == MATCH_NO)
2396 : {
2397 0 : gfc_error ("Expected association at %C");
2398 0 : goto error;
2399 : }
2400 :
2401 1549 : if (gfc_match_char (')') != MATCH_YES)
2402 : {
2403 : /* This should never happen as we peek above. */
2404 0 : gcc_unreachable ();
2405 : }
2406 :
2407 1549 : if (gfc_match_eos () != MATCH_YES)
2408 : {
2409 1 : gfc_error ("Junk after ASSOCIATE statement at %C");
2410 1 : goto error;
2411 : }
2412 :
2413 : return MATCH_YES;
2414 :
2415 15 : error:
2416 15 : gfc_free_association_list (new_st.ext.block.assoc);
2417 15 : return MATCH_ERROR;
2418 : }
2419 :
2420 :
2421 : /* Match a Fortran 2003 derived-type-spec (F03:R455), which is just the name of
2422 : an accessible derived type. */
2423 :
2424 : static match
2425 36438 : match_derived_type_spec (gfc_typespec *ts)
2426 : {
2427 36438 : char name[GFC_MAX_SYMBOL_LEN + 1];
2428 36438 : locus old_locus;
2429 36438 : gfc_symbol *derived, *der_type;
2430 36438 : match m = MATCH_YES;
2431 36438 : gfc_actual_arglist *decl_type_param_list = NULL;
2432 36438 : bool is_pdt_template = false;
2433 :
2434 36438 : old_locus = gfc_current_locus;
2435 :
2436 36438 : if (gfc_match ("%n", name) != MATCH_YES)
2437 : {
2438 1 : gfc_current_locus = old_locus;
2439 1 : return MATCH_NO;
2440 : }
2441 :
2442 36437 : gfc_find_symbol (name, NULL, 1, &derived);
2443 :
2444 : /* Match the PDT spec list, if there. */
2445 36437 : if (derived && derived->attr.flavor == FL_PROCEDURE)
2446 : {
2447 7108 : gfc_find_symbol (gfc_dt_upper_string (name), NULL, 1, &der_type);
2448 7108 : is_pdt_template = der_type
2449 4998 : && der_type->attr.flavor == FL_DERIVED
2450 12106 : && der_type->attr.pdt_template;
2451 : }
2452 :
2453 236 : if (is_pdt_template)
2454 236 : m = gfc_match_actual_arglist (1, &decl_type_param_list, true);
2455 :
2456 9111 : if (m == MATCH_ERROR)
2457 : {
2458 0 : gfc_free_actual_arglist (decl_type_param_list);
2459 0 : return m;
2460 : }
2461 :
2462 36437 : if (derived && derived->attr.flavor == FL_PROCEDURE && derived->attr.generic)
2463 5022 : derived = gfc_find_dt_in_generic (derived);
2464 :
2465 : /* If this is a PDT, find the specific instance. */
2466 36437 : if (m == MATCH_YES && is_pdt_template)
2467 : {
2468 236 : gfc_namespace *old_ns;
2469 :
2470 236 : old_ns = gfc_current_ns;
2471 443 : while (gfc_current_ns && gfc_current_ns->parent)
2472 207 : gfc_current_ns = gfc_current_ns->parent;
2473 :
2474 236 : if (type_param_spec_list)
2475 6 : gfc_free_actual_arglist (type_param_spec_list);
2476 236 : m = gfc_get_pdt_instance (decl_type_param_list, &der_type,
2477 : &type_param_spec_list);
2478 236 : gfc_free_actual_arglist (decl_type_param_list);
2479 :
2480 236 : if (m != MATCH_YES)
2481 : return m;
2482 231 : derived = der_type;
2483 231 : gcc_assert (!derived->attr.pdt_template && derived->attr.pdt_type);
2484 231 : gfc_set_sym_referenced (derived);
2485 :
2486 231 : gfc_current_ns = old_ns;
2487 : }
2488 :
2489 36432 : if (derived && derived->attr.flavor == FL_DERIVED)
2490 : {
2491 4993 : ts->type = BT_DERIVED;
2492 4993 : ts->u.derived = derived;
2493 4993 : return MATCH_YES;
2494 : }
2495 :
2496 31439 : gfc_current_locus = old_locus;
2497 31439 : return MATCH_NO;
2498 : }
2499 :
2500 :
2501 : /* Match a Fortran 2003 type-spec (F03:R401). This is similar to
2502 : gfc_match_decl_type_spec() from decl.cc, with the following exceptions:
2503 : It only includes the intrinsic types from the Fortran 2003 standard
2504 : (thus, neither BYTE nor forms like REAL*4 are allowed). Additionally,
2505 : the implicit_flag is not needed, so it was removed. Derived types are
2506 : identified by their name alone. */
2507 :
2508 : static match
2509 155344 : match_type_spec (gfc_typespec *ts)
2510 : {
2511 155344 : match m;
2512 155344 : locus old_locus;
2513 155344 : char c, name[GFC_MAX_SYMBOL_LEN + 1];
2514 :
2515 155344 : gfc_clear_ts (ts);
2516 155344 : gfc_gobble_whitespace ();
2517 155344 : old_locus = gfc_current_locus;
2518 :
2519 : /* If c isn't [a-z], then return immediately. */
2520 155344 : c = gfc_peek_ascii_char ();
2521 155344 : if (!ISALPHA(c))
2522 : return MATCH_NO;
2523 :
2524 36080 : type_param_spec_list = NULL;
2525 :
2526 36080 : if (match_derived_type_spec (ts) == MATCH_YES)
2527 : {
2528 : /* Enforce F03:C401. */
2529 4639 : if (ts->u.derived->attr.abstract)
2530 : {
2531 1 : gfc_error ("Derived type %qs at %L may not be ABSTRACT",
2532 : ts->u.derived->name, &old_locus);
2533 1 : return MATCH_ERROR;
2534 : }
2535 : return MATCH_YES;
2536 : }
2537 :
2538 31441 : if (gfc_match ("integer") == MATCH_YES)
2539 : {
2540 1625 : ts->type = BT_INTEGER;
2541 1625 : ts->kind = gfc_default_integer_kind;
2542 1625 : goto kind_selector;
2543 : }
2544 :
2545 29816 : if (flag_unsigned && gfc_match ("unsigned") == MATCH_YES)
2546 : {
2547 6 : ts->type = BT_UNSIGNED;
2548 6 : ts->kind = gfc_default_integer_kind;
2549 6 : goto kind_selector;
2550 : }
2551 :
2552 29810 : if (gfc_match ("double precision") == MATCH_YES)
2553 : {
2554 59 : ts->type = BT_REAL;
2555 59 : ts->kind = gfc_default_double_kind;
2556 59 : return MATCH_YES;
2557 : }
2558 :
2559 29751 : if (gfc_match ("complex") == MATCH_YES)
2560 : {
2561 139 : ts->type = BT_COMPLEX;
2562 139 : ts->kind = gfc_default_complex_kind;
2563 139 : goto kind_selector;
2564 : }
2565 :
2566 29612 : if (gfc_match ("character") == MATCH_YES)
2567 : {
2568 2993 : ts->type = BT_CHARACTER;
2569 :
2570 2993 : m = gfc_match_char_spec (ts);
2571 :
2572 2993 : if (m == MATCH_NO)
2573 0 : m = MATCH_YES;
2574 :
2575 2993 : return m;
2576 : }
2577 :
2578 : /* REAL is a real pain because it can be a type, intrinsic subprogram,
2579 : or list item in a type-list of an OpenMP reduction clause. Need to
2580 : differentiate REAL([KIND]=scalar-int-initialization-expr) from
2581 : REAL(A,[KIND]) and REAL(KIND,A). Logically, when this code was
2582 : written the use of LOGICAL as a type-spec or intrinsic subprogram
2583 : was overlooked. */
2584 :
2585 26619 : m = gfc_match (" %n", name);
2586 26619 : if (m == MATCH_YES
2587 26614 : && (strcmp (name, "real") == 0 || strcmp (name, "logical") == 0))
2588 : {
2589 3506 : char c;
2590 3506 : gfc_expr *e;
2591 3506 : locus where;
2592 :
2593 3506 : if (*name == 'r')
2594 : {
2595 2982 : ts->type = BT_REAL;
2596 2982 : ts->kind = gfc_default_real_kind;
2597 : }
2598 : else
2599 : {
2600 524 : ts->type = BT_LOGICAL;
2601 524 : ts->kind = gfc_default_logical_kind;
2602 : }
2603 :
2604 3506 : gfc_gobble_whitespace ();
2605 :
2606 : /* Prevent REAL*4, etc. */
2607 3506 : c = gfc_peek_ascii_char ();
2608 3506 : if (c == '*')
2609 : {
2610 4 : gfc_error ("Invalid type-spec at %C");
2611 3487 : return MATCH_ERROR;
2612 : }
2613 :
2614 : /* Found leading colon in REAL::, a trailing ')' in for example
2615 : TYPE IS (REAL), or REAL, for an OpenMP list-item. */
2616 3502 : if (c == ':' || c == ')' || (flag_openmp && c == ','))
2617 : return MATCH_YES;
2618 :
2619 : /* Found something other than the opening '(' in REAL(... */
2620 558 : if (c != '(')
2621 : return MATCH_NO;
2622 : else
2623 558 : gfc_next_char (); /* Burn the '('. */
2624 :
2625 : /* Look for the optional KIND=. */
2626 558 : where = gfc_current_locus;
2627 558 : m = gfc_match ("%n", name);
2628 558 : if (m == MATCH_YES)
2629 : {
2630 416 : gfc_gobble_whitespace ();
2631 416 : c = gfc_next_char ();
2632 416 : if (c == '=')
2633 : {
2634 145 : if (strcmp(name, "a") == 0 || strcmp(name, "l") == 0)
2635 : return MATCH_NO;
2636 141 : else if (strcmp(name, "kind") == 0)
2637 141 : goto found;
2638 : else
2639 : return MATCH_ERROR;
2640 : }
2641 : else
2642 271 : gfc_current_locus = where;
2643 : }
2644 : else
2645 142 : gfc_current_locus = where;
2646 :
2647 554 : found:
2648 :
2649 554 : m = gfc_match_expr (&e);
2650 554 : if (m == MATCH_NO || m == MATCH_ERROR)
2651 : return m;
2652 :
2653 : /* If a comma appears, it is an intrinsic subprogram. */
2654 554 : gfc_gobble_whitespace ();
2655 554 : c = gfc_peek_ascii_char ();
2656 554 : if (c == ',')
2657 : {
2658 23 : gfc_free_expr (e);
2659 23 : return MATCH_NO;
2660 : }
2661 :
2662 : /* If ')' appears, we have REAL(initialization-expr), here check for
2663 : a scalar integer initialization-expr and valid kind parameter. */
2664 531 : if (c == ')')
2665 : {
2666 531 : bool ok = true;
2667 531 : if (e->expr_type != EXPR_CONSTANT && e->expr_type != EXPR_VARIABLE)
2668 7 : ok = gfc_reduce_init_expr (e);
2669 531 : if (!ok || e->ts.type != BT_INTEGER || e->rank > 0)
2670 : {
2671 3 : gfc_free_expr (e);
2672 3 : return MATCH_NO;
2673 : }
2674 :
2675 528 : if (e->expr_type != EXPR_CONSTANT)
2676 23 : goto ohno;
2677 :
2678 505 : gfc_next_char (); /* Burn the ')'. */
2679 505 : ts->kind = (int) mpz_get_si (e->value.integer);
2680 505 : if (gfc_validate_kind (ts->type, ts->kind , true) == -1)
2681 : {
2682 1 : gfc_error ("Invalid type-spec at %C");
2683 1 : return MATCH_ERROR;
2684 : }
2685 :
2686 504 : gfc_free_expr (e);
2687 :
2688 504 : return MATCH_YES;
2689 : }
2690 : }
2691 :
2692 23113 : ohno:
2693 :
2694 : /* If a type is not matched, simply return MATCH_NO. */
2695 23136 : gfc_current_locus = old_locus;
2696 23136 : return MATCH_NO;
2697 :
2698 1770 : kind_selector:
2699 :
2700 1770 : gfc_gobble_whitespace ();
2701 :
2702 : /* This prevents INTEGER*4, etc. */
2703 1770 : if (gfc_peek_ascii_char () == '*')
2704 : {
2705 0 : gfc_error ("Invalid type-spec at %C");
2706 0 : return MATCH_ERROR;
2707 : }
2708 :
2709 1770 : m = gfc_match_kind_spec (ts, false);
2710 :
2711 : /* No kind specifier found. */
2712 1770 : if (m == MATCH_NO)
2713 6174 : m = MATCH_YES;
2714 :
2715 : return m;
2716 : }
2717 :
2718 :
2719 : match
2720 155344 : gfc_match_type_spec (gfc_typespec *ts)
2721 : {
2722 155344 : match m;
2723 155344 : gfc_namespace *old_ns = gfc_current_ns;
2724 155344 : m = match_type_spec (ts);
2725 155344 : gfc_current_ns = old_ns;
2726 155344 : return m;
2727 : }
2728 :
2729 :
2730 : /******************** FORALL subroutines ********************/
2731 :
2732 : /* Free a list of FORALL iterators. */
2733 :
2734 : void
2735 4949 : gfc_free_forall_iterator (gfc_forall_iterator *iter)
2736 : {
2737 4949 : gfc_forall_iterator *next;
2738 :
2739 9823 : while (iter)
2740 : {
2741 4874 : next = iter->next;
2742 4874 : gfc_free_expr (iter->var);
2743 4874 : gfc_free_expr (iter->start);
2744 4874 : gfc_free_expr (iter->end);
2745 4874 : gfc_free_expr (iter->stride);
2746 4874 : free (iter);
2747 4874 : iter = next;
2748 : }
2749 4949 : }
2750 :
2751 :
2752 : /* Match an iterator as part of a FORALL statement. The format is:
2753 :
2754 : <var> = <start>:<end>[:<stride>]
2755 :
2756 : On MATCH_NO, the caller tests for the possibility that there is a
2757 : scalar mask expression. */
2758 :
2759 : static match
2760 4874 : match_forall_iterator (gfc_forall_iterator **result)
2761 : {
2762 4874 : gfc_forall_iterator *iter;
2763 4874 : locus where;
2764 4874 : match m;
2765 :
2766 4874 : where = gfc_current_locus;
2767 4874 : iter = XCNEW (gfc_forall_iterator);
2768 :
2769 4874 : m = gfc_match_expr (&iter->var);
2770 4874 : if (m != MATCH_YES)
2771 0 : goto cleanup;
2772 :
2773 4874 : if (gfc_match_char ('=') != MATCH_YES
2774 4874 : || iter->var->expr_type != EXPR_VARIABLE)
2775 : {
2776 732 : m = MATCH_NO;
2777 732 : goto cleanup;
2778 : }
2779 :
2780 4142 : m = gfc_match_expr (&iter->start);
2781 4142 : if (m != MATCH_YES)
2782 0 : goto cleanup;
2783 :
2784 4142 : if (gfc_match_char (':') != MATCH_YES)
2785 0 : goto syntax;
2786 :
2787 4142 : m = gfc_match_expr (&iter->end);
2788 4142 : if (m == MATCH_NO)
2789 0 : goto syntax;
2790 4142 : if (m == MATCH_ERROR)
2791 0 : goto cleanup;
2792 :
2793 4142 : if (gfc_match_char (':') == MATCH_NO)
2794 4088 : iter->stride = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
2795 : else
2796 : {
2797 54 : m = gfc_match_expr (&iter->stride);
2798 54 : if (m == MATCH_NO)
2799 0 : goto syntax;
2800 54 : if (m == MATCH_ERROR)
2801 0 : goto cleanup;
2802 : }
2803 :
2804 : /* Mark the iteration variable's symbol as used as a FORALL index. */
2805 4142 : iter->var->symtree->n.sym->forall_index = true;
2806 :
2807 4142 : *result = iter;
2808 4142 : return MATCH_YES;
2809 :
2810 0 : syntax:
2811 0 : gfc_error ("Syntax error in FORALL iterator at %C");
2812 0 : m = MATCH_ERROR;
2813 :
2814 732 : cleanup:
2815 :
2816 732 : gfc_current_locus = where;
2817 732 : gfc_free_forall_iterator (iter);
2818 732 : return m;
2819 : }
2820 :
2821 :
2822 : /* Apply type-spec to iterator and create shadow variable if needed. */
2823 :
2824 : static void
2825 46 : apply_typespec_to_iterator (gfc_forall_iterator *iter, gfc_typespec *ts,
2826 : locus *loc)
2827 : {
2828 46 : char *name;
2829 46 : gfc_expr *v;
2830 46 : gfc_symtree *st;
2831 :
2832 : /* When a type-spec is provided in DO CONCURRENT/FORALL, F2018 19.4(6)
2833 : requires the index-name to have scope limited to the construct,
2834 : shadowing any variable with the same name from outer scope.
2835 : If the index-name was not previously declared, we can simply set its
2836 : type. Otherwise, create a shadow variable with "_" prefix. */
2837 46 : iter->shadow = false;
2838 46 : v = iter->var;
2839 46 : if (v->ts.type == BT_UNKNOWN)
2840 : {
2841 : /* Variable not declared in outer scope - just set the type. */
2842 22 : v->ts.type = v->symtree->n.sym->ts.type = BT_INTEGER;
2843 22 : v->ts.kind = v->symtree->n.sym->ts.kind = ts->kind;
2844 22 : gfc_set_sym_referenced (v->symtree->n.sym);
2845 : }
2846 : else
2847 : {
2848 : /* Variable exists in outer scope - must create shadow to comply
2849 : with F2018 19.4(6) scoping rules. */
2850 24 : name = (char *) alloca (strlen (v->symtree->name) + 2);
2851 24 : strcpy (name, "_");
2852 24 : strcat (name, v->symtree->name);
2853 24 : if (gfc_get_sym_tree (name, NULL, &st, false) != 0)
2854 0 : gfc_internal_error ("Failed to create shadow variable symtree for "
2855 : "DO CONCURRENT type-spec at %L", loc);
2856 :
2857 24 : v = gfc_get_expr ();
2858 24 : v->where = gfc_current_locus;
2859 24 : v->expr_type = EXPR_VARIABLE;
2860 24 : v->ts.type = st->n.sym->ts.type = ts->type;
2861 24 : v->ts.kind = st->n.sym->ts.kind = ts->kind;
2862 24 : st->n.sym->forall_index = true;
2863 24 : v->symtree = st;
2864 24 : gfc_replace_expr (iter->var, v);
2865 24 : iter->shadow = true;
2866 24 : gfc_set_sym_referenced (st->n.sym);
2867 : }
2868 :
2869 : /* Convert iterator bounds to the specified type. */
2870 46 : gfc_convert_type (iter->start, ts, 1);
2871 46 : gfc_convert_type (iter->end, ts, 1);
2872 46 : gfc_convert_type (iter->stride, ts, 1);
2873 46 : }
2874 :
2875 :
2876 : /* Match the header of a FORALL statement. In F2008 and F2018, the form of
2877 : the header is:
2878 :
2879 : ([ type-spec :: ] concurrent-control-list [, scalar-mask-expr ] )
2880 :
2881 : where type-spec is INTEGER. */
2882 :
2883 : static match
2884 2226 : match_forall_header (gfc_forall_iterator **phead, gfc_expr **mask)
2885 : {
2886 2226 : gfc_forall_iterator *head, *tail, *new_iter;
2887 2226 : gfc_expr *msk;
2888 2226 : match m;
2889 2226 : gfc_typespec ts;
2890 2226 : bool seen_ts = false;
2891 2226 : locus loc;
2892 :
2893 2226 : gfc_gobble_whitespace ();
2894 :
2895 2226 : head = tail = NULL;
2896 2226 : msk = NULL;
2897 :
2898 2226 : if (gfc_match_char ('(') != MATCH_YES)
2899 : return MATCH_NO;
2900 :
2901 : /* Check for an optional type-spec. */
2902 2224 : gfc_clear_ts (&ts);
2903 2224 : loc = gfc_current_locus;
2904 2224 : m = gfc_match_type_spec (&ts);
2905 2224 : if (m == MATCH_YES)
2906 : {
2907 38 : seen_ts = (gfc_match (" ::") == MATCH_YES);
2908 :
2909 38 : if (seen_ts)
2910 : {
2911 38 : if (!gfc_notify_std (GFC_STD_F2008, "FORALL or DO CONCURRENT "
2912 : "construct includes type specification "
2913 : "at %L", &loc))
2914 0 : goto cleanup;
2915 :
2916 38 : if (ts.type != BT_INTEGER)
2917 : {
2918 0 : gfc_error ("Type-spec at %L must be an INTEGER type", &loc);
2919 0 : goto cleanup;
2920 : }
2921 : }
2922 : }
2923 2186 : else if (m == MATCH_ERROR)
2924 0 : goto syntax;
2925 :
2926 2224 : m = match_forall_iterator (&new_iter);
2927 2224 : if (m == MATCH_ERROR)
2928 0 : goto cleanup;
2929 2224 : if (m == MATCH_NO)
2930 0 : goto syntax;
2931 :
2932 2224 : if (seen_ts)
2933 38 : apply_typespec_to_iterator (new_iter, &ts, &loc);
2934 :
2935 2224 : head = tail = new_iter;
2936 :
2937 6060 : for (;;)
2938 : {
2939 4142 : if (gfc_match_char (',') != MATCH_YES)
2940 : break;
2941 :
2942 2650 : m = match_forall_iterator (&new_iter);
2943 2650 : if (m == MATCH_ERROR)
2944 0 : goto cleanup;
2945 :
2946 2650 : if (m == MATCH_YES)
2947 : {
2948 1918 : if (seen_ts)
2949 8 : apply_typespec_to_iterator (new_iter, &ts, &loc);
2950 :
2951 1918 : tail->next = new_iter;
2952 1918 : tail = new_iter;
2953 1918 : continue;
2954 : }
2955 :
2956 : /* Have to have a mask expression. */
2957 :
2958 732 : m = gfc_match_expr (&msk);
2959 732 : if (m == MATCH_NO)
2960 0 : goto syntax;
2961 732 : if (m == MATCH_ERROR)
2962 0 : goto cleanup;
2963 :
2964 : break;
2965 : }
2966 :
2967 2224 : if (gfc_match_char (')') == MATCH_NO)
2968 0 : goto syntax;
2969 :
2970 2224 : *phead = head;
2971 2224 : *mask = msk;
2972 2224 : return MATCH_YES;
2973 :
2974 0 : syntax:
2975 0 : gfc_syntax_error (ST_FORALL);
2976 :
2977 0 : cleanup:
2978 0 : gfc_free_expr (msk);
2979 0 : gfc_free_forall_iterator (head);
2980 :
2981 0 : return MATCH_ERROR;
2982 : }
2983 :
2984 : /* Match the rest of a simple FORALL statement that follows an
2985 : IF statement. */
2986 :
2987 : static match
2988 6 : match_simple_forall (void)
2989 : {
2990 6 : gfc_forall_iterator *head;
2991 6 : gfc_expr *mask;
2992 6 : gfc_code *c;
2993 6 : match m;
2994 :
2995 6 : mask = NULL;
2996 6 : head = NULL;
2997 6 : c = NULL;
2998 :
2999 6 : m = match_forall_header (&head, &mask);
3000 :
3001 6 : if (m == MATCH_NO)
3002 0 : goto syntax;
3003 6 : if (m != MATCH_YES)
3004 0 : goto cleanup;
3005 :
3006 6 : m = gfc_match_assignment ();
3007 :
3008 6 : if (m == MATCH_ERROR)
3009 0 : goto cleanup;
3010 6 : if (m == MATCH_NO)
3011 : {
3012 0 : m = gfc_match_pointer_assignment ();
3013 0 : if (m == MATCH_ERROR)
3014 0 : goto cleanup;
3015 0 : if (m == MATCH_NO)
3016 0 : goto syntax;
3017 : }
3018 :
3019 6 : c = XCNEW (gfc_code);
3020 6 : *c = new_st;
3021 6 : c->loc = gfc_current_locus;
3022 :
3023 6 : if (gfc_match_eos () != MATCH_YES)
3024 0 : goto syntax;
3025 :
3026 6 : gfc_clear_new_st ();
3027 6 : new_st.op = EXEC_FORALL;
3028 6 : new_st.expr1 = mask;
3029 6 : new_st.ext.concur.forall_iterator = head;
3030 6 : new_st.block = gfc_get_code (EXEC_FORALL);
3031 6 : new_st.block->next = c;
3032 :
3033 6 : return MATCH_YES;
3034 :
3035 0 : syntax:
3036 0 : gfc_syntax_error (ST_FORALL);
3037 :
3038 0 : cleanup:
3039 0 : gfc_free_forall_iterator (head);
3040 0 : gfc_free_expr (mask);
3041 :
3042 0 : return MATCH_ERROR;
3043 : }
3044 :
3045 :
3046 : /* Match a FORALL statement. */
3047 :
3048 : match
3049 533058 : gfc_match_forall (gfc_statement *st)
3050 : {
3051 533058 : gfc_forall_iterator *head;
3052 533058 : gfc_expr *mask;
3053 533058 : gfc_code *c;
3054 533058 : match m0, m;
3055 :
3056 533058 : head = NULL;
3057 533058 : mask = NULL;
3058 533058 : c = NULL;
3059 :
3060 533058 : m0 = gfc_match_label ();
3061 533058 : if (m0 == MATCH_ERROR)
3062 : return MATCH_ERROR;
3063 :
3064 533050 : m = gfc_match (" forall");
3065 533050 : if (m != MATCH_YES)
3066 : return m;
3067 :
3068 1987 : m = match_forall_header (&head, &mask);
3069 1987 : if (m == MATCH_ERROR)
3070 0 : goto cleanup;
3071 1987 : if (m == MATCH_NO)
3072 0 : goto syntax;
3073 :
3074 1987 : if (gfc_match_eos () == MATCH_YES)
3075 : {
3076 507 : *st = ST_FORALL_BLOCK;
3077 507 : new_st.op = EXEC_FORALL;
3078 507 : new_st.expr1 = mask;
3079 507 : new_st.ext.concur.forall_iterator = head;
3080 507 : return MATCH_YES;
3081 : }
3082 :
3083 1480 : m = gfc_match_assignment ();
3084 1480 : if (m == MATCH_ERROR)
3085 0 : goto cleanup;
3086 1480 : if (m == MATCH_NO)
3087 : {
3088 0 : m = gfc_match_pointer_assignment ();
3089 0 : if (m == MATCH_ERROR)
3090 0 : goto cleanup;
3091 0 : if (m == MATCH_NO)
3092 0 : goto syntax;
3093 : }
3094 :
3095 1480 : c = XCNEW (gfc_code);
3096 1480 : *c = new_st;
3097 1480 : c->loc = gfc_current_locus;
3098 :
3099 1480 : gfc_clear_new_st ();
3100 1480 : new_st.op = EXEC_FORALL;
3101 1480 : new_st.expr1 = mask;
3102 1480 : new_st.ext.concur.forall_iterator = head;
3103 1480 : new_st.block = gfc_get_code (EXEC_FORALL);
3104 1480 : new_st.block->next = c;
3105 :
3106 1480 : *st = ST_FORALL;
3107 1480 : return MATCH_YES;
3108 :
3109 0 : syntax:
3110 0 : gfc_syntax_error (ST_FORALL);
3111 :
3112 0 : cleanup:
3113 0 : gfc_free_forall_iterator (head);
3114 0 : gfc_free_expr (mask);
3115 0 : gfc_free_statements (c);
3116 0 : return MATCH_NO;
3117 : }
3118 :
3119 :
3120 : /* Match a DO statement. */
3121 :
3122 : match
3123 531052 : gfc_match_do (void)
3124 : {
3125 531052 : gfc_iterator iter, *ip;
3126 531052 : locus old_loc;
3127 531052 : gfc_st_label *label;
3128 531052 : match m;
3129 :
3130 531052 : old_loc = gfc_current_locus;
3131 :
3132 531052 : memset (&iter, '\0', sizeof (gfc_iterator));
3133 531052 : label = NULL;
3134 :
3135 531052 : m = gfc_match_label ();
3136 531052 : if (m == MATCH_ERROR)
3137 : return m;
3138 :
3139 531044 : if (gfc_match (" do") != MATCH_YES)
3140 : return MATCH_NO;
3141 :
3142 32948 : m = gfc_match_st_label (&label);
3143 32948 : if (m == MATCH_ERROR)
3144 0 : goto cleanup;
3145 :
3146 : /* Match an infinite DO, make it like a DO WHILE(.TRUE.). */
3147 :
3148 32948 : if (gfc_match_eos () == MATCH_YES)
3149 : {
3150 243 : iter.end = gfc_get_logical_expr (gfc_default_logical_kind, NULL, true);
3151 243 : new_st.op = EXEC_DO_WHILE;
3152 243 : goto done;
3153 : }
3154 :
3155 : /* Match an optional comma, if no comma is found, a space is obligatory. */
3156 32705 : if (gfc_match_char (',') != MATCH_YES && gfc_match ("% ") != MATCH_YES)
3157 : return MATCH_NO;
3158 :
3159 : /* Check for balanced parens. */
3160 :
3161 32705 : if (gfc_match_parens () == MATCH_ERROR)
3162 : return MATCH_ERROR;
3163 :
3164 : /* Handle DO CONCURRENT construct. */
3165 :
3166 32703 : if (gfc_match (" concurrent") == MATCH_YES)
3167 : {
3168 233 : gfc_forall_iterator *head = NULL;
3169 233 : gfc_expr_list *local = NULL;
3170 233 : gfc_expr_list *local_tail = NULL;
3171 233 : gfc_expr_list *local_init = NULL;
3172 233 : gfc_expr_list *local_init_tail = NULL;
3173 233 : gfc_expr_list *shared = NULL;
3174 233 : gfc_expr_list *shared_tail = NULL;
3175 233 : gfc_expr_list *reduce = NULL;
3176 233 : gfc_expr_list *reduce_tail = NULL;
3177 233 : bool default_none = false;
3178 233 : gfc_expr *mask;
3179 :
3180 233 : if (!gfc_notify_std (GFC_STD_F2008, "DO CONCURRENT construct at %C"))
3181 231 : return MATCH_ERROR;
3182 :
3183 :
3184 233 : mask = NULL;
3185 233 : head = NULL;
3186 233 : m = match_forall_header (&head, &mask);
3187 :
3188 233 : if (m == MATCH_NO)
3189 2 : goto match_do_loop;
3190 231 : if (m == MATCH_ERROR)
3191 0 : goto concurr_cleanup;
3192 :
3193 669 : while (true)
3194 : {
3195 450 : gfc_gobble_whitespace ();
3196 450 : locus where = gfc_current_locus;
3197 :
3198 450 : if (gfc_match_eos () == MATCH_YES)
3199 224 : goto concurr_ok;
3200 :
3201 226 : else if (gfc_match ("local ( ") == MATCH_YES)
3202 : {
3203 110 : gfc_expr *e;
3204 168 : while (true)
3205 : {
3206 110 : if (gfc_match_variable (&e, 0) != MATCH_YES)
3207 0 : goto concurr_cleanup;
3208 :
3209 110 : if (local == NULL)
3210 46 : local = local_tail = gfc_get_expr_list ();
3211 :
3212 : else
3213 : {
3214 64 : local_tail->next = gfc_get_expr_list ();
3215 64 : local_tail = local_tail->next;
3216 : }
3217 110 : local_tail->expr = e;
3218 :
3219 110 : if (gfc_match_char (',') == MATCH_YES)
3220 58 : continue;
3221 52 : if (gfc_match_char (')') == MATCH_YES)
3222 : break;
3223 0 : goto concurr_cleanup;
3224 : }
3225 : }
3226 :
3227 174 : else if (gfc_match ("local_init ( ") == MATCH_YES)
3228 : {
3229 77 : gfc_expr *e;
3230 :
3231 117 : while (true)
3232 : {
3233 77 : if (gfc_match_variable (&e, 0) != MATCH_YES)
3234 0 : goto concurr_cleanup;
3235 :
3236 77 : if (local_init == NULL)
3237 31 : local_init = local_init_tail = gfc_get_expr_list ();
3238 :
3239 : else
3240 : {
3241 46 : local_init_tail->next = gfc_get_expr_list ();
3242 46 : local_init_tail = local_init_tail->next;
3243 : }
3244 77 : local_init_tail->expr = e;
3245 :
3246 77 : if (gfc_match_char (',') == MATCH_YES)
3247 40 : continue;
3248 37 : if (gfc_match_char (')') == MATCH_YES)
3249 : break;
3250 0 : goto concurr_cleanup;
3251 : }
3252 : }
3253 :
3254 137 : else if (gfc_match ("shared ( ") == MATCH_YES)
3255 : {
3256 161 : gfc_expr *e;
3257 267 : while (true)
3258 : {
3259 161 : if (gfc_match_variable (&e, 0) != MATCH_YES)
3260 0 : goto concurr_cleanup;
3261 :
3262 161 : if (shared == NULL)
3263 55 : shared = shared_tail = gfc_get_expr_list ();
3264 :
3265 : else
3266 : {
3267 106 : shared_tail->next = gfc_get_expr_list ();
3268 106 : shared_tail = shared_tail->next;
3269 : }
3270 161 : shared_tail->expr = e;
3271 :
3272 161 : if (gfc_match_char (',') == MATCH_YES)
3273 106 : continue;
3274 55 : if (gfc_match_char (')') == MATCH_YES)
3275 : break;
3276 0 : goto concurr_cleanup;
3277 : }
3278 : }
3279 :
3280 82 : else if (gfc_match ("default (none)") == MATCH_YES)
3281 : {
3282 52 : if (default_none)
3283 : {
3284 1 : gfc_error ("DEFAULT (NONE) specified more than once in DO "
3285 : "CONCURRENT at %C");
3286 1 : goto concurr_cleanup;
3287 : }
3288 : default_none = true;
3289 : }
3290 :
3291 30 : else if (gfc_match ("reduce ( ") == MATCH_YES)
3292 : {
3293 29 : gfc_expr *reduction_expr;
3294 29 : where = gfc_current_locus;
3295 :
3296 29 : if (gfc_match_char ('+') == MATCH_YES)
3297 15 : reduction_expr = gfc_get_operator_expr (&where,
3298 : INTRINSIC_PLUS,
3299 : NULL, NULL);
3300 :
3301 14 : else if (gfc_match_char ('*') == MATCH_YES)
3302 6 : reduction_expr = gfc_get_operator_expr (&where,
3303 : INTRINSIC_TIMES,
3304 : NULL, NULL);
3305 :
3306 8 : else if (gfc_match (".and.") == MATCH_YES)
3307 0 : reduction_expr = gfc_get_operator_expr (&where,
3308 : INTRINSIC_AND,
3309 : NULL, NULL);
3310 :
3311 8 : else if (gfc_match (".or.") == MATCH_YES)
3312 0 : reduction_expr = gfc_get_operator_expr (&where,
3313 : INTRINSIC_OR,
3314 : NULL, NULL);
3315 :
3316 8 : else if (gfc_match (".eqv.") == MATCH_YES)
3317 0 : reduction_expr = gfc_get_operator_expr (&where,
3318 : INTRINSIC_EQV,
3319 : NULL, NULL);
3320 :
3321 8 : else if (gfc_match (".neqv.") == MATCH_YES)
3322 0 : reduction_expr = gfc_get_operator_expr (&where,
3323 : INTRINSIC_NEQV,
3324 : NULL, NULL);
3325 :
3326 8 : else if (gfc_match ("min") == MATCH_YES)
3327 : {
3328 1 : reduction_expr = gfc_get_expr ();
3329 1 : reduction_expr->expr_type = EXPR_FUNCTION;
3330 1 : reduction_expr->value.function.isym
3331 1 : = gfc_intrinsic_function_by_id (GFC_ISYM_MIN);
3332 1 : reduction_expr->where = where;
3333 : }
3334 :
3335 7 : else if (gfc_match ("max") == MATCH_YES)
3336 : {
3337 5 : reduction_expr = gfc_get_expr ();
3338 5 : reduction_expr->expr_type = EXPR_FUNCTION;
3339 5 : reduction_expr->value.function.isym
3340 5 : = gfc_intrinsic_function_by_id (GFC_ISYM_MAX);
3341 5 : reduction_expr->where = where;
3342 : }
3343 :
3344 2 : else if (gfc_match ("iand") == MATCH_YES)
3345 : {
3346 1 : reduction_expr = gfc_get_expr ();
3347 1 : reduction_expr->expr_type = EXPR_FUNCTION;
3348 1 : reduction_expr->value.function.isym
3349 1 : = gfc_intrinsic_function_by_id (GFC_ISYM_IAND);
3350 1 : reduction_expr->where = where;
3351 : }
3352 :
3353 1 : else if (gfc_match ("ior") == MATCH_YES)
3354 : {
3355 0 : reduction_expr = gfc_get_expr ();
3356 0 : reduction_expr->expr_type = EXPR_FUNCTION;
3357 0 : reduction_expr->value.function.isym
3358 0 : = gfc_intrinsic_function_by_id (GFC_ISYM_IOR);
3359 0 : reduction_expr->where = where;
3360 : }
3361 :
3362 1 : else if (gfc_match ("ieor") == MATCH_YES)
3363 : {
3364 0 : reduction_expr = gfc_get_expr ();
3365 0 : reduction_expr->expr_type = EXPR_FUNCTION;
3366 0 : reduction_expr->value.function.isym
3367 0 : = gfc_intrinsic_function_by_id (GFC_ISYM_IEOR);
3368 0 : reduction_expr->where = where;
3369 : }
3370 :
3371 : else
3372 : {
3373 1 : gfc_error ("Expected reduction operator or function name "
3374 : "at %C");
3375 1 : goto concurr_cleanup;
3376 : }
3377 :
3378 28 : if (!reduce)
3379 : {
3380 20 : reduce = reduce_tail = gfc_get_expr_list ();
3381 : }
3382 : else
3383 : {
3384 8 : reduce_tail->next = gfc_get_expr_list ();
3385 8 : reduce_tail = reduce_tail->next;
3386 : }
3387 28 : reduce_tail->expr = reduction_expr;
3388 :
3389 28 : gfc_gobble_whitespace ();
3390 :
3391 28 : if (gfc_match_char (':') != MATCH_YES)
3392 : {
3393 2 : gfc_error ("Expected %<:%> at %C");
3394 2 : goto concurr_cleanup;
3395 : }
3396 :
3397 26 : while (true)
3398 : {
3399 26 : gfc_expr *reduction_expr;
3400 :
3401 26 : if (gfc_match_variable (&reduction_expr, 0) != MATCH_YES)
3402 : {
3403 0 : gfc_error ("Expected variable name in reduction list "
3404 : "at %C");
3405 0 : goto concurr_cleanup;
3406 : }
3407 :
3408 26 : if (reduce == NULL)
3409 : reduce = reduce_tail = gfc_get_expr_list ();
3410 : else
3411 : {
3412 26 : reduce_tail = reduce_tail->next = gfc_get_expr_list ();
3413 26 : reduce_tail->expr = reduction_expr;
3414 : }
3415 :
3416 26 : if (gfc_match_char (',') == MATCH_YES)
3417 0 : continue;
3418 26 : else if (gfc_match_char (')') == MATCH_YES)
3419 : break;
3420 : else
3421 : {
3422 0 : gfc_error ("Expected ',' or ')' in reduction list "
3423 : "at %C");
3424 0 : goto concurr_cleanup;
3425 : }
3426 : }
3427 :
3428 26 : if (!gfc_notify_std (GFC_STD_F2023, "REDUCE locality spec at "
3429 : "%L", &where))
3430 2 : goto concurr_cleanup;
3431 : }
3432 : else
3433 1 : goto concurr_cleanup;
3434 :
3435 219 : if (!gfc_notify_std (GFC_STD_F2018, "Locality spec at %L",
3436 : &gfc_current_locus))
3437 0 : goto concurr_cleanup;
3438 219 : }
3439 :
3440 : if (m == MATCH_NO)
3441 : return m;
3442 : if (m == MATCH_ERROR)
3443 : goto concurr_cleanup;
3444 :
3445 : if (gfc_match_eos () != MATCH_YES)
3446 : goto concurr_cleanup;
3447 :
3448 224 : concurr_ok:
3449 224 : if (label != NULL
3450 224 : && !gfc_reference_st_label (label, ST_LABEL_DO_TARGET))
3451 0 : goto concurr_cleanup;
3452 :
3453 224 : new_st.label1 = label;
3454 224 : new_st.op = EXEC_DO_CONCURRENT;
3455 224 : new_st.expr1 = mask;
3456 224 : new_st.ext.concur.forall_iterator = head;
3457 224 : new_st.ext.concur.locality[LOCALITY_LOCAL] = local;
3458 224 : new_st.ext.concur.locality[LOCALITY_LOCAL_INIT] = local_init;
3459 224 : new_st.ext.concur.locality[LOCALITY_SHARED] = shared;
3460 224 : new_st.ext.concur.locality[LOCALITY_REDUCE] = reduce;
3461 224 : new_st.ext.concur.default_none = default_none;
3462 :
3463 224 : return MATCH_YES;
3464 :
3465 7 : concurr_cleanup:
3466 7 : gfc_free_expr (mask);
3467 7 : gfc_free_forall_iterator (head);
3468 7 : gfc_free_expr_list (local);
3469 7 : gfc_free_expr_list (local_init);
3470 7 : gfc_free_expr_list (shared);
3471 7 : gfc_free_expr_list (reduce);
3472 :
3473 7 : if (!gfc_error_check ())
3474 1 : gfc_syntax_error (ST_DO);
3475 :
3476 7 : return MATCH_ERROR;
3477 : }
3478 :
3479 : /* See if we have a DO WHILE. */
3480 32470 : if (gfc_match (" while ( %e )%t", &iter.end) == MATCH_YES)
3481 : {
3482 289 : new_st.op = EXEC_DO_WHILE;
3483 289 : goto done;
3484 : }
3485 :
3486 32181 : match_do_loop:
3487 : /* The abortive DO WHILE may have done something to the symbol
3488 : table, so we start over. */
3489 32183 : gfc_undo_symbols ();
3490 32183 : gfc_current_locus = old_loc;
3491 :
3492 32183 : gfc_match_label (); /* This won't error. */
3493 32183 : gfc_match (" do "); /* This will work. */
3494 :
3495 32183 : gfc_match_st_label (&label); /* Can't error out. */
3496 32183 : gfc_match_char (','); /* Optional comma. */
3497 :
3498 32183 : m = gfc_match_iterator (&iter, 0);
3499 32183 : if (m == MATCH_NO)
3500 : return MATCH_NO;
3501 32182 : if (m == MATCH_ERROR)
3502 5 : goto cleanup;
3503 :
3504 32177 : iter.var->symtree->n.sym->attr.implied_index = 0;
3505 32177 : gfc_check_do_variable (iter.var->symtree);
3506 :
3507 32177 : if (gfc_match_eos () != MATCH_YES)
3508 : {
3509 0 : gfc_syntax_error (ST_DO);
3510 0 : goto cleanup;
3511 : }
3512 :
3513 32177 : new_st.op = EXEC_DO;
3514 :
3515 32709 : done:
3516 32709 : if (label != NULL
3517 32709 : && !gfc_reference_st_label (label, ST_LABEL_DO_TARGET))
3518 0 : goto cleanup;
3519 :
3520 32709 : new_st.label1 = label;
3521 :
3522 32709 : if (new_st.op == EXEC_DO_WHILE)
3523 532 : new_st.expr1 = iter.end;
3524 : else
3525 : {
3526 32177 : new_st.ext.iterator = ip = gfc_get_iterator ();
3527 32177 : *ip = iter;
3528 : }
3529 :
3530 : return MATCH_YES;
3531 :
3532 5 : cleanup:
3533 5 : gfc_free_iterator (&iter, 0);
3534 :
3535 5 : return MATCH_ERROR;
3536 : }
3537 :
3538 :
3539 : /* Match an EXIT or CYCLE statement. */
3540 :
3541 : static match
3542 767 : match_exit_cycle (gfc_statement st, gfc_exec_op op)
3543 : {
3544 767 : gfc_state_data *p, *o;
3545 767 : gfc_symbol *sym;
3546 767 : match m;
3547 767 : int cnt;
3548 :
3549 767 : if (gfc_match_eos () == MATCH_YES)
3550 : sym = NULL;
3551 : else
3552 : {
3553 239 : char name[GFC_MAX_SYMBOL_LEN + 1];
3554 239 : gfc_symtree* stree;
3555 :
3556 239 : m = gfc_match ("% %n%t", name);
3557 239 : if (m == MATCH_ERROR)
3558 3 : return MATCH_ERROR;
3559 239 : if (m == MATCH_NO)
3560 : {
3561 0 : gfc_syntax_error (st);
3562 0 : return MATCH_ERROR;
3563 : }
3564 :
3565 : /* Find the corresponding symbol. If there's a BLOCK statement
3566 : between here and the label, it is not in gfc_current_ns but a parent
3567 : namespace! */
3568 239 : stree = gfc_find_symtree_in_proc (name, gfc_current_ns);
3569 239 : if (!stree)
3570 : {
3571 2 : gfc_error ("Name %qs in %s statement at %C is unknown",
3572 : name, gfc_ascii_statement (st));
3573 2 : return MATCH_ERROR;
3574 : }
3575 :
3576 237 : sym = stree->n.sym;
3577 237 : if (sym->attr.flavor != FL_LABEL)
3578 : {
3579 1 : gfc_error ("Name %qs in %s statement at %C is not a construct name",
3580 : name, gfc_ascii_statement (st));
3581 1 : return MATCH_ERROR;
3582 : }
3583 : }
3584 :
3585 : /* Find the loop specified by the label (or lack of a label). */
3586 1110 : for (o = NULL, p = gfc_state_stack; p; p = p->previous)
3587 1107 : if (o == NULL && p->state == COMP_OMP_STRUCTURED_BLOCK)
3588 : o = p;
3589 1104 : else if (p->state == COMP_CRITICAL)
3590 : {
3591 3 : gfc_error("%s statement at %C leaves CRITICAL construct",
3592 : gfc_ascii_statement (st));
3593 3 : return MATCH_ERROR;
3594 : }
3595 1101 : else if (p->state == COMP_DO_CONCURRENT
3596 11 : && (op == EXEC_EXIT || (sym && sym != p->sym)))
3597 : {
3598 : /* F2008, C821 & C845. */
3599 3 : gfc_error("%s statement at %C leaves DO CONCURRENT construct",
3600 : gfc_ascii_statement (st));
3601 3 : return MATCH_ERROR;
3602 : }
3603 1091 : else if ((sym && sym == p->sym)
3604 868 : || (!sym && (p->state == COMP_DO
3605 221 : || p->state == COMP_DO_CONCURRENT)))
3606 : break;
3607 :
3608 758 : if (p == NULL)
3609 : {
3610 3 : if (sym == NULL)
3611 1 : gfc_error ("%s statement at %C is not within a construct",
3612 : gfc_ascii_statement (st));
3613 : else
3614 2 : gfc_error ("%s statement at %C is not within construct %qs",
3615 : gfc_ascii_statement (st), sym->name);
3616 :
3617 3 : return MATCH_ERROR;
3618 : }
3619 :
3620 : /* Special checks for EXIT from non-loop constructs. */
3621 755 : switch (p->state)
3622 : {
3623 : case COMP_DO:
3624 : case COMP_DO_CONCURRENT:
3625 : break;
3626 :
3627 0 : case COMP_CRITICAL:
3628 : /* This is already handled above. */
3629 0 : gcc_unreachable ();
3630 :
3631 91 : case COMP_ASSOCIATE:
3632 91 : case COMP_BLOCK:
3633 91 : case COMP_CHANGE_TEAM:
3634 91 : case COMP_IF:
3635 91 : case COMP_SELECT:
3636 91 : case COMP_SELECT_TYPE:
3637 91 : case COMP_SELECT_RANK:
3638 91 : gcc_assert (sym);
3639 91 : if (op == EXEC_CYCLE)
3640 : {
3641 2 : gfc_error ("CYCLE statement at %C is not applicable to non-loop"
3642 : " construct %qs", sym->name);
3643 2 : return MATCH_ERROR;
3644 : }
3645 89 : gcc_assert (op == EXEC_EXIT);
3646 89 : if (!gfc_notify_std (GFC_STD_F2008, "EXIT statement with no"
3647 : " do-construct-name at %C"))
3648 : return MATCH_ERROR;
3649 : break;
3650 :
3651 1 : default:
3652 1 : gfc_error ("%s statement at %C is not applicable to construct %qs",
3653 : gfc_ascii_statement (st), sym->name);
3654 1 : return MATCH_ERROR;
3655 : }
3656 :
3657 751 : if (o != NULL)
3658 : {
3659 3 : gfc_error (is_oacc (p)
3660 : ? G_("%s statement at %C leaving OpenACC structured block")
3661 : : G_("%s statement at %C leaving OpenMP structured block"),
3662 : gfc_ascii_statement (st));
3663 3 : return MATCH_ERROR;
3664 : }
3665 :
3666 1573 : for (o = p, cnt = 0; o->state == COMP_DO && o->previous != NULL; cnt++)
3667 825 : o = o->previous;
3668 :
3669 748 : int count = 1;
3670 748 : if (cnt > 0
3671 : && o != NULL
3672 652 : && o->state == COMP_OMP_STRUCTURED_BLOCK)
3673 150 : switch (o->head->op)
3674 : {
3675 20 : case EXEC_OACC_LOOP:
3676 20 : case EXEC_OACC_KERNELS_LOOP:
3677 20 : case EXEC_OACC_PARALLEL_LOOP:
3678 20 : case EXEC_OACC_SERIAL_LOOP:
3679 20 : gcc_assert (o->head->next != NULL
3680 : && (o->head->next->op == EXEC_DO
3681 : || o->head->next->op == EXEC_DO_WHILE)
3682 : && o->previous != NULL
3683 : && o->previous->tail->op == o->head->op);
3684 20 : if (o->previous->tail->ext.omp_clauses != NULL)
3685 : {
3686 : /* Both collapsed and tiled loops are lowered the same way, but are
3687 : not compatible. In gfc_trans_omp_do, the tile is prioritized. */
3688 20 : if (o->previous->tail->ext.omp_clauses->tile_list)
3689 : {
3690 : count = 0;
3691 : gfc_expr_list *el
3692 : = o->previous->tail->ext.omp_clauses->tile_list;
3693 6 : for ( ; el; el = el->next)
3694 4 : ++count;
3695 : }
3696 18 : else if (o->previous->tail->ext.omp_clauses->collapse > 1)
3697 20 : count = o->previous->tail->ext.omp_clauses->collapse;
3698 : }
3699 20 : if (st == ST_EXIT && cnt <= count)
3700 : {
3701 14 : gfc_error ("EXIT statement at %C terminating !$ACC LOOP loop");
3702 14 : return MATCH_ERROR;
3703 : }
3704 6 : if (st == ST_CYCLE && cnt < count)
3705 : {
3706 4 : gfc_error (o->previous->tail->ext.omp_clauses->tile_list
3707 : ? G_("CYCLE statement at %C to non-innermost tiled "
3708 : "!$ACC LOOP loop")
3709 : : G_("CYCLE statement at %C to non-innermost collapsed "
3710 : "!$ACC LOOP loop"));
3711 4 : return MATCH_ERROR;
3712 : }
3713 : break;
3714 127 : case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
3715 127 : case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
3716 127 : case EXEC_OMP_TARGET_SIMD:
3717 127 : case EXEC_OMP_TASKLOOP_SIMD:
3718 127 : case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
3719 127 : case EXEC_OMP_MASTER_TASKLOOP_SIMD:
3720 127 : case EXEC_OMP_PARALLEL_MASKED_TASKLOOP_SIMD:
3721 127 : case EXEC_OMP_MASKED_TASKLOOP_SIMD:
3722 127 : case EXEC_OMP_PARALLEL_DO_SIMD:
3723 127 : case EXEC_OMP_DISTRIBUTE_SIMD:
3724 127 : case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
3725 127 : case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
3726 127 : case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
3727 127 : case EXEC_OMP_LOOP:
3728 127 : case EXEC_OMP_PARALLEL_LOOP:
3729 127 : case EXEC_OMP_TEAMS_LOOP:
3730 127 : case EXEC_OMP_TARGET_PARALLEL_LOOP:
3731 127 : case EXEC_OMP_TARGET_TEAMS_LOOP:
3732 127 : case EXEC_OMP_DO:
3733 127 : case EXEC_OMP_PARALLEL_DO:
3734 127 : case EXEC_OMP_SIMD:
3735 127 : case EXEC_OMP_DO_SIMD:
3736 127 : case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
3737 127 : case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
3738 127 : case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
3739 127 : case EXEC_OMP_TARGET_PARALLEL_DO:
3740 127 : case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
3741 :
3742 127 : gcc_assert (o->head->next != NULL
3743 : && (o->head->next->op == EXEC_DO
3744 : || o->head->next->op == EXEC_DO_WHILE)
3745 : && o->previous != NULL
3746 : && o->previous->tail->op == o->head->op);
3747 127 : if (o->previous->tail->ext.omp_clauses != NULL)
3748 : {
3749 127 : if (o->previous->tail->ext.omp_clauses->collapse > 1)
3750 : count = o->previous->tail->ext.omp_clauses->collapse;
3751 127 : if (o->previous->tail->ext.omp_clauses->orderedc)
3752 0 : count = o->previous->tail->ext.omp_clauses->orderedc;
3753 : }
3754 127 : if (st == ST_EXIT && cnt <= count)
3755 : {
3756 63 : gfc_error ("EXIT statement at %C terminating !$OMP DO loop");
3757 63 : return MATCH_ERROR;
3758 : }
3759 64 : if (st == ST_CYCLE && cnt < count)
3760 : {
3761 3 : gfc_error ("CYCLE statement at %C to non-innermost collapsed "
3762 : "!$OMP DO loop");
3763 3 : return MATCH_ERROR;
3764 : }
3765 : break;
3766 : default:
3767 : break;
3768 : }
3769 :
3770 : /* Save the first statement in the construct - needed by the backend. */
3771 664 : new_st.ext.which_construct = p->construct;
3772 :
3773 664 : new_st.op = op;
3774 :
3775 664 : return MATCH_YES;
3776 : }
3777 :
3778 :
3779 : /* Match the EXIT statement. */
3780 :
3781 : match
3782 622 : gfc_match_exit (void)
3783 : {
3784 622 : return match_exit_cycle (ST_EXIT, EXEC_EXIT);
3785 : }
3786 :
3787 :
3788 : /* Match the CYCLE statement. */
3789 :
3790 : match
3791 145 : gfc_match_cycle (void)
3792 : {
3793 145 : return match_exit_cycle (ST_CYCLE, EXEC_CYCLE);
3794 : }
3795 :
3796 :
3797 : /* Match a stop-code after an (ERROR) STOP or PAUSE statement. The
3798 : requirements for a stop-code differ in the standards.
3799 :
3800 : Fortran 95 has
3801 :
3802 : R840 stop-stmt is STOP [ stop-code ]
3803 : R841 stop-code is scalar-char-constant
3804 : or digit [ digit [ digit [ digit [ digit ] ] ] ]
3805 :
3806 : Fortran 2003 matches Fortran 95 except R840 and R841 are now R849 and R850.
3807 : Fortran 2008 has
3808 :
3809 : R855 stop-stmt is STOP [ stop-code ]
3810 : R856 allstop-stmt is ALL STOP [ stop-code ]
3811 : R857 stop-code is scalar-default-char-constant-expr
3812 : or scalar-int-constant-expr
3813 : Fortran 2018 has
3814 :
3815 : R1160 stop-stmt is STOP [ stop-code ] [ , QUIET = scalar-logical-expr]
3816 : R1161 error-stop-stmt is
3817 : ERROR STOP [ stop-code ] [ , QUIET = scalar-logical-expr]
3818 : R1162 stop-code is scalar-default-char-expr
3819 : or scalar-int-expr
3820 :
3821 : For free-form source code, all standards contain a statement of the form:
3822 :
3823 : A blank shall be used to separate names, constants, or labels from
3824 : adjacent keywords, names, constants, or labels.
3825 :
3826 : A stop-code is not a name, constant, or label. So, under Fortran 95 and 2003,
3827 :
3828 : STOP123
3829 :
3830 : is valid, but it is invalid Fortran 2008. */
3831 :
3832 : static match
3833 218789 : gfc_match_stopcode (gfc_statement st)
3834 : {
3835 218789 : gfc_expr *e = NULL;
3836 218789 : gfc_expr *quiet = NULL;
3837 218789 : match m;
3838 218789 : bool f95, f03, f08;
3839 218789 : char c;
3840 :
3841 : /* Set f95 for -std=f95. */
3842 218789 : f95 = (gfc_option.allow_std == GFC_STD_OPT_F95);
3843 :
3844 : /* Set f03 for -std=f2003. */
3845 218789 : f03 = (gfc_option.allow_std == GFC_STD_OPT_F03);
3846 :
3847 : /* Set f08 for -std=f2008. */
3848 218789 : f08 = (gfc_option.allow_std == GFC_STD_OPT_F08);
3849 :
3850 : /* Plain STOP statement? */
3851 218789 : if (gfc_match_eos () == MATCH_YES)
3852 20460 : goto checks;
3853 :
3854 : /* Look for a blank between STOP and the stop-code for F2008 or later.
3855 : But allow for F2018's ,QUIET= specifier. */
3856 198329 : c = gfc_peek_ascii_char ();
3857 :
3858 198329 : if (gfc_current_form != FORM_FIXED && !(f95 || f03) && c != ',')
3859 : {
3860 : /* Look for end-of-statement. There is no stop-code. */
3861 : if (c == '\n' || c == '!' || c == ';')
3862 0 : goto done;
3863 :
3864 : if (c != ' ')
3865 : {
3866 3 : gfc_error ("Blank required in %s statement near %C",
3867 : gfc_ascii_statement (st));
3868 3 : return MATCH_ERROR;
3869 : }
3870 : }
3871 :
3872 5010 : if (c == ' ')
3873 : {
3874 193922 : gfc_gobble_whitespace ();
3875 193922 : c = gfc_peek_ascii_char ();
3876 : }
3877 198326 : if (c != ',')
3878 : {
3879 198322 : int stopcode;
3880 198322 : locus old_locus;
3881 :
3882 : /* First look for the F95 or F2003 digit [...] construct. */
3883 198322 : old_locus = gfc_current_locus;
3884 198322 : m = gfc_match_small_int (&stopcode);
3885 198322 : if (m == MATCH_YES && (f95 || f03))
3886 : {
3887 611 : if (stopcode < 0)
3888 : {
3889 2 : gfc_error ("STOP code at %C cannot be negative");
3890 4 : return MATCH_ERROR;
3891 : }
3892 :
3893 609 : if (stopcode > 99999)
3894 : {
3895 2 : gfc_error ("STOP code at %C contains too many digits");
3896 2 : return MATCH_ERROR;
3897 : }
3898 : }
3899 :
3900 : /* Reset the locus and now load gfc_expr. */
3901 198318 : gfc_current_locus = old_locus;
3902 198318 : m = gfc_match_expr (&e);
3903 198318 : if (m == MATCH_ERROR)
3904 0 : goto cleanup;
3905 198318 : if (m == MATCH_NO)
3906 0 : goto syntax;
3907 : }
3908 :
3909 198322 : if (gfc_match (" , quiet = %e", &quiet) == MATCH_YES)
3910 : {
3911 38 : if (!gfc_notify_std (GFC_STD_F2018, "QUIET= specifier for %s at %L",
3912 38 : gfc_ascii_statement (st), &quiet->where))
3913 0 : goto cleanup;
3914 : }
3915 :
3916 198322 : if (gfc_match_eos () != MATCH_YES)
3917 1 : goto syntax;
3918 :
3919 198321 : checks:
3920 :
3921 218781 : if (gfc_pure (NULL))
3922 : {
3923 267 : if (st == ST_ERROR_STOP)
3924 : {
3925 267 : if (!gfc_notify_std (GFC_STD_F2018, "%s statement at %C in PURE "
3926 : "procedure", gfc_ascii_statement (st)))
3927 1 : goto cleanup;
3928 : }
3929 : else
3930 : {
3931 0 : gfc_error ("%s statement not allowed in PURE procedure at %C",
3932 : gfc_ascii_statement (st));
3933 0 : goto cleanup;
3934 : }
3935 : }
3936 :
3937 218780 : gfc_unset_implicit_pure (NULL);
3938 :
3939 218780 : if (st == ST_STOP && gfc_find_state (COMP_CRITICAL))
3940 : {
3941 1 : gfc_error ("Image control statement STOP at %C in CRITICAL block");
3942 1 : goto cleanup;
3943 : }
3944 218779 : if (st == ST_STOP && gfc_find_state (COMP_DO_CONCURRENT))
3945 : {
3946 1 : gfc_error ("Image control statement STOP at %C in DO CONCURRENT block");
3947 1 : goto cleanup;
3948 : }
3949 :
3950 218778 : if (e != NULL)
3951 : {
3952 198315 : if (!gfc_simplify_expr (e, 0))
3953 1 : goto cleanup;
3954 :
3955 : /* Test for F95 and F2003 style STOP stop-code. */
3956 198314 : if (e->expr_type != EXPR_CONSTANT && (f95 || f03))
3957 : {
3958 0 : gfc_error ("STOP code at %L must be a scalar CHARACTER constant "
3959 : "or digit[digit[digit[digit[digit]]]]", &e->where);
3960 0 : goto cleanup;
3961 : }
3962 :
3963 : /* If this is F2008, it could be an init expression. */
3964 198314 : if (f08)
3965 : {
3966 635 : gfc_reduce_init_expr (e);
3967 635 : if (e->expr_type != EXPR_CONSTANT)
3968 : {
3969 1 : gfc_error ("STOP code at %L must be a scalar constant "
3970 : "expression", &e->where);
3971 1 : goto cleanup;
3972 : }
3973 : }
3974 :
3975 : /* For types known at parse time, check immediately. For BT_UNKNOWN
3976 : (e.g. a forward-referenced contained function) defer to resolve. */
3977 198313 : if (e->ts.type != BT_UNKNOWN
3978 198297 : && !(e->ts.type == BT_CHARACTER || e->ts.type == BT_INTEGER))
3979 : {
3980 1 : gfc_error ("STOP code at %L must be either INTEGER or CHARACTER type",
3981 : &e->where);
3982 1 : goto cleanup;
3983 : }
3984 :
3985 198312 : if (e->rank != 0)
3986 : {
3987 1 : gfc_error ("STOP code at %L must be scalar", &e->where);
3988 1 : goto cleanup;
3989 : }
3990 :
3991 198311 : if (e->ts.type == BT_CHARACTER
3992 488 : && e->ts.kind != gfc_default_character_kind)
3993 : {
3994 0 : gfc_error ("STOP code at %L must be default character KIND=%d",
3995 : &e->where, (int) gfc_default_character_kind);
3996 0 : goto cleanup;
3997 : }
3998 :
3999 197807 : if (e->ts.type == BT_INTEGER && e->ts.kind != gfc_default_integer_kind
4000 198319 : && !gfc_notify_std (GFC_STD_F2018,
4001 : "STOP code at %L must be default integer KIND=%d",
4002 : &e->where, (int) gfc_default_integer_kind))
4003 0 : goto cleanup;
4004 : }
4005 :
4006 218774 : if (quiet != NULL)
4007 : {
4008 38 : if (!gfc_simplify_expr (quiet, 0))
4009 0 : goto cleanup;
4010 :
4011 38 : if (quiet->rank != 0)
4012 : {
4013 1 : gfc_error ("QUIET specifier at %L must be a scalar LOGICAL",
4014 : &quiet->where);
4015 1 : goto cleanup;
4016 : }
4017 : }
4018 :
4019 218736 : done:
4020 :
4021 218773 : switch (st)
4022 : {
4023 179610 : case ST_STOP:
4024 179610 : new_st.op = EXEC_STOP;
4025 179610 : break;
4026 39133 : case ST_ERROR_STOP:
4027 39133 : new_st.op = EXEC_ERROR_STOP;
4028 39133 : break;
4029 30 : case ST_PAUSE:
4030 30 : new_st.op = EXEC_PAUSE;
4031 30 : break;
4032 0 : default:
4033 0 : gcc_unreachable ();
4034 : }
4035 :
4036 218773 : new_st.expr1 = e;
4037 218773 : new_st.expr2 = quiet;
4038 218773 : new_st.ext.stop_code = -1;
4039 :
4040 218773 : return MATCH_YES;
4041 :
4042 1 : syntax:
4043 1 : gfc_syntax_error (st);
4044 :
4045 9 : cleanup:
4046 :
4047 9 : gfc_free_expr (e);
4048 9 : gfc_free_expr (quiet);
4049 9 : return MATCH_ERROR;
4050 : }
4051 :
4052 :
4053 : /* Match the (deprecated) PAUSE statement. */
4054 :
4055 : match
4056 30 : gfc_match_pause (void)
4057 : {
4058 30 : match m;
4059 :
4060 30 : m = gfc_match_stopcode (ST_PAUSE);
4061 30 : if (m == MATCH_YES)
4062 : {
4063 30 : if (!gfc_notify_std (GFC_STD_F95_DEL, "PAUSE statement at %C"))
4064 0 : m = MATCH_ERROR;
4065 : }
4066 30 : return m;
4067 : }
4068 :
4069 :
4070 : /* Match the STOP statement. */
4071 :
4072 : match
4073 179625 : gfc_match_stop (void)
4074 : {
4075 179625 : return gfc_match_stopcode (ST_STOP);
4076 : }
4077 :
4078 :
4079 : /* Match the ERROR STOP statement. */
4080 :
4081 : match
4082 39135 : gfc_match_error_stop (void)
4083 : {
4084 39135 : if (!gfc_notify_std (GFC_STD_F2008, "ERROR STOP statement at %C"))
4085 : return MATCH_ERROR;
4086 :
4087 39134 : return gfc_match_stopcode (ST_ERROR_STOP);
4088 : }
4089 :
4090 : /* Match EVENT POST/WAIT statement. Syntax:
4091 : EVENT POST ( event-variable [, sync-stat-list] )
4092 : EVENT WAIT ( event-variable [, wait-spec-list] )
4093 : with
4094 : wait-spec-list is sync-stat-list or until-spec
4095 : until-spec is UNTIL_COUNT = scalar-int-expr
4096 : sync-stat is STAT= or ERRMSG=. */
4097 :
4098 : static match
4099 59 : event_statement (gfc_statement st)
4100 : {
4101 59 : match m;
4102 59 : gfc_expr *tmp, *eventvar, *until_count, *stat, *errmsg;
4103 59 : bool saw_until_count, saw_stat, saw_errmsg;
4104 :
4105 59 : tmp = eventvar = until_count = stat = errmsg = NULL;
4106 59 : saw_until_count = saw_stat = saw_errmsg = false;
4107 :
4108 59 : if (gfc_pure (NULL))
4109 : {
4110 0 : gfc_error ("Image control statement EVENT %s at %C in PURE procedure",
4111 : st == ST_EVENT_POST ? "POST" : "WAIT");
4112 0 : return MATCH_ERROR;
4113 : }
4114 :
4115 59 : gfc_unset_implicit_pure (NULL);
4116 :
4117 59 : if (flag_coarray == GFC_FCOARRAY_NONE)
4118 : {
4119 0 : gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
4120 : return MATCH_ERROR;
4121 : }
4122 :
4123 59 : if (gfc_find_state (COMP_CRITICAL))
4124 : {
4125 0 : gfc_error ("Image control statement EVENT %s at %C in CRITICAL block",
4126 : st == ST_EVENT_POST ? "POST" : "WAIT");
4127 0 : return MATCH_ERROR;
4128 : }
4129 :
4130 59 : if (gfc_find_state (COMP_DO_CONCURRENT))
4131 : {
4132 0 : gfc_error ("Image control statement EVENT %s at %C in DO CONCURRENT "
4133 : "block", st == ST_EVENT_POST ? "POST" : "WAIT");
4134 0 : return MATCH_ERROR;
4135 : }
4136 :
4137 59 : if (gfc_match_char ('(') != MATCH_YES)
4138 0 : goto syntax;
4139 :
4140 59 : if (gfc_match ("%e", &eventvar) != MATCH_YES)
4141 1 : goto syntax;
4142 58 : m = gfc_match_char (',');
4143 58 : if (m == MATCH_ERROR)
4144 0 : goto syntax;
4145 58 : if (m == MATCH_NO)
4146 : {
4147 34 : m = gfc_match_char (')');
4148 34 : if (m == MATCH_YES)
4149 34 : goto done;
4150 0 : goto syntax;
4151 : }
4152 :
4153 30 : for (;;)
4154 : {
4155 30 : m = gfc_match (" stat = %v", &tmp);
4156 30 : if (m == MATCH_ERROR)
4157 0 : goto syntax;
4158 30 : if (m == MATCH_YES)
4159 : {
4160 12 : if (saw_stat)
4161 : {
4162 0 : gfc_error ("Redundant STAT tag found at %L", &tmp->where);
4163 0 : goto cleanup;
4164 : }
4165 12 : stat = tmp;
4166 12 : saw_stat = true;
4167 :
4168 12 : m = gfc_match_char (',');
4169 12 : if (m == MATCH_YES)
4170 6 : continue;
4171 :
4172 6 : tmp = NULL;
4173 6 : break;
4174 : }
4175 :
4176 18 : m = gfc_match (" errmsg = %v", &tmp);
4177 18 : if (m == MATCH_ERROR)
4178 0 : goto syntax;
4179 18 : if (m == MATCH_YES)
4180 : {
4181 0 : if (saw_errmsg)
4182 : {
4183 0 : gfc_error ("Redundant ERRMSG tag found at %L", &tmp->where);
4184 0 : goto cleanup;
4185 : }
4186 0 : errmsg = tmp;
4187 0 : saw_errmsg = true;
4188 :
4189 0 : m = gfc_match_char (',');
4190 0 : if (m == MATCH_YES)
4191 0 : continue;
4192 :
4193 0 : tmp = NULL;
4194 0 : break;
4195 : }
4196 :
4197 18 : m = gfc_match (" until_count = %e", &tmp);
4198 18 : if (m == MATCH_ERROR || st == ST_EVENT_POST)
4199 0 : goto syntax;
4200 18 : if (m == MATCH_YES)
4201 : {
4202 18 : if (saw_until_count)
4203 : {
4204 0 : gfc_error ("Redundant UNTIL_COUNT tag found at %L",
4205 0 : &tmp->where);
4206 0 : goto cleanup;
4207 : }
4208 18 : until_count = tmp;
4209 18 : saw_until_count = true;
4210 :
4211 18 : m = gfc_match_char (',');
4212 18 : if (m == MATCH_YES)
4213 0 : continue;
4214 :
4215 18 : tmp = NULL;
4216 18 : break;
4217 : }
4218 :
4219 : break;
4220 : }
4221 :
4222 24 : if (m == MATCH_ERROR)
4223 0 : goto syntax;
4224 :
4225 24 : if (gfc_match (" )%t") != MATCH_YES)
4226 0 : goto syntax;
4227 :
4228 24 : done:
4229 58 : switch (st)
4230 : {
4231 34 : case ST_EVENT_POST:
4232 34 : new_st.op = EXEC_EVENT_POST;
4233 34 : break;
4234 24 : case ST_EVENT_WAIT:
4235 24 : new_st.op = EXEC_EVENT_WAIT;
4236 24 : break;
4237 0 : default:
4238 0 : gcc_unreachable ();
4239 : }
4240 :
4241 58 : new_st.expr1 = eventvar;
4242 58 : new_st.expr2 = stat;
4243 58 : new_st.expr3 = errmsg;
4244 58 : new_st.expr4 = until_count;
4245 :
4246 58 : return MATCH_YES;
4247 :
4248 1 : syntax:
4249 1 : gfc_syntax_error (st);
4250 :
4251 1 : cleanup:
4252 1 : if (until_count != tmp)
4253 0 : gfc_free_expr (until_count);
4254 1 : if (errmsg != tmp)
4255 0 : gfc_free_expr (errmsg);
4256 1 : if (stat != tmp)
4257 0 : gfc_free_expr (stat);
4258 :
4259 1 : gfc_free_expr (tmp);
4260 1 : gfc_free_expr (eventvar);
4261 :
4262 1 : return MATCH_ERROR;
4263 :
4264 : }
4265 :
4266 :
4267 : match
4268 35 : gfc_match_event_post (void)
4269 : {
4270 35 : if (!gfc_notify_std (GFC_STD_F2018, "EVENT POST statement at %C"))
4271 : return MATCH_ERROR;
4272 :
4273 35 : return event_statement (ST_EVENT_POST);
4274 : }
4275 :
4276 :
4277 : match
4278 24 : gfc_match_event_wait (void)
4279 : {
4280 24 : if (!gfc_notify_std (GFC_STD_F2018, "EVENT WAIT statement at %C"))
4281 : return MATCH_ERROR;
4282 :
4283 24 : return event_statement (ST_EVENT_WAIT);
4284 : }
4285 :
4286 :
4287 : /* Match a FAIL IMAGE statement. */
4288 :
4289 : match
4290 16 : gfc_match_fail_image (void)
4291 : {
4292 16 : if (!gfc_notify_std (GFC_STD_F2018, "FAIL IMAGE statement at %C"))
4293 : return MATCH_ERROR;
4294 :
4295 16 : if (gfc_match_char ('(') == MATCH_YES)
4296 3 : goto syntax;
4297 :
4298 13 : new_st.op = EXEC_FAIL_IMAGE;
4299 :
4300 13 : return MATCH_YES;
4301 :
4302 3 : syntax:
4303 3 : gfc_syntax_error (ST_FAIL_IMAGE);
4304 :
4305 3 : return MATCH_ERROR;
4306 : }
4307 :
4308 : /* Match a FORM TEAM statement. */
4309 :
4310 : match
4311 138 : gfc_match_form_team (void)
4312 : {
4313 138 : match m;
4314 138 : gfc_expr *teamid, *team, *new_index;
4315 :
4316 138 : teamid = team = new_index = NULL;
4317 :
4318 138 : if (!gfc_notify_std (GFC_STD_F2018, "FORM TEAM statement at %C"))
4319 : return MATCH_ERROR;
4320 :
4321 138 : if (gfc_match_char ('(') == MATCH_NO)
4322 1 : goto syntax;
4323 :
4324 137 : new_st.op = EXEC_FORM_TEAM;
4325 :
4326 137 : if (gfc_match ("%e", &teamid) != MATCH_YES)
4327 0 : goto syntax;
4328 137 : m = gfc_match_char (',');
4329 137 : if (m == MATCH_ERROR)
4330 0 : goto syntax;
4331 137 : if (gfc_match ("%e", &team) != MATCH_YES)
4332 1 : goto syntax;
4333 :
4334 136 : m = gfc_match_char (',');
4335 136 : if (m == MATCH_ERROR)
4336 0 : goto syntax;
4337 136 : if (m == MATCH_NO)
4338 : {
4339 86 : m = gfc_match_char (')');
4340 86 : if (m == MATCH_YES)
4341 86 : goto done;
4342 0 : goto syntax;
4343 : }
4344 :
4345 116 : for (;;)
4346 : {
4347 83 : m = match_stat_errmsg (&new_st.ext.sync_stat, ST_FORM_TEAM);
4348 83 : if (m == MATCH_ERROR)
4349 2 : goto cleanup;
4350 :
4351 81 : m = match_named_arg (" new_index = %e", "NEW_INDEX", &new_index,
4352 : ST_FORM_TEAM);
4353 81 : if (m == MATCH_ERROR)
4354 3 : goto cleanup;
4355 :
4356 78 : m = gfc_match_char (',');
4357 78 : if (m == MATCH_YES)
4358 33 : continue;
4359 :
4360 45 : break;
4361 : }
4362 :
4363 45 : if (m == MATCH_ERROR)
4364 0 : goto syntax;
4365 :
4366 45 : if (gfc_match (" )%t") != MATCH_YES)
4367 1 : goto syntax;
4368 :
4369 44 : done:
4370 :
4371 130 : new_st.expr1 = teamid;
4372 130 : new_st.expr2 = team;
4373 130 : new_st.expr3 = new_index;
4374 :
4375 130 : return MATCH_YES;
4376 :
4377 3 : syntax:
4378 3 : gfc_syntax_error (ST_FORM_TEAM);
4379 :
4380 8 : cleanup:
4381 8 : gfc_free_expr (new_index);
4382 8 : gfc_free_expr (new_st.ext.sync_stat.stat);
4383 8 : gfc_free_expr (new_st.ext.sync_stat.errmsg);
4384 8 : new_st.ext.sync_stat = {NULL, NULL};
4385 :
4386 8 : gfc_free_expr (team);
4387 8 : gfc_free_expr (teamid);
4388 :
4389 8 : return MATCH_ERROR;
4390 : }
4391 :
4392 : /* Match a CHANGE TEAM statement. */
4393 :
4394 : match
4395 495179 : gfc_match_change_team (void)
4396 : {
4397 495179 : match m;
4398 495179 : gfc_expr *team = NULL;
4399 :
4400 495179 : if (gfc_match_label () == MATCH_ERROR)
4401 : return MATCH_ERROR;
4402 :
4403 495171 : if (gfc_match (" change% team") != MATCH_YES)
4404 : return MATCH_NO;
4405 :
4406 82 : if (!gfc_notify_std (GFC_STD_F2018, "CHANGE TEAM statement at %C"))
4407 : return MATCH_ERROR;
4408 :
4409 82 : if (gfc_match_char ('(') == MATCH_NO)
4410 1 : goto syntax;
4411 :
4412 81 : if (gfc_match ("%e", &team) != MATCH_YES)
4413 0 : goto syntax;
4414 :
4415 81 : m = gfc_match_char (',');
4416 81 : if (m == MATCH_ERROR)
4417 0 : goto syntax;
4418 81 : if (m == MATCH_NO)
4419 : {
4420 56 : m = gfc_match_char (')');
4421 56 : if (m == MATCH_YES)
4422 56 : goto done;
4423 0 : goto syntax;
4424 : }
4425 :
4426 25 : m = match_association_list (true);
4427 25 : if (m == MATCH_ERROR)
4428 6 : goto cleanup;
4429 19 : else if (m == MATCH_NO)
4430 36 : for (;;)
4431 : {
4432 26 : m = match_stat_errmsg (&new_st.ext.block.sync_stat, ST_CHANGE_TEAM);
4433 26 : if (m == MATCH_ERROR)
4434 2 : goto cleanup;
4435 :
4436 24 : if (gfc_match_char (',') == MATCH_YES)
4437 10 : continue;
4438 :
4439 : break;
4440 : }
4441 :
4442 17 : if (gfc_match (" )%t") != MATCH_YES)
4443 0 : goto syntax;
4444 :
4445 17 : done:
4446 :
4447 73 : new_st.expr1 = team;
4448 :
4449 73 : return MATCH_YES;
4450 :
4451 1 : syntax:
4452 1 : gfc_syntax_error (ST_CHANGE_TEAM);
4453 :
4454 9 : cleanup:
4455 9 : gfc_free_expr (new_st.ext.block.sync_stat.stat);
4456 9 : gfc_free_expr (new_st.ext.block.sync_stat.errmsg);
4457 9 : new_st.ext.block.sync_stat = {NULL, NULL};
4458 9 : gfc_free_association_list (new_st.ext.block.assoc);
4459 9 : new_st.ext.block.assoc = NULL;
4460 9 : gfc_free_expr (team);
4461 :
4462 9 : return MATCH_ERROR;
4463 : }
4464 :
4465 : /* Match an END TEAM statement. */
4466 :
4467 : match
4468 74 : gfc_match_end_team (void)
4469 : {
4470 74 : if (gfc_match_eos () == MATCH_YES)
4471 55 : goto done;
4472 :
4473 19 : if (gfc_match_char ('(') != MATCH_YES)
4474 : {
4475 : /* There could be a team-construct-name following. Let caller decide
4476 : about error. */
4477 2 : new_st.op = EXEC_END_TEAM;
4478 2 : return MATCH_NO;
4479 : }
4480 :
4481 37 : for (;;)
4482 : {
4483 27 : if (match_stat_errmsg (&new_st.ext.sync_stat, ST_END_TEAM) == MATCH_ERROR)
4484 2 : goto cleanup;
4485 :
4486 25 : if (gfc_match_char (',') == MATCH_YES)
4487 10 : continue;
4488 :
4489 15 : break;
4490 : }
4491 :
4492 15 : if (gfc_match_char (')') != MATCH_YES)
4493 0 : goto syntax;
4494 :
4495 15 : done:
4496 :
4497 70 : new_st.op = EXEC_END_TEAM;
4498 :
4499 70 : return MATCH_YES;
4500 :
4501 0 : syntax:
4502 0 : gfc_syntax_error (ST_END_TEAM);
4503 :
4504 2 : cleanup:
4505 2 : gfc_free_expr (new_st.ext.sync_stat.stat);
4506 2 : gfc_free_expr (new_st.ext.sync_stat.errmsg);
4507 2 : new_st.ext.sync_stat = {NULL, NULL};
4508 :
4509 : /* Try to match the closing bracket to allow error recovery. */
4510 2 : gfc_match_char (')');
4511 :
4512 2 : return MATCH_ERROR;
4513 : }
4514 :
4515 : /* Match a SYNC TEAM statement. */
4516 :
4517 : match
4518 47 : gfc_match_sync_team (void)
4519 : {
4520 47 : match m;
4521 47 : gfc_expr *team = NULL;
4522 :
4523 47 : if (!gfc_notify_std (GFC_STD_F2018, "SYNC TEAM statement at %C"))
4524 : return MATCH_ERROR;
4525 :
4526 47 : if (gfc_match_char ('(') == MATCH_NO)
4527 1 : goto syntax;
4528 :
4529 46 : new_st.op = EXEC_SYNC_TEAM;
4530 :
4531 46 : if (gfc_match ("%e", &team) != MATCH_YES)
4532 0 : goto syntax;
4533 :
4534 46 : m = gfc_match_char (',');
4535 46 : if (m == MATCH_ERROR)
4536 0 : goto syntax;
4537 46 : if (m == MATCH_NO)
4538 : {
4539 29 : m = gfc_match_char (')');
4540 29 : if (m == MATCH_YES)
4541 29 : goto done;
4542 0 : goto syntax;
4543 : }
4544 :
4545 37 : for (;;)
4546 : {
4547 27 : m = match_stat_errmsg (&new_st.ext.sync_stat, ST_SYNC_TEAM);
4548 27 : if (m == MATCH_ERROR)
4549 2 : goto cleanup;
4550 :
4551 25 : if (gfc_match_char (',') == MATCH_YES)
4552 10 : continue;
4553 :
4554 15 : break;
4555 : }
4556 :
4557 15 : if (gfc_match (" )%t") != MATCH_YES)
4558 1 : goto syntax;
4559 :
4560 14 : done:
4561 :
4562 43 : new_st.expr1 = team;
4563 :
4564 43 : return MATCH_YES;
4565 :
4566 2 : syntax:
4567 2 : gfc_syntax_error (ST_SYNC_TEAM);
4568 :
4569 4 : cleanup:
4570 4 : gfc_free_expr (new_st.ext.sync_stat.stat);
4571 4 : gfc_free_expr (new_st.ext.sync_stat.errmsg);
4572 4 : new_st.ext.sync_stat = {NULL, NULL};
4573 :
4574 4 : gfc_free_expr (team);
4575 :
4576 4 : return MATCH_ERROR;
4577 : }
4578 :
4579 : /* Match LOCK/UNLOCK statement. Syntax:
4580 : LOCK ( lock-variable [ , lock-stat-list ] )
4581 : UNLOCK ( lock-variable [ , sync-stat-list ] )
4582 : where lock-stat is ACQUIRED_LOCK or sync-stat
4583 : and sync-stat is STAT= or ERRMSG=. */
4584 :
4585 : static match
4586 144 : lock_unlock_statement (gfc_statement st)
4587 : {
4588 144 : match m;
4589 144 : gfc_expr *tmp, *lockvar, *acq_lock, *stat, *errmsg;
4590 144 : bool saw_acq_lock, saw_stat, saw_errmsg;
4591 :
4592 144 : tmp = lockvar = acq_lock = stat = errmsg = NULL;
4593 144 : saw_acq_lock = saw_stat = saw_errmsg = false;
4594 :
4595 144 : if (gfc_pure (NULL))
4596 : {
4597 0 : gfc_error ("Image control statement %s at %C in PURE procedure",
4598 : st == ST_LOCK ? "LOCK" : "UNLOCK");
4599 0 : return MATCH_ERROR;
4600 : }
4601 :
4602 144 : gfc_unset_implicit_pure (NULL);
4603 :
4604 144 : if (flag_coarray == GFC_FCOARRAY_NONE)
4605 : {
4606 0 : gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
4607 : return MATCH_ERROR;
4608 : }
4609 :
4610 144 : if (gfc_find_state (COMP_CRITICAL))
4611 : {
4612 2 : gfc_error ("Image control statement %s at %C in CRITICAL block",
4613 : st == ST_LOCK ? "LOCK" : "UNLOCK");
4614 2 : return MATCH_ERROR;
4615 : }
4616 :
4617 142 : if (gfc_find_state (COMP_DO_CONCURRENT))
4618 : {
4619 2 : gfc_error ("Image control statement %s at %C in DO CONCURRENT block",
4620 : st == ST_LOCK ? "LOCK" : "UNLOCK");
4621 2 : return MATCH_ERROR;
4622 : }
4623 :
4624 140 : if (gfc_match_char ('(') != MATCH_YES)
4625 0 : goto syntax;
4626 :
4627 140 : if (gfc_match ("%e", &lockvar) != MATCH_YES)
4628 1 : goto syntax;
4629 139 : m = gfc_match_char (',');
4630 139 : if (m == MATCH_ERROR)
4631 0 : goto syntax;
4632 139 : if (m == MATCH_NO)
4633 : {
4634 77 : m = gfc_match_char (')');
4635 77 : if (m == MATCH_YES)
4636 77 : goto done;
4637 0 : goto syntax;
4638 : }
4639 :
4640 66 : for (;;)
4641 : {
4642 66 : m = gfc_match (" stat = %v", &tmp);
4643 66 : if (m == MATCH_ERROR)
4644 0 : goto syntax;
4645 66 : if (m == MATCH_YES)
4646 : {
4647 42 : if (saw_stat)
4648 : {
4649 0 : gfc_error ("Redundant STAT tag found at %L", &tmp->where);
4650 0 : goto cleanup;
4651 : }
4652 42 : stat = tmp;
4653 42 : saw_stat = true;
4654 :
4655 42 : m = gfc_match_char (',');
4656 42 : if (m == MATCH_YES)
4657 2 : continue;
4658 :
4659 40 : tmp = NULL;
4660 40 : break;
4661 : }
4662 :
4663 24 : m = gfc_match (" errmsg = %v", &tmp);
4664 24 : if (m == MATCH_ERROR)
4665 0 : goto syntax;
4666 24 : if (m == MATCH_YES)
4667 : {
4668 2 : if (saw_errmsg)
4669 : {
4670 0 : gfc_error ("Redundant ERRMSG tag found at %L", &tmp->where);
4671 0 : goto cleanup;
4672 : }
4673 2 : errmsg = tmp;
4674 2 : saw_errmsg = true;
4675 :
4676 2 : m = gfc_match_char (',');
4677 2 : if (m == MATCH_YES)
4678 0 : continue;
4679 :
4680 2 : tmp = NULL;
4681 2 : break;
4682 : }
4683 :
4684 22 : m = gfc_match (" acquired_lock = %v", &tmp);
4685 22 : if (m == MATCH_ERROR || st == ST_UNLOCK)
4686 0 : goto syntax;
4687 22 : if (m == MATCH_YES)
4688 : {
4689 22 : if (saw_acq_lock)
4690 : {
4691 0 : gfc_error ("Redundant ACQUIRED_LOCK tag found at %L",
4692 0 : &tmp->where);
4693 0 : goto cleanup;
4694 : }
4695 22 : acq_lock = tmp;
4696 22 : saw_acq_lock = true;
4697 :
4698 22 : m = gfc_match_char (',');
4699 22 : if (m == MATCH_YES)
4700 2 : continue;
4701 :
4702 20 : tmp = NULL;
4703 20 : break;
4704 : }
4705 :
4706 : break;
4707 : }
4708 :
4709 62 : if (m == MATCH_ERROR)
4710 0 : goto syntax;
4711 :
4712 62 : if (gfc_match (" )%t") != MATCH_YES)
4713 0 : goto syntax;
4714 :
4715 62 : done:
4716 139 : switch (st)
4717 : {
4718 74 : case ST_LOCK:
4719 74 : new_st.op = EXEC_LOCK;
4720 74 : break;
4721 65 : case ST_UNLOCK:
4722 65 : new_st.op = EXEC_UNLOCK;
4723 65 : break;
4724 0 : default:
4725 0 : gcc_unreachable ();
4726 : }
4727 :
4728 139 : new_st.expr1 = lockvar;
4729 139 : new_st.expr2 = stat;
4730 139 : new_st.expr3 = errmsg;
4731 139 : new_st.expr4 = acq_lock;
4732 :
4733 139 : return MATCH_YES;
4734 :
4735 1 : syntax:
4736 1 : gfc_syntax_error (st);
4737 :
4738 1 : cleanup:
4739 1 : if (acq_lock != tmp)
4740 0 : gfc_free_expr (acq_lock);
4741 1 : if (errmsg != tmp)
4742 0 : gfc_free_expr (errmsg);
4743 1 : if (stat != tmp)
4744 0 : gfc_free_expr (stat);
4745 :
4746 1 : gfc_free_expr (tmp);
4747 1 : gfc_free_expr (lockvar);
4748 :
4749 1 : return MATCH_ERROR;
4750 : }
4751 :
4752 :
4753 : match
4754 78 : gfc_match_lock (void)
4755 : {
4756 78 : if (!gfc_notify_std (GFC_STD_F2008, "LOCK statement at %C"))
4757 : return MATCH_ERROR;
4758 :
4759 77 : return lock_unlock_statement (ST_LOCK);
4760 : }
4761 :
4762 :
4763 : match
4764 68 : gfc_match_unlock (void)
4765 : {
4766 68 : if (!gfc_notify_std (GFC_STD_F2008, "UNLOCK statement at %C"))
4767 : return MATCH_ERROR;
4768 :
4769 67 : return lock_unlock_statement (ST_UNLOCK);
4770 : }
4771 :
4772 :
4773 : /* Match SYNC ALL/IMAGES/MEMORY statement. Syntax:
4774 : SYNC ALL [(sync-stat-list)]
4775 : SYNC MEMORY [(sync-stat-list)]
4776 : SYNC IMAGES (image-set [, sync-stat-list] )
4777 : with sync-stat is int-expr or *. */
4778 :
4779 : static match
4780 1324 : sync_statement (gfc_statement st)
4781 : {
4782 1324 : match m;
4783 1324 : gfc_expr *tmp, *imageset, *stat, *errmsg;
4784 1324 : bool saw_stat, saw_errmsg;
4785 :
4786 1324 : tmp = imageset = stat = errmsg = NULL;
4787 1324 : saw_stat = saw_errmsg = false;
4788 :
4789 1324 : if (gfc_pure (NULL))
4790 : {
4791 1 : gfc_error ("Image control statement SYNC at %C in PURE procedure");
4792 1 : return MATCH_ERROR;
4793 : }
4794 :
4795 1323 : gfc_unset_implicit_pure (NULL);
4796 :
4797 1323 : if (!gfc_notify_std (GFC_STD_F2008, "SYNC statement at %C"))
4798 : return MATCH_ERROR;
4799 :
4800 1320 : if (flag_coarray == GFC_FCOARRAY_NONE)
4801 : {
4802 0 : gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to "
4803 : "enable");
4804 : return MATCH_ERROR;
4805 : }
4806 :
4807 1320 : if (gfc_find_state (COMP_CRITICAL))
4808 : {
4809 1 : gfc_error ("Image control statement SYNC at %C in CRITICAL block");
4810 1 : return MATCH_ERROR;
4811 : }
4812 :
4813 1319 : if (gfc_find_state (COMP_DO_CONCURRENT))
4814 : {
4815 1 : gfc_error ("Image control statement SYNC at %C in DO CONCURRENT block");
4816 1 : return MATCH_ERROR;
4817 : }
4818 :
4819 1318 : if (gfc_match_eos () == MATCH_YES)
4820 : {
4821 1084 : if (st == ST_SYNC_IMAGES)
4822 0 : goto syntax;
4823 1084 : goto done;
4824 : }
4825 :
4826 234 : if (gfc_match_char ('(') != MATCH_YES)
4827 0 : goto syntax;
4828 :
4829 234 : if (st == ST_SYNC_IMAGES)
4830 : {
4831 : /* Denote '*' as imageset == NULL. */
4832 107 : m = gfc_match_char ('*');
4833 107 : if (m == MATCH_ERROR)
4834 0 : goto syntax;
4835 107 : if (m == MATCH_NO)
4836 : {
4837 71 : if (gfc_match ("%e", &imageset) != MATCH_YES)
4838 0 : goto syntax;
4839 : }
4840 107 : m = gfc_match_char (',');
4841 107 : if (m == MATCH_ERROR)
4842 0 : goto syntax;
4843 107 : if (m == MATCH_NO)
4844 : {
4845 53 : m = gfc_match_char (')');
4846 53 : if (m == MATCH_YES)
4847 53 : goto done;
4848 0 : goto syntax;
4849 : }
4850 : }
4851 :
4852 224 : for (;;)
4853 : {
4854 224 : m = gfc_match (" stat = %e", &tmp);
4855 224 : if (m == MATCH_ERROR)
4856 0 : goto syntax;
4857 224 : if (m == MATCH_YES)
4858 : {
4859 110 : if (saw_stat)
4860 : {
4861 1 : gfc_error ("Redundant STAT tag found at %L", &tmp->where);
4862 1 : goto cleanup;
4863 : }
4864 109 : stat = tmp;
4865 109 : saw_stat = true;
4866 :
4867 109 : if (gfc_match_char (',') == MATCH_YES)
4868 15 : continue;
4869 :
4870 94 : tmp = NULL;
4871 94 : break;
4872 : }
4873 :
4874 114 : m = gfc_match (" errmsg = %e", &tmp);
4875 114 : if (m == MATCH_ERROR)
4876 0 : goto syntax;
4877 114 : if (m == MATCH_YES)
4878 : {
4879 90 : if (saw_errmsg)
4880 : {
4881 0 : gfc_error ("Redundant ERRMSG tag found at %L", &tmp->where);
4882 0 : goto cleanup;
4883 : }
4884 90 : errmsg = tmp;
4885 90 : saw_errmsg = true;
4886 :
4887 90 : if (gfc_match_char (',') == MATCH_YES)
4888 28 : continue;
4889 :
4890 62 : tmp = NULL;
4891 62 : break;
4892 : }
4893 :
4894 : break;
4895 : }
4896 :
4897 180 : if (gfc_match (" )%t") != MATCH_YES)
4898 0 : goto syntax;
4899 :
4900 180 : done:
4901 1317 : switch (st)
4902 : {
4903 1136 : case ST_SYNC_ALL:
4904 1136 : new_st.op = EXEC_SYNC_ALL;
4905 1136 : break;
4906 107 : case ST_SYNC_IMAGES:
4907 107 : new_st.op = EXEC_SYNC_IMAGES;
4908 107 : break;
4909 74 : case ST_SYNC_MEMORY:
4910 74 : new_st.op = EXEC_SYNC_MEMORY;
4911 74 : break;
4912 0 : default:
4913 0 : gcc_unreachable ();
4914 : }
4915 :
4916 1317 : new_st.expr1 = imageset;
4917 1317 : new_st.expr2 = stat;
4918 1317 : new_st.expr3 = errmsg;
4919 :
4920 1317 : return MATCH_YES;
4921 :
4922 0 : syntax:
4923 0 : gfc_syntax_error (st);
4924 :
4925 1 : cleanup:
4926 1 : if (stat != tmp)
4927 1 : gfc_free_expr (stat);
4928 1 : if (errmsg != tmp)
4929 1 : gfc_free_expr (errmsg);
4930 :
4931 1 : gfc_free_expr (tmp);
4932 1 : gfc_free_expr (imageset);
4933 :
4934 1 : return MATCH_ERROR;
4935 : }
4936 :
4937 :
4938 : /* Match SYNC ALL statement. */
4939 :
4940 : match
4941 1141 : gfc_match_sync_all (void)
4942 : {
4943 1141 : return sync_statement (ST_SYNC_ALL);
4944 : }
4945 :
4946 :
4947 : /* Match SYNC IMAGES statement. */
4948 :
4949 : match
4950 108 : gfc_match_sync_images (void)
4951 : {
4952 108 : return sync_statement (ST_SYNC_IMAGES);
4953 : }
4954 :
4955 :
4956 : /* Match SYNC MEMORY statement. */
4957 :
4958 : match
4959 75 : gfc_match_sync_memory (void)
4960 : {
4961 75 : return sync_statement (ST_SYNC_MEMORY);
4962 : }
4963 :
4964 :
4965 : /* Match a CONTINUE statement. */
4966 :
4967 : match
4968 2817 : gfc_match_continue (void)
4969 : {
4970 2817 : if (gfc_match_eos () != MATCH_YES)
4971 : {
4972 0 : gfc_syntax_error (ST_CONTINUE);
4973 0 : return MATCH_ERROR;
4974 : }
4975 :
4976 2817 : new_st.op = EXEC_CONTINUE;
4977 2817 : return MATCH_YES;
4978 : }
4979 :
4980 :
4981 : /* Match the (deprecated) ASSIGN statement. */
4982 :
4983 : match
4984 126 : gfc_match_assign (void)
4985 : {
4986 126 : gfc_expr *expr;
4987 126 : gfc_st_label *label;
4988 :
4989 126 : if (gfc_match (" %l", &label) == MATCH_YES)
4990 : {
4991 126 : if (!gfc_reference_st_label (label, ST_LABEL_UNKNOWN))
4992 : return MATCH_ERROR;
4993 126 : if (gfc_match (" to %v%t", &expr) == MATCH_YES)
4994 : {
4995 126 : if (!gfc_notify_std (GFC_STD_F95_DEL, "ASSIGN statement at %C"))
4996 : return MATCH_ERROR;
4997 :
4998 126 : expr->symtree->n.sym->attr.assign = 1;
4999 :
5000 126 : new_st.op = EXEC_LABEL_ASSIGN;
5001 126 : new_st.label1 = label;
5002 126 : new_st.expr1 = expr;
5003 126 : return MATCH_YES;
5004 : }
5005 : }
5006 : return MATCH_NO;
5007 : }
5008 :
5009 :
5010 : /* Match the GO TO statement. As a computed GOTO statement is
5011 : matched, it is transformed into an equivalent SELECT block. No
5012 : tree is necessary, and the resulting jumps-to-jumps are
5013 : specifically optimized away by the back end. */
5014 :
5015 : match
5016 1002 : gfc_match_goto (void)
5017 : {
5018 1002 : gfc_code *head, *tail;
5019 1002 : gfc_expr *expr;
5020 1002 : gfc_case *cp;
5021 1002 : gfc_st_label *label;
5022 1002 : int i;
5023 1002 : match m;
5024 :
5025 1002 : if (gfc_match (" %l%t", &label) == MATCH_YES)
5026 : {
5027 919 : if (!gfc_reference_st_label (label, ST_LABEL_TARGET))
5028 : return MATCH_ERROR;
5029 :
5030 919 : new_st.op = EXEC_GOTO;
5031 919 : new_st.label1 = label;
5032 919 : return MATCH_YES;
5033 : }
5034 :
5035 : /* The assigned GO TO statement. */
5036 :
5037 83 : if (gfc_match_variable (&expr, 0) == MATCH_YES)
5038 : {
5039 78 : if (!gfc_notify_std (GFC_STD_F95_DEL, "Assigned GOTO statement at %C"))
5040 : return MATCH_ERROR;
5041 :
5042 78 : new_st.op = EXEC_GOTO;
5043 78 : new_st.expr1 = expr;
5044 :
5045 78 : if (gfc_match_eos () == MATCH_YES)
5046 : return MATCH_YES;
5047 :
5048 : /* Match label list. */
5049 27 : gfc_match_char (',');
5050 27 : if (gfc_match_char ('(') != MATCH_YES)
5051 : {
5052 0 : gfc_syntax_error (ST_GOTO);
5053 0 : return MATCH_ERROR;
5054 : }
5055 : head = tail = NULL;
5056 :
5057 76 : do
5058 : {
5059 76 : m = gfc_match_st_label (&label);
5060 76 : if (m != MATCH_YES)
5061 0 : goto syntax;
5062 :
5063 76 : if (!gfc_reference_st_label (label, ST_LABEL_TARGET))
5064 0 : goto cleanup;
5065 :
5066 76 : if (head == NULL)
5067 27 : head = tail = gfc_get_code (EXEC_GOTO);
5068 : else
5069 : {
5070 49 : tail->block = gfc_get_code (EXEC_GOTO);
5071 49 : tail = tail->block;
5072 : }
5073 :
5074 76 : tail->label1 = label;
5075 : }
5076 76 : while (gfc_match_char (',') == MATCH_YES);
5077 :
5078 27 : if (gfc_match (" )%t") != MATCH_YES)
5079 0 : goto syntax;
5080 :
5081 27 : if (head == NULL)
5082 : {
5083 0 : gfc_error ("Statement label list in GOTO at %C cannot be empty");
5084 0 : goto syntax;
5085 : }
5086 27 : new_st.block = head;
5087 :
5088 27 : return MATCH_YES;
5089 : }
5090 :
5091 : /* Last chance is a computed GO TO statement. */
5092 5 : if (gfc_match_char ('(') != MATCH_YES)
5093 : {
5094 0 : gfc_syntax_error (ST_GOTO);
5095 0 : return MATCH_ERROR;
5096 : }
5097 :
5098 : head = tail = NULL;
5099 : i = 1;
5100 :
5101 13 : do
5102 : {
5103 13 : m = gfc_match_st_label (&label);
5104 13 : if (m != MATCH_YES)
5105 0 : goto syntax;
5106 :
5107 13 : if (!gfc_reference_st_label (label, ST_LABEL_TARGET))
5108 0 : goto cleanup;
5109 :
5110 13 : if (head == NULL)
5111 5 : head = tail = gfc_get_code (EXEC_SELECT);
5112 : else
5113 : {
5114 8 : tail->block = gfc_get_code (EXEC_SELECT);
5115 8 : tail = tail->block;
5116 : }
5117 :
5118 13 : cp = gfc_get_case ();
5119 26 : cp->low = cp->high = gfc_get_int_expr (gfc_default_integer_kind,
5120 13 : NULL, i++);
5121 :
5122 13 : tail->ext.block.case_list = cp;
5123 :
5124 13 : tail->next = gfc_get_code (EXEC_GOTO);
5125 13 : tail->next->label1 = label;
5126 : }
5127 13 : while (gfc_match_char (',') == MATCH_YES);
5128 :
5129 5 : if (gfc_match_char (')') != MATCH_YES)
5130 0 : goto syntax;
5131 :
5132 5 : if (head == NULL)
5133 : {
5134 0 : gfc_error ("Statement label list in GOTO at %C cannot be empty");
5135 0 : goto syntax;
5136 : }
5137 :
5138 : /* Get the rest of the statement. */
5139 5 : gfc_match_char (',');
5140 :
5141 5 : if (gfc_match (" %e%t", &expr) != MATCH_YES)
5142 0 : goto syntax;
5143 :
5144 5 : if (!gfc_notify_std (GFC_STD_F95_OBS, "Computed GOTO at %C"))
5145 : return MATCH_ERROR;
5146 :
5147 : /* At this point, a computed GOTO has been fully matched and an
5148 : equivalent SELECT statement constructed. */
5149 :
5150 5 : new_st.op = EXEC_SELECT;
5151 5 : new_st.expr1 = NULL;
5152 :
5153 : /* Hack: For a "real" SELECT, the expression is in expr. We put
5154 : it in expr2 so we can distinguish then and produce the correct
5155 : diagnostics. */
5156 5 : new_st.expr2 = expr;
5157 5 : new_st.block = head;
5158 5 : return MATCH_YES;
5159 :
5160 0 : syntax:
5161 0 : gfc_syntax_error (ST_GOTO);
5162 0 : cleanup:
5163 0 : gfc_free_statements (head);
5164 0 : return MATCH_ERROR;
5165 : }
5166 :
5167 :
5168 : /* A reduced version of gfc_spec_list_type, which only looks for deferred
5169 : type spec list parameters. */
5170 :
5171 : static gfc_param_spec_type
5172 0 : spec_list_type (gfc_actual_arglist *param_list)
5173 : {
5174 598 : gfc_param_spec_type res = SPEC_EXPLICIT;
5175 :
5176 598 : for (; param_list; param_list = param_list->next)
5177 445 : if (param_list->spec_type == SPEC_DEFERRED)
5178 : {
5179 : res = param_list->spec_type;
5180 : break;
5181 : }
5182 :
5183 268 : return res;
5184 : }
5185 :
5186 :
5187 : /* Frees a list of gfc_alloc structures. */
5188 :
5189 : void
5190 23991 : gfc_free_alloc_list (gfc_alloc *p)
5191 : {
5192 23991 : gfc_alloc *q;
5193 :
5194 53216 : for (; p; p = q)
5195 : {
5196 29225 : q = p->next;
5197 29225 : gfc_free_expr (p->expr);
5198 29225 : free (p);
5199 : }
5200 23991 : }
5201 :
5202 :
5203 : /* Match an ALLOCATE statement. */
5204 :
5205 : match
5206 14530 : gfc_match_allocate (void)
5207 : {
5208 14530 : gfc_alloc *head, *tail;
5209 14530 : gfc_expr *stat, *errmsg, *tmp, *source, *mold;
5210 14530 : gfc_typespec ts;
5211 14530 : gfc_symbol *sym;
5212 14530 : gfc_ref *ref;
5213 14530 : match m;
5214 14530 : locus old_locus, deferred_locus, assumed_locus;
5215 14530 : bool saw_stat, saw_errmsg, saw_source, saw_mold, saw_deferred, b1, b2, b3;
5216 14530 : bool saw_unlimited = false, saw_assumed = false;
5217 :
5218 14530 : head = tail = NULL;
5219 14530 : stat = errmsg = source = mold = tmp = NULL;
5220 14530 : saw_stat = saw_errmsg = saw_source = saw_mold = saw_deferred = false;
5221 :
5222 14530 : if (gfc_match_char ('(') != MATCH_YES)
5223 : {
5224 1 : gfc_syntax_error (ST_ALLOCATE);
5225 1 : return MATCH_ERROR;
5226 : }
5227 :
5228 : /* Match an optional type-spec. */
5229 14529 : old_locus = gfc_current_locus;
5230 14529 : m = gfc_match_type_spec (&ts);
5231 14529 : if (m == MATCH_ERROR)
5232 7 : goto cleanup;
5233 14522 : else if (m == MATCH_NO)
5234 : {
5235 12975 : char name[GFC_MAX_SYMBOL_LEN + 3];
5236 :
5237 12975 : if (gfc_match ("%n :: ", name) == MATCH_YES)
5238 : {
5239 7 : gfc_error ("Error in type-spec at %L", &old_locus);
5240 7 : goto cleanup;
5241 : }
5242 :
5243 12968 : ts.type = BT_UNKNOWN;
5244 : }
5245 : else
5246 : {
5247 : /* Needed for the F2008:C631 check below. */
5248 1547 : assumed_locus = gfc_current_locus;
5249 :
5250 1547 : if (gfc_match (" :: ") == MATCH_YES)
5251 : {
5252 1535 : if (!gfc_notify_std (GFC_STD_F2003, "typespec in ALLOCATE at %L",
5253 : &old_locus))
5254 0 : goto cleanup;
5255 :
5256 1535 : if (ts.deferred)
5257 : {
5258 5 : gfc_error ("Type-spec at %L cannot contain a deferred "
5259 : "type parameter", &old_locus);
5260 5 : goto cleanup;
5261 : }
5262 :
5263 1530 : if (ts.type == BT_CHARACTER)
5264 : {
5265 475 : if (!ts.u.cl->length)
5266 : saw_assumed = true;
5267 : else
5268 462 : ts.u.cl->length_from_typespec = true;
5269 : }
5270 :
5271 1530 : if (type_param_spec_list
5272 1613 : && spec_list_type (type_param_spec_list) == SPEC_DEFERRED)
5273 : {
5274 0 : gfc_error ("The type parameter spec list in the type-spec at "
5275 : "%L cannot contain DEFERRED parameters", &old_locus);
5276 0 : goto cleanup;
5277 : }
5278 : }
5279 : else
5280 : {
5281 12 : ts.type = BT_UNKNOWN;
5282 12 : gfc_current_locus = old_locus;
5283 : }
5284 : }
5285 :
5286 17553 : for (;;)
5287 : {
5288 17553 : if (head == NULL)
5289 14510 : head = tail = gfc_get_alloc ();
5290 : else
5291 : {
5292 3043 : tail->next = gfc_get_alloc ();
5293 3043 : tail = tail->next;
5294 : }
5295 :
5296 17553 : m = gfc_match_variable (&tail->expr, 0);
5297 17553 : if (m == MATCH_NO)
5298 0 : goto syntax;
5299 17553 : if (m == MATCH_ERROR)
5300 11 : goto cleanup;
5301 :
5302 17542 : if (tail->expr->expr_type == EXPR_CONSTANT)
5303 : {
5304 1 : gfc_error ("Unexpected constant at %C");
5305 1 : goto cleanup;
5306 : }
5307 :
5308 17541 : if (gfc_check_do_variable (tail->expr->symtree))
5309 0 : goto cleanup;
5310 :
5311 17541 : bool impure = gfc_impure_variable (tail->expr->symtree->n.sym);
5312 17541 : if (impure && gfc_pure (NULL))
5313 : {
5314 0 : gfc_error ("Bad allocate-object at %C for a PURE procedure");
5315 0 : goto cleanup;
5316 : }
5317 :
5318 17541 : if (impure)
5319 523 : gfc_unset_implicit_pure (NULL);
5320 :
5321 : /* F2008:C631 (R626) A type-param-value in a type-spec shall be an
5322 : asterisk if and only if each allocate-object is a dummy argument
5323 : for which the corresponding type parameter is assumed. */
5324 17541 : if (saw_assumed
5325 20 : && (tail->expr->ts.deferred
5326 19 : || (tail->expr->ts.u.cl && tail->expr->ts.u.cl->length)
5327 17 : || tail->expr->symtree->n.sym->attr.dummy == 0))
5328 : {
5329 4 : gfc_error ("Incompatible allocate-object at %C for CHARACTER "
5330 : "type-spec at %L", &assumed_locus);
5331 4 : goto cleanup;
5332 : }
5333 :
5334 17537 : if (tail->expr->ts.deferred
5335 17537 : || (tail->expr->symtree->n.sym->param_list
5336 167 : && spec_list_type (tail->expr->symtree->n.sym->param_list)
5337 : == SPEC_DEFERRED))
5338 : {
5339 1222 : saw_deferred = true;
5340 1222 : deferred_locus = tail->expr->where;
5341 : }
5342 16315 : else if ((tail->expr->ts.type == BT_DERIVED
5343 13620 : || tail->expr->ts.type == BT_CLASS)
5344 6294 : && tail->expr->ref)
5345 : {
5346 9870 : for (ref = tail->expr->ref; ref; ref = ref->next)
5347 5866 : if (ref->type == REF_COMPONENT
5348 1989 : && ref->u.c.component->param_list
5349 5884 : && spec_list_type (ref->u.c.component->param_list)
5350 : == SPEC_DEFERRED)
5351 : {
5352 4 : saw_deferred = true;
5353 4 : deferred_locus = tail->expr->where;
5354 : }
5355 : }
5356 :
5357 17537 : if (gfc_find_state (COMP_DO_CONCURRENT)
5358 17537 : || gfc_find_state (COMP_CRITICAL))
5359 : {
5360 2 : gfc_ref *ref;
5361 2 : bool coarray = tail->expr->symtree->n.sym->attr.codimension;
5362 4 : for (ref = tail->expr->ref; ref; ref = ref->next)
5363 2 : if (ref->type == REF_COMPONENT)
5364 0 : coarray = ref->u.c.component->attr.codimension;
5365 :
5366 2 : if (coarray && gfc_find_state (COMP_DO_CONCURRENT))
5367 : {
5368 1 : gfc_error ("ALLOCATE of coarray at %C in DO CONCURRENT block");
5369 1 : goto cleanup;
5370 : }
5371 1 : if (coarray && gfc_find_state (COMP_CRITICAL))
5372 : {
5373 1 : gfc_error ("ALLOCATE of coarray at %C in CRITICAL block");
5374 1 : goto cleanup;
5375 : }
5376 : }
5377 :
5378 : /* Check for F08:C628. */
5379 17535 : sym = tail->expr->symtree->n.sym;
5380 17535 : b1 = !(tail->expr->ref
5381 13296 : && (tail->expr->ref->type == REF_COMPONENT
5382 : || tail->expr->ref->type == REF_ARRAY));
5383 17535 : if (sym && sym->ts.type == BT_CLASS && sym->attr.class_ok)
5384 3430 : b2 = !(CLASS_DATA (sym)->attr.allocatable
5385 805 : || CLASS_DATA (sym)->attr.class_pointer);
5386 : else
5387 14105 : b2 = sym && !(sym->attr.allocatable || sym->attr.pointer
5388 2653 : || sym->attr.proc_pointer);
5389 17535 : b3 = sym && sym->ns && sym->ns->proc_name
5390 17535 : && (sym->ns->proc_name->attr.allocatable
5391 17474 : || sym->ns->proc_name->attr.pointer
5392 17437 : || sym->ns->proc_name->attr.proc_pointer);
5393 17535 : if (b1 && b2 && !b3)
5394 : {
5395 6 : gfc_error ("Allocate-object at %L is neither a data pointer "
5396 : "nor an allocatable variable", &tail->expr->where);
5397 6 : goto cleanup;
5398 : }
5399 :
5400 : /* The ALLOCATE statement had an optional typespec. Check the
5401 : constraints. */
5402 17529 : if (ts.type != BT_UNKNOWN)
5403 : {
5404 : /* Enforce F03:C624. */
5405 1765 : if (!gfc_type_compatible (&tail->expr->ts, &ts))
5406 : {
5407 13 : gfc_error ("Type of entity at %L is type incompatible with "
5408 13 : "typespec", &tail->expr->where);
5409 13 : goto cleanup;
5410 : }
5411 :
5412 : /* Enforce F03:C627. */
5413 1752 : if (ts.kind != tail->expr->ts.kind && !UNLIMITED_POLY (tail->expr))
5414 : {
5415 8 : gfc_error ("Kind type parameter for entity at %L differs from "
5416 : "the kind type parameter of the typespec",
5417 : &tail->expr->where);
5418 8 : goto cleanup;
5419 : }
5420 : }
5421 :
5422 17508 : if (tail->expr->ts.type == BT_DERIVED)
5423 2771 : tail->expr->ts.u.derived = gfc_use_derived (tail->expr->ts.u.derived);
5424 :
5425 17508 : if (type_param_spec_list)
5426 86 : tail->expr->param_list = gfc_copy_actual_arglist (type_param_spec_list);
5427 :
5428 17508 : saw_unlimited = saw_unlimited | UNLIMITED_POLY (tail->expr);
5429 :
5430 17508 : if (gfc_peek_ascii_char () == '(' && !sym->attr.dimension)
5431 : {
5432 2 : gfc_error ("Shape specification for allocatable scalar at %C");
5433 2 : goto cleanup;
5434 : }
5435 :
5436 17506 : if (gfc_match_char (',') != MATCH_YES)
5437 : break;
5438 :
5439 7132 : alloc_opt_list:
5440 :
5441 7264 : m = gfc_match (" stat = %e", &tmp);
5442 7264 : if (m == MATCH_ERROR)
5443 7 : goto cleanup;
5444 7257 : if (m == MATCH_YES)
5445 : {
5446 : /* Enforce C630. */
5447 336 : if (saw_stat)
5448 : {
5449 1 : gfc_error ("Redundant STAT tag found at %L", &tmp->where);
5450 1 : goto cleanup;
5451 : }
5452 :
5453 335 : stat = tmp;
5454 335 : tmp = NULL;
5455 335 : saw_stat = true;
5456 :
5457 335 : if (stat->expr_type == EXPR_CONSTANT)
5458 : {
5459 5 : gfc_error ("STAT tag at %L cannot be a constant", &stat->where);
5460 5 : goto cleanup;
5461 : }
5462 :
5463 330 : if (gfc_check_do_variable (stat->symtree))
5464 0 : goto cleanup;
5465 :
5466 330 : if (gfc_match_char (',') == MATCH_YES)
5467 84 : goto alloc_opt_list;
5468 : }
5469 :
5470 7167 : m = gfc_match (" errmsg = %e", &tmp);
5471 7167 : if (m == MATCH_ERROR)
5472 0 : goto cleanup;
5473 7167 : if (m == MATCH_YES)
5474 : {
5475 89 : if (!gfc_notify_std (GFC_STD_F2003, "ERRMSG tag at %L", &tmp->where))
5476 1 : goto cleanup;
5477 :
5478 : /* Enforce C630. */
5479 88 : if (saw_errmsg)
5480 : {
5481 1 : gfc_error ("Redundant ERRMSG tag found at %L", &tmp->where);
5482 1 : goto cleanup;
5483 : }
5484 :
5485 87 : errmsg = tmp;
5486 87 : tmp = NULL;
5487 87 : saw_errmsg = true;
5488 :
5489 87 : if (gfc_match_char (',') == MATCH_YES)
5490 4 : goto alloc_opt_list;
5491 : }
5492 :
5493 7161 : m = gfc_match (" source = %e", &tmp);
5494 7161 : if (m == MATCH_ERROR)
5495 2 : goto cleanup;
5496 7159 : if (m == MATCH_YES)
5497 : {
5498 3417 : if (!gfc_notify_std (GFC_STD_F2003, "SOURCE tag at %L", &tmp->where))
5499 1 : goto cleanup;
5500 :
5501 : /* Enforce C630. */
5502 3416 : if (saw_source)
5503 : {
5504 1 : gfc_error ("Redundant SOURCE tag found at %L", &tmp->where);
5505 1 : goto cleanup;
5506 : }
5507 :
5508 : /* The next 2 conditionals check C631. */
5509 3415 : if (ts.type != BT_UNKNOWN)
5510 : {
5511 1 : gfc_error ("SOURCE tag at %L conflicts with the typespec at %L",
5512 1 : &tmp->where, &old_locus);
5513 1 : goto cleanup;
5514 : }
5515 :
5516 3414 : if (head->next
5517 3440 : && !gfc_notify_std (GFC_STD_F2008, "SOURCE tag at %L"
5518 : " with more than a single allocate object",
5519 26 : &tmp->where))
5520 1 : goto cleanup;
5521 :
5522 3413 : source = tmp;
5523 3413 : tmp = NULL;
5524 3413 : saw_source = true;
5525 :
5526 3413 : if (gfc_match_char (',') == MATCH_YES)
5527 41 : goto alloc_opt_list;
5528 : }
5529 :
5530 7114 : m = gfc_match (" mold = %e", &tmp);
5531 7114 : if (m == MATCH_ERROR)
5532 0 : goto cleanup;
5533 7114 : if (m == MATCH_YES)
5534 : {
5535 370 : if (!gfc_notify_std (GFC_STD_F2008, "MOLD tag at %L", &tmp->where))
5536 1 : goto cleanup;
5537 :
5538 : /* Check F08:C636. */
5539 369 : if (saw_mold)
5540 : {
5541 1 : gfc_error ("Redundant MOLD tag found at %L", &tmp->where);
5542 1 : goto cleanup;
5543 : }
5544 :
5545 : /* Check F08:C637. */
5546 368 : if (ts.type != BT_UNKNOWN)
5547 : {
5548 1 : gfc_error ("MOLD tag at %L conflicts with the typespec at %L",
5549 1 : &tmp->where, &old_locus);
5550 1 : goto cleanup;
5551 : }
5552 :
5553 367 : mold = tmp;
5554 367 : tmp = NULL;
5555 367 : saw_mold = true;
5556 367 : mold->mold = 1;
5557 :
5558 367 : if (gfc_match_char (',') == MATCH_YES)
5559 3 : goto alloc_opt_list;
5560 : }
5561 :
5562 7108 : gfc_gobble_whitespace ();
5563 :
5564 7108 : if (gfc_peek_char () == ')')
5565 : break;
5566 : }
5567 :
5568 14439 : if (gfc_match (" )%t") != MATCH_YES)
5569 1 : goto syntax;
5570 :
5571 : /* Check F08:C637. */
5572 14438 : if (source && mold)
5573 : {
5574 1 : gfc_error ("MOLD tag at %L conflicts with SOURCE tag at %L",
5575 : &mold->where, &source->where);
5576 1 : goto cleanup;
5577 : }
5578 :
5579 : /* Check F03:C623, */
5580 14437 : if (saw_deferred && ts.type == BT_UNKNOWN && !source && !mold)
5581 : {
5582 15 : gfc_error ("Allocate-object at %L with a deferred type parameter "
5583 : "requires either a type-spec or SOURCE tag or a MOLD tag",
5584 : &deferred_locus);
5585 15 : goto cleanup;
5586 : }
5587 :
5588 : /* Check F03:C625, */
5589 14422 : if (saw_unlimited && ts.type == BT_UNKNOWN && !source && !mold)
5590 : {
5591 2 : for (tail = head; tail; tail = tail->next)
5592 : {
5593 1 : if (UNLIMITED_POLY (tail->expr))
5594 1 : gfc_error ("Unlimited polymorphic allocate-object at %L "
5595 : "requires either a type-spec or SOURCE tag "
5596 : "or a MOLD tag", &tail->expr->where);
5597 : }
5598 1 : goto cleanup;
5599 : }
5600 :
5601 14421 : new_st.op = EXEC_ALLOCATE;
5602 14421 : new_st.expr1 = stat;
5603 14421 : new_st.expr2 = errmsg;
5604 14421 : if (source)
5605 3411 : new_st.expr3 = source;
5606 : else
5607 11010 : new_st.expr3 = mold;
5608 14421 : new_st.ext.alloc.list = head;
5609 14421 : new_st.ext.alloc.ts = ts;
5610 :
5611 14421 : if (type_param_spec_list)
5612 83 : gfc_free_actual_arglist (type_param_spec_list);
5613 :
5614 : return MATCH_YES;
5615 :
5616 1 : syntax:
5617 1 : gfc_syntax_error (ST_ALLOCATE);
5618 :
5619 108 : cleanup:
5620 108 : gfc_free_expr (errmsg);
5621 108 : gfc_free_expr (source);
5622 108 : gfc_free_expr (stat);
5623 108 : gfc_free_expr (mold);
5624 108 : if (tmp && tmp->expr_type) gfc_free_expr (tmp);
5625 108 : gfc_free_alloc_list (head);
5626 108 : if (type_param_spec_list)
5627 0 : gfc_free_actual_arglist (type_param_spec_list);
5628 : return MATCH_ERROR;
5629 : }
5630 :
5631 :
5632 : /* Match a NULLIFY statement. A NULLIFY statement is transformed into
5633 : a set of pointer assignments to intrinsic NULL(). */
5634 :
5635 : match
5636 582 : gfc_match_nullify (void)
5637 : {
5638 582 : gfc_code *tail;
5639 582 : gfc_expr *e, *p = NULL;
5640 582 : match m;
5641 :
5642 582 : tail = NULL;
5643 :
5644 582 : if (gfc_match_char ('(') != MATCH_YES)
5645 0 : goto syntax;
5646 :
5647 986 : for (;;)
5648 : {
5649 986 : m = gfc_match_variable (&p, 0);
5650 986 : if (m == MATCH_ERROR)
5651 2 : goto cleanup;
5652 984 : if (m == MATCH_NO)
5653 0 : goto syntax;
5654 :
5655 984 : if (gfc_check_do_variable (p->symtree))
5656 0 : goto cleanup;
5657 :
5658 : /* F2008, C1242. */
5659 984 : if (gfc_is_coindexed (p))
5660 : {
5661 1 : gfc_error ("Pointer object at %C shall not be coindexed");
5662 1 : goto cleanup;
5663 : }
5664 :
5665 : /* Check for valid array pointer object. Bounds remapping is not
5666 : allowed with NULLIFY. */
5667 983 : if (p->ref)
5668 : {
5669 : gfc_ref *remap = p->ref;
5670 943 : for (; remap; remap = remap->next)
5671 492 : if (!remap->next && remap->type == REF_ARRAY
5672 320 : && remap->u.ar.type != AR_FULL)
5673 : break;
5674 : if (remap)
5675 : {
5676 2 : gfc_error ("NULLIFY does not allow bounds remapping for "
5677 : "pointer object at %C");
5678 2 : goto cleanup;
5679 : }
5680 : }
5681 :
5682 : /* build ' => NULL() '. */
5683 981 : e = gfc_get_null_expr (&gfc_current_locus);
5684 :
5685 : /* Chain to list. */
5686 981 : if (tail == NULL)
5687 : {
5688 578 : tail = &new_st;
5689 578 : tail->op = EXEC_POINTER_ASSIGN;
5690 : }
5691 : else
5692 : {
5693 403 : tail->next = gfc_get_code (EXEC_POINTER_ASSIGN);
5694 403 : tail = tail->next;
5695 : }
5696 :
5697 981 : tail->expr1 = p;
5698 981 : tail->expr2 = e;
5699 :
5700 981 : if (gfc_match (" )%t") == MATCH_YES)
5701 : break;
5702 404 : if (gfc_match_char (',') != MATCH_YES)
5703 0 : goto syntax;
5704 : }
5705 :
5706 : return MATCH_YES;
5707 :
5708 0 : syntax:
5709 0 : gfc_syntax_error (ST_NULLIFY);
5710 :
5711 5 : cleanup:
5712 5 : gfc_free_statements (new_st.next);
5713 5 : new_st.next = NULL;
5714 5 : gfc_free_expr (new_st.expr1);
5715 5 : new_st.expr1 = NULL;
5716 5 : gfc_free_expr (new_st.expr2);
5717 5 : new_st.expr2 = NULL;
5718 5 : gfc_free_expr (p);
5719 5 : return MATCH_ERROR;
5720 : }
5721 :
5722 :
5723 : /* Match a DEALLOCATE statement. */
5724 :
5725 : match
5726 6134 : gfc_match_deallocate (void)
5727 : {
5728 6134 : gfc_alloc *head, *tail;
5729 6134 : gfc_expr *stat, *errmsg, *tmp;
5730 6134 : gfc_symbol *sym;
5731 6134 : match m;
5732 6134 : bool saw_stat, saw_errmsg, b1, b2;
5733 :
5734 6134 : head = tail = NULL;
5735 6134 : stat = errmsg = tmp = NULL;
5736 6134 : saw_stat = saw_errmsg = false;
5737 :
5738 6134 : if (gfc_match_char ('(') != MATCH_YES)
5739 0 : goto syntax;
5740 :
5741 8411 : for (;;)
5742 : {
5743 8411 : if (head == NULL)
5744 6134 : head = tail = gfc_get_alloc ();
5745 : else
5746 : {
5747 2277 : tail->next = gfc_get_alloc ();
5748 2277 : tail = tail->next;
5749 : }
5750 :
5751 8411 : m = gfc_match_variable (&tail->expr, 0);
5752 8411 : if (m == MATCH_ERROR)
5753 0 : goto cleanup;
5754 8411 : if (m == MATCH_NO)
5755 0 : goto syntax;
5756 :
5757 8411 : if (tail->expr->expr_type == EXPR_CONSTANT)
5758 : {
5759 1 : gfc_error ("Unexpected constant at %C");
5760 1 : goto cleanup;
5761 : }
5762 :
5763 8410 : if (gfc_check_do_variable (tail->expr->symtree))
5764 0 : goto cleanup;
5765 :
5766 8410 : sym = tail->expr->symtree->n.sym;
5767 :
5768 8410 : bool impure = gfc_impure_variable (sym);
5769 8410 : if (impure && gfc_pure (NULL))
5770 : {
5771 0 : gfc_error ("Illegal allocate-object at %C for a PURE procedure");
5772 0 : goto cleanup;
5773 : }
5774 :
5775 8410 : if (impure)
5776 429 : gfc_unset_implicit_pure (NULL);
5777 :
5778 8410 : if (gfc_is_coarray (tail->expr)
5779 8410 : && gfc_find_state (COMP_DO_CONCURRENT))
5780 : {
5781 1 : gfc_error ("DEALLOCATE of coarray at %C in DO CONCURRENT block");
5782 1 : goto cleanup;
5783 : }
5784 :
5785 8409 : if (gfc_is_coarray (tail->expr)
5786 8409 : && gfc_find_state (COMP_CRITICAL))
5787 : {
5788 1 : gfc_error ("DEALLOCATE of coarray at %C in CRITICAL block");
5789 1 : goto cleanup;
5790 : }
5791 :
5792 : /* FIXME: disable the checking on derived types. */
5793 8408 : b1 = !(tail->expr->ref
5794 6377 : && (tail->expr->ref->type == REF_COMPONENT
5795 : || tail->expr->ref->type == REF_ARRAY));
5796 8408 : if (sym && sym->ts.type == BT_CLASS)
5797 1577 : b2 = !(CLASS_DATA (sym) && (CLASS_DATA (sym)->attr.allocatable
5798 391 : || CLASS_DATA (sym)->attr.class_pointer));
5799 : else
5800 6831 : b2 = sym && !(sym->attr.allocatable || sym->attr.pointer
5801 1368 : || sym->attr.proc_pointer);
5802 1438 : if (b1 && b2)
5803 : {
5804 3 : gfc_error ("Allocate-object at %C is not a nonprocedure pointer "
5805 : "nor an allocatable variable");
5806 3 : goto cleanup;
5807 : }
5808 :
5809 8405 : if (gfc_match_char (',') != MATCH_YES)
5810 : break;
5811 :
5812 2615 : dealloc_opt_list:
5813 :
5814 2680 : m = gfc_match (" stat = %e", &tmp);
5815 2680 : if (m == MATCH_ERROR)
5816 2 : goto cleanup;
5817 2678 : if (m == MATCH_YES)
5818 : {
5819 335 : if (saw_stat)
5820 : {
5821 1 : gfc_error ("Redundant STAT tag found at %L", &tmp->where);
5822 1 : gfc_free_expr (tmp);
5823 1 : goto cleanup;
5824 : }
5825 :
5826 334 : stat = tmp;
5827 334 : saw_stat = true;
5828 :
5829 334 : if (gfc_check_do_variable (stat->symtree))
5830 0 : goto cleanup;
5831 :
5832 334 : if (gfc_match_char (',') == MATCH_YES)
5833 61 : goto dealloc_opt_list;
5834 : }
5835 :
5836 2616 : m = gfc_match (" errmsg = %e", &tmp);
5837 2616 : if (m == MATCH_ERROR)
5838 0 : goto cleanup;
5839 2616 : if (m == MATCH_YES)
5840 : {
5841 66 : if (!gfc_notify_std (GFC_STD_F2003, "ERRMSG at %L", &tmp->where))
5842 0 : goto cleanup;
5843 :
5844 66 : if (saw_errmsg)
5845 : {
5846 1 : gfc_error ("Redundant ERRMSG tag found at %L", &tmp->where);
5847 1 : gfc_free_expr (tmp);
5848 1 : goto cleanup;
5849 : }
5850 :
5851 65 : errmsg = tmp;
5852 65 : saw_errmsg = true;
5853 :
5854 65 : if (gfc_match_char (',') == MATCH_YES)
5855 4 : goto dealloc_opt_list;
5856 : }
5857 :
5858 2611 : gfc_gobble_whitespace ();
5859 :
5860 2611 : if (gfc_peek_char () == ')')
5861 : break;
5862 : }
5863 :
5864 6124 : if (gfc_match (" )%t") != MATCH_YES)
5865 1 : goto syntax;
5866 :
5867 6123 : new_st.op = EXEC_DEALLOCATE;
5868 6123 : new_st.expr1 = stat;
5869 6123 : new_st.expr2 = errmsg;
5870 6123 : new_st.ext.alloc.list = head;
5871 :
5872 6123 : return MATCH_YES;
5873 :
5874 1 : syntax:
5875 1 : gfc_syntax_error (ST_DEALLOCATE);
5876 :
5877 11 : cleanup:
5878 11 : gfc_free_expr (errmsg);
5879 11 : gfc_free_expr (stat);
5880 11 : gfc_free_alloc_list (head);
5881 11 : return MATCH_ERROR;
5882 : }
5883 :
5884 :
5885 : /* Match a RETURN statement. */
5886 :
5887 : match
5888 3209 : gfc_match_return (void)
5889 : {
5890 3209 : gfc_expr *e;
5891 3209 : match m;
5892 3209 : gfc_compile_state s;
5893 :
5894 3209 : e = NULL;
5895 :
5896 3209 : if (gfc_find_state (COMP_CRITICAL))
5897 : {
5898 1 : gfc_error ("Image control statement RETURN at %C in CRITICAL block");
5899 1 : return MATCH_ERROR;
5900 : }
5901 :
5902 3208 : if (gfc_find_state (COMP_DO_CONCURRENT))
5903 : {
5904 1 : gfc_error ("Image control statement RETURN at %C in DO CONCURRENT block");
5905 1 : return MATCH_ERROR;
5906 : }
5907 :
5908 3207 : if (gfc_find_state (COMP_CHANGE_TEAM))
5909 : {
5910 : /* F2018, C1111: A RETURN statement shall not appear within a CHANGE TEAM
5911 : construct. */
5912 1 : gfc_error (
5913 : "Image control statement RETURN at %C in CHANGE TEAM-END TEAM block");
5914 1 : return MATCH_ERROR;
5915 : }
5916 :
5917 3206 : if (gfc_match_eos () == MATCH_YES)
5918 3152 : goto done;
5919 :
5920 54 : if (!gfc_find_state (COMP_SUBROUTINE))
5921 : {
5922 0 : gfc_error ("Alternate RETURN statement at %C is only allowed within "
5923 : "a SUBROUTINE");
5924 0 : goto cleanup;
5925 : }
5926 :
5927 54 : if (gfc_current_form == FORM_FREE)
5928 : {
5929 : /* The following are valid, so we can't require a blank after the
5930 : RETURN keyword:
5931 : return+1
5932 : return(1) */
5933 54 : char c = gfc_peek_ascii_char ();
5934 54 : if (ISALPHA (c) || ISDIGIT (c))
5935 : return MATCH_NO;
5936 : }
5937 :
5938 53 : m = gfc_match (" %e%t", &e);
5939 53 : if (m == MATCH_YES)
5940 53 : goto done;
5941 0 : if (m == MATCH_ERROR)
5942 0 : goto cleanup;
5943 :
5944 0 : gfc_syntax_error (ST_RETURN);
5945 :
5946 0 : cleanup:
5947 0 : gfc_free_expr (e);
5948 0 : return MATCH_ERROR;
5949 :
5950 3205 : done:
5951 3205 : gfc_enclosing_unit (&s);
5952 3205 : if (s == COMP_PROGRAM
5953 3205 : && !gfc_notify_std (GFC_STD_GNU, "RETURN statement in "
5954 : "main program at %C"))
5955 : return MATCH_ERROR;
5956 :
5957 3205 : new_st.op = EXEC_RETURN;
5958 3205 : new_st.expr1 = e;
5959 :
5960 3205 : return MATCH_YES;
5961 : }
5962 :
5963 :
5964 : /* Match the call of a type-bound procedure, if CALL%var has already been
5965 : matched and var found to be a derived-type variable. */
5966 :
5967 : static match
5968 1438 : match_typebound_call (gfc_symtree* varst)
5969 : {
5970 1438 : gfc_expr* base;
5971 1438 : match m;
5972 :
5973 1438 : base = gfc_get_expr ();
5974 1438 : base->expr_type = EXPR_VARIABLE;
5975 1438 : base->symtree = varst;
5976 1438 : base->where = gfc_current_locus;
5977 1438 : gfc_set_sym_referenced (varst->n.sym);
5978 :
5979 1438 : m = gfc_match_varspec (base, 0, true, true);
5980 1438 : if (m == MATCH_NO)
5981 0 : gfc_error ("Expected component reference at %C");
5982 1438 : if (m != MATCH_YES)
5983 : {
5984 5 : gfc_free_expr (base);
5985 5 : return MATCH_ERROR;
5986 : }
5987 :
5988 1433 : if (gfc_match_eos () != MATCH_YES)
5989 : {
5990 1 : gfc_error ("Junk after CALL at %C");
5991 1 : gfc_free_expr (base);
5992 1 : return MATCH_ERROR;
5993 : }
5994 :
5995 1432 : if (base->expr_type == EXPR_COMPCALL)
5996 1307 : new_st.op = EXEC_COMPCALL;
5997 125 : else if (base->expr_type == EXPR_PPC)
5998 124 : new_st.op = EXEC_CALL_PPC;
5999 : else
6000 : {
6001 1 : gfc_error ("Expected type-bound procedure or procedure pointer component "
6002 : "at %C");
6003 1 : gfc_free_expr (base);
6004 1 : return MATCH_ERROR;
6005 : }
6006 1431 : new_st.expr1 = base;
6007 :
6008 1431 : return MATCH_YES;
6009 : }
6010 :
6011 :
6012 : /* Match a CALL statement. The tricky part here are possible
6013 : alternate return specifiers. We handle these by having all
6014 : "subroutines" actually return an integer via a register that gives
6015 : the return number. If the call specifies alternate returns, we
6016 : generate code for a SELECT statement whose case clauses contain
6017 : GOTOs to the various labels. */
6018 :
6019 : match
6020 80913 : gfc_match_call (void)
6021 : {
6022 80913 : char name[GFC_MAX_SYMBOL_LEN + 1];
6023 80913 : gfc_actual_arglist *a, *arglist;
6024 80913 : gfc_case *new_case;
6025 80913 : gfc_symbol *sym;
6026 80913 : gfc_symtree *st;
6027 80913 : gfc_code *c;
6028 80913 : match m;
6029 80913 : int i;
6030 :
6031 80913 : arglist = NULL;
6032 :
6033 80913 : m = gfc_match ("% %n", name);
6034 80913 : if (m == MATCH_NO)
6035 0 : goto syntax;
6036 80913 : if (m != MATCH_YES)
6037 : return m;
6038 :
6039 80913 : if (gfc_get_ha_sym_tree (name, &st))
6040 : return MATCH_ERROR;
6041 :
6042 80911 : sym = st->n.sym;
6043 :
6044 : /* If this is a variable of derived-type, it probably starts a type-bound
6045 : procedure call. Associate variable targets have to be resolved for the
6046 : target type. */
6047 80911 : if (((sym->attr.flavor != FL_PROCEDURE
6048 57652 : || gfc_is_function_return_value (sym, gfc_current_ns))
6049 23261 : && (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS))
6050 79487 : ||
6051 : /* Skip gfc_resolve_expr for ASSOCIATE names followed by '%'.
6052 : resolving a contained-function selector before CONTAINS is
6053 : parsed prematurely, marks it EXTERNAL, conflicting with its
6054 : later INTERNAL declaration. */
6055 79487 : (sym->assoc && sym->assoc->target && gfc_peek_ascii_char () == '%')
6056 80911 : ||
6057 79473 : (sym->assoc && sym->assoc->target
6058 0 : && gfc_resolve_expr (sym->assoc->target)
6059 0 : && (sym->assoc->target->ts.type == BT_DERIVED
6060 0 : || sym->assoc->target->ts.type == BT_CLASS)))
6061 1438 : return match_typebound_call (st);
6062 :
6063 : /* If it does not seem to be callable (include functions so that the
6064 : right association is made. They are thrown out in resolution.)
6065 : ... */
6066 79473 : if (!sym->attr.generic
6067 76661 : && !sym->attr.proc_pointer
6068 76428 : && !sym->attr.subroutine
6069 22598 : && !sym->attr.function)
6070 : {
6071 22593 : if (!(sym->attr.external && !sym->attr.referenced))
6072 : {
6073 : /* ...create a symbol in this scope... */
6074 21961 : if (sym->ns != gfc_current_ns
6075 21961 : && gfc_get_sym_tree (name, NULL, &st, false) == 1)
6076 : return MATCH_ERROR;
6077 :
6078 21961 : if (sym != st->n.sym)
6079 22593 : sym = st->n.sym;
6080 : }
6081 :
6082 : /* ...and then to try to make the symbol into a subroutine. */
6083 22593 : if (!gfc_add_subroutine (&sym->attr, sym->name, NULL))
6084 : return MATCH_ERROR;
6085 : }
6086 :
6087 79471 : gfc_set_sym_referenced (sym);
6088 :
6089 79471 : if (gfc_match_eos () != MATCH_YES)
6090 : {
6091 72125 : m = gfc_match_actual_arglist (1, &arglist);
6092 72125 : if (m == MATCH_NO)
6093 0 : goto syntax;
6094 72125 : if (m == MATCH_ERROR)
6095 10 : goto cleanup;
6096 :
6097 72115 : if (gfc_match_eos () != MATCH_YES)
6098 1 : goto syntax;
6099 : }
6100 :
6101 : /* Walk the argument list looking for invalid BOZ. */
6102 248633 : for (a = arglist; a; a = a->next)
6103 169174 : if (a->expr && a->expr->ts.type == BT_BOZ)
6104 : {
6105 1 : gfc_error ("A BOZ literal constant at %L cannot appear as an actual "
6106 : "argument in a subroutine reference", &a->expr->where);
6107 1 : goto cleanup;
6108 : }
6109 :
6110 :
6111 : /* If any alternate return labels were found, construct a SELECT
6112 : statement that will jump to the right place. */
6113 :
6114 248340 : i = 0;
6115 248340 : for (a = arglist; a; a = a->next)
6116 169031 : if (a->expr == NULL)
6117 : {
6118 : i = 1;
6119 : break;
6120 : }
6121 :
6122 79459 : if (i)
6123 : {
6124 150 : gfc_symtree *select_st;
6125 150 : gfc_symbol *select_sym;
6126 150 : char name[GFC_MAX_SYMBOL_LEN + 1];
6127 :
6128 150 : new_st.next = c = gfc_get_code (EXEC_SELECT);
6129 150 : sprintf (name, "_result_%s", sym->name);
6130 150 : gfc_get_ha_sym_tree (name, &select_st); /* Can't fail. */
6131 :
6132 150 : select_sym = select_st->n.sym;
6133 150 : select_sym->ts.type = BT_INTEGER;
6134 150 : select_sym->ts.kind = gfc_default_integer_kind;
6135 150 : gfc_set_sym_referenced (select_sym);
6136 150 : c->expr1 = gfc_get_expr ();
6137 150 : c->expr1->expr_type = EXPR_VARIABLE;
6138 150 : c->expr1->symtree = select_st;
6139 150 : c->expr1->ts = select_sym->ts;
6140 150 : c->expr1->where = gfc_current_locus;
6141 :
6142 150 : i = 0;
6143 618 : for (a = arglist; a; a = a->next)
6144 : {
6145 468 : if (a->expr != NULL)
6146 232 : continue;
6147 :
6148 236 : if (!gfc_reference_st_label (a->label, ST_LABEL_TARGET))
6149 0 : continue;
6150 :
6151 236 : i++;
6152 :
6153 236 : c->block = gfc_get_code (EXEC_SELECT);
6154 236 : c = c->block;
6155 :
6156 236 : new_case = gfc_get_case ();
6157 236 : new_case->high = gfc_get_int_expr (gfc_default_integer_kind, NULL, i);
6158 236 : new_case->low = new_case->high;
6159 236 : c->ext.block.case_list = new_case;
6160 :
6161 236 : c->next = gfc_get_code (EXEC_GOTO);
6162 236 : c->next->label1 = a->label;
6163 : }
6164 : }
6165 :
6166 79459 : new_st.op = EXEC_CALL;
6167 79459 : new_st.symtree = st;
6168 79459 : new_st.ext.actual = arglist;
6169 :
6170 79459 : return MATCH_YES;
6171 :
6172 1 : syntax:
6173 1 : gfc_syntax_error (ST_CALL);
6174 :
6175 12 : cleanup:
6176 12 : gfc_free_actual_arglist (arglist);
6177 12 : return MATCH_ERROR;
6178 : }
6179 :
6180 :
6181 : /* Given a name, return a pointer to the common head structure,
6182 : creating it if it does not exist. If FROM_MODULE is nonzero, we
6183 : mangle the name so that it doesn't interfere with commons defined
6184 : in the using namespace.
6185 : TODO: Add to global symbol tree. */
6186 :
6187 : gfc_common_head *
6188 2078 : gfc_get_common (const char *name, int from_module)
6189 : {
6190 2078 : gfc_symtree *st;
6191 2078 : static int serial = 0;
6192 2078 : char mangled_name[GFC_MAX_SYMBOL_LEN + 1];
6193 :
6194 2078 : if (from_module)
6195 : {
6196 : /* A use associated common block is only needed to correctly layout
6197 : the variables it contains. */
6198 170 : snprintf (mangled_name, GFC_MAX_SYMBOL_LEN, "_%d_%s", serial++, name);
6199 170 : st = gfc_new_symtree (&gfc_current_ns->common_root, mangled_name);
6200 : }
6201 : else
6202 : {
6203 1908 : st = gfc_find_symtree (gfc_current_ns->common_root, name);
6204 :
6205 1908 : if (st == NULL)
6206 1820 : st = gfc_new_symtree (&gfc_current_ns->common_root, name);
6207 : }
6208 :
6209 2078 : if (st->n.common == NULL)
6210 : {
6211 1990 : st->n.common = gfc_get_common_head ();
6212 1990 : st->n.common->where = gfc_current_locus;
6213 1990 : strcpy (st->n.common->name, name);
6214 : }
6215 :
6216 2078 : return st->n.common;
6217 : }
6218 :
6219 :
6220 : /* Match a common block name. */
6221 :
6222 : match
6223 2114 : gfc_match_common_name (char *name)
6224 : {
6225 2114 : match m;
6226 :
6227 2114 : if (gfc_match_char ('/') == MATCH_NO)
6228 : {
6229 122 : name[0] = '\0';
6230 122 : return MATCH_YES;
6231 : }
6232 :
6233 1992 : if (gfc_match_char ('/') == MATCH_YES)
6234 : {
6235 85 : name[0] = '\0';
6236 85 : return MATCH_YES;
6237 : }
6238 :
6239 1907 : m = gfc_match_name (name);
6240 :
6241 1907 : if (m == MATCH_ERROR)
6242 : return MATCH_ERROR;
6243 1907 : if (m == MATCH_YES && gfc_match_char ('/') == MATCH_YES)
6244 : return MATCH_YES;
6245 :
6246 0 : gfc_error ("Syntax error in common block name at %C");
6247 0 : return MATCH_ERROR;
6248 : }
6249 :
6250 :
6251 : /* Match a COMMON statement. */
6252 :
6253 : match
6254 2034 : gfc_match_common (void)
6255 : {
6256 2034 : gfc_symbol *sym, **head, *tail, *other;
6257 2034 : char name[GFC_MAX_SYMBOL_LEN + 1];
6258 2034 : gfc_common_head *t;
6259 2034 : gfc_array_spec *as;
6260 2034 : gfc_equiv *e1, *e2;
6261 2034 : match m;
6262 2034 : char c;
6263 :
6264 : /* COMMON has been matched. In free form source code, the next character
6265 : needs to be whitespace or '/'. Check that here. Fixed form source
6266 : code needs to be checked below. */
6267 2034 : c = gfc_peek_ascii_char ();
6268 2034 : if (gfc_current_form == FORM_FREE && !gfc_is_whitespace (c) && c != '/')
6269 : return MATCH_NO;
6270 :
6271 2033 : as = NULL;
6272 :
6273 2038 : for (;;)
6274 : {
6275 2038 : m = gfc_match_common_name (name);
6276 2038 : if (m == MATCH_ERROR)
6277 0 : goto cleanup;
6278 :
6279 2038 : if (name[0] == '\0')
6280 : {
6281 207 : t = &gfc_current_ns->blank_common;
6282 207 : if (t->head == NULL)
6283 205 : t->where = gfc_current_locus;
6284 : }
6285 : else
6286 : {
6287 1831 : t = gfc_get_common (name, 0);
6288 : }
6289 2038 : head = &t->head;
6290 :
6291 2038 : if (*head == NULL)
6292 : tail = NULL;
6293 : else
6294 : {
6295 : tail = *head;
6296 114 : while (tail->common_next)
6297 : tail = tail->common_next;
6298 : }
6299 :
6300 : /* Grab the list of symbols. */
6301 5877 : for (;;)
6302 : {
6303 5877 : m = gfc_match_symbol (&sym, 0);
6304 5877 : if (m == MATCH_ERROR)
6305 0 : goto cleanup;
6306 5877 : if (m == MATCH_NO)
6307 7 : goto syntax;
6308 :
6309 : /* See if we know the current common block is bind(c), and if
6310 : so, then see if we can check if the symbol is (which it'll
6311 : need to be). This can happen if the bind(c) attr stmt was
6312 : applied to the common block, and the variable(s) already
6313 : defined, before declaring the common block. */
6314 5870 : if (t->is_bind_c == 1)
6315 : {
6316 13 : if (sym->ts.type != BT_UNKNOWN && sym->ts.is_c_interop != 1)
6317 : {
6318 : /* If we find an error, just print it and continue,
6319 : cause it's just semantic, and we can see if there
6320 : are more errors. */
6321 0 : gfc_error_now ("Variable %qs at %L in common block %qs "
6322 : "at %C must be declared with a C "
6323 : "interoperable kind since common block "
6324 : "%qs is bind(c)",
6325 : sym->name, &(sym->declared_at), t->name,
6326 0 : t->name);
6327 : }
6328 :
6329 13 : if (sym->attr.is_bind_c == 1)
6330 0 : gfc_error_now ("Variable %qs in common block %qs at %C cannot "
6331 : "be bind(c) since it is not global", sym->name,
6332 0 : t->name);
6333 : }
6334 :
6335 5870 : if (sym->attr.in_common)
6336 : {
6337 2 : gfc_error ("Symbol %qs at %C is already in a COMMON block",
6338 : sym->name);
6339 2 : goto cleanup;
6340 : }
6341 :
6342 5868 : if (((sym->value != NULL && sym->value->expr_type != EXPR_NULL)
6343 5868 : || sym->attr.data) && gfc_current_state () != COMP_BLOCK_DATA)
6344 : {
6345 7 : if (!gfc_notify_std (GFC_STD_GNU, "Initialized symbol %qs at "
6346 : "%C can only be COMMON in BLOCK DATA",
6347 : sym->name))
6348 2 : goto cleanup;
6349 : }
6350 :
6351 : /* F2018:R874: common-block-object is variable-name [ (array-spec) ]
6352 : F2018:C8121: A variable-name shall not be a name made accessible
6353 : by use association. */
6354 5866 : if (sym->attr.use_assoc)
6355 : {
6356 2 : gfc_error ("Symbol %qs at %C is USE associated from module %qs "
6357 : "and cannot occur in COMMON", sym->name, sym->module);
6358 2 : goto cleanup;
6359 : }
6360 :
6361 : /* Deal with an optional array specification after the
6362 : symbol name. */
6363 5864 : m = gfc_match_array_spec (&as, true, true);
6364 5864 : if (m == MATCH_ERROR)
6365 2 : goto cleanup;
6366 :
6367 5862 : if (m == MATCH_YES)
6368 : {
6369 2127 : if (as->type != AS_EXPLICIT)
6370 : {
6371 0 : gfc_error ("Array specification for symbol %qs in COMMON "
6372 : "at %C must be explicit", sym->name);
6373 0 : goto cleanup;
6374 : }
6375 :
6376 2127 : if (as->corank)
6377 : {
6378 1 : gfc_error ("Symbol %qs in COMMON at %C cannot be a "
6379 : "coarray", sym->name);
6380 1 : goto cleanup;
6381 : }
6382 :
6383 2126 : if (!gfc_add_dimension (&sym->attr, sym->name, NULL))
6384 0 : goto cleanup;
6385 :
6386 2126 : if (sym->attr.pointer)
6387 : {
6388 0 : gfc_error ("Symbol %qs in COMMON at %C cannot be a "
6389 : "POINTER array", sym->name);
6390 0 : goto cleanup;
6391 : }
6392 :
6393 2126 : sym->as = as;
6394 2126 : as = NULL;
6395 :
6396 : }
6397 :
6398 : /* Add the in_common attribute, but ignore the reported errors
6399 : if any, and continue matching. */
6400 5861 : gfc_add_in_common (&sym->attr, sym->name, NULL);
6401 :
6402 5861 : sym->common_block = t;
6403 5861 : sym->common_block->refs++;
6404 :
6405 5861 : if (tail != NULL)
6406 3851 : tail->common_next = sym;
6407 : else
6408 2010 : *head = sym;
6409 :
6410 5861 : tail = sym;
6411 :
6412 5861 : sym->common_head = t;
6413 :
6414 : /* Check to see if the symbol is already in an equivalence group.
6415 : If it is, set the other members as being in common. */
6416 5861 : if (sym->attr.in_equivalence)
6417 : {
6418 20 : for (e1 = gfc_current_ns->equiv; e1; e1 = e1->next)
6419 : {
6420 29 : for (e2 = e1; e2; e2 = e2->eq)
6421 23 : if (e2->expr->symtree->n.sym == sym)
6422 8 : goto equiv_found;
6423 :
6424 6 : continue;
6425 :
6426 8 : equiv_found:
6427 :
6428 23 : for (e2 = e1; e2; e2 = e2->eq)
6429 : {
6430 16 : other = e2->expr->symtree->n.sym;
6431 16 : if (other->common_head
6432 9 : && other->common_head != sym->common_head)
6433 : {
6434 1 : gfc_error ("Symbol %qs, in COMMON block %qs at "
6435 : "%C is being indirectly equivalenced to "
6436 : "another COMMON block %qs",
6437 1 : sym->name, sym->common_head->name,
6438 1 : other->common_head->name);
6439 1 : goto cleanup;
6440 : }
6441 15 : other->attr.in_common = 1;
6442 15 : other->common_head = t;
6443 : }
6444 : }
6445 : }
6446 :
6447 :
6448 5860 : gfc_gobble_whitespace ();
6449 5860 : if (gfc_match_eos () == MATCH_YES)
6450 2015 : goto done;
6451 3845 : c = gfc_peek_ascii_char ();
6452 3845 : if (c == '/')
6453 : break;
6454 3842 : if (c != ',')
6455 : {
6456 : /* In Fixed form source code, gfortran can end up here for an
6457 : expression of the form COMMONI = RHS. This may not be an
6458 : error, so return MATCH_NO. */
6459 1 : if (gfc_current_form == FORM_FIXED && c == '=')
6460 : {
6461 1 : gfc_free_array_spec (as);
6462 1 : return MATCH_NO;
6463 : }
6464 0 : goto syntax;
6465 : }
6466 : else
6467 3841 : gfc_match_char (',');
6468 :
6469 3841 : gfc_gobble_whitespace ();
6470 3841 : if (gfc_peek_ascii_char () == '/')
6471 : break;
6472 : }
6473 : }
6474 :
6475 2015 : done:
6476 2015 : return MATCH_YES;
6477 :
6478 7 : syntax:
6479 7 : gfc_syntax_error (ST_COMMON);
6480 :
6481 17 : cleanup:
6482 17 : gfc_free_array_spec (as);
6483 17 : return MATCH_ERROR;
6484 : }
6485 :
6486 :
6487 : /* Match a BLOCK DATA program unit. */
6488 :
6489 : match
6490 88 : gfc_match_block_data (void)
6491 : {
6492 88 : char name[GFC_MAX_SYMBOL_LEN + 1];
6493 88 : gfc_symbol *sym;
6494 88 : match m;
6495 :
6496 88 : if (!gfc_notify_std (GFC_STD_F2018_OBS, "BLOCK DATA construct at %L",
6497 : &gfc_current_locus))
6498 : return MATCH_ERROR;
6499 :
6500 88 : if (gfc_match_eos () == MATCH_YES)
6501 : {
6502 50 : gfc_new_block = NULL;
6503 50 : return MATCH_YES;
6504 : }
6505 :
6506 38 : m = gfc_match ("% %n%t", name);
6507 38 : if (m != MATCH_YES)
6508 : return MATCH_ERROR;
6509 :
6510 38 : if (gfc_get_symbol (name, NULL, &sym))
6511 : return MATCH_ERROR;
6512 :
6513 38 : if (!gfc_add_flavor (&sym->attr, FL_BLOCK_DATA, sym->name, NULL))
6514 : return MATCH_ERROR;
6515 :
6516 38 : gfc_new_block = sym;
6517 :
6518 38 : return MATCH_YES;
6519 : }
6520 :
6521 :
6522 : /* Free a namelist structure. */
6523 :
6524 : void
6525 6286404 : gfc_free_namelist (gfc_namelist *name)
6526 : {
6527 6286404 : gfc_namelist *n;
6528 :
6529 6288584 : for (; name; name = n)
6530 : {
6531 2180 : n = name->next;
6532 2180 : free (name);
6533 : }
6534 6286404 : }
6535 :
6536 :
6537 : /* Free an OpenMP namelist structure. */
6538 :
6539 : void
6540 1350489 : gfc_free_omp_namelist (gfc_omp_namelist *name, enum gfc_omp_list_type list)
6541 : {
6542 2700978 : bool free_ns = (list == OMP_LIST_AFFINITY || list == OMP_LIST_DEPEND
6543 : || list == OMP_LIST_MAP
6544 1350489 : || list == OMP_LIST_TO || list == OMP_LIST_FROM);
6545 1350489 : bool free_align_allocator = (list == OMP_LIST_ALLOCATE);
6546 1350489 : bool free_mem_traits_space = (list == OMP_LIST_USES_ALLOCATORS);
6547 1350489 : bool free_init = (list == OMP_LIST_INIT);
6548 1350489 : bool free_mapper = (list == OMP_LIST_MAP
6549 : || list == OMP_LIST_TO
6550 1350489 : || list == OMP_LIST_FROM);
6551 :
6552 1350489 : gfc_omp_namelist *n;
6553 1350489 : gfc_expr *last_allocator = NULL;
6554 1350489 : char *last_init_interop = NULL;
6555 :
6556 1396663 : for (; name; name = n)
6557 : {
6558 46174 : gfc_free_expr (name->expr);
6559 46174 : if (free_align_allocator)
6560 297 : gfc_free_expr (name->u.align);
6561 : else if (free_mem_traits_space)
6562 : { } /* name->u.memspace_sym: shall not call gfc_free_symbol here. */
6563 :
6564 46174 : if (free_ns)
6565 21077 : gfc_free_namespace (name->u2.ns);
6566 25097 : else if (free_align_allocator)
6567 : {
6568 297 : if (last_allocator != name->u2.allocator)
6569 : {
6570 114 : last_allocator = name->u2.allocator;
6571 114 : gfc_free_expr (name->u2.allocator);
6572 : }
6573 : }
6574 24800 : else if (free_mem_traits_space)
6575 : { } /* name->u2.traits_sym: shall not call gfc_free_symbol here. */
6576 24672 : else if (free_init)
6577 : {
6578 84 : if (name->u2.init_interop != last_init_interop)
6579 : {
6580 31 : last_init_interop = name->u2.init_interop;
6581 31 : free (name->u2.init_interop);
6582 : }
6583 : }
6584 24588 : else if (free_mapper && name->u3.udm)
6585 0 : free (name->u3.udm);
6586 24588 : else if (!free_mapper && name->u2.udr)
6587 : {
6588 470 : if (name->u2.udr->combiner)
6589 470 : gfc_free_statement (name->u2.udr->combiner);
6590 470 : if (name->u2.udr->initializer)
6591 331 : gfc_free_statement (name->u2.udr->initializer);
6592 470 : free (name->u2.udr);
6593 : }
6594 46174 : n = name->next;
6595 46174 : free (name);
6596 : }
6597 1350489 : }
6598 :
6599 :
6600 : /* Match a NAMELIST statement. */
6601 :
6602 : match
6603 1038 : gfc_match_namelist (void)
6604 : {
6605 1038 : gfc_symbol *group_name, *sym;
6606 1038 : gfc_namelist *nl;
6607 1038 : match m, m2;
6608 :
6609 1038 : m = gfc_match (" / %s /", &group_name);
6610 1038 : if (m == MATCH_NO)
6611 0 : goto syntax;
6612 1038 : if (m == MATCH_ERROR)
6613 0 : goto error;
6614 :
6615 1038 : for (;;)
6616 : {
6617 1038 : if (group_name->ts.type != BT_UNKNOWN)
6618 : {
6619 0 : gfc_error ("Namelist group name %qs at %C already has a basic "
6620 : "type of %s", group_name->name,
6621 : gfc_typename (&group_name->ts));
6622 0 : return MATCH_ERROR;
6623 : }
6624 :
6625 : /* A use associated name shall not be used as a namelist group name
6626 : (e.g. F2003:C581). It is only supported as a legacy extension. */
6627 1038 : if (group_name->attr.flavor == FL_NAMELIST
6628 220 : && group_name->attr.use_assoc
6629 1047 : && !gfc_notify_std (GFC_STD_LEGACY, "Namelist group name %qs "
6630 : "at %C already is USE associated and can"
6631 : "not be respecified.", group_name->name))
6632 : return MATCH_ERROR;
6633 :
6634 1036 : if (group_name->attr.flavor != FL_NAMELIST
6635 1036 : && !gfc_add_flavor (&group_name->attr, FL_NAMELIST,
6636 : group_name->name, NULL))
6637 : return MATCH_ERROR;
6638 :
6639 2102 : for (;;)
6640 : {
6641 2102 : m = gfc_match_symbol (&sym, 1);
6642 2102 : if (m == MATCH_NO)
6643 1 : goto syntax;
6644 2101 : if (m == MATCH_ERROR)
6645 0 : goto error;
6646 :
6647 2101 : if (sym->ts.type == BT_UNKNOWN)
6648 : {
6649 50 : if (gfc_current_ns->seen_implicit_none)
6650 : {
6651 : /* It is required that members of a namelist be declared
6652 : before the namelist. We check this by checking if the
6653 : symbol has a defined type for IMPLICIT NONE. */
6654 1 : gfc_error ("Symbol %qs in namelist %qs at %C must be "
6655 : "declared before the namelist is declared.",
6656 : sym->name, group_name->name);
6657 1 : gfc_error_check ();
6658 : }
6659 : else
6660 : {
6661 : /* Before the symbol is given an implicit type, check to
6662 : see if the symbol is already available in the namespace,
6663 : possibly through host association. Importantly, the
6664 : symbol may be a user defined type. */
6665 :
6666 49 : gfc_symbol *tmp;
6667 :
6668 49 : gfc_find_symbol (sym->name, NULL, 1, &tmp);
6669 49 : if (tmp && tmp->attr.generic
6670 51 : && (tmp = gfc_find_dt_in_generic (tmp)))
6671 : {
6672 2 : if (tmp->attr.flavor == FL_DERIVED)
6673 : {
6674 2 : gfc_error ("Derived type %qs at %L conflicts with "
6675 : "namelist object %qs at %C",
6676 : tmp->name, &tmp->declared_at, sym->name);
6677 2 : goto error;
6678 : }
6679 : }
6680 :
6681 : /* Set type of the symbol to its implicit default type. It is
6682 : not allowed to set it later to any other type. */
6683 47 : gfc_set_default_type (sym, 0, gfc_current_ns);
6684 : }
6685 : }
6686 2099 : if (sym->attr.in_namelist == 0
6687 2099 : && !gfc_add_in_namelist (&sym->attr, sym->name, NULL))
6688 2 : goto error;
6689 :
6690 : /* Use gfc_error_check here, rather than goto error, so that
6691 : these are the only errors for the next two lines. */
6692 2097 : if (sym->as && sym->as->type == AS_ASSUMED_SIZE)
6693 : {
6694 1 : gfc_error ("Assumed size array %qs in namelist %qs at "
6695 : "%C is not allowed", sym->name, group_name->name);
6696 1 : gfc_error_check ();
6697 : }
6698 :
6699 2097 : nl = gfc_get_namelist ();
6700 2097 : nl->sym = sym;
6701 2097 : sym->refs++;
6702 :
6703 2097 : if (group_name->namelist == NULL)
6704 812 : group_name->namelist = group_name->namelist_tail = nl;
6705 : else
6706 : {
6707 1285 : group_name->namelist_tail->next = nl;
6708 1285 : group_name->namelist_tail = nl;
6709 : }
6710 :
6711 2097 : if (gfc_match_eos () == MATCH_YES)
6712 1029 : goto done;
6713 :
6714 1068 : m = gfc_match_char (',');
6715 :
6716 1068 : if (gfc_match_char ('/') == MATCH_YES)
6717 : {
6718 0 : m2 = gfc_match (" %s /", &group_name);
6719 0 : if (m2 == MATCH_YES)
6720 : break;
6721 0 : if (m2 == MATCH_ERROR)
6722 0 : goto error;
6723 0 : goto syntax;
6724 : }
6725 :
6726 1068 : if (m != MATCH_YES)
6727 0 : goto syntax;
6728 : }
6729 : }
6730 :
6731 1029 : done:
6732 1029 : return MATCH_YES;
6733 :
6734 1 : syntax:
6735 1 : gfc_syntax_error (ST_NAMELIST);
6736 :
6737 : error:
6738 : return MATCH_ERROR;
6739 : }
6740 :
6741 :
6742 : /* Match a MODULE statement. */
6743 :
6744 : match
6745 9918 : gfc_match_module (void)
6746 : {
6747 9918 : match m;
6748 :
6749 9918 : m = gfc_match (" %s%t", &gfc_new_block);
6750 9918 : if (m != MATCH_YES)
6751 : return m;
6752 :
6753 9892 : if (!gfc_add_flavor (&gfc_new_block->attr, FL_MODULE,
6754 : gfc_new_block->name, NULL))
6755 0 : return MATCH_ERROR;
6756 :
6757 : return MATCH_YES;
6758 : }
6759 :
6760 :
6761 : /* Free equivalence sets and lists. Recursively is the easiest way to
6762 : do this. */
6763 :
6764 : void
6765 9666408 : gfc_free_equiv_until (gfc_equiv *eq, gfc_equiv *stop)
6766 : {
6767 9666408 : if (eq == stop)
6768 : return;
6769 :
6770 3201 : gfc_free_equiv (eq->eq);
6771 3201 : gfc_free_equiv_until (eq->next, stop);
6772 3201 : gfc_free_expr (eq->expr);
6773 3201 : free (eq);
6774 : }
6775 :
6776 :
6777 : void
6778 538212 : gfc_free_equiv (gfc_equiv *eq)
6779 : {
6780 538212 : gfc_free_equiv_until (eq, NULL);
6781 538212 : }
6782 :
6783 :
6784 : /* Match an EQUIVALENCE statement. */
6785 :
6786 : match
6787 1021 : gfc_match_equivalence (void)
6788 : {
6789 1021 : gfc_equiv *eq, *set, *tail;
6790 1021 : gfc_ref *ref;
6791 1021 : gfc_symbol *sym;
6792 1021 : match m;
6793 1021 : gfc_common_head *common_head = NULL;
6794 1021 : bool common_flag;
6795 1021 : int cnt;
6796 1021 : char c;
6797 :
6798 : /* EQUIVALENCE has been matched. After gobbling any possible whitespace,
6799 : the next character needs to be '('. Check that here, and return
6800 : MATCH_NO for a variable of the form equivalence. */
6801 1021 : gfc_gobble_whitespace ();
6802 1021 : c = gfc_peek_ascii_char ();
6803 1021 : if (c != '(')
6804 : return MATCH_NO;
6805 :
6806 : tail = NULL;
6807 :
6808 1453 : for (;;)
6809 : {
6810 1453 : eq = gfc_get_equiv ();
6811 1453 : if (tail == NULL)
6812 1020 : tail = eq;
6813 :
6814 1453 : eq->next = gfc_current_ns->equiv;
6815 1453 : gfc_current_ns->equiv = eq;
6816 :
6817 1453 : if (gfc_match_char ('(') != MATCH_YES)
6818 0 : goto syntax;
6819 :
6820 : set = eq;
6821 : common_flag = false;
6822 : cnt = 0;
6823 :
6824 4441 : for (;;)
6825 : {
6826 2947 : m = gfc_match_equiv_variable (&set->expr);
6827 2947 : if (m == MATCH_ERROR)
6828 1 : goto cleanup;
6829 2946 : if (m == MATCH_NO)
6830 0 : goto syntax;
6831 :
6832 : /* count the number of objects. */
6833 2946 : cnt++;
6834 :
6835 2946 : if (gfc_match_char ('%') == MATCH_YES)
6836 : {
6837 0 : gfc_error ("Derived type component %C is not a "
6838 : "permitted EQUIVALENCE member");
6839 0 : goto cleanup;
6840 : }
6841 :
6842 5020 : for (ref = set->expr->ref; ref; ref = ref->next)
6843 2074 : if (ref->type == REF_ARRAY && ref->u.ar.type == AR_SECTION)
6844 : {
6845 0 : gfc_error ("Array reference in EQUIVALENCE at %C cannot "
6846 : "be an array section");
6847 0 : goto cleanup;
6848 : }
6849 :
6850 2946 : sym = set->expr->symtree->n.sym;
6851 :
6852 2946 : if (!gfc_add_in_equivalence (&sym->attr, sym->name, NULL))
6853 6 : goto cleanup;
6854 2940 : if (sym->ts.type == BT_CLASS
6855 3 : && CLASS_DATA (sym)
6856 2943 : && !gfc_add_in_equivalence (&CLASS_DATA (sym)->attr,
6857 : sym->name, NULL))
6858 3 : goto cleanup;
6859 :
6860 2937 : if (sym->attr.in_common)
6861 : {
6862 301 : common_flag = true;
6863 301 : common_head = sym->common_head;
6864 : }
6865 :
6866 2937 : if (gfc_match_char (')') == MATCH_YES)
6867 : break;
6868 :
6869 1494 : if (gfc_match_char (',') != MATCH_YES)
6870 0 : goto syntax;
6871 :
6872 1494 : set->eq = gfc_get_equiv ();
6873 1494 : set = set->eq;
6874 : }
6875 :
6876 1443 : if (cnt < 2)
6877 : {
6878 1 : gfc_error ("EQUIVALENCE at %C requires two or more objects");
6879 1 : goto cleanup;
6880 : }
6881 :
6882 : /* If one of the members of an equivalence is in common, then
6883 : mark them all as being in common. Before doing this, check
6884 : that members of the equivalence group are not in different
6885 : common blocks. */
6886 1442 : if (common_flag)
6887 901 : for (set = eq; set; set = set->eq)
6888 : {
6889 609 : sym = set->expr->symtree->n.sym;
6890 609 : if (sym->common_head && sym->common_head != common_head)
6891 : {
6892 1 : gfc_error ("Attempt to indirectly overlap COMMON "
6893 : "blocks %s and %s by EQUIVALENCE at %C",
6894 1 : sym->common_head->name, common_head->name);
6895 1 : goto cleanup;
6896 : }
6897 608 : sym->attr.in_common = 1;
6898 608 : sym->common_head = common_head;
6899 : }
6900 :
6901 1441 : if (gfc_match_eos () == MATCH_YES)
6902 : break;
6903 434 : if (gfc_match_char (',') != MATCH_YES)
6904 : {
6905 1 : gfc_error ("Expecting a comma in EQUIVALENCE at %C");
6906 1 : goto cleanup;
6907 : }
6908 : }
6909 :
6910 1007 : if (!gfc_notify_std (GFC_STD_F2018_OBS, "EQUIVALENCE statement at %C"))
6911 : return MATCH_ERROR;
6912 :
6913 : return MATCH_YES;
6914 :
6915 0 : syntax:
6916 0 : gfc_syntax_error (ST_EQUIVALENCE);
6917 :
6918 13 : cleanup:
6919 13 : eq = tail->next;
6920 13 : tail->next = NULL;
6921 :
6922 13 : gfc_free_equiv (gfc_current_ns->equiv);
6923 13 : gfc_current_ns->equiv = eq;
6924 :
6925 13 : return MATCH_ERROR;
6926 : }
6927 :
6928 :
6929 : /* Check that a statement function is not recursive. This is done by looking
6930 : for the statement function symbol(sym) by looking recursively through its
6931 : expression(e). If a reference to sym is found, true is returned.
6932 : 12.5.4 requires that any variable of function that is implicitly typed
6933 : shall have that type confirmed by any subsequent type declaration. The
6934 : implicit typing is conveniently done here. */
6935 : static bool
6936 : recursive_stmt_fcn (gfc_expr *, gfc_symbol *);
6937 :
6938 : static bool
6939 908 : check_stmt_fcn (gfc_expr *e, gfc_symbol *sym, int *f ATTRIBUTE_UNUSED)
6940 : {
6941 :
6942 908 : if (e == NULL)
6943 : return false;
6944 :
6945 908 : switch (e->expr_type)
6946 : {
6947 118 : case EXPR_FUNCTION:
6948 118 : if (e->symtree == NULL)
6949 : return false;
6950 :
6951 : /* Check the name before testing for nested recursion! */
6952 118 : if (sym->name == e->symtree->n.sym->name)
6953 : return true;
6954 :
6955 : /* Catch recursion via other statement functions. */
6956 117 : if (e->symtree->n.sym->attr.proc == PROC_ST_FUNCTION
6957 4 : && e->symtree->n.sym->value
6958 121 : && recursive_stmt_fcn (e->symtree->n.sym->value, sym))
6959 : return true;
6960 :
6961 115 : if (e->symtree->n.sym->ts.type == BT_UNKNOWN)
6962 65 : gfc_set_default_type (e->symtree->n.sym, 0, NULL);
6963 :
6964 : break;
6965 :
6966 418 : case EXPR_VARIABLE:
6967 418 : if (e->symtree && sym->name == e->symtree->n.sym->name)
6968 : return true;
6969 :
6970 418 : if (e->symtree->n.sym->ts.type == BT_UNKNOWN)
6971 152 : gfc_set_default_type (e->symtree->n.sym, 0, NULL);
6972 : break;
6973 :
6974 : default:
6975 : break;
6976 : }
6977 :
6978 : return false;
6979 : }
6980 :
6981 :
6982 : static bool
6983 239 : recursive_stmt_fcn (gfc_expr *e, gfc_symbol *sym)
6984 : {
6985 4 : return gfc_traverse_expr (e, sym, check_stmt_fcn, 0);
6986 : }
6987 :
6988 :
6989 : /* Check for invalid uses of statement function dummy arguments in body. */
6990 :
6991 : static bool
6992 879 : chk_stmt_fcn_body (gfc_expr *e, gfc_symbol *sym, int *f ATTRIBUTE_UNUSED)
6993 : {
6994 879 : gfc_formal_arglist *formal;
6995 :
6996 879 : if (e == NULL || e->symtree == NULL || e->expr_type != EXPR_FUNCTION)
6997 : return false;
6998 :
6999 275 : for (formal = sym->formal; formal; formal = formal->next)
7000 : {
7001 165 : if (formal->sym == e->symtree->n.sym)
7002 : {
7003 2 : gfc_error ("Invalid use of statement function argument at %L",
7004 : &e->where);
7005 2 : return true;
7006 : }
7007 : }
7008 :
7009 : return false;
7010 : }
7011 :
7012 :
7013 : /* Match a statement function declaration. It is so easy to match
7014 : non-statement function statements with a MATCH_ERROR as opposed to
7015 : MATCH_NO that we suppress error message in most cases. */
7016 :
7017 : match
7018 424272 : gfc_match_st_function (void)
7019 : {
7020 424272 : gfc_error_buffer old_error;
7021 424272 : gfc_symbol *sym;
7022 424272 : gfc_expr *expr;
7023 424272 : match m;
7024 424272 : char name[GFC_MAX_SYMBOL_LEN + 1];
7025 424272 : locus old_locus;
7026 424272 : bool fcn;
7027 424272 : gfc_formal_arglist *ptr;
7028 :
7029 : /* Read the possible statement function name, and then check to see if
7030 : a symbol is already present in the namespace. Record if it is a
7031 : function and whether it has been referenced. */
7032 424272 : fcn = false;
7033 424272 : ptr = NULL;
7034 424272 : old_locus = gfc_current_locus;
7035 424272 : m = gfc_match_name (name);
7036 424272 : if (m == MATCH_YES)
7037 : {
7038 424272 : gfc_find_symbol (name, NULL, 1, &sym);
7039 424272 : if (sym && sym->attr.function && !sym->attr.referenced)
7040 : {
7041 138 : fcn = true;
7042 138 : ptr = sym->formal;
7043 : }
7044 : }
7045 :
7046 424272 : gfc_current_locus = old_locus;
7047 424272 : m = gfc_match_symbol (&sym, 0);
7048 424272 : if (m != MATCH_YES)
7049 : return m;
7050 :
7051 424259 : gfc_push_error (&old_error);
7052 :
7053 424259 : if (!gfc_add_procedure (&sym->attr, PROC_ST_FUNCTION, sym->name, NULL))
7054 422 : goto undo_error;
7055 :
7056 423837 : if (gfc_match_formal_arglist (sym, 1, 0) != MATCH_YES)
7057 346752 : goto undo_error;
7058 :
7059 77085 : m = gfc_match (" = %e%t", &expr);
7060 77085 : if (m == MATCH_NO)
7061 76850 : goto undo_error;
7062 :
7063 235 : gfc_free_error (&old_error);
7064 :
7065 235 : if (m == MATCH_ERROR)
7066 : return m;
7067 :
7068 235 : if (recursive_stmt_fcn (expr, sym))
7069 : {
7070 1 : gfc_error ("Statement function at %L is recursive", &expr->where);
7071 1 : return MATCH_ERROR;
7072 : }
7073 :
7074 234 : if (fcn && ptr != sym->formal)
7075 : {
7076 4 : gfc_error ("Statement function %qs at %L conflicts with function name",
7077 4 : sym->name, &expr->where);
7078 4 : return MATCH_ERROR;
7079 : }
7080 :
7081 230 : if (gfc_traverse_expr (expr, sym, chk_stmt_fcn_body, 0))
7082 : return MATCH_ERROR;
7083 :
7084 228 : sym->value = expr;
7085 :
7086 228 : if ((gfc_current_state () == COMP_FUNCTION
7087 228 : || gfc_current_state () == COMP_SUBROUTINE)
7088 138 : && gfc_state_stack->previous->state == COMP_INTERFACE)
7089 : {
7090 1 : gfc_error ("Statement function at %L cannot appear within an INTERFACE",
7091 : &expr->where);
7092 1 : return MATCH_ERROR;
7093 : }
7094 :
7095 227 : if (!gfc_notify_std (GFC_STD_F95_OBS, "Statement function at %C"))
7096 : return MATCH_ERROR;
7097 :
7098 : return MATCH_YES;
7099 :
7100 424024 : undo_error:
7101 424024 : gfc_pop_error (&old_error);
7102 424024 : return MATCH_NO;
7103 424272 : }
7104 :
7105 :
7106 : /* Match an assignment to a pointer function (F2008). This could, in
7107 : general be ambiguous with a statement function. In this implementation
7108 : it remains so if it is the first statement after the specification
7109 : block. */
7110 :
7111 : match
7112 1023074 : gfc_match_ptr_fcn_assign (void)
7113 : {
7114 1023074 : gfc_error_buffer old_error;
7115 1023074 : locus old_loc;
7116 1023074 : gfc_symbol *sym;
7117 1023074 : gfc_expr *expr;
7118 1023074 : match m;
7119 1023074 : char name[GFC_MAX_SYMBOL_LEN + 1];
7120 :
7121 1023074 : old_loc = gfc_current_locus;
7122 1023074 : m = gfc_match_name (name);
7123 1023074 : if (m != MATCH_YES)
7124 : return m;
7125 :
7126 1023071 : gfc_find_symbol (name, NULL, 1, &sym);
7127 1023071 : if (sym && sym->attr.flavor != FL_PROCEDURE)
7128 : return MATCH_NO;
7129 :
7130 1022795 : gfc_push_error (&old_error);
7131 :
7132 1022795 : if (sym && sym->attr.function)
7133 924 : goto match_actual_arglist;
7134 :
7135 1021871 : gfc_current_locus = old_loc;
7136 1021871 : m = gfc_match_symbol (&sym, 0);
7137 1021871 : if (m != MATCH_YES)
7138 : return m;
7139 :
7140 1021858 : if (!gfc_add_procedure (&sym->attr, PROC_UNKNOWN, sym->name, NULL))
7141 1 : goto undo_error;
7142 :
7143 1021857 : match_actual_arglist:
7144 1022781 : gfc_current_locus = old_loc;
7145 1022781 : m = gfc_match (" %e", &expr);
7146 1022780 : if (m != MATCH_YES)
7147 635142 : goto undo_error;
7148 :
7149 387638 : new_st.op = EXEC_ASSIGN;
7150 387638 : new_st.expr1 = expr;
7151 387638 : expr = NULL;
7152 :
7153 387638 : m = gfc_match (" = %e%t", &expr);
7154 387638 : if (m != MATCH_YES)
7155 387488 : goto undo_error;
7156 :
7157 150 : new_st.expr2 = expr;
7158 150 : return MATCH_YES;
7159 :
7160 1022631 : undo_error:
7161 1022631 : gfc_pop_error (&old_error);
7162 1022631 : return MATCH_NO;
7163 1023073 : }
7164 :
7165 :
7166 : /***************** SELECT CASE subroutines ******************/
7167 :
7168 : /* Free a single case structure. */
7169 :
7170 : static void
7171 10288 : free_case (gfc_case *p)
7172 : {
7173 10288 : if (p->low == p->high)
7174 4784 : p->high = NULL;
7175 10288 : gfc_free_expr (p->low);
7176 10288 : gfc_free_expr (p->high);
7177 10288 : free (p);
7178 10288 : }
7179 :
7180 :
7181 : /* Free a list of case structures. */
7182 :
7183 : void
7184 10092 : gfc_free_case_list (gfc_case *p)
7185 : {
7186 10092 : gfc_case *q;
7187 :
7188 20370 : for (; p; p = q)
7189 : {
7190 10278 : q = p->next;
7191 10278 : free_case (p);
7192 : }
7193 10092 : }
7194 :
7195 :
7196 : /* Match a single case selector. Combining the requirements of F08:C830
7197 : and F08:C832 (R838) means that the case-value must have either CHARACTER,
7198 : INTEGER, or LOGICAL type. */
7199 :
7200 : static match
7201 1434 : match_case_selector (gfc_case **cp)
7202 : {
7203 1434 : gfc_case *c;
7204 1434 : match m;
7205 :
7206 1434 : c = gfc_get_case ();
7207 1434 : c->where = gfc_current_locus;
7208 :
7209 1434 : if (gfc_match_char (':') == MATCH_YES)
7210 : {
7211 48 : m = gfc_match_init_expr (&c->high);
7212 48 : if (m == MATCH_NO)
7213 0 : goto need_expr;
7214 48 : if (m == MATCH_ERROR)
7215 0 : goto cleanup;
7216 :
7217 48 : if (c->high->ts.type != BT_LOGICAL && c->high->ts.type != BT_INTEGER
7218 2 : && c->high->ts.type != BT_CHARACTER
7219 2 : && (!flag_unsigned
7220 0 : || (flag_unsigned && c->high->ts.type != BT_UNSIGNED)))
7221 : {
7222 2 : gfc_error ("Expression in CASE selector at %L cannot be %s",
7223 2 : &c->high->where, gfc_typename (&c->high->ts));
7224 2 : goto cleanup;
7225 : }
7226 : }
7227 : else
7228 : {
7229 1386 : m = gfc_match_init_expr (&c->low);
7230 1386 : if (m == MATCH_ERROR)
7231 0 : goto cleanup;
7232 1386 : if (m == MATCH_NO)
7233 0 : goto need_expr;
7234 :
7235 1386 : if (c->low->ts.type != BT_LOGICAL && c->low->ts.type != BT_INTEGER
7236 357 : && c->low->ts.type != BT_CHARACTER
7237 43 : && (!flag_unsigned
7238 42 : || (flag_unsigned && c->low->ts.type != BT_UNSIGNED)))
7239 : {
7240 1 : gfc_error ("Expression in CASE selector at %L cannot be %s",
7241 1 : &c->low->where, gfc_typename (&c->low->ts));
7242 1 : goto cleanup;
7243 : }
7244 :
7245 : /* If we're not looking at a ':' now, make a range out of a single
7246 : target. Else get the upper bound for the case range. */
7247 1385 : if (gfc_match_char (':') != MATCH_YES)
7248 1218 : c->high = c->low;
7249 : else
7250 : {
7251 167 : m = gfc_match_init_expr (&c->high);
7252 167 : if (m == MATCH_ERROR)
7253 0 : goto cleanup;
7254 167 : if (m == MATCH_YES
7255 119 : && c->high->ts.type != BT_LOGICAL
7256 : && c->high->ts.type != BT_INTEGER
7257 : && c->high->ts.type != BT_CHARACTER
7258 1 : && (!flag_unsigned
7259 0 : || (flag_unsigned && c->high->ts.type != BT_UNSIGNED)))
7260 : {
7261 1 : gfc_error ("Expression in CASE selector at %L cannot be %s",
7262 1 : &c->high->where, gfc_typename (c->high));
7263 1 : goto cleanup;
7264 : }
7265 : /* MATCH_NO is fine. It's OK if nothing is there! */
7266 : }
7267 : }
7268 :
7269 1430 : if (c->low && c->low->rank != 0)
7270 : {
7271 4 : gfc_error ("Expression in CASE selector at %L must be scalar",
7272 : &c->low->where);
7273 4 : goto cleanup;
7274 : }
7275 1426 : if (c->high && c->high->rank != 0)
7276 : {
7277 2 : gfc_error ("Expression in CASE selector at %L must be scalar",
7278 : &c->high->where);
7279 2 : goto cleanup;
7280 : }
7281 :
7282 1424 : *cp = c;
7283 1424 : return MATCH_YES;
7284 :
7285 0 : need_expr:
7286 0 : gfc_error ("Expected initialization expression in CASE at %C");
7287 :
7288 10 : cleanup:
7289 10 : free_case (c);
7290 10 : return MATCH_ERROR;
7291 : }
7292 :
7293 :
7294 : /* Match the end of a case statement. */
7295 :
7296 : static match
7297 9408 : match_case_eos (void)
7298 : {
7299 9408 : char name[GFC_MAX_SYMBOL_LEN + 1];
7300 9408 : match m;
7301 :
7302 9408 : if (gfc_match_eos () == MATCH_YES)
7303 : return MATCH_YES;
7304 :
7305 : /* If the case construct doesn't have a case-construct-name, we
7306 : should have matched the EOS. */
7307 21 : if (!gfc_current_block ())
7308 : return MATCH_NO;
7309 :
7310 17 : gfc_gobble_whitespace ();
7311 :
7312 17 : m = gfc_match_name (name);
7313 17 : if (m != MATCH_YES)
7314 : return m;
7315 :
7316 17 : if (strcmp (name, gfc_current_block ()->name) != 0)
7317 : {
7318 1 : gfc_error ("Expected block name %qs of SELECT construct at %C",
7319 : gfc_current_block ()->name);
7320 1 : return MATCH_ERROR;
7321 : }
7322 :
7323 16 : return gfc_match_eos ();
7324 : }
7325 :
7326 :
7327 : /* Match a SELECT statement. */
7328 :
7329 : match
7330 495052 : gfc_match_select (void)
7331 : {
7332 495052 : gfc_expr *expr;
7333 495052 : match m;
7334 :
7335 495052 : m = gfc_match_label ();
7336 495052 : if (m == MATCH_ERROR)
7337 : return m;
7338 :
7339 495044 : m = gfc_match (" select case ( %e )%t", &expr);
7340 495044 : if (m != MATCH_YES)
7341 : return m;
7342 :
7343 532 : new_st.op = EXEC_SELECT;
7344 532 : new_st.expr1 = expr;
7345 :
7346 532 : return MATCH_YES;
7347 : }
7348 :
7349 :
7350 : /* Transfer the selector typespec to the associate name. */
7351 :
7352 : static void
7353 653 : copy_ts_from_selector_to_associate (gfc_expr *associate, gfc_expr *selector,
7354 : bool select_type = false)
7355 : {
7356 653 : gfc_ref *ref;
7357 653 : gfc_symbol *assoc_sym;
7358 653 : int rank = 0, corank = 0;
7359 :
7360 653 : assoc_sym = associate->symtree->n.sym;
7361 :
7362 : /* At this stage the expression rank and arrayspec dimensions have
7363 : not been completely sorted out. We must get the expr2->rank
7364 : right here, so that the correct class container is obtained. */
7365 653 : ref = selector->ref;
7366 913 : while (ref && ref->next)
7367 : ref = ref->next;
7368 :
7369 653 : if (selector->ts.type == BT_CLASS
7370 638 : && CLASS_DATA (selector)
7371 636 : && CLASS_DATA (selector)->as
7372 388 : && CLASS_DATA (selector)->as->type == AS_ASSUMED_RANK)
7373 : {
7374 12 : assoc_sym->attr.dimension = 1;
7375 12 : assoc_sym->as = gfc_copy_array_spec (CLASS_DATA (selector)->as);
7376 12 : corank = assoc_sym->as->corank;
7377 12 : goto build_class_sym;
7378 : }
7379 641 : else if (selector->ts.type == BT_CLASS
7380 626 : && CLASS_DATA (selector)
7381 624 : && CLASS_DATA (selector)->as
7382 376 : && ((ref && ref->type == REF_ARRAY)
7383 2 : || selector->expr_type == EXPR_OP))
7384 : {
7385 : /* Ensure that the array reference type is set. We cannot use
7386 : gfc_resolve_expr at this point, so the usable parts of
7387 : resolve.cc(resolve_array_ref) are employed to do it. */
7388 376 : if (ref && ref->u.ar.type == AR_UNKNOWN)
7389 : {
7390 108 : ref->u.ar.type = AR_ELEMENT;
7391 185 : for (int i = 0; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
7392 114 : if (ref->u.ar.dimen_type[i] == DIMEN_RANGE
7393 114 : || ref->u.ar.dimen_type[i] == DIMEN_VECTOR
7394 78 : || (ref->u.ar.dimen_type[i] == DIMEN_UNKNOWN
7395 78 : && ref->u.ar.start[i] && ref->u.ar.start[i]->rank))
7396 : {
7397 37 : ref->u.ar.type = AR_SECTION;
7398 37 : break;
7399 : }
7400 : }
7401 :
7402 374 : if (!ref || ref->u.ar.type == AR_FULL)
7403 : {
7404 268 : selector->rank = CLASS_DATA (selector)->as->rank;
7405 268 : selector->corank = CLASS_DATA (selector)->as->corank;
7406 : }
7407 108 : else if (ref->u.ar.type == AR_SECTION)
7408 : {
7409 37 : selector->rank = ref->u.ar.dimen;
7410 37 : selector->corank = ref->u.ar.codimen;
7411 : }
7412 : else
7413 71 : selector->rank = 0;
7414 :
7415 376 : rank = selector->rank;
7416 376 : corank = selector->corank;
7417 : }
7418 :
7419 376 : if (rank)
7420 : {
7421 296 : if (ref)
7422 : {
7423 343 : for (int i = 0; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
7424 49 : if (ref->u.ar.dimen_type[i] == DIMEN_ELEMENT
7425 49 : || (ref->u.ar.dimen_type[i] == DIMEN_UNKNOWN
7426 7 : && ref->u.ar.end[i] == NULL
7427 7 : && ref->u.ar.stride[i] == NULL))
7428 7 : rank--;
7429 : }
7430 :
7431 296 : if (rank)
7432 : {
7433 295 : assoc_sym->attr.dimension = 1;
7434 295 : assoc_sym->as = gfc_get_array_spec ();
7435 295 : assoc_sym->as->rank = rank;
7436 295 : assoc_sym->as->type = AS_DEFERRED;
7437 : }
7438 : }
7439 :
7440 641 : if (corank != 0 && rank == 0)
7441 : {
7442 9 : if (!assoc_sym->as)
7443 9 : assoc_sym->as = gfc_get_array_spec ();
7444 9 : assoc_sym->as->corank = corank;
7445 9 : assoc_sym->attr.codimension = 1;
7446 : }
7447 632 : else if (corank == 0 && rank == 0 && assoc_sym->as)
7448 : {
7449 0 : free (assoc_sym->as);
7450 0 : assoc_sym->as = NULL;
7451 : }
7452 632 : build_class_sym:
7453 : /* Deal with the very specific case of a SELECT_TYPE selector being an
7454 : associate_name whose type has been identified by component references.
7455 : It must be assumed that it will be identified as a CLASS expression,
7456 : so convert it now. */
7457 653 : if (select_type
7458 641 : && IS_INFERRED_TYPE (selector)
7459 13 : && selector->ts.type == BT_DERIVED)
7460 : {
7461 13 : gfc_find_derived_vtab (selector->ts.u.derived);
7462 : /* The correct class container has to be available. */
7463 13 : assoc_sym->ts.u.derived = selector->ts.u.derived;
7464 13 : assoc_sym->ts.type = BT_CLASS;
7465 13 : assoc_sym->attr.pointer = 1;
7466 13 : if (!selector->ts.u.derived->attr.is_class)
7467 13 : gfc_build_class_symbol (&assoc_sym->ts, &assoc_sym->attr, &assoc_sym->as);
7468 13 : associate->ts = assoc_sym->ts;
7469 : }
7470 640 : else if (selector->ts.type == BT_CLASS)
7471 : {
7472 : /* The correct class container has to be available. */
7473 638 : assoc_sym->ts.type = BT_CLASS;
7474 1276 : assoc_sym->ts.u.derived = CLASS_DATA (selector)
7475 638 : ? CLASS_DATA (selector)->ts.u.derived
7476 : : selector->ts.u.derived;
7477 638 : assoc_sym->attr.pointer = 1;
7478 638 : gfc_build_class_symbol (&assoc_sym->ts, &assoc_sym->attr, &assoc_sym->as);
7479 : }
7480 653 : }
7481 :
7482 :
7483 : /* Build the associate name */
7484 : static int
7485 672 : build_associate_name (const char *name, gfc_expr **e1, gfc_expr **e2)
7486 : {
7487 672 : gfc_expr *expr1 = *e1;
7488 672 : gfc_expr *expr2 = *e2;
7489 672 : gfc_symbol *sym;
7490 :
7491 : /* For the case where the associate name is already an associate name. */
7492 672 : if (!expr2)
7493 63 : expr2 = expr1;
7494 672 : expr1 = gfc_get_expr ();
7495 672 : expr1->expr_type = EXPR_VARIABLE;
7496 672 : expr1->where = expr2->where;
7497 672 : if (gfc_get_sym_tree (name, NULL, &expr1->symtree, false))
7498 : return 1;
7499 :
7500 672 : sym = expr1->symtree->n.sym;
7501 672 : if (expr2->ts.type == BT_UNKNOWN)
7502 31 : sym->attr.untyped = 1;
7503 : else
7504 641 : copy_ts_from_selector_to_associate (expr1, expr2, true);
7505 :
7506 672 : sym->attr.flavor = FL_VARIABLE;
7507 672 : sym->attr.referenced = 1;
7508 672 : sym->attr.class_ok = 1;
7509 :
7510 672 : *e1 = expr1;
7511 672 : *e2 = expr2;
7512 672 : return 0;
7513 : }
7514 :
7515 :
7516 : /* Push the current selector onto the SELECT TYPE stack. */
7517 :
7518 : static void
7519 4120 : select_type_push (gfc_symbol *sel)
7520 : {
7521 4120 : gfc_select_type_stack *top = gfc_get_select_type_stack ();
7522 4120 : top->selector = sel;
7523 4120 : top->tmp = NULL;
7524 4120 : top->prev = select_type_stack;
7525 :
7526 4120 : select_type_stack = top;
7527 4120 : }
7528 :
7529 :
7530 : /* Set the temporary for the current intrinsic SELECT TYPE selector. */
7531 :
7532 : static gfc_symtree *
7533 3828 : select_intrinsic_set_tmp (gfc_typespec *ts, const char *var_name)
7534 : {
7535 : /* Keep size in sync with the buffer size in resolve_select_type as it
7536 : determines the final name through truncation. */
7537 3828 : char name[GFC_MAX_SYMBOL_LEN + 12 + 1];
7538 3828 : gfc_symtree *tmp;
7539 3828 : HOST_WIDE_INT charlen = 0;
7540 3828 : gfc_symbol *selector = select_type_stack->selector;
7541 3828 : gfc_symbol *sym;
7542 :
7543 3828 : if (ts->type == BT_CLASS || ts->type == BT_DERIVED)
7544 : return NULL;
7545 :
7546 1461 : if (selector->ts.type == BT_CLASS && !selector->attr.class_ok)
7547 : return NULL;
7548 :
7549 : /* Case value == NULL corresponds to SELECT TYPE cases otherwise
7550 : the values correspond to SELECT rank cases. */
7551 1460 : if (ts->type == BT_CHARACTER && ts->u.cl && ts->u.cl->length
7552 0 : && ts->u.cl->length->expr_type == EXPR_CONSTANT)
7553 0 : charlen = gfc_mpz_get_hwi (ts->u.cl->length->value.integer);
7554 :
7555 1460 : if (ts->type != BT_CHARACTER)
7556 717 : snprintf (name, sizeof (name), "__tmp_%s_%d_%s",
7557 : gfc_basic_typename (ts->type), ts->kind, var_name);
7558 : else
7559 743 : snprintf (name, sizeof (name),
7560 : "__tmp_%s_" HOST_WIDE_INT_PRINT_DEC "_%d_%s",
7561 : gfc_basic_typename (ts->type), charlen, ts->kind, var_name);
7562 :
7563 1460 : gfc_get_sym_tree (name, gfc_current_ns, &tmp, false);
7564 1460 : sym = tmp->n.sym;
7565 1460 : gfc_add_type (sym, ts, NULL);
7566 :
7567 : /* Copy across the array spec to the selector. */
7568 1460 : if (selector->ts.type == BT_CLASS
7569 1458 : && (CLASS_DATA (selector)->attr.dimension
7570 730 : || CLASS_DATA (selector)->attr.codimension))
7571 : {
7572 740 : sym->attr.pointer = 1;
7573 740 : sym->attr.dimension = CLASS_DATA (selector)->attr.dimension;
7574 740 : sym->attr.codimension = CLASS_DATA (selector)->attr.codimension;
7575 740 : sym->as = gfc_copy_array_spec (CLASS_DATA (selector)->as);
7576 : }
7577 :
7578 1460 : gfc_set_sym_referenced (sym);
7579 1460 : gfc_add_flavor (&sym->attr, FL_VARIABLE, name, NULL);
7580 1460 : sym->attr.select_type_temporary = 1;
7581 :
7582 1460 : return tmp;
7583 : }
7584 :
7585 :
7586 : /* Set up a temporary for the current TYPE IS / CLASS IS branch . */
7587 :
7588 : static void
7589 5471 : select_type_set_tmp (gfc_typespec *ts)
7590 : {
7591 5471 : char name[GFC_MAX_SYMBOL_LEN + 12 + 1];
7592 5471 : gfc_symtree *tmp = NULL;
7593 5471 : gfc_symbol *selector = select_type_stack->selector;
7594 5471 : gfc_symbol *sym;
7595 5471 : gfc_expr *expr2;
7596 :
7597 5471 : if (!ts)
7598 : {
7599 1643 : select_type_stack->tmp = NULL;
7600 1644 : return;
7601 : }
7602 :
7603 3828 : gfc_expr *select_type_expr = gfc_state_stack->construct->expr1;
7604 3828 : const char *var_name = gfc_var_name_for_select_type_temp (select_type_expr);
7605 3828 : tmp = select_intrinsic_set_tmp (ts, var_name);
7606 :
7607 3828 : if (tmp == NULL)
7608 : {
7609 2368 : if (!ts->u.derived)
7610 : return;
7611 :
7612 2367 : if (ts->type == BT_CLASS)
7613 352 : snprintf (name, sizeof (name), "__tmp_class_%s_%s", ts->u.derived->name,
7614 : var_name);
7615 : else
7616 2015 : snprintf (name, sizeof (name), "__tmp_type_%s_%s", ts->u.derived->name,
7617 : var_name);
7618 :
7619 2367 : gfc_get_sym_tree (name, gfc_current_ns, &tmp, false);
7620 2367 : sym = tmp->n.sym;
7621 2367 : gfc_add_type (sym, ts, NULL);
7622 :
7623 : /* If the SELECT TYPE selector is a function we might be able to obtain
7624 : a typespec from the result. Since the function might not have been
7625 : parsed yet we have to check that there is indeed a result symbol. */
7626 2367 : if (selector->ts.type == BT_UNKNOWN
7627 46 : && gfc_state_stack->construct
7628 :
7629 46 : && (expr2 = gfc_state_stack->construct->expr2)
7630 33 : && expr2->expr_type == EXPR_FUNCTION
7631 14 : && expr2->symtree
7632 2381 : && expr2->symtree->n.sym && expr2->symtree->n.sym->result)
7633 14 : selector->ts = expr2->symtree->n.sym->result->ts;
7634 :
7635 2367 : if (selector->ts.type == BT_CLASS
7636 2327 : && selector->attr.class_ok
7637 2325 : && selector->ts.u.derived && CLASS_DATA (selector))
7638 : {
7639 2323 : sym->attr.pointer
7640 2323 : = CLASS_DATA (selector)->attr.class_pointer;
7641 :
7642 : /* Copy across the array spec to the selector. */
7643 2323 : if (CLASS_DATA (selector)->attr.dimension
7644 1589 : || CLASS_DATA (selector)->attr.codimension)
7645 : {
7646 741 : sym->attr.dimension
7647 741 : = CLASS_DATA (selector)->attr.dimension;
7648 741 : sym->attr.codimension
7649 741 : = CLASS_DATA (selector)->attr.codimension;
7650 741 : if (CLASS_DATA (selector)->as->type != AS_EXPLICIT)
7651 698 : sym->as = gfc_copy_array_spec (CLASS_DATA (selector)->as);
7652 : else
7653 : {
7654 43 : sym->as = gfc_get_array_spec();
7655 43 : sym->as->rank = CLASS_DATA (selector)->as->rank;
7656 43 : sym->as->type = AS_DEFERRED;
7657 : }
7658 : }
7659 : }
7660 :
7661 2367 : gfc_set_sym_referenced (sym);
7662 2367 : gfc_add_flavor (&sym->attr, FL_VARIABLE, name, NULL);
7663 2367 : sym->attr.select_type_temporary = 1;
7664 :
7665 2367 : if (ts->type == BT_CLASS)
7666 352 : gfc_build_class_symbol (&sym->ts, &sym->attr, &sym->as);
7667 : }
7668 : else
7669 1460 : sym = tmp->n.sym;
7670 :
7671 :
7672 : /* Add an association for it, so the rest of the parser knows it is
7673 : an associate-name. The target will be set during resolution. */
7674 3827 : sym->assoc = gfc_get_association_list ();
7675 3827 : sym->assoc->dangling = 1;
7676 3827 : sym->assoc->st = tmp;
7677 :
7678 3827 : select_type_stack->tmp = tmp;
7679 : }
7680 :
7681 :
7682 : /* Match a SELECT TYPE statement. */
7683 :
7684 : match
7685 494520 : gfc_match_select_type (void)
7686 : {
7687 494520 : gfc_expr *expr1, *expr2 = NULL;
7688 494520 : match m;
7689 494520 : char name[GFC_MAX_SYMBOL_LEN + 1];
7690 494520 : bool class_array;
7691 494520 : gfc_namespace *ns = gfc_current_ns;
7692 :
7693 494520 : m = gfc_match_label ();
7694 494520 : if (m == MATCH_ERROR)
7695 : return m;
7696 :
7697 494512 : m = gfc_match (" select type ( ");
7698 494512 : if (m != MATCH_YES)
7699 : return m;
7700 :
7701 3093 : if (gfc_current_state() == COMP_MODULE
7702 3093 : || gfc_current_state() == COMP_SUBMODULE)
7703 : {
7704 2 : gfc_error ("SELECT TYPE at %C cannot appear in this scope");
7705 2 : return MATCH_ERROR;
7706 : }
7707 :
7708 3091 : gfc_current_ns = gfc_build_block_ns (ns);
7709 3091 : m = gfc_match (" %n => %e", name, &expr2);
7710 3091 : if (m == MATCH_YES)
7711 : {
7712 609 : if (build_associate_name (name, &expr1, &expr2))
7713 : {
7714 0 : m = MATCH_ERROR;
7715 0 : goto cleanup;
7716 : }
7717 : }
7718 : else
7719 : {
7720 2482 : m = gfc_match (" %e ", &expr1);
7721 2482 : if (m == MATCH_NO)
7722 : {
7723 0 : std::swap (ns, gfc_current_ns);
7724 0 : gfc_free_namespace (ns);
7725 0 : return m;
7726 : }
7727 : /* On MATCH_ERROR, the temporary block namespace may already contain
7728 : broken state from the failed expression match. Avoid freeing it
7729 : through the normal rollback path. */
7730 2482 : else if (m == MATCH_ERROR)
7731 : return m;
7732 : }
7733 :
7734 3090 : m = gfc_match (" )%t");
7735 3090 : if (m != MATCH_YES)
7736 : {
7737 2 : gfc_error ("parse error in SELECT TYPE statement at %C");
7738 2 : goto cleanup;
7739 : }
7740 :
7741 : /* This ghastly expression seems to be needed to distinguish a CLASS
7742 : array, which can have a reference, from other expressions that
7743 : have references, such as derived type components, and are not
7744 : allowed by the standard.
7745 : TODO: see if it is sufficient to exclude component and substring
7746 : references. */
7747 6176 : class_array = (expr1->expr_type == EXPR_VARIABLE
7748 3087 : && expr1->ts.type == BT_CLASS
7749 2468 : && CLASS_DATA (expr1)
7750 2466 : && (strcmp (CLASS_DATA (expr1)->name, "_data") == 0)
7751 2466 : && (CLASS_DATA (expr1)->attr.dimension
7752 1553 : || CLASS_DATA (expr1)->attr.codimension)
7753 923 : && expr1->ref
7754 923 : && expr1->ref->type == REF_ARRAY
7755 923 : && expr1->ref->u.ar.type == AR_FULL
7756 4010 : && expr1->ref->next == NULL);
7757 :
7758 : /* Check for F03:C811 (F08:C835). */
7759 3088 : if (!expr2 && (expr1->expr_type != EXPR_VARIABLE
7760 2479 : || (!class_array && expr1->ref != NULL)))
7761 : {
7762 4 : gfc_error ("Selector in SELECT TYPE at %C is not a named variable; "
7763 : "use associate-name=>");
7764 4 : m = MATCH_ERROR;
7765 4 : goto cleanup;
7766 : }
7767 :
7768 : /* Prevent an existing associate name from reuse here by pushing expr1 to
7769 : expr2 and building a new associate name. */
7770 2476 : if (!expr2 && expr1->symtree->n.sym->assoc
7771 131 : && !expr1->symtree->n.sym->attr.select_type_temporary
7772 63 : && !expr1->symtree->n.sym->attr.select_rank_temporary
7773 3147 : && build_associate_name (expr1->symtree->n.sym->name, &expr1, &expr2))
7774 : {
7775 0 : m = MATCH_ERROR;
7776 0 : goto cleanup;
7777 : }
7778 :
7779 : /* Select type namespaces are not filled until resolution. Therefore, the
7780 : namespace must be marked as having an inferred type associate name if
7781 : either expr1 is an inferred type variable or expr2 is. In the latter
7782 : case, as well as the symbol being marked as inferred type, it might be
7783 : that it has not been detected to be so. In this case the target has
7784 : unknown type. Once the namespace is marked, the fixups in resolution can
7785 : be triggered. */
7786 3084 : if (!expr2
7787 2413 : && expr1->symtree->n.sym->assoc
7788 68 : && expr1->symtree->n.sym->assoc->inferred_type)
7789 0 : gfc_current_ns->assoc_name_inferred = 1;
7790 3084 : else if (expr2 && expr2->expr_type == EXPR_VARIABLE
7791 655 : && expr2->symtree->n.sym->assoc)
7792 : {
7793 184 : if (expr2->symtree->n.sym->assoc->inferred_type)
7794 13 : gfc_current_ns->assoc_name_inferred = 1;
7795 171 : else if (expr2->symtree->n.sym->assoc->target
7796 119 : && expr2->symtree->n.sym->assoc->target->ts.type == BT_UNKNOWN)
7797 36 : gfc_current_ns->assoc_name_inferred = 1;
7798 : }
7799 :
7800 3084 : new_st.op = EXEC_SELECT_TYPE;
7801 3084 : new_st.expr1 = expr1;
7802 3084 : new_st.expr2 = expr2;
7803 3084 : new_st.ext.block.ns = gfc_current_ns;
7804 :
7805 3084 : select_type_push (expr1->symtree->n.sym);
7806 3084 : gfc_current_ns = ns;
7807 :
7808 3084 : return MATCH_YES;
7809 :
7810 6 : cleanup:
7811 6 : gfc_free_expr (expr1);
7812 6 : gfc_free_expr (expr2);
7813 6 : gfc_undo_symbols ();
7814 6 : std::swap (ns, gfc_current_ns);
7815 6 : gfc_free_namespace (ns);
7816 6 : return m;
7817 : }
7818 :
7819 :
7820 : /* Set the temporary for the current intrinsic SELECT RANK selector. */
7821 :
7822 : static void
7823 1413 : select_rank_set_tmp (gfc_typespec *ts, int *case_value)
7824 : {
7825 1413 : char name[2 * GFC_MAX_SYMBOL_LEN];
7826 1413 : char tname[GFC_MAX_SYMBOL_LEN + 7];
7827 1413 : gfc_symtree *tmp;
7828 1413 : gfc_symbol *selector = select_type_stack->selector;
7829 1413 : gfc_symbol *sym;
7830 1413 : gfc_symtree *st;
7831 1413 : HOST_WIDE_INT charlen = 0;
7832 :
7833 1413 : if (case_value == NULL)
7834 2 : return;
7835 :
7836 1413 : if (ts->type == BT_CHARACTER && ts->u.cl && ts->u.cl->length
7837 265 : && ts->u.cl->length->expr_type == EXPR_CONSTANT)
7838 186 : charlen = gfc_mpz_get_hwi (ts->u.cl->length->value.integer);
7839 :
7840 1413 : if (ts->type == BT_CLASS)
7841 145 : sprintf (tname, "class_%s", ts->u.derived->name);
7842 1268 : else if (ts->type == BT_DERIVED)
7843 110 : sprintf (tname, "type_%s", ts->u.derived->name);
7844 1158 : else if (ts->type != BT_CHARACTER)
7845 599 : sprintf (tname, "%s_%d", gfc_basic_typename (ts->type), ts->kind);
7846 : else
7847 559 : sprintf (tname, "%s_" HOST_WIDE_INT_PRINT_DEC "_%d",
7848 : gfc_basic_typename (ts->type), charlen, ts->kind);
7849 :
7850 : /* Case value == NULL corresponds to SELECT TYPE cases otherwise
7851 : the values correspond to SELECT rank cases. */
7852 1413 : if (*case_value >=0)
7853 1380 : sprintf (name, "__tmp_%s_rank_%d", tname, *case_value);
7854 : else
7855 33 : sprintf (name, "__tmp_%s_rank_m%d", tname, -*case_value);
7856 :
7857 1413 : gfc_find_sym_tree (name, gfc_current_ns, 0, &st);
7858 1413 : if (st)
7859 : return;
7860 :
7861 1411 : gfc_get_sym_tree (name, gfc_current_ns, &tmp, false);
7862 1411 : sym = tmp->n.sym;
7863 1411 : gfc_add_type (sym, ts, NULL);
7864 :
7865 : /* Copy across the array spec to the selector. */
7866 1411 : if (selector->ts.type == BT_CLASS)
7867 : {
7868 145 : sym->ts.u.derived = CLASS_DATA (selector)->ts.u.derived;
7869 145 : sym->attr.pointer = CLASS_DATA (selector)->attr.pointer;
7870 145 : sym->attr.allocatable = CLASS_DATA (selector)->attr.allocatable;
7871 145 : sym->attr.target = CLASS_DATA (selector)->attr.target;
7872 145 : sym->attr.class_ok = 0;
7873 145 : if (case_value && *case_value != 0)
7874 : {
7875 114 : sym->attr.dimension = 1;
7876 114 : sym->as = gfc_copy_array_spec (CLASS_DATA (selector)->as);
7877 114 : if (*case_value > 0)
7878 : {
7879 114 : sym->as->type = AS_DEFERRED;
7880 114 : sym->as->rank = *case_value;
7881 : }
7882 0 : else if (*case_value == -1)
7883 : {
7884 0 : sym->as->type = AS_ASSUMED_SIZE;
7885 0 : sym->as->rank = 1;
7886 : }
7887 : }
7888 : }
7889 : else
7890 : {
7891 1266 : sym->attr.pointer = selector->attr.pointer;
7892 1266 : sym->attr.allocatable = selector->attr.allocatable;
7893 1266 : sym->attr.target = selector->attr.target;
7894 1266 : if (case_value && *case_value != 0)
7895 : {
7896 1217 : sym->attr.dimension = 1;
7897 1217 : sym->as = gfc_copy_array_spec (selector->as);
7898 1217 : if (*case_value > 0)
7899 : {
7900 1185 : sym->as->type = AS_DEFERRED;
7901 1185 : sym->as->rank = *case_value;
7902 : }
7903 32 : else if (*case_value == -1)
7904 : {
7905 32 : sym->as->type = AS_ASSUMED_SIZE;
7906 32 : sym->as->rank = 1;
7907 : }
7908 : }
7909 : }
7910 :
7911 1411 : gfc_set_sym_referenced (sym);
7912 1411 : gfc_add_flavor (&sym->attr, FL_VARIABLE, name, NULL);
7913 1411 : sym->attr.select_type_temporary = 1;
7914 1411 : if (case_value)
7915 1411 : sym->attr.select_rank_temporary = 1;
7916 :
7917 1411 : if (ts->type == BT_CLASS)
7918 145 : gfc_build_class_symbol (&sym->ts, &sym->attr, &sym->as);
7919 :
7920 : /* Add an association for it, so the rest of the parser knows it is
7921 : an associate-name. The target will be set during resolution. */
7922 1411 : sym->assoc = gfc_get_association_list ();
7923 1411 : sym->assoc->dangling = 1;
7924 1411 : sym->assoc->st = tmp;
7925 :
7926 1411 : select_type_stack->tmp = tmp;
7927 : }
7928 :
7929 :
7930 : /* Match a SELECT RANK statement. */
7931 :
7932 : match
7933 491436 : gfc_match_select_rank (void)
7934 : {
7935 491436 : gfc_expr *expr1, *expr2 = NULL;
7936 491436 : match m;
7937 491436 : char name[GFC_MAX_SYMBOL_LEN + 1];
7938 491436 : gfc_symbol *sym, *sym2;
7939 491436 : gfc_namespace *ns = gfc_current_ns;
7940 491436 : gfc_array_spec *as = NULL;
7941 :
7942 491436 : m = gfc_match_label ();
7943 491436 : if (m == MATCH_ERROR)
7944 : return m;
7945 :
7946 491428 : m = gfc_match (" select% rank ( ");
7947 491428 : if (m != MATCH_YES)
7948 : return m;
7949 :
7950 1041 : if (!gfc_notify_std (GFC_STD_F2018, "SELECT RANK statement at %C"))
7951 : return MATCH_NO;
7952 :
7953 1041 : gfc_current_ns = gfc_build_block_ns (ns);
7954 1041 : m = gfc_match (" %n => %e", name, &expr2);
7955 :
7956 1041 : if (m == MATCH_YES)
7957 : {
7958 : /* If expr2 corresponds to an implicitly typed variable, then the
7959 : actual type of the variable may not have been set. Set it here. */
7960 43 : if (!gfc_current_ns->seen_implicit_none
7961 43 : && expr2->expr_type == EXPR_VARIABLE
7962 42 : && expr2->ts.type == BT_UNKNOWN
7963 1 : && expr2->symtree && expr2->symtree->n.sym)
7964 : {
7965 1 : gfc_set_default_type (expr2->symtree->n.sym, 0, gfc_current_ns);
7966 1 : expr2->ts.type = expr2->symtree->n.sym->ts.type;
7967 : }
7968 :
7969 43 : expr1 = gfc_get_expr ();
7970 43 : expr1->expr_type = EXPR_VARIABLE;
7971 43 : expr1->where = expr2->where;
7972 43 : expr1->ref = gfc_copy_ref (expr2->ref);
7973 43 : if (gfc_get_sym_tree (name, NULL, &expr1->symtree, false))
7974 : {
7975 0 : m = MATCH_ERROR;
7976 0 : goto cleanup;
7977 : }
7978 :
7979 43 : sym = expr1->symtree->n.sym;
7980 :
7981 43 : if (expr2->symtree)
7982 : {
7983 42 : sym2 = expr2->symtree->n.sym;
7984 42 : as = (sym2->ts.type == BT_CLASS
7985 42 : && CLASS_DATA (sym2)) ? CLASS_DATA (sym2)->as : sym2->as;
7986 : }
7987 :
7988 43 : if (expr2->expr_type != EXPR_VARIABLE
7989 42 : || !(as && as->type == AS_ASSUMED_RANK))
7990 : {
7991 1 : gfc_error ("The SELECT RANK selector at %C must be an assumed "
7992 : "rank variable");
7993 1 : m = MATCH_ERROR;
7994 1 : goto cleanup;
7995 : }
7996 :
7997 42 : if (expr2->ts.type == BT_CLASS && CLASS_DATA (sym2))
7998 : {
7999 12 : copy_ts_from_selector_to_associate (expr1, expr2);
8000 :
8001 12 : sym->attr.flavor = FL_VARIABLE;
8002 12 : sym->attr.referenced = 1;
8003 12 : sym->attr.class_ok = 1;
8004 12 : CLASS_DATA (sym)->attr.allocatable = CLASS_DATA (sym2)->attr.allocatable;
8005 12 : CLASS_DATA (sym)->attr.pointer = CLASS_DATA (sym2)->attr.pointer;
8006 12 : CLASS_DATA (sym)->attr.target = CLASS_DATA (sym2)->attr.target;
8007 12 : sym->attr.pointer = 1;
8008 : }
8009 : else
8010 : {
8011 30 : sym->ts = sym2->ts;
8012 30 : sym->as = gfc_copy_array_spec (sym2->as);
8013 30 : sym->attr.dimension = 1;
8014 :
8015 30 : sym->attr.flavor = FL_VARIABLE;
8016 30 : sym->attr.referenced = 1;
8017 30 : sym->attr.class_ok = sym2->attr.class_ok;
8018 30 : sym->attr.allocatable = sym2->attr.allocatable;
8019 30 : sym->attr.pointer = sym2->attr.pointer;
8020 30 : sym->attr.target = sym2->attr.target;
8021 : }
8022 : }
8023 : else
8024 : {
8025 998 : m = gfc_match (" %e ", &expr1);
8026 :
8027 998 : if (m != MATCH_YES)
8028 : {
8029 1 : gfc_undo_symbols ();
8030 1 : std::swap (ns, gfc_current_ns);
8031 1 : gfc_free_namespace (ns);
8032 1 : return m;
8033 : }
8034 :
8035 997 : if (expr1->symtree)
8036 : {
8037 996 : sym = expr1->symtree->n.sym;
8038 996 : as = (sym->ts.type == BT_CLASS
8039 996 : && CLASS_DATA (sym)) ? CLASS_DATA (sym)->as : sym->as;
8040 : }
8041 :
8042 997 : if (expr1->expr_type != EXPR_VARIABLE
8043 996 : || !(as && as->type == AS_ASSUMED_RANK))
8044 : {
8045 3 : gfc_error("The SELECT RANK selector at %C must be an assumed "
8046 : "rank variable");
8047 3 : m = MATCH_ERROR;
8048 3 : goto cleanup;
8049 : }
8050 : }
8051 :
8052 1036 : m = gfc_match (" )%t");
8053 1036 : if (m != MATCH_YES)
8054 : {
8055 0 : gfc_error ("parse error in SELECT RANK statement at %C");
8056 0 : goto cleanup;
8057 : }
8058 :
8059 1036 : new_st.op = EXEC_SELECT_RANK;
8060 1036 : new_st.expr1 = expr1;
8061 1036 : new_st.expr2 = expr2;
8062 1036 : new_st.ext.block.ns = gfc_current_ns;
8063 :
8064 1036 : select_type_push (expr1->symtree->n.sym);
8065 1036 : gfc_current_ns = ns;
8066 :
8067 1036 : return MATCH_YES;
8068 :
8069 4 : cleanup:
8070 4 : gfc_free_expr (expr1);
8071 4 : gfc_free_expr (expr2);
8072 4 : gfc_undo_symbols ();
8073 4 : std::swap (ns, gfc_current_ns);
8074 4 : gfc_free_namespace (ns);
8075 4 : return m;
8076 : }
8077 :
8078 :
8079 : /* Match a CASE statement. */
8080 :
8081 : match
8082 1602 : gfc_match_case (void)
8083 : {
8084 1602 : gfc_case *c, *head, *tail;
8085 1602 : match m;
8086 :
8087 1602 : head = tail = NULL;
8088 :
8089 1602 : if (gfc_current_state () != COMP_SELECT)
8090 : {
8091 3 : gfc_error ("Unexpected CASE statement at %C");
8092 3 : return MATCH_ERROR;
8093 : }
8094 :
8095 1599 : if (gfc_match ("% default") == MATCH_YES)
8096 : {
8097 363 : m = match_case_eos ();
8098 363 : if (m == MATCH_NO)
8099 1 : goto syntax;
8100 362 : if (m == MATCH_ERROR)
8101 0 : goto cleanup;
8102 :
8103 362 : new_st.op = EXEC_SELECT;
8104 362 : c = gfc_get_case ();
8105 362 : c->where = gfc_current_locus;
8106 362 : new_st.ext.block.case_list = c;
8107 362 : return MATCH_YES;
8108 : }
8109 :
8110 1236 : if (gfc_match_char ('(') != MATCH_YES)
8111 0 : goto syntax;
8112 :
8113 1434 : for (;;)
8114 : {
8115 1434 : if (match_case_selector (&c) == MATCH_ERROR)
8116 10 : goto cleanup;
8117 :
8118 1424 : if (head == NULL)
8119 1226 : head = c;
8120 : else
8121 198 : tail->next = c;
8122 :
8123 1424 : tail = c;
8124 :
8125 1424 : if (gfc_match_char (')') == MATCH_YES)
8126 : break;
8127 198 : if (gfc_match_char (',') != MATCH_YES)
8128 0 : goto syntax;
8129 : }
8130 :
8131 1226 : m = match_case_eos ();
8132 1226 : if (m == MATCH_NO)
8133 2 : goto syntax;
8134 1224 : if (m == MATCH_ERROR)
8135 0 : goto cleanup;
8136 :
8137 1224 : new_st.op = EXEC_SELECT;
8138 1224 : new_st.ext.block.case_list = head;
8139 :
8140 1224 : return MATCH_YES;
8141 :
8142 3 : syntax:
8143 3 : gfc_error ("Syntax error in CASE specification at %C");
8144 :
8145 13 : cleanup:
8146 13 : gfc_free_case_list (head); /* new_st is cleaned up in parse.cc. */
8147 13 : return MATCH_ERROR;
8148 : }
8149 :
8150 :
8151 : /* Match a TYPE IS statement. */
8152 :
8153 : match
8154 3485 : gfc_match_type_is (void)
8155 : {
8156 3485 : gfc_case *c = NULL;
8157 3485 : match m;
8158 :
8159 3485 : if (gfc_current_state () != COMP_SELECT_TYPE)
8160 : {
8161 2 : gfc_error ("Unexpected TYPE IS statement at %C");
8162 2 : return MATCH_ERROR;
8163 : }
8164 :
8165 3483 : if (gfc_match_char ('(') != MATCH_YES)
8166 1 : goto syntax;
8167 :
8168 3482 : c = gfc_get_case ();
8169 3482 : c->where = gfc_current_locus;
8170 :
8171 3482 : m = gfc_match_type_spec (&c->ts);
8172 3482 : if (m == MATCH_NO)
8173 4 : goto syntax;
8174 3478 : if (m == MATCH_ERROR)
8175 0 : goto cleanup;
8176 :
8177 3478 : if (gfc_match_char (')') != MATCH_YES)
8178 0 : goto syntax;
8179 :
8180 3478 : m = match_case_eos ();
8181 3478 : if (m == MATCH_NO)
8182 0 : goto syntax;
8183 3478 : if (m == MATCH_ERROR)
8184 0 : goto cleanup;
8185 :
8186 3478 : new_st.op = EXEC_SELECT_TYPE;
8187 3478 : new_st.ext.block.case_list = c;
8188 :
8189 3478 : if (c->ts.type == BT_DERIVED && c->ts.u.derived
8190 2017 : && (c->ts.u.derived->attr.sequence
8191 2016 : || c->ts.u.derived->attr.is_bind_c))
8192 : {
8193 1 : gfc_error ("The type-spec shall not specify a sequence derived "
8194 : "type or a type with the BIND attribute in SELECT "
8195 : "TYPE at %C [F2003:C815]");
8196 1 : return MATCH_ERROR;
8197 : }
8198 :
8199 3477 : if (IS_PDT (c) && gfc_spec_list_type (type_param_spec_list,
8200 : c->ts.u.derived) != SPEC_ASSUMED)
8201 : {
8202 1 : gfc_error ("All the LEN type parameters in the TYPE IS statement "
8203 : "at %C must be ASSUMED");
8204 1 : return MATCH_ERROR;
8205 : }
8206 :
8207 : /* Create temporary variable. */
8208 3476 : select_type_set_tmp (&c->ts);
8209 :
8210 3476 : return MATCH_YES;
8211 :
8212 5 : syntax:
8213 :
8214 5 : if (!gfc_error_check ())
8215 3 : gfc_error ("Syntax error in TYPE IS specification at %C");
8216 :
8217 2 : cleanup:
8218 5 : if (c != NULL)
8219 4 : gfc_free_case_list (c); /* new_st is cleaned up in parse.cc. */
8220 : return MATCH_ERROR;
8221 : }
8222 :
8223 :
8224 : /* Match a CLASS IS or CLASS DEFAULT statement. */
8225 :
8226 : match
8227 2029 : gfc_match_class_is (void)
8228 : {
8229 2029 : gfc_case *c = NULL;
8230 2029 : match m;
8231 :
8232 2029 : if (gfc_current_state () != COMP_SELECT_TYPE)
8233 : return MATCH_NO;
8234 :
8235 2001 : if (gfc_match ("% default") == MATCH_YES)
8236 : {
8237 1643 : m = match_case_eos ();
8238 1643 : if (m == MATCH_NO)
8239 0 : goto syntax;
8240 1643 : if (m == MATCH_ERROR)
8241 0 : goto cleanup;
8242 :
8243 1643 : new_st.op = EXEC_SELECT_TYPE;
8244 1643 : c = gfc_get_case ();
8245 1643 : c->where = gfc_current_locus;
8246 1643 : c->ts.type = BT_UNKNOWN;
8247 1643 : new_st.ext.block.case_list = c;
8248 1643 : select_type_set_tmp (NULL);
8249 1643 : return MATCH_YES;
8250 : }
8251 :
8252 358 : m = gfc_match ("% is");
8253 358 : if (m == MATCH_NO)
8254 0 : goto syntax;
8255 358 : if (m == MATCH_ERROR)
8256 0 : goto cleanup;
8257 :
8258 358 : if (gfc_match_char ('(') != MATCH_YES)
8259 0 : goto syntax;
8260 :
8261 358 : c = gfc_get_case ();
8262 358 : c->where = gfc_current_locus;
8263 :
8264 358 : m = match_derived_type_spec (&c->ts);
8265 358 : if (m == MATCH_NO)
8266 4 : goto syntax;
8267 354 : if (m == MATCH_ERROR)
8268 0 : goto cleanup;
8269 :
8270 354 : if (c->ts.type == BT_DERIVED)
8271 354 : c->ts.type = BT_CLASS;
8272 :
8273 354 : if (gfc_match_char (')') != MATCH_YES)
8274 0 : goto syntax;
8275 :
8276 354 : m = match_case_eos ();
8277 354 : if (m == MATCH_NO)
8278 1 : goto syntax;
8279 353 : if (m == MATCH_ERROR)
8280 1 : goto cleanup;
8281 :
8282 352 : new_st.op = EXEC_SELECT_TYPE;
8283 352 : new_st.ext.block.case_list = c;
8284 :
8285 : /* Create temporary variable. */
8286 352 : select_type_set_tmp (&c->ts);
8287 :
8288 352 : return MATCH_YES;
8289 :
8290 5 : syntax:
8291 5 : gfc_error ("Syntax error in CLASS IS specification at %C");
8292 :
8293 6 : cleanup:
8294 6 : if (c != NULL)
8295 6 : gfc_free_case_list (c); /* new_st is cleaned up in parse.cc. */
8296 : return MATCH_ERROR;
8297 : }
8298 :
8299 :
8300 : /* Match a RANK statement. */
8301 :
8302 : match
8303 2352 : gfc_match_rank_is (void)
8304 : {
8305 2352 : gfc_case *c = NULL;
8306 2352 : match m;
8307 2352 : int case_value;
8308 :
8309 2352 : if (gfc_current_state () != COMP_SELECT_RANK)
8310 : {
8311 5 : gfc_error ("Unexpected RANK statement at %C");
8312 5 : return MATCH_ERROR;
8313 : }
8314 :
8315 2347 : if (gfc_match ("% default") == MATCH_YES)
8316 : {
8317 931 : m = match_case_eos ();
8318 931 : if (m == MATCH_NO)
8319 0 : goto syntax;
8320 931 : if (m == MATCH_ERROR)
8321 0 : goto cleanup;
8322 :
8323 931 : new_st.op = EXEC_SELECT_RANK;
8324 931 : c = gfc_get_case ();
8325 931 : c->ts.type = BT_UNKNOWN;
8326 931 : c->where = gfc_current_locus;
8327 931 : new_st.ext.block.case_list = c;
8328 931 : select_type_stack->tmp = NULL;
8329 931 : return MATCH_YES;
8330 : }
8331 :
8332 1416 : if (gfc_match_char ('(') != MATCH_YES)
8333 0 : goto syntax;
8334 :
8335 1416 : c = gfc_get_case ();
8336 1416 : c->where = gfc_current_locus;
8337 1416 : c->ts = select_type_stack->selector->ts;
8338 :
8339 1416 : m = gfc_match_expr (&c->low);
8340 1416 : if (m == MATCH_NO)
8341 : {
8342 33 : if (gfc_match_char ('*') == MATCH_YES)
8343 33 : c->low = gfc_get_int_expr (gfc_default_integer_kind,
8344 : NULL, -1);
8345 : else
8346 0 : goto syntax;
8347 :
8348 33 : case_value = -1;
8349 : }
8350 1383 : else if (m == MATCH_YES)
8351 : {
8352 : /* F2018: R1150 */
8353 1383 : if (c->low->expr_type != EXPR_CONSTANT
8354 1382 : || c->low->ts.type != BT_INTEGER
8355 1382 : || c->low->rank)
8356 : {
8357 1 : gfc_error ("The SELECT RANK CASE expression at %C must be a "
8358 : "scalar, integer constant");
8359 1 : goto cleanup;
8360 : }
8361 :
8362 1382 : case_value = (int) mpz_get_si (c->low->value.integer);
8363 : /* F2018: C1151 */
8364 1382 : if ((case_value < 0) || (case_value > GFC_MAX_DIMENSIONS))
8365 : {
8366 2 : gfc_error ("The value of the SELECT RANK CASE expression at "
8367 : "%C must not be less than zero or greater than %d",
8368 : GFC_MAX_DIMENSIONS);
8369 2 : goto cleanup;
8370 : }
8371 : }
8372 : else
8373 0 : goto cleanup;
8374 :
8375 1413 : if (gfc_match_char (')') != MATCH_YES)
8376 0 : goto syntax;
8377 :
8378 1413 : m = match_case_eos ();
8379 1413 : if (m == MATCH_NO)
8380 0 : goto syntax;
8381 1413 : if (m == MATCH_ERROR)
8382 0 : goto cleanup;
8383 :
8384 1413 : new_st.op = EXEC_SELECT_RANK;
8385 1413 : new_st.ext.block.case_list = c;
8386 :
8387 : /* Create temporary variable. Recycle the select type code. */
8388 1413 : select_rank_set_tmp (&c->ts, &case_value);
8389 :
8390 1413 : return MATCH_YES;
8391 :
8392 0 : syntax:
8393 0 : gfc_error ("Syntax error in RANK specification at %C");
8394 :
8395 3 : cleanup:
8396 3 : if (c != NULL)
8397 3 : gfc_free_case_list (c); /* new_st is cleaned up in parse.cc. */
8398 : return MATCH_ERROR;
8399 : }
8400 :
8401 : /********************* WHERE subroutines ********************/
8402 :
8403 : /* Match the rest of a simple WHERE statement that follows an IF statement.
8404 : */
8405 :
8406 : static match
8407 7 : match_simple_where (void)
8408 : {
8409 7 : gfc_expr *expr;
8410 7 : gfc_code *c;
8411 7 : match m;
8412 :
8413 7 : m = gfc_match (" ( %e )", &expr);
8414 7 : if (m != MATCH_YES)
8415 : return m;
8416 :
8417 7 : m = gfc_match_assignment ();
8418 7 : if (m == MATCH_NO)
8419 0 : goto syntax;
8420 7 : if (m == MATCH_ERROR)
8421 0 : goto cleanup;
8422 :
8423 7 : if (gfc_match_eos () != MATCH_YES)
8424 0 : goto syntax;
8425 :
8426 7 : c = gfc_get_code (EXEC_WHERE);
8427 7 : c->expr1 = expr;
8428 :
8429 7 : c->next = XCNEW (gfc_code);
8430 7 : *c->next = new_st;
8431 7 : c->next->loc = gfc_current_locus;
8432 7 : gfc_clear_new_st ();
8433 :
8434 7 : new_st.op = EXEC_WHERE;
8435 7 : new_st.block = c;
8436 :
8437 7 : return MATCH_YES;
8438 :
8439 0 : syntax:
8440 0 : gfc_syntax_error (ST_WHERE);
8441 :
8442 0 : cleanup:
8443 0 : gfc_free_expr (expr);
8444 0 : return MATCH_ERROR;
8445 : }
8446 :
8447 :
8448 : /* Match a WHERE statement. */
8449 :
8450 : match
8451 533504 : gfc_match_where (gfc_statement *st)
8452 : {
8453 533504 : gfc_expr *expr;
8454 533504 : match m0, m;
8455 533504 : gfc_code *c;
8456 :
8457 533504 : m0 = gfc_match_label ();
8458 533504 : if (m0 == MATCH_ERROR)
8459 : return m0;
8460 :
8461 533496 : m = gfc_match (" where ( %e )", &expr);
8462 533496 : if (m != MATCH_YES)
8463 : return m;
8464 :
8465 446 : if (gfc_match_eos () == MATCH_YES)
8466 : {
8467 371 : *st = ST_WHERE_BLOCK;
8468 371 : new_st.op = EXEC_WHERE;
8469 371 : new_st.expr1 = expr;
8470 371 : return MATCH_YES;
8471 : }
8472 :
8473 75 : m = gfc_match_assignment ();
8474 75 : if (m == MATCH_NO)
8475 0 : gfc_syntax_error (ST_WHERE);
8476 :
8477 75 : if (m != MATCH_YES)
8478 : {
8479 0 : gfc_free_expr (expr);
8480 0 : return MATCH_ERROR;
8481 : }
8482 :
8483 : /* We've got a simple WHERE statement. */
8484 75 : *st = ST_WHERE;
8485 75 : c = gfc_get_code (EXEC_WHERE);
8486 75 : c->expr1 = expr;
8487 :
8488 : /* Put in the assignment. It will not be processed by add_statement, so we
8489 : need to copy the location here. */
8490 :
8491 75 : c->next = XCNEW (gfc_code);
8492 75 : *c->next = new_st;
8493 75 : c->next->loc = gfc_current_locus;
8494 75 : gfc_clear_new_st ();
8495 :
8496 75 : new_st.op = EXEC_WHERE;
8497 75 : new_st.block = c;
8498 :
8499 75 : return MATCH_YES;
8500 : }
8501 :
8502 :
8503 : /* Match an ELSEWHERE statement. We leave behind a WHERE node in
8504 : new_st if successful. */
8505 :
8506 : match
8507 313 : gfc_match_elsewhere (void)
8508 : {
8509 313 : char name[GFC_MAX_SYMBOL_LEN + 1];
8510 313 : gfc_expr *expr;
8511 313 : match m;
8512 :
8513 313 : if (gfc_current_state () != COMP_WHERE)
8514 : {
8515 0 : gfc_error ("ELSEWHERE statement at %C not enclosed in WHERE block");
8516 0 : return MATCH_ERROR;
8517 : }
8518 :
8519 313 : expr = NULL;
8520 :
8521 313 : if (gfc_match_char ('(') == MATCH_YES)
8522 : {
8523 179 : m = gfc_match_expr (&expr);
8524 179 : if (m == MATCH_NO)
8525 0 : goto syntax;
8526 179 : if (m == MATCH_ERROR)
8527 : return MATCH_ERROR;
8528 :
8529 179 : if (gfc_match_char (')') != MATCH_YES)
8530 0 : goto syntax;
8531 : }
8532 :
8533 313 : if (gfc_match_eos () != MATCH_YES)
8534 : {
8535 : /* Only makes sense if we have a where-construct-name. */
8536 2 : if (!gfc_current_block ())
8537 : {
8538 1 : m = MATCH_ERROR;
8539 1 : goto cleanup;
8540 : }
8541 : /* Better be a name at this point. */
8542 1 : m = gfc_match_name (name);
8543 1 : if (m == MATCH_NO)
8544 0 : goto syntax;
8545 1 : if (m == MATCH_ERROR)
8546 0 : goto cleanup;
8547 :
8548 1 : if (gfc_match_eos () != MATCH_YES)
8549 0 : goto syntax;
8550 :
8551 1 : if (strcmp (name, gfc_current_block ()->name) != 0)
8552 : {
8553 0 : gfc_error ("Label %qs at %C doesn't match WHERE label %qs",
8554 : name, gfc_current_block ()->name);
8555 0 : goto cleanup;
8556 : }
8557 : }
8558 :
8559 312 : new_st.op = EXEC_WHERE;
8560 312 : new_st.expr1 = expr;
8561 312 : return MATCH_YES;
8562 :
8563 0 : syntax:
8564 0 : gfc_syntax_error (ST_ELSEWHERE);
8565 :
8566 1 : cleanup:
8567 1 : gfc_free_expr (expr);
8568 1 : return MATCH_ERROR;
8569 : }
|