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