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