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 9044350 : gfc_op2string (gfc_intrinsic_op op)
43 : {
44 9044350 : switch (op)
45 : {
46 : case INTRINSIC_UPLUS:
47 : case INTRINSIC_PLUS:
48 : return "+";
49 :
50 695545 : case INTRINSIC_UMINUS:
51 695545 : case INTRINSIC_MINUS:
52 695545 : return "-";
53 :
54 347653 : case INTRINSIC_POWER:
55 347653 : return "**";
56 347652 : case INTRINSIC_CONCAT:
57 347652 : return "//";
58 348122 : case INTRINSIC_TIMES:
59 348122 : return "*";
60 347653 : case INTRINSIC_DIVIDE:
61 347653 : return "/";
62 :
63 347781 : case INTRINSIC_AND:
64 347781 : return ".and.";
65 348478 : case INTRINSIC_OR:
66 348478 : return ".or.";
67 347770 : case INTRINSIC_EQV:
68 347770 : return ".eqv.";
69 347767 : case INTRINSIC_NEQV:
70 347767 : return ".neqv.";
71 :
72 347673 : case INTRINSIC_EQ_OS:
73 347673 : return ".eq.";
74 347675 : case INTRINSIC_EQ:
75 347675 : return "==";
76 347673 : case INTRINSIC_NE_OS:
77 347673 : return ".ne.";
78 347661 : case INTRINSIC_NE:
79 347661 : return "/=";
80 347664 : case INTRINSIC_GE_OS:
81 347664 : return ".ge.";
82 347658 : case INTRINSIC_GE:
83 347658 : return ">=";
84 347665 : case INTRINSIC_LE_OS:
85 347665 : return ".le.";
86 347658 : case INTRINSIC_LE:
87 347658 : return "<=";
88 347710 : case INTRINSIC_LT_OS:
89 347710 : return ".lt.";
90 347682 : case INTRINSIC_LT:
91 347682 : return "<";
92 347673 : case INTRINSIC_GT_OS:
93 347673 : return ".gt.";
94 347658 : case INTRINSIC_GT:
95 347658 : return ">";
96 347651 : case INTRINSIC_NOT:
97 347651 : return ".not.";
98 :
99 877 : case INTRINSIC_ASSIGN:
100 877 : return "=";
101 :
102 347651 : case INTRINSIC_PARENTHESES:
103 347651 : 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 8254038 : gfc_match_member_sep(gfc_symbol *sym)
152 : {
153 8254038 : char name[GFC_MAX_SYMBOL_LEN + 1];
154 8254038 : locus dot_loc, start_loc;
155 8254038 : gfc_intrinsic_op iop;
156 8254038 : match m;
157 8254038 : gfc_symbol *tsym;
158 8254038 : gfc_component *c = NULL;
159 :
160 : /* What a relief: '%' is an unambiguous member separator. */
161 8254038 : if (gfc_match_char ('%') == MATCH_YES)
162 : return MATCH_YES;
163 :
164 : /* Beware ye who enter here. */
165 8070736 : 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 382107 : gfc_match_parens (void)
252 : {
253 382107 : locus old_loc, where;
254 382107 : int count;
255 382107 : gfc_instring instring;
256 382107 : gfc_char_t c, quote;
257 :
258 382107 : old_loc = gfc_current_locus;
259 382107 : count = 0;
260 382107 : instring = NONSTRING;
261 382107 : quote = ' ';
262 :
263 14695344 : for (;;)
264 : {
265 14695344 : if (count > 0)
266 8233903 : where = gfc_current_locus;
267 14695344 : c = gfc_next_char_literal (instring);
268 14695344 : if (c == '\n')
269 : break;
270 14313237 : if (quote == ' ' && ((c == '\'') || (c == '"')))
271 : {
272 58267 : quote = c;
273 58267 : instring = INSTRING_WARN;
274 58267 : continue;
275 : }
276 14254970 : if (quote != ' ' && c == quote)
277 : {
278 58267 : quote = ' ';
279 58267 : instring = NONSTRING;
280 58267 : continue;
281 : }
282 :
283 14196703 : if (c == '(' && quote == ' ')
284 : {
285 685878 : count++;
286 : }
287 14196703 : if (c == ')' && quote == ' ')
288 : {
289 685872 : count--;
290 685872 : where = gfc_current_locus;
291 : }
292 : }
293 :
294 382107 : gfc_current_locus = old_loc;
295 :
296 382107 : 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 450434 : gfc_match_space (void)
386 : {
387 450434 : locus old_loc;
388 450434 : char c;
389 :
390 450434 : if (gfc_current_form == FORM_FIXED)
391 : return MATCH_YES;
392 :
393 429136 : old_loc = gfc_current_locus;
394 :
395 429136 : c = gfc_next_ascii_char ();
396 429136 : if (!gfc_is_whitespace (c))
397 : {
398 13468 : gfc_current_locus = old_loc;
399 13468 : return MATCH_NO;
400 : }
401 :
402 415668 : gfc_gobble_whitespace ();
403 :
404 415668 : 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 3592914 : gfc_match_eos (void)
414 : {
415 3592914 : locus old_loc;
416 3592914 : int flag;
417 3592914 : char c;
418 :
419 3592914 : flag = 0;
420 :
421 3659222 : for (;;)
422 : {
423 3626068 : old_loc = gfc_current_locus;
424 3626068 : gfc_gobble_whitespace ();
425 :
426 3626068 : c = gfc_next_ascii_char ();
427 3626068 : 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 33154 : case ';':
442 33154 : flag = 1;
443 33154 : continue;
444 : }
445 :
446 2258197 : break;
447 : }
448 :
449 2258197 : gfc_current_locus = old_loc;
450 2258197 : 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 793361 : gfc_match_small_literal_int (int *value, int *cnt, bool gobble_ws)
462 : {
463 793361 : locus old_loc;
464 793361 : char c;
465 793361 : int i, j;
466 :
467 793361 : old_loc = gfc_current_locus;
468 :
469 793361 : *value = -1;
470 793361 : if (gobble_ws)
471 319853 : gfc_gobble_whitespace ();
472 793361 : c = gfc_next_ascii_char ();
473 793361 : if (cnt)
474 316062 : *cnt = 0;
475 :
476 793361 : if (!ISDIGIT (c))
477 : {
478 400468 : gfc_current_locus = old_loc;
479 400468 : return MATCH_NO;
480 : }
481 :
482 392893 : i = c - '0';
483 392893 : j = 1;
484 :
485 483604 : for (;;)
486 : {
487 483604 : old_loc = gfc_current_locus;
488 483604 : c = gfc_next_ascii_char ();
489 :
490 483604 : if (!ISDIGIT (c))
491 : break;
492 :
493 90711 : i = 10 * i + c - '0';
494 90711 : j++;
495 :
496 90711 : if (i > 99999999)
497 : {
498 0 : gfc_error ("Integer too large at %C");
499 0 : return MATCH_ERROR;
500 : }
501 : }
502 :
503 392893 : gfc_current_locus = old_loc;
504 :
505 392893 : *value = i;
506 392893 : if (cnt)
507 11124 : *cnt = j;
508 : return MATCH_YES;
509 : }
510 :
511 :
512 : /* Match a small, constant integer expression, like in a kind
513 : statement. On MATCH_YES, 'value' is set. */
514 :
515 : match
516 198027 : gfc_match_small_int (int *value)
517 : {
518 198027 : gfc_expr *expr;
519 198027 : match m;
520 198027 : int i;
521 :
522 198027 : m = gfc_match_expr (&expr);
523 198027 : if (m != MATCH_YES)
524 : return m;
525 :
526 198027 : if (gfc_extract_int (expr, &i, 1))
527 1380 : m = MATCH_ERROR;
528 198027 : gfc_free_expr (expr);
529 :
530 198027 : *value = i;
531 198027 : 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 316058 : gfc_match_st_label (gfc_st_label **label)
540 : {
541 316058 : locus old_loc;
542 316058 : match m;
543 316058 : int i, cnt;
544 :
545 316058 : old_loc = gfc_current_locus;
546 :
547 316058 : m = gfc_match_small_literal_int (&i, &cnt);
548 316058 : if (m != MATCH_YES)
549 : return m;
550 :
551 11122 : if (cnt > 5)
552 : {
553 2 : gfc_error ("Too many digits in statement label at %C");
554 2 : goto cleanup;
555 : }
556 :
557 11120 : if (i == 0)
558 : {
559 2 : gfc_error ("Statement label at %C is zero");
560 2 : goto cleanup;
561 : }
562 :
563 11118 : *label = gfc_get_st_label (i);
564 11118 : return MATCH_YES;
565 :
566 4 : cleanup:
567 :
568 4 : gfc_current_locus = old_loc;
569 4 : return MATCH_ERROR;
570 : }
571 :
572 :
573 : /* Match and validate a label associated with a named IF, DO or SELECT
574 : statement. If the symbol does not have the label attribute, we add
575 : it. We also make sure the symbol does not refer to another
576 : (active) block. A matched label is pointed to by gfc_new_block. */
577 :
578 : static match
579 5819761 : gfc_match_label (void)
580 : {
581 5819761 : char name[GFC_MAX_SYMBOL_LEN + 1];
582 5819761 : match m;
583 :
584 5819761 : gfc_new_block = NULL;
585 :
586 5819761 : m = gfc_match (" %n :", name);
587 5819761 : if (m != MATCH_YES)
588 : return m;
589 :
590 125555 : 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 125555 : 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 125478 : 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 28441890 : gfc_match_name (char *buffer, bool gobble_ws)
618 : {
619 28441890 : locus old_loc;
620 28441890 : int i;
621 28441890 : char c;
622 :
623 28441890 : old_loc = gfc_current_locus;
624 28441890 : if (gobble_ws)
625 28346864 : gfc_gobble_whitespace ();
626 :
627 28441890 : c = gfc_next_ascii_char ();
628 28441890 : 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 1654445 : if (!gfc_error_flag_test () && c != '(' && c != '-' && c != '+')
634 428181 : gfc_error ("Invalid character in name at %C");
635 1654445 : gfc_current_locus = old_loc;
636 1654445 : return MATCH_NO;
637 : }
638 :
639 : i = 0;
640 :
641 122569798 : do
642 : {
643 122569798 : buffer[i++] = c;
644 :
645 122569798 : 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 122569798 : old_loc = gfc_current_locus;
652 122569798 : c = gfc_next_ascii_char ();
653 : }
654 122569798 : while (ISALNUM (c) || c == '_' || (flag_dollar_ok && c == '$'));
655 :
656 26787445 : 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 26787443 : buffer[i] = '\0';
664 26787443 : gfc_current_locus = old_loc;
665 :
666 26787443 : 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 4342040 : gfc_match_sym_tree (gfc_symtree **matched_symbol, int host_assoc)
675 : {
676 4342040 : char buffer[GFC_MAX_SYMBOL_LEN + 1];
677 4342040 : match m;
678 4342040 : int ret;
679 :
680 4342040 : locus loc = gfc_current_locus;
681 4342040 : m = gfc_match_name (buffer);
682 4342039 : if (m != MATCH_YES)
683 : return m;
684 4341842 : loc = gfc_get_location_range (NULL, 0, &loc, 1, &gfc_current_locus);
685 4341842 : if (host_assoc)
686 : {
687 2659691 : ret = gfc_get_ha_sym_tree (buffer, matched_symbol, &loc);
688 5319380 : return ret ? MATCH_ERROR : MATCH_YES;
689 : }
690 :
691 1682151 : ret = gfc_get_sym_tree (buffer, NULL, matched_symbol, false, &loc);
692 1682151 : if (ret)
693 30 : return MATCH_ERROR;
694 :
695 : return MATCH_YES;
696 : }
697 :
698 :
699 : match
700 1485211 : gfc_match_symbol (gfc_symbol **matched_symbol, int host_assoc)
701 : {
702 1485211 : gfc_symtree *st;
703 1485211 : match m;
704 :
705 1485211 : m = gfc_match_sym_tree (&st, host_assoc);
706 :
707 1485211 : if (m == MATCH_YES)
708 : {
709 1485011 : if (st)
710 1485011 : *matched_symbol = st->n.sym;
711 : else
712 0 : *matched_symbol = NULL;
713 : }
714 : else
715 200 : *matched_symbol = NULL;
716 1485211 : 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 82268938 : gfc_match_intrinsic_op (gfc_intrinsic_op *result)
726 : {
727 82268938 : locus orig_loc = gfc_current_locus;
728 82268938 : char ch;
729 :
730 82268938 : gfc_gobble_whitespace ();
731 82268938 : ch = gfc_next_ascii_char ();
732 82268938 : switch (ch)
733 : {
734 349445 : case '+':
735 : /* Matched "+". */
736 349445 : *result = INTRINSIC_PLUS;
737 349445 : return MATCH_YES;
738 :
739 529185 : case '-':
740 : /* Matched "-". */
741 529185 : *result = INTRINSIC_MINUS;
742 529185 : return MATCH_YES;
743 :
744 275065 : case '=':
745 275065 : if (gfc_next_ascii_char () == '=')
746 : {
747 : /* Matched "==". */
748 156151 : *result = INTRINSIC_EQ;
749 156151 : return MATCH_YES;
750 : }
751 : break;
752 :
753 78227 : case '<':
754 78227 : 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 44394 : *result = INTRINSIC_LT;
763 44394 : return MATCH_YES;
764 :
765 281076 : case '>':
766 281076 : if (gfc_peek_ascii_char () == '=')
767 : {
768 : /* Matched ">=". */
769 13015 : gfc_next_ascii_char ();
770 13015 : *result = INTRINSIC_GE;
771 13015 : return MATCH_YES;
772 : }
773 : /* Matched ">". */
774 268061 : *result = INTRINSIC_GT;
775 268061 : return MATCH_YES;
776 :
777 275102 : case '*':
778 275102 : if (gfc_peek_ascii_char () == '*')
779 : {
780 : /* Matched "**". */
781 68665 : gfc_next_ascii_char ();
782 68665 : *result = INTRINSIC_POWER;
783 68665 : return MATCH_YES;
784 : }
785 : /* Matched "*". */
786 206437 : *result = INTRINSIC_TIMES;
787 206437 : return MATCH_YES;
788 :
789 5220546 : case '/':
790 5220546 : ch = gfc_peek_ascii_char ();
791 5220546 : if (ch == '=')
792 : {
793 : /* Matched "/=". */
794 4500835 : gfc_next_ascii_char ();
795 4500835 : *result = INTRINSIC_NE;
796 4500835 : return MATCH_YES;
797 : }
798 719711 : 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 686300 : *result = INTRINSIC_DIVIDE;
807 686300 : return MATCH_YES;
808 :
809 4002130 : case '.':
810 4002130 : ch = gfc_next_ascii_char ();
811 4002130 : switch (ch)
812 : {
813 129714 : case 'a':
814 129714 : if (gfc_next_ascii_char () == 'n'
815 128804 : && gfc_next_ascii_char () == 'd'
816 258518 : && gfc_next_ascii_char () == '.')
817 : {
818 : /* Matched ".and.". */
819 128804 : *result = INTRINSIC_AND;
820 128804 : return MATCH_YES;
821 : }
822 : break;
823 :
824 99890 : case 'e':
825 99890 : if (gfc_next_ascii_char () == 'q')
826 : {
827 99806 : ch = gfc_next_ascii_char ();
828 99806 : if (ch == '.')
829 : {
830 : /* Matched ".eq.". */
831 79867 : *result = INTRINSIC_EQ_OS;
832 79867 : return MATCH_YES;
833 : }
834 19939 : else if (ch == 'v')
835 : {
836 19937 : if (gfc_next_ascii_char () == '.')
837 : {
838 : /* Matched ".eqv.". */
839 19937 : *result = INTRINSIC_EQV;
840 19937 : return MATCH_YES;
841 : }
842 : }
843 : }
844 : break;
845 :
846 78013 : case 'g':
847 78013 : ch = gfc_next_ascii_char ();
848 78013 : if (ch == 'e')
849 : {
850 20232 : if (gfc_next_ascii_char () == '.')
851 : {
852 : /* Matched ".ge.". */
853 20154 : *result = INTRINSIC_GE_OS;
854 20154 : return MATCH_YES;
855 : }
856 : }
857 57781 : else if (ch == 't')
858 : {
859 57735 : if (gfc_next_ascii_char () == '.')
860 : {
861 : /* Matched ".gt.". */
862 57735 : *result = INTRINSIC_GT_OS;
863 57735 : return MATCH_YES;
864 : }
865 : }
866 : break;
867 :
868 52626 : case 'l':
869 52626 : ch = gfc_next_ascii_char ();
870 52626 : if (ch == 'e')
871 : {
872 18288 : if (gfc_next_ascii_char () == '.')
873 : {
874 : /* Matched ".le.". */
875 18288 : *result = INTRINSIC_LE_OS;
876 18288 : return MATCH_YES;
877 : }
878 : }
879 34338 : else if (ch == 't')
880 : {
881 34128 : if (gfc_next_ascii_char () == '.')
882 : {
883 : /* Matched ".lt.". */
884 34128 : *result = INTRINSIC_LT_OS;
885 34128 : return MATCH_YES;
886 : }
887 : }
888 : break;
889 :
890 1823121 : case 'n':
891 1823121 : ch = gfc_next_ascii_char ();
892 1823121 : if (ch == 'e')
893 : {
894 1744965 : ch = gfc_next_ascii_char ();
895 1744965 : if (ch == '.')
896 : {
897 : /* Matched ".ne.". */
898 1499740 : *result = INTRINSIC_NE_OS;
899 1499740 : return MATCH_YES;
900 : }
901 245225 : else if (ch == 'q')
902 : {
903 245225 : if (gfc_next_ascii_char () == 'v'
904 245225 : && gfc_next_ascii_char () == '.')
905 : {
906 : /* Matched ".neqv.". */
907 245225 : *result = INTRINSIC_NEQV;
908 245225 : return MATCH_YES;
909 : }
910 : }
911 : }
912 78156 : else if (ch == 'o')
913 : {
914 78153 : if (gfc_next_ascii_char () == 't'
915 78153 : && gfc_next_ascii_char () == '.')
916 : {
917 : /* Matched ".not.". */
918 78108 : *result = INTRINSIC_NOT;
919 78108 : return MATCH_YES;
920 : }
921 : }
922 : break;
923 :
924 1641008 : case 'o':
925 1641008 : if (gfc_next_ascii_char () == 'r'
926 1641008 : && gfc_next_ascii_char () == '.')
927 : {
928 : /* Matched ".or.". */
929 1640779 : *result = INTRINSIC_OR;
930 1640779 : 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 71556114 : gfc_current_locus = orig_loc;
957 71556114 : 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 43237 : gfc_match_iterator (gfc_iterator *iter, int init_flag)
971 : {
972 43237 : char name[GFC_MAX_SYMBOL_LEN + 1];
973 43237 : gfc_expr *var, *e1, *e2, *e3;
974 43237 : locus start;
975 43237 : match m;
976 :
977 43237 : e1 = e2 = e3 = NULL;
978 :
979 : /* Match the start of an iterator without affecting the symbol table. */
980 :
981 43237 : start = gfc_current_locus;
982 43237 : m = gfc_match (" %n =", name);
983 43237 : gfc_current_locus = start;
984 :
985 43237 : if (m != MATCH_YES)
986 : return MATCH_NO;
987 :
988 41421 : m = gfc_match_variable (&var, 0);
989 41421 : if (m != MATCH_YES)
990 : return MATCH_NO;
991 :
992 41421 : 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 41417 : 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 41416 : 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 41416 : gfc_match_char ('=');
1012 :
1013 41416 : var->symtree->n.sym->attr.implied_index = 1;
1014 :
1015 41416 : m = init_flag ? gfc_match_init_expr (&e1) : gfc_match_expr (&e1);
1016 41416 : if (m == MATCH_NO)
1017 0 : goto syntax;
1018 41416 : if (m == MATCH_ERROR)
1019 0 : goto cleanup;
1020 :
1021 41416 : if (gfc_match_char (',') != MATCH_YES)
1022 1 : goto syntax;
1023 :
1024 41415 : m = init_flag ? gfc_match_init_expr (&e2) : gfc_match_expr (&e2);
1025 41415 : if (m == MATCH_NO)
1026 0 : goto syntax;
1027 41415 : if (m == MATCH_ERROR)
1028 0 : goto cleanup;
1029 :
1030 41415 : if (gfc_match_char (',') != MATCH_YES)
1031 : {
1032 37828 : e3 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
1033 37828 : 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 41415 : iter->var = var;
1047 41415 : iter->start = e1;
1048 41415 : iter->end = e2;
1049 41415 : iter->step = e3;
1050 41415 : 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 41713007 : gfc_match_char (char c, bool gobble_ws)
1070 : {
1071 41713007 : locus where;
1072 :
1073 41713007 : where = gfc_current_locus;
1074 41713007 : if (gobble_ws)
1075 37104857 : gfc_gobble_whitespace ();
1076 :
1077 41713007 : if (gfc_next_ascii_char () == c)
1078 : return MATCH_YES;
1079 :
1080 33958234 : gfc_current_locus = where;
1081 33958234 : 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 91555529 : gfc_match (const char *target, ...)
1104 : {
1105 91555529 : gfc_st_label **label;
1106 91555529 : int matches, *ip;
1107 91555529 : locus old_loc;
1108 91555529 : va_list argp;
1109 91555529 : char c, *np;
1110 91555529 : match m, n;
1111 91555529 : void **vp;
1112 91555529 : const char *p;
1113 :
1114 91555529 : old_loc = gfc_current_locus;
1115 91555529 : va_start (argp, target);
1116 91555529 : m = MATCH_NO;
1117 91555529 : matches = 0;
1118 91555529 : p = target;
1119 :
1120 388829557 : loop:
1121 388829557 : c = *p++;
1122 388829557 : switch (c)
1123 : {
1124 114581586 : case ' ':
1125 114581586 : gfc_gobble_whitespace ();
1126 114581586 : goto loop;
1127 : case '\0':
1128 : m = MATCH_YES;
1129 : break;
1130 :
1131 23286547 : case '%':
1132 23286547 : c = *p++;
1133 23286547 : switch (c)
1134 : {
1135 2018844 : case 'e':
1136 2018844 : vp = va_arg (argp, void **);
1137 2018844 : n = gfc_match_expr ((gfc_expr **) vp);
1138 2018843 : if (n != MATCH_YES)
1139 : {
1140 640605 : m = n;
1141 640605 : goto not_yes;
1142 : }
1143 :
1144 1378238 : matches++;
1145 1378238 : goto loop;
1146 :
1147 2768009 : case 'v':
1148 2768009 : vp = va_arg (argp, void **);
1149 2768009 : n = gfc_match_variable ((gfc_expr **) vp, 0);
1150 2768008 : if (n != MATCH_YES)
1151 : {
1152 2970 : m = n;
1153 2970 : goto not_yes;
1154 : }
1155 :
1156 2765038 : matches++;
1157 2765038 : goto loop;
1158 :
1159 30562 : case 's':
1160 30562 : case 'S':
1161 30562 : vp = va_arg (argp, void **);
1162 30562 : n = gfc_match_symbol ((gfc_symbol **) vp, c == 'S');
1163 30562 : if (n != MATCH_YES)
1164 : {
1165 3 : m = n;
1166 3 : goto not_yes;
1167 : }
1168 :
1169 30559 : matches++;
1170 30559 : goto loop;
1171 :
1172 13255641 : case 'n':
1173 13255641 : np = va_arg (argp, char *);
1174 13255641 : n = gfc_match_name (np);
1175 13255641 : if (n != MATCH_YES)
1176 : {
1177 27043 : m = n;
1178 27043 : goto not_yes;
1179 : }
1180 :
1181 13228598 : matches++;
1182 13228598 : goto loop;
1183 :
1184 234001 : case 'l':
1185 234001 : label = va_arg (argp, gfc_st_label **);
1186 234001 : n = gfc_match_st_label (label);
1187 234001 : if (n != MATCH_YES)
1188 : {
1189 231727 : m = n;
1190 231727 : goto not_yes;
1191 : }
1192 :
1193 2274 : matches++;
1194 2274 : goto loop;
1195 :
1196 1717 : case 'o':
1197 1717 : ip = va_arg (argp, int *);
1198 1717 : n = gfc_match_intrinsic_op ((gfc_intrinsic_op *) ip);
1199 1717 : if (n != MATCH_YES)
1200 : {
1201 803 : m = n;
1202 803 : goto not_yes;
1203 : }
1204 :
1205 914 : matches++;
1206 914 : goto loop;
1207 :
1208 378261 : case 't':
1209 378261 : if (gfc_match_eos () != MATCH_YES)
1210 : {
1211 2334 : m = MATCH_NO;
1212 2334 : goto not_yes;
1213 : }
1214 375927 : goto loop;
1215 :
1216 347855 : case ' ':
1217 347855 : if (gfc_match_space () == MATCH_YES)
1218 343697 : goto loop;
1219 4158 : m = MATCH_NO;
1220 4158 : 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 237058623 : default:
1231 :
1232 : /* gfc_next_ascii_char converts characters to lower-case, so we shouldn't
1233 : expect an upper case character here! */
1234 237058623 : gcc_assert (TOLOWER (c) == c);
1235 :
1236 237058623 : if (c == gfc_next_ascii_char ())
1237 164567197 : goto loop;
1238 : break;
1239 : }
1240 :
1241 91555527 : not_yes:
1242 91555527 : va_end (argp);
1243 :
1244 91555527 : if (m != MATCH_YES)
1245 : {
1246 : /* Clean up after a failed match. */
1247 73401069 : gfc_current_locus = old_loc;
1248 73401069 : va_start (argp, target);
1249 :
1250 73401069 : p = target;
1251 81715578 : for (; matches > 0; matches--)
1252 : {
1253 16914686 : while (*p++ != '%');
1254 :
1255 8314509 : switch (*p++)
1256 : {
1257 0 : case '%':
1258 0 : matches++;
1259 0 : break; /* Skip. */
1260 :
1261 : /* Matches that don't have to be undone */
1262 5859899 : case 'o':
1263 5859899 : case 'l':
1264 5859899 : case 'n':
1265 5859899 : case 's':
1266 5859899 : (void) va_arg (argp, void **);
1267 5859899 : break;
1268 :
1269 2454610 : case 'e':
1270 2454610 : case 'v':
1271 2454610 : vp = va_arg (argp, void **);
1272 2454610 : gfc_free_expr ((struct gfc_expr *)*vp);
1273 2454610 : *vp = NULL;
1274 2454610 : break;
1275 : }
1276 : }
1277 :
1278 73401069 : va_end (argp);
1279 : }
1280 :
1281 91555527 : 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 19251 : gfc_match_program (void)
1292 : {
1293 19251 : gfc_symbol *sym;
1294 19251 : match m;
1295 :
1296 19251 : m = gfc_match ("% %s%t", &sym);
1297 :
1298 19251 : if (m == MATCH_NO)
1299 : {
1300 0 : gfc_error ("Invalid form of PROGRAM statement at %C");
1301 0 : m = MATCH_ERROR;
1302 : }
1303 :
1304 19251 : if (m == MATCH_ERROR)
1305 0 : return m;
1306 :
1307 19251 : if (!gfc_add_flavor (&sym->attr, FL_PROGRAM, sym->name, NULL))
1308 : return MATCH_ERROR;
1309 :
1310 19251 : gfc_new_block = sym;
1311 :
1312 19251 : return MATCH_YES;
1313 : }
1314 :
1315 :
1316 : /* Match a simple assignment statement. */
1317 :
1318 : match
1319 1524596 : gfc_match_assignment (void)
1320 : {
1321 1524596 : gfc_expr *lvalue, *rvalue;
1322 1524596 : locus old_loc;
1323 1524596 : match m;
1324 :
1325 1524596 : old_loc = gfc_current_locus;
1326 :
1327 1524596 : lvalue = NULL;
1328 1524596 : m = gfc_match (" %v =", &lvalue);
1329 1524595 : if (m != MATCH_YES)
1330 : {
1331 1226325 : gfc_current_locus = old_loc;
1332 1226325 : gfc_free_expr (lvalue);
1333 1226325 : return MATCH_NO;
1334 : }
1335 :
1336 298270 : rvalue = NULL;
1337 298270 : m = gfc_match (" %e%t", &rvalue);
1338 :
1339 298270 : if (m == MATCH_YES
1340 286622 : && 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 298270 : 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 298270 : if (m != MATCH_YES)
1357 : {
1358 11654 : gfc_current_locus = old_loc;
1359 11654 : gfc_free_expr (lvalue);
1360 11654 : gfc_free_expr (rvalue);
1361 11654 : return m;
1362 : }
1363 :
1364 286616 : 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 286616 : gfc_set_sym_referenced (lvalue->symtree->n.sym);
1373 :
1374 286616 : new_st.op = EXEC_ASSIGN;
1375 286616 : new_st.expr1 = lvalue;
1376 286616 : new_st.expr2 = rvalue;
1377 :
1378 286616 : gfc_check_do_variable (lvalue->symtree);
1379 :
1380 286616 : return MATCH_YES;
1381 : }
1382 :
1383 :
1384 : /* Match a pointer assignment statement. */
1385 :
1386 : match
1387 1237979 : gfc_match_pointer_assignment (void)
1388 : {
1389 1237979 : gfc_expr *lvalue, *rvalue;
1390 1237979 : locus old_loc;
1391 1237979 : match m;
1392 :
1393 1237979 : old_loc = gfc_current_locus;
1394 :
1395 1237979 : lvalue = rvalue = NULL;
1396 1237979 : gfc_matching_ptr_assignment = 0;
1397 1237979 : gfc_matching_procptr_assignment = 0;
1398 :
1399 1237979 : m = gfc_match (" %v =>", &lvalue);
1400 1237979 : if (m != MATCH_YES || !lvalue->symtree)
1401 : {
1402 1228703 : m = MATCH_NO;
1403 1228703 : goto cleanup;
1404 : }
1405 :
1406 9276 : if (lvalue->symtree->n.sym->attr.proc_pointer
1407 9276 : || gfc_is_proc_ptr_comp (lvalue))
1408 1286 : gfc_matching_procptr_assignment = 1;
1409 : else
1410 7990 : gfc_matching_ptr_assignment = 1;
1411 :
1412 9276 : m = gfc_match (" %e%t", &rvalue);
1413 9276 : gfc_matching_ptr_assignment = 0;
1414 9276 : gfc_matching_procptr_assignment = 0;
1415 9276 : if (m != MATCH_YES)
1416 1 : goto cleanup;
1417 :
1418 9275 : new_st.op = EXEC_POINTER_ASSIGN;
1419 9275 : new_st.expr1 = lvalue;
1420 9275 : new_st.expr2 = rvalue;
1421 :
1422 9275 : return MATCH_YES;
1423 :
1424 1228704 : cleanup:
1425 1228704 : gfc_current_locus = old_loc;
1426 1228704 : gfc_free_expr (lvalue);
1427 1228704 : gfc_free_expr (rvalue);
1428 1228704 : 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 761281 : gfc_match_if (gfc_statement *if_type)
1485 : {
1486 761281 : gfc_expr *expr;
1487 761281 : gfc_st_label *l1, *l2, *l3;
1488 761281 : locus old_loc, old_loc2;
1489 761281 : gfc_code *p;
1490 761281 : match m, n;
1491 :
1492 761281 : n = gfc_match_label ();
1493 761281 : if (n == MATCH_ERROR)
1494 : return n;
1495 :
1496 761273 : old_loc = gfc_current_locus;
1497 :
1498 761273 : m = gfc_match (" if ", &expr);
1499 761273 : if (m != MATCH_YES)
1500 : return m;
1501 :
1502 231724 : 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 231721 : m = gfc_match ("%e", &expr);
1509 231721 : if (m != MATCH_YES)
1510 : return m;
1511 :
1512 231697 : old_loc2 = gfc_current_locus;
1513 231697 : gfc_current_locus = old_loc;
1514 :
1515 231697 : if (gfc_match_parens () == MATCH_ERROR)
1516 : return MATCH_ERROR;
1517 :
1518 231690 : gfc_current_locus = old_loc2;
1519 :
1520 231690 : 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 231688 : m = gfc_match (" %l , %l , %l%t", &l1, &l2, &l3);
1528 :
1529 231688 : 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 231640 : if (gfc_match (" then%t") == MATCH_YES)
1562 : {
1563 14808 : new_st.op = EXEC_IF;
1564 14808 : new_st.expr1 = expr;
1565 14808 : *if_type = ST_IF_BLOCK;
1566 14808 : return MATCH_YES;
1567 : }
1568 :
1569 216832 : 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 216832 : *if_type = ST_SIMPLE_IF;
1582 :
1583 216832 : m = gfc_match_assignment ();
1584 216832 : if (m == MATCH_YES)
1585 4793 : goto got_match;
1586 :
1587 212039 : gfc_free_expr (expr);
1588 212039 : gfc_undo_symbols ();
1589 212039 : 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 212039 : if (m == MATCH_ERROR)
1595 : return MATCH_ERROR;
1596 :
1597 212039 : gfc_match (" if ( %e ) ", &expr); /* Guaranteed to match. */
1598 :
1599 212039 : m = gfc_match_pointer_assignment ();
1600 212039 : if (m == MATCH_YES)
1601 68 : goto got_match;
1602 :
1603 211971 : gfc_free_expr (expr);
1604 211971 : gfc_undo_symbols ();
1605 211971 : gfc_current_locus = old_loc;
1606 :
1607 211971 : 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 211971 : gfc_clear_error ();
1617 :
1618 211971 : match ("allocate", gfc_match_allocate, ST_ALLOCATE)
1619 211895 : match ("assign", gfc_match_assign, ST_LABEL_ASSIGNMENT)
1620 211893 : match ("backspace", gfc_match_backspace, ST_BACKSPACE)
1621 211887 : match ("call", gfc_match_call, ST_CALL)
1622 211206 : match ("change% team", gfc_match_change_team, ST_CHANGE_TEAM)
1623 211206 : match ("close", gfc_match_close, ST_CLOSE)
1624 211206 : match ("continue", gfc_match_continue, ST_CONTINUE)
1625 211206 : match ("cycle", gfc_match_cycle, ST_CYCLE)
1626 211100 : match ("deallocate", gfc_match_deallocate, ST_DEALLOCATE)
1627 210621 : match ("end file", gfc_match_endfile, ST_END_FILE)
1628 210621 : match ("end team", gfc_match_end_team, ST_END_TEAM)
1629 210621 : match ("error% stop", gfc_match_error_stop, ST_ERROR_STOP)
1630 172454 : match ("event% post", gfc_match_event_post, ST_EVENT_POST)
1631 172454 : match ("event% wait", gfc_match_event_wait, ST_EVENT_WAIT)
1632 172451 : match ("exit", gfc_match_exit, ST_EXIT)
1633 172145 : match ("fail% image", gfc_match_fail_image, ST_FAIL_IMAGE)
1634 172138 : match ("flush", gfc_match_flush, ST_FLUSH)
1635 172138 : match ("forall", match_simple_forall, ST_FORALL)
1636 172132 : match ("form% team", gfc_match_form_team, ST_FORM_TEAM)
1637 172132 : match ("go to", gfc_match_goto, ST_GOTO)
1638 171753 : match ("if", match_arithmetic_if, ST_ARITHMETIC_IF)
1639 171729 : match ("inquire", gfc_match_inquire, ST_INQUIRE)
1640 171729 : match ("lock", gfc_match_lock, ST_LOCK)
1641 171729 : match ("nullify", gfc_match_nullify, ST_NULLIFY)
1642 171729 : match ("open", gfc_match_open, ST_OPEN)
1643 171729 : match ("pause", gfc_match_pause, ST_NONE)
1644 171729 : match ("print", gfc_match_print, ST_WRITE)
1645 171327 : match ("read", gfc_match_read, ST_READ)
1646 171325 : match ("return", gfc_match_return, ST_RETURN)
1647 170936 : match ("rewind", gfc_match_rewind, ST_REWIND)
1648 170936 : 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 216827 : got_match:
1670 216827 : if (m == MATCH_NO)
1671 0 : gfc_error ("Syntax error in IF-clause after %C");
1672 216827 : 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 216750 : p = gfc_get_code (EXEC_IF);
1683 216750 : p->next = XCNEW (gfc_code);
1684 216750 : *p->next = new_st;
1685 216750 : p->next->loc = gfc_current_locus;
1686 :
1687 216750 : p->expr1 = expr;
1688 :
1689 216750 : gfc_clear_new_st ();
1690 :
1691 216750 : new_st.op = EXEC_IF;
1692 216750 : new_st.block = p;
1693 :
1694 216750 : return MATCH_YES;
1695 : }
1696 :
1697 : #undef match
1698 :
1699 :
1700 : /* Match an ELSE statement. */
1701 :
1702 : match
1703 6382 : gfc_match_else (void)
1704 : {
1705 6382 : char name[GFC_MAX_SYMBOL_LEN + 1];
1706 :
1707 6382 : 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 97491 : gfc_free_iterator (gfc_iterator *iter, int flag)
1803 : {
1804 :
1805 97491 : if (iter == NULL)
1806 : return;
1807 :
1808 55627 : gfc_free_expr (iter->var);
1809 55627 : gfc_free_expr (iter->start);
1810 55627 : gfc_free_expr (iter->end);
1811 55627 : gfc_free_expr (iter->step);
1812 :
1813 55627 : if (flag)
1814 50107 : 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 491411 : gfc_match_critical (void)
1861 : {
1862 491411 : gfc_st_label *label = NULL;
1863 491411 : match m;
1864 :
1865 491411 : if (gfc_match_label () == MATCH_ERROR)
1866 : return MATCH_ERROR;
1867 :
1868 491403 : 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 494394 : gfc_match_block (void)
1950 : {
1951 494394 : match m;
1952 :
1953 494394 : if (gfc_match_label () == MATCH_ERROR)
1954 : return MATCH_ERROR;
1955 :
1956 494386 : 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 1451 : m = gfc_match_eos ();
1961 1451 : if (m == MATCH_ERROR)
1962 : return MATCH_ERROR;
1963 1451 : 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 493032 : gfc_match_associate (void)
2377 : {
2378 493032 : match m;
2379 493032 : if (gfc_match_label () == MATCH_ERROR)
2380 : return MATCH_ERROR;
2381 :
2382 493024 : 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 36356 : match_derived_type_spec (gfc_typespec *ts)
2426 : {
2427 36356 : char name[GFC_MAX_SYMBOL_LEN + 1];
2428 36356 : locus old_locus;
2429 36356 : gfc_symbol *derived, *der_type;
2430 36356 : match m = MATCH_YES;
2431 36356 : gfc_actual_arglist *decl_type_param_list = NULL;
2432 36356 : bool is_pdt_template = false;
2433 :
2434 36356 : old_locus = gfc_current_locus;
2435 :
2436 36356 : if (gfc_match ("%n", name) != MATCH_YES)
2437 : {
2438 1 : gfc_current_locus = old_locus;
2439 1 : return MATCH_NO;
2440 : }
2441 :
2442 36355 : gfc_find_symbol (name, NULL, 1, &derived);
2443 :
2444 : /* Match the PDT spec list, if there. */
2445 36355 : if (derived && derived->attr.flavor == FL_PROCEDURE)
2446 : {
2447 7079 : gfc_find_symbol (gfc_dt_upper_string (name), NULL, 1, &der_type);
2448 7079 : is_pdt_template = der_type
2449 4969 : && der_type->attr.flavor == FL_DERIVED
2450 12048 : && der_type->attr.pdt_template;
2451 : }
2452 :
2453 212 : if (is_pdt_template)
2454 212 : m = gfc_match_actual_arglist (1, &decl_type_param_list, true);
2455 :
2456 9068 : if (m == MATCH_ERROR)
2457 : {
2458 0 : gfc_free_actual_arglist (decl_type_param_list);
2459 0 : return m;
2460 : }
2461 :
2462 36355 : if (derived && derived->attr.flavor == FL_PROCEDURE && derived->attr.generic)
2463 4993 : derived = gfc_find_dt_in_generic (derived);
2464 :
2465 : /* If this is a PDT, find the specific instance. */
2466 36355 : if (m == MATCH_YES && is_pdt_template)
2467 : {
2468 212 : gfc_namespace *old_ns;
2469 :
2470 212 : old_ns = gfc_current_ns;
2471 377 : while (gfc_current_ns && gfc_current_ns->parent)
2472 165 : gfc_current_ns = gfc_current_ns->parent;
2473 :
2474 212 : if (type_param_spec_list)
2475 6 : gfc_free_actual_arglist (type_param_spec_list);
2476 212 : m = gfc_get_pdt_instance (decl_type_param_list, &der_type,
2477 : &type_param_spec_list);
2478 212 : gfc_free_actual_arglist (decl_type_param_list);
2479 :
2480 212 : if (m != MATCH_YES)
2481 : return m;
2482 207 : derived = der_type;
2483 207 : gcc_assert (!derived->attr.pdt_template && derived->attr.pdt_type);
2484 207 : gfc_set_sym_referenced (derived);
2485 :
2486 207 : gfc_current_ns = old_ns;
2487 : }
2488 :
2489 36350 : if (derived && derived->attr.flavor == FL_DERIVED)
2490 : {
2491 4964 : ts->type = BT_DERIVED;
2492 4964 : ts->u.derived = derived;
2493 4964 : return MATCH_YES;
2494 : }
2495 :
2496 31386 : gfc_current_locus = old_locus;
2497 31386 : 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 154889 : match_type_spec (gfc_typespec *ts)
2510 : {
2511 154889 : match m;
2512 154889 : locus old_locus;
2513 154889 : char c, name[GFC_MAX_SYMBOL_LEN + 1];
2514 :
2515 154889 : gfc_clear_ts (ts);
2516 154889 : gfc_gobble_whitespace ();
2517 154889 : old_locus = gfc_current_locus;
2518 :
2519 : /* If c isn't [a-z], then return immediately. */
2520 154889 : c = gfc_peek_ascii_char ();
2521 154889 : if (!ISALPHA(c))
2522 : return MATCH_NO;
2523 :
2524 35998 : type_param_spec_list = NULL;
2525 :
2526 35998 : if (match_derived_type_spec (ts) == MATCH_YES)
2527 : {
2528 : /* Enforce F03:C401. */
2529 4610 : 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 31388 : if (gfc_match ("integer") == MATCH_YES)
2539 : {
2540 1619 : ts->type = BT_INTEGER;
2541 1619 : ts->kind = gfc_default_integer_kind;
2542 1619 : goto kind_selector;
2543 : }
2544 :
2545 29769 : 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 29763 : 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 29704 : 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 29565 : if (gfc_match ("character") == MATCH_YES)
2567 : {
2568 2987 : ts->type = BT_CHARACTER;
2569 :
2570 2987 : m = gfc_match_char_spec (ts);
2571 :
2572 2987 : if (m == MATCH_NO)
2573 0 : m = MATCH_YES;
2574 :
2575 2987 : 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 26578 : m = gfc_match (" %n", name);
2586 26578 : if (m == MATCH_YES
2587 26573 : && (strcmp (name, "real") == 0 || strcmp (name, "logical") == 0))
2588 : {
2589 3505 : char c;
2590 3505 : gfc_expr *e;
2591 3505 : locus where;
2592 :
2593 3505 : if (*name == 'r')
2594 : {
2595 2981 : ts->type = BT_REAL;
2596 2981 : 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 3505 : gfc_gobble_whitespace ();
2605 :
2606 : /* Prevent REAL*4, etc. */
2607 3505 : c = gfc_peek_ascii_char ();
2608 3505 : 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 3501 : if (c == ':' || c == ')' || (flag_openmp && c == ','))
2617 : return MATCH_YES;
2618 :
2619 : /* Found something other than the opening '(' in REAL(... */
2620 557 : if (c != '(')
2621 : return MATCH_NO;
2622 : else
2623 557 : gfc_next_char (); /* Burn the '('. */
2624 :
2625 : /* Look for the optional KIND=. */
2626 557 : where = gfc_current_locus;
2627 557 : m = gfc_match ("%n", name);
2628 557 : if (m == MATCH_YES)
2629 : {
2630 415 : gfc_gobble_whitespace ();
2631 415 : c = gfc_next_char ();
2632 415 : 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 270 : gfc_current_locus = where;
2643 : }
2644 : else
2645 142 : gfc_current_locus = where;
2646 :
2647 553 : found:
2648 :
2649 553 : m = gfc_match_expr (&e);
2650 553 : if (m == MATCH_NO || m == MATCH_ERROR)
2651 : return m;
2652 :
2653 : /* If a comma appears, it is an intrinsic subprogram. */
2654 553 : gfc_gobble_whitespace ();
2655 553 : c = gfc_peek_ascii_char ();
2656 553 : 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 530 : if (c == ')')
2665 : {
2666 530 : bool ok = true;
2667 530 : if (e->expr_type != EXPR_CONSTANT && e->expr_type != EXPR_VARIABLE)
2668 7 : ok = gfc_reduce_init_expr (e);
2669 530 : 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 527 : if (e->expr_type != EXPR_CONSTANT)
2676 22 : 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 23073 : ohno:
2693 :
2694 : /* If a type is not matched, simply return MATCH_NO. */
2695 23095 : gfc_current_locus = old_locus;
2696 23095 : return MATCH_NO;
2697 :
2698 1764 : kind_selector:
2699 :
2700 1764 : gfc_gobble_whitespace ();
2701 :
2702 : /* This prevents INTEGER*4, etc. */
2703 1764 : if (gfc_peek_ascii_char () == '*')
2704 : {
2705 0 : gfc_error ("Invalid type-spec at %C");
2706 0 : return MATCH_ERROR;
2707 : }
2708 :
2709 1764 : m = gfc_match_kind_spec (ts, false);
2710 :
2711 : /* No kind specifier found. */
2712 1764 : if (m == MATCH_NO)
2713 6139 : m = MATCH_YES;
2714 :
2715 : return m;
2716 : }
2717 :
2718 :
2719 : match
2720 154889 : gfc_match_type_spec (gfc_typespec *ts)
2721 : {
2722 154889 : match m;
2723 154889 : gfc_namespace *old_ns = gfc_current_ns;
2724 154889 : m = match_type_spec (ts);
2725 154889 : gfc_current_ns = old_ns;
2726 154889 : 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 529229 : gfc_match_forall (gfc_statement *st)
3050 : {
3051 529229 : gfc_forall_iterator *head;
3052 529229 : gfc_expr *mask;
3053 529229 : gfc_code *c;
3054 529229 : match m0, m;
3055 :
3056 529229 : head = NULL;
3057 529229 : mask = NULL;
3058 529229 : c = NULL;
3059 :
3060 529229 : m0 = gfc_match_label ();
3061 529229 : if (m0 == MATCH_ERROR)
3062 : return MATCH_ERROR;
3063 :
3064 529221 : m = gfc_match (" forall");
3065 529221 : 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 527223 : gfc_match_do (void)
3124 : {
3125 527223 : gfc_iterator iter, *ip;
3126 527223 : locus old_loc;
3127 527223 : gfc_st_label *label;
3128 527223 : match m;
3129 :
3130 527223 : old_loc = gfc_current_locus;
3131 :
3132 527223 : memset (&iter, '\0', sizeof (gfc_iterator));
3133 527223 : label = NULL;
3134 :
3135 527223 : m = gfc_match_label ();
3136 527223 : if (m == MATCH_ERROR)
3137 : return m;
3138 :
3139 527215 : if (gfc_match (" do") != MATCH_YES)
3140 : return MATCH_NO;
3141 :
3142 32844 : m = gfc_match_st_label (&label);
3143 32844 : if (m == MATCH_ERROR)
3144 0 : goto cleanup;
3145 :
3146 : /* Match an infinite DO, make it like a DO WHILE(.TRUE.). */
3147 :
3148 32844 : 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 32601 : if (gfc_match_char (',') != MATCH_YES && gfc_match ("% ") != MATCH_YES)
3157 : return MATCH_NO;
3158 :
3159 : /* Check for balanced parens. */
3160 :
3161 32601 : if (gfc_match_parens () == MATCH_ERROR)
3162 : return MATCH_ERROR;
3163 :
3164 : /* Handle DO CONCURRENT construct. */
3165 :
3166 32599 : 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 32366 : 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 32077 : match_do_loop:
3487 : /* The abortive DO WHILE may have done something to the symbol
3488 : table, so we start over. */
3489 32079 : gfc_undo_symbols ();
3490 32079 : gfc_current_locus = old_loc;
3491 :
3492 32079 : gfc_match_label (); /* This won't error. */
3493 32079 : gfc_match (" do "); /* This will work. */
3494 :
3495 32079 : gfc_match_st_label (&label); /* Can't error out. */
3496 32079 : gfc_match_char (','); /* Optional comma. */
3497 :
3498 32079 : m = gfc_match_iterator (&iter, 0);
3499 32079 : if (m == MATCH_NO)
3500 : return MATCH_NO;
3501 32078 : if (m == MATCH_ERROR)
3502 5 : goto cleanup;
3503 :
3504 32073 : iter.var->symtree->n.sym->attr.implied_index = 0;
3505 32073 : gfc_check_do_variable (iter.var->symtree);
3506 :
3507 32073 : if (gfc_match_eos () != MATCH_YES)
3508 : {
3509 0 : gfc_syntax_error (ST_DO);
3510 0 : goto cleanup;
3511 : }
3512 :
3513 32073 : new_st.op = EXEC_DO;
3514 :
3515 32605 : done:
3516 32605 : if (label != NULL
3517 32605 : && !gfc_reference_st_label (label, ST_LABEL_DO_TARGET))
3518 0 : goto cleanup;
3519 :
3520 32605 : new_st.label1 = label;
3521 :
3522 32605 : if (new_st.op == EXEC_DO_WHILE)
3523 532 : new_st.expr1 = iter.end;
3524 : else
3525 : {
3526 32073 : new_st.ext.iterator = ip = gfc_get_iterator ();
3527 32073 : *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 218475 : gfc_match_stopcode (gfc_statement st)
3834 : {
3835 218475 : gfc_expr *e = NULL;
3836 218475 : gfc_expr *quiet = NULL;
3837 218475 : match m;
3838 218475 : bool f95, f03, f08;
3839 218475 : char c;
3840 :
3841 : /* Set f95 for -std=f95. */
3842 218475 : f95 = (gfc_option.allow_std == GFC_STD_OPT_F95);
3843 :
3844 : /* Set f03 for -std=f2003. */
3845 218475 : f03 = (gfc_option.allow_std == GFC_STD_OPT_F03);
3846 :
3847 : /* Set f08 for -std=f2008. */
3848 218475 : f08 = (gfc_option.allow_std == GFC_STD_OPT_F08);
3849 :
3850 : /* Plain STOP statement? */
3851 218475 : if (gfc_match_eos () == MATCH_YES)
3852 20460 : goto checks;
3853 :
3854 : /* Look for a blank between STOP and the stop-code for F2008 or later.
3855 : But allow for F2018's ,QUIET= specifier. */
3856 198015 : c = gfc_peek_ascii_char ();
3857 :
3858 198015 : 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 193608 : gfc_gobble_whitespace ();
3875 193608 : c = gfc_peek_ascii_char ();
3876 : }
3877 198012 : if (c != ',')
3878 : {
3879 198008 : int stopcode;
3880 198008 : locus old_locus;
3881 :
3882 : /* First look for the F95 or F2003 digit [...] construct. */
3883 198008 : old_locus = gfc_current_locus;
3884 198008 : m = gfc_match_small_int (&stopcode);
3885 198008 : 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 198004 : gfc_current_locus = old_locus;
3902 198004 : m = gfc_match_expr (&e);
3903 198004 : if (m == MATCH_ERROR)
3904 0 : goto cleanup;
3905 198004 : if (m == MATCH_NO)
3906 0 : goto syntax;
3907 : }
3908 :
3909 198008 : 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 198008 : if (gfc_match_eos () != MATCH_YES)
3917 1 : goto syntax;
3918 :
3919 198007 : checks:
3920 :
3921 218467 : 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 218466 : gfc_unset_implicit_pure (NULL);
3938 :
3939 218466 : 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 218465 : 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 218464 : if (e != NULL)
3951 : {
3952 198001 : if (!gfc_simplify_expr (e, 0))
3953 1 : goto cleanup;
3954 :
3955 : /* Test for F95 and F2003 style STOP stop-code. */
3956 198000 : 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 : /* Use the machinery for an initialization expression to reduce the
3964 : stop-code to a constant. */
3965 198000 : gfc_reduce_init_expr (e);
3966 :
3967 : /* Test for F2008 style STOP stop-code. */
3968 198000 : if (e->expr_type != EXPR_CONSTANT && f08)
3969 : {
3970 1 : gfc_error ("STOP code at %L must be a scalar default CHARACTER or "
3971 : "INTEGER constant expression", &e->where);
3972 1 : goto cleanup;
3973 : }
3974 :
3975 197999 : if (!(e->ts.type == BT_CHARACTER || e->ts.type == BT_INTEGER))
3976 : {
3977 2 : gfc_error ("STOP code at %L must be either INTEGER or CHARACTER type",
3978 : &e->where);
3979 2 : goto cleanup;
3980 : }
3981 :
3982 197997 : if (e->rank != 0)
3983 : {
3984 1 : gfc_error ("STOP code at %L must be scalar", &e->where);
3985 1 : goto cleanup;
3986 : }
3987 :
3988 197996 : if (e->ts.type == BT_CHARACTER
3989 476 : && e->ts.kind != gfc_default_character_kind)
3990 : {
3991 0 : gfc_error ("STOP code at %L must be default character KIND=%d",
3992 : &e->where, (int) gfc_default_character_kind);
3993 0 : goto cleanup;
3994 : }
3995 :
3996 197520 : if (e->ts.type == BT_INTEGER && e->ts.kind != gfc_default_integer_kind
3997 198004 : && !gfc_notify_std (GFC_STD_F2018,
3998 : "STOP code at %L must be default integer KIND=%d",
3999 : &e->where, (int) gfc_default_integer_kind))
4000 0 : goto cleanup;
4001 : }
4002 :
4003 218459 : if (quiet != NULL)
4004 : {
4005 38 : if (!gfc_simplify_expr (quiet, 0))
4006 0 : goto cleanup;
4007 :
4008 38 : if (quiet->rank != 0)
4009 : {
4010 1 : gfc_error ("QUIET specifier at %L must be a scalar LOGICAL",
4011 : &quiet->where);
4012 1 : goto cleanup;
4013 : }
4014 : }
4015 :
4016 218421 : done:
4017 :
4018 218458 : switch (st)
4019 : {
4020 179312 : case ST_STOP:
4021 179312 : new_st.op = EXEC_STOP;
4022 179312 : break;
4023 39118 : case ST_ERROR_STOP:
4024 39118 : new_st.op = EXEC_ERROR_STOP;
4025 39118 : break;
4026 28 : case ST_PAUSE:
4027 28 : new_st.op = EXEC_PAUSE;
4028 28 : break;
4029 0 : default:
4030 0 : gcc_unreachable ();
4031 : }
4032 :
4033 218458 : new_st.expr1 = e;
4034 218458 : new_st.expr2 = quiet;
4035 218458 : new_st.ext.stop_code = -1;
4036 :
4037 218458 : return MATCH_YES;
4038 :
4039 1 : syntax:
4040 1 : gfc_syntax_error (st);
4041 :
4042 10 : cleanup:
4043 :
4044 10 : gfc_free_expr (e);
4045 10 : gfc_free_expr (quiet);
4046 10 : return MATCH_ERROR;
4047 : }
4048 :
4049 :
4050 : /* Match the (deprecated) PAUSE statement. */
4051 :
4052 : match
4053 28 : gfc_match_pause (void)
4054 : {
4055 28 : match m;
4056 :
4057 28 : m = gfc_match_stopcode (ST_PAUSE);
4058 28 : if (m == MATCH_YES)
4059 : {
4060 28 : if (!gfc_notify_std (GFC_STD_F95_DEL, "PAUSE statement at %C"))
4061 0 : m = MATCH_ERROR;
4062 : }
4063 28 : return m;
4064 : }
4065 :
4066 :
4067 : /* Match the STOP statement. */
4068 :
4069 : match
4070 179328 : gfc_match_stop (void)
4071 : {
4072 179328 : return gfc_match_stopcode (ST_STOP);
4073 : }
4074 :
4075 :
4076 : /* Match the ERROR STOP statement. */
4077 :
4078 : match
4079 39120 : gfc_match_error_stop (void)
4080 : {
4081 39120 : if (!gfc_notify_std (GFC_STD_F2008, "ERROR STOP statement at %C"))
4082 : return MATCH_ERROR;
4083 :
4084 39119 : return gfc_match_stopcode (ST_ERROR_STOP);
4085 : }
4086 :
4087 : /* Match EVENT POST/WAIT statement. Syntax:
4088 : EVENT POST ( event-variable [, sync-stat-list] )
4089 : EVENT WAIT ( event-variable [, wait-spec-list] )
4090 : with
4091 : wait-spec-list is sync-stat-list or until-spec
4092 : until-spec is UNTIL_COUNT = scalar-int-expr
4093 : sync-stat is STAT= or ERRMSG=. */
4094 :
4095 : static match
4096 59 : event_statement (gfc_statement st)
4097 : {
4098 59 : match m;
4099 59 : gfc_expr *tmp, *eventvar, *until_count, *stat, *errmsg;
4100 59 : bool saw_until_count, saw_stat, saw_errmsg;
4101 :
4102 59 : tmp = eventvar = until_count = stat = errmsg = NULL;
4103 59 : saw_until_count = saw_stat = saw_errmsg = false;
4104 :
4105 59 : if (gfc_pure (NULL))
4106 : {
4107 0 : gfc_error ("Image control statement EVENT %s at %C in PURE procedure",
4108 : st == ST_EVENT_POST ? "POST" : "WAIT");
4109 0 : return MATCH_ERROR;
4110 : }
4111 :
4112 59 : gfc_unset_implicit_pure (NULL);
4113 :
4114 59 : if (flag_coarray == GFC_FCOARRAY_NONE)
4115 : {
4116 0 : gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
4117 : return MATCH_ERROR;
4118 : }
4119 :
4120 59 : if (gfc_find_state (COMP_CRITICAL))
4121 : {
4122 0 : gfc_error ("Image control statement EVENT %s at %C in CRITICAL block",
4123 : st == ST_EVENT_POST ? "POST" : "WAIT");
4124 0 : return MATCH_ERROR;
4125 : }
4126 :
4127 59 : if (gfc_find_state (COMP_DO_CONCURRENT))
4128 : {
4129 0 : gfc_error ("Image control statement EVENT %s at %C in DO CONCURRENT "
4130 : "block", st == ST_EVENT_POST ? "POST" : "WAIT");
4131 0 : return MATCH_ERROR;
4132 : }
4133 :
4134 59 : if (gfc_match_char ('(') != MATCH_YES)
4135 0 : goto syntax;
4136 :
4137 59 : if (gfc_match ("%e", &eventvar) != MATCH_YES)
4138 1 : goto syntax;
4139 58 : m = gfc_match_char (',');
4140 58 : if (m == MATCH_ERROR)
4141 0 : goto syntax;
4142 58 : if (m == MATCH_NO)
4143 : {
4144 34 : m = gfc_match_char (')');
4145 34 : if (m == MATCH_YES)
4146 34 : goto done;
4147 0 : goto syntax;
4148 : }
4149 :
4150 30 : for (;;)
4151 : {
4152 30 : m = gfc_match (" stat = %v", &tmp);
4153 30 : if (m == MATCH_ERROR)
4154 0 : goto syntax;
4155 30 : if (m == MATCH_YES)
4156 : {
4157 12 : if (saw_stat)
4158 : {
4159 0 : gfc_error ("Redundant STAT tag found at %L", &tmp->where);
4160 0 : goto cleanup;
4161 : }
4162 12 : stat = tmp;
4163 12 : saw_stat = true;
4164 :
4165 12 : m = gfc_match_char (',');
4166 12 : if (m == MATCH_YES)
4167 6 : continue;
4168 :
4169 6 : tmp = NULL;
4170 6 : break;
4171 : }
4172 :
4173 18 : m = gfc_match (" errmsg = %v", &tmp);
4174 18 : if (m == MATCH_ERROR)
4175 0 : goto syntax;
4176 18 : if (m == MATCH_YES)
4177 : {
4178 0 : if (saw_errmsg)
4179 : {
4180 0 : gfc_error ("Redundant ERRMSG tag found at %L", &tmp->where);
4181 0 : goto cleanup;
4182 : }
4183 0 : errmsg = tmp;
4184 0 : saw_errmsg = true;
4185 :
4186 0 : m = gfc_match_char (',');
4187 0 : if (m == MATCH_YES)
4188 0 : continue;
4189 :
4190 0 : tmp = NULL;
4191 0 : break;
4192 : }
4193 :
4194 18 : m = gfc_match (" until_count = %e", &tmp);
4195 18 : if (m == MATCH_ERROR || st == ST_EVENT_POST)
4196 0 : goto syntax;
4197 18 : if (m == MATCH_YES)
4198 : {
4199 18 : if (saw_until_count)
4200 : {
4201 0 : gfc_error ("Redundant UNTIL_COUNT tag found at %L",
4202 0 : &tmp->where);
4203 0 : goto cleanup;
4204 : }
4205 18 : until_count = tmp;
4206 18 : saw_until_count = true;
4207 :
4208 18 : m = gfc_match_char (',');
4209 18 : if (m == MATCH_YES)
4210 0 : continue;
4211 :
4212 18 : tmp = NULL;
4213 18 : break;
4214 : }
4215 :
4216 : break;
4217 : }
4218 :
4219 24 : if (m == MATCH_ERROR)
4220 0 : goto syntax;
4221 :
4222 24 : if (gfc_match (" )%t") != MATCH_YES)
4223 0 : goto syntax;
4224 :
4225 24 : done:
4226 58 : switch (st)
4227 : {
4228 34 : case ST_EVENT_POST:
4229 34 : new_st.op = EXEC_EVENT_POST;
4230 34 : break;
4231 24 : case ST_EVENT_WAIT:
4232 24 : new_st.op = EXEC_EVENT_WAIT;
4233 24 : break;
4234 0 : default:
4235 0 : gcc_unreachable ();
4236 : }
4237 :
4238 58 : new_st.expr1 = eventvar;
4239 58 : new_st.expr2 = stat;
4240 58 : new_st.expr3 = errmsg;
4241 58 : new_st.expr4 = until_count;
4242 :
4243 58 : return MATCH_YES;
4244 :
4245 1 : syntax:
4246 1 : gfc_syntax_error (st);
4247 :
4248 1 : cleanup:
4249 1 : if (until_count != tmp)
4250 0 : gfc_free_expr (until_count);
4251 1 : if (errmsg != tmp)
4252 0 : gfc_free_expr (errmsg);
4253 1 : if (stat != tmp)
4254 0 : gfc_free_expr (stat);
4255 :
4256 1 : gfc_free_expr (tmp);
4257 1 : gfc_free_expr (eventvar);
4258 :
4259 1 : return MATCH_ERROR;
4260 :
4261 : }
4262 :
4263 :
4264 : match
4265 35 : gfc_match_event_post (void)
4266 : {
4267 35 : if (!gfc_notify_std (GFC_STD_F2018, "EVENT POST statement at %C"))
4268 : return MATCH_ERROR;
4269 :
4270 35 : return event_statement (ST_EVENT_POST);
4271 : }
4272 :
4273 :
4274 : match
4275 24 : gfc_match_event_wait (void)
4276 : {
4277 24 : if (!gfc_notify_std (GFC_STD_F2018, "EVENT WAIT statement at %C"))
4278 : return MATCH_ERROR;
4279 :
4280 24 : return event_statement (ST_EVENT_WAIT);
4281 : }
4282 :
4283 :
4284 : /* Match a FAIL IMAGE statement. */
4285 :
4286 : match
4287 16 : gfc_match_fail_image (void)
4288 : {
4289 16 : if (!gfc_notify_std (GFC_STD_F2018, "FAIL IMAGE statement at %C"))
4290 : return MATCH_ERROR;
4291 :
4292 16 : if (gfc_match_char ('(') == MATCH_YES)
4293 3 : goto syntax;
4294 :
4295 13 : new_st.op = EXEC_FAIL_IMAGE;
4296 :
4297 13 : return MATCH_YES;
4298 :
4299 3 : syntax:
4300 3 : gfc_syntax_error (ST_FAIL_IMAGE);
4301 :
4302 3 : return MATCH_ERROR;
4303 : }
4304 :
4305 : /* Match a FORM TEAM statement. */
4306 :
4307 : match
4308 138 : gfc_match_form_team (void)
4309 : {
4310 138 : match m;
4311 138 : gfc_expr *teamid, *team, *new_index;
4312 :
4313 138 : teamid = team = new_index = NULL;
4314 :
4315 138 : if (!gfc_notify_std (GFC_STD_F2018, "FORM TEAM statement at %C"))
4316 : return MATCH_ERROR;
4317 :
4318 138 : if (gfc_match_char ('(') == MATCH_NO)
4319 1 : goto syntax;
4320 :
4321 137 : new_st.op = EXEC_FORM_TEAM;
4322 :
4323 137 : if (gfc_match ("%e", &teamid) != MATCH_YES)
4324 0 : goto syntax;
4325 137 : m = gfc_match_char (',');
4326 137 : if (m == MATCH_ERROR)
4327 0 : goto syntax;
4328 137 : if (gfc_match ("%e", &team) != MATCH_YES)
4329 1 : goto syntax;
4330 :
4331 136 : m = gfc_match_char (',');
4332 136 : if (m == MATCH_ERROR)
4333 0 : goto syntax;
4334 136 : if (m == MATCH_NO)
4335 : {
4336 86 : m = gfc_match_char (')');
4337 86 : if (m == MATCH_YES)
4338 86 : goto done;
4339 0 : goto syntax;
4340 : }
4341 :
4342 116 : for (;;)
4343 : {
4344 83 : m = match_stat_errmsg (&new_st.ext.sync_stat, ST_FORM_TEAM);
4345 83 : if (m == MATCH_ERROR)
4346 2 : goto cleanup;
4347 :
4348 81 : m = match_named_arg (" new_index = %e", "NEW_INDEX", &new_index,
4349 : ST_FORM_TEAM);
4350 81 : if (m == MATCH_ERROR)
4351 3 : goto cleanup;
4352 :
4353 78 : m = gfc_match_char (',');
4354 78 : if (m == MATCH_YES)
4355 33 : continue;
4356 :
4357 45 : break;
4358 : }
4359 :
4360 45 : if (m == MATCH_ERROR)
4361 0 : goto syntax;
4362 :
4363 45 : if (gfc_match (" )%t") != MATCH_YES)
4364 1 : goto syntax;
4365 :
4366 44 : done:
4367 :
4368 130 : new_st.expr1 = teamid;
4369 130 : new_st.expr2 = team;
4370 130 : new_st.expr3 = new_index;
4371 :
4372 130 : return MATCH_YES;
4373 :
4374 3 : syntax:
4375 3 : gfc_syntax_error (ST_FORM_TEAM);
4376 :
4377 8 : cleanup:
4378 8 : gfc_free_expr (new_index);
4379 8 : gfc_free_expr (new_st.ext.sync_stat.stat);
4380 8 : gfc_free_expr (new_st.ext.sync_stat.errmsg);
4381 8 : new_st.ext.sync_stat = {NULL, NULL};
4382 :
4383 8 : gfc_free_expr (team);
4384 8 : gfc_free_expr (teamid);
4385 :
4386 8 : return MATCH_ERROR;
4387 : }
4388 :
4389 : /* Match a CHANGE TEAM statement. */
4390 :
4391 : match
4392 491484 : gfc_match_change_team (void)
4393 : {
4394 491484 : match m;
4395 491484 : gfc_expr *team = NULL;
4396 :
4397 491484 : if (gfc_match_label () == MATCH_ERROR)
4398 : return MATCH_ERROR;
4399 :
4400 491476 : if (gfc_match (" change% team") != MATCH_YES)
4401 : return MATCH_NO;
4402 :
4403 82 : if (!gfc_notify_std (GFC_STD_F2018, "CHANGE TEAM statement at %C"))
4404 : return MATCH_ERROR;
4405 :
4406 82 : if (gfc_match_char ('(') == MATCH_NO)
4407 1 : goto syntax;
4408 :
4409 81 : if (gfc_match ("%e", &team) != MATCH_YES)
4410 0 : goto syntax;
4411 :
4412 81 : m = gfc_match_char (',');
4413 81 : if (m == MATCH_ERROR)
4414 0 : goto syntax;
4415 81 : if (m == MATCH_NO)
4416 : {
4417 56 : m = gfc_match_char (')');
4418 56 : if (m == MATCH_YES)
4419 56 : goto done;
4420 0 : goto syntax;
4421 : }
4422 :
4423 25 : m = match_association_list (true);
4424 25 : if (m == MATCH_ERROR)
4425 6 : goto cleanup;
4426 19 : else if (m == MATCH_NO)
4427 36 : for (;;)
4428 : {
4429 26 : m = match_stat_errmsg (&new_st.ext.block.sync_stat, ST_CHANGE_TEAM);
4430 26 : if (m == MATCH_ERROR)
4431 2 : goto cleanup;
4432 :
4433 24 : if (gfc_match_char (',') == MATCH_YES)
4434 10 : continue;
4435 :
4436 : break;
4437 : }
4438 :
4439 17 : if (gfc_match (" )%t") != MATCH_YES)
4440 0 : goto syntax;
4441 :
4442 17 : done:
4443 :
4444 73 : new_st.expr1 = team;
4445 :
4446 73 : return MATCH_YES;
4447 :
4448 1 : syntax:
4449 1 : gfc_syntax_error (ST_CHANGE_TEAM);
4450 :
4451 9 : cleanup:
4452 9 : gfc_free_expr (new_st.ext.block.sync_stat.stat);
4453 9 : gfc_free_expr (new_st.ext.block.sync_stat.errmsg);
4454 9 : new_st.ext.block.sync_stat = {NULL, NULL};
4455 9 : gfc_free_association_list (new_st.ext.block.assoc);
4456 9 : new_st.ext.block.assoc = NULL;
4457 9 : gfc_free_expr (team);
4458 :
4459 9 : return MATCH_ERROR;
4460 : }
4461 :
4462 : /* Match an END TEAM statement. */
4463 :
4464 : match
4465 74 : gfc_match_end_team (void)
4466 : {
4467 74 : if (gfc_match_eos () == MATCH_YES)
4468 55 : goto done;
4469 :
4470 19 : if (gfc_match_char ('(') != MATCH_YES)
4471 : {
4472 : /* There could be a team-construct-name following. Let caller decide
4473 : about error. */
4474 2 : new_st.op = EXEC_END_TEAM;
4475 2 : return MATCH_NO;
4476 : }
4477 :
4478 37 : for (;;)
4479 : {
4480 27 : if (match_stat_errmsg (&new_st.ext.sync_stat, ST_END_TEAM) == MATCH_ERROR)
4481 2 : goto cleanup;
4482 :
4483 25 : if (gfc_match_char (',') == MATCH_YES)
4484 10 : continue;
4485 :
4486 15 : break;
4487 : }
4488 :
4489 15 : if (gfc_match_char (')') != MATCH_YES)
4490 0 : goto syntax;
4491 :
4492 15 : done:
4493 :
4494 70 : new_st.op = EXEC_END_TEAM;
4495 :
4496 70 : return MATCH_YES;
4497 :
4498 0 : syntax:
4499 0 : gfc_syntax_error (ST_END_TEAM);
4500 :
4501 2 : cleanup:
4502 2 : gfc_free_expr (new_st.ext.sync_stat.stat);
4503 2 : gfc_free_expr (new_st.ext.sync_stat.errmsg);
4504 2 : new_st.ext.sync_stat = {NULL, NULL};
4505 :
4506 : /* Try to match the closing bracket to allow error recovery. */
4507 2 : gfc_match_char (')');
4508 :
4509 2 : return MATCH_ERROR;
4510 : }
4511 :
4512 : /* Match a SYNC TEAM statement. */
4513 :
4514 : match
4515 47 : gfc_match_sync_team (void)
4516 : {
4517 47 : match m;
4518 47 : gfc_expr *team = NULL;
4519 :
4520 47 : if (!gfc_notify_std (GFC_STD_F2018, "SYNC TEAM statement at %C"))
4521 : return MATCH_ERROR;
4522 :
4523 47 : if (gfc_match_char ('(') == MATCH_NO)
4524 1 : goto syntax;
4525 :
4526 46 : new_st.op = EXEC_SYNC_TEAM;
4527 :
4528 46 : if (gfc_match ("%e", &team) != MATCH_YES)
4529 0 : goto syntax;
4530 :
4531 46 : m = gfc_match_char (',');
4532 46 : if (m == MATCH_ERROR)
4533 0 : goto syntax;
4534 46 : if (m == MATCH_NO)
4535 : {
4536 29 : m = gfc_match_char (')');
4537 29 : if (m == MATCH_YES)
4538 29 : goto done;
4539 0 : goto syntax;
4540 : }
4541 :
4542 37 : for (;;)
4543 : {
4544 27 : m = match_stat_errmsg (&new_st.ext.sync_stat, ST_SYNC_TEAM);
4545 27 : if (m == MATCH_ERROR)
4546 2 : goto cleanup;
4547 :
4548 25 : if (gfc_match_char (',') == MATCH_YES)
4549 10 : continue;
4550 :
4551 15 : break;
4552 : }
4553 :
4554 15 : if (gfc_match (" )%t") != MATCH_YES)
4555 1 : goto syntax;
4556 :
4557 14 : done:
4558 :
4559 43 : new_st.expr1 = team;
4560 :
4561 43 : return MATCH_YES;
4562 :
4563 2 : syntax:
4564 2 : gfc_syntax_error (ST_SYNC_TEAM);
4565 :
4566 4 : cleanup:
4567 4 : gfc_free_expr (new_st.ext.sync_stat.stat);
4568 4 : gfc_free_expr (new_st.ext.sync_stat.errmsg);
4569 4 : new_st.ext.sync_stat = {NULL, NULL};
4570 :
4571 4 : gfc_free_expr (team);
4572 :
4573 4 : return MATCH_ERROR;
4574 : }
4575 :
4576 : /* Match LOCK/UNLOCK statement. Syntax:
4577 : LOCK ( lock-variable [ , lock-stat-list ] )
4578 : UNLOCK ( lock-variable [ , sync-stat-list ] )
4579 : where lock-stat is ACQUIRED_LOCK or sync-stat
4580 : and sync-stat is STAT= or ERRMSG=. */
4581 :
4582 : static match
4583 144 : lock_unlock_statement (gfc_statement st)
4584 : {
4585 144 : match m;
4586 144 : gfc_expr *tmp, *lockvar, *acq_lock, *stat, *errmsg;
4587 144 : bool saw_acq_lock, saw_stat, saw_errmsg;
4588 :
4589 144 : tmp = lockvar = acq_lock = stat = errmsg = NULL;
4590 144 : saw_acq_lock = saw_stat = saw_errmsg = false;
4591 :
4592 144 : if (gfc_pure (NULL))
4593 : {
4594 0 : gfc_error ("Image control statement %s at %C in PURE procedure",
4595 : st == ST_LOCK ? "LOCK" : "UNLOCK");
4596 0 : return MATCH_ERROR;
4597 : }
4598 :
4599 144 : gfc_unset_implicit_pure (NULL);
4600 :
4601 144 : if (flag_coarray == GFC_FCOARRAY_NONE)
4602 : {
4603 0 : gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
4604 : return MATCH_ERROR;
4605 : }
4606 :
4607 144 : if (gfc_find_state (COMP_CRITICAL))
4608 : {
4609 2 : gfc_error ("Image control statement %s at %C in CRITICAL block",
4610 : st == ST_LOCK ? "LOCK" : "UNLOCK");
4611 2 : return MATCH_ERROR;
4612 : }
4613 :
4614 142 : if (gfc_find_state (COMP_DO_CONCURRENT))
4615 : {
4616 2 : gfc_error ("Image control statement %s at %C in DO CONCURRENT block",
4617 : st == ST_LOCK ? "LOCK" : "UNLOCK");
4618 2 : return MATCH_ERROR;
4619 : }
4620 :
4621 140 : if (gfc_match_char ('(') != MATCH_YES)
4622 0 : goto syntax;
4623 :
4624 140 : if (gfc_match ("%e", &lockvar) != MATCH_YES)
4625 1 : goto syntax;
4626 139 : m = gfc_match_char (',');
4627 139 : if (m == MATCH_ERROR)
4628 0 : goto syntax;
4629 139 : if (m == MATCH_NO)
4630 : {
4631 77 : m = gfc_match_char (')');
4632 77 : if (m == MATCH_YES)
4633 77 : goto done;
4634 0 : goto syntax;
4635 : }
4636 :
4637 66 : for (;;)
4638 : {
4639 66 : m = gfc_match (" stat = %v", &tmp);
4640 66 : if (m == MATCH_ERROR)
4641 0 : goto syntax;
4642 66 : if (m == MATCH_YES)
4643 : {
4644 42 : if (saw_stat)
4645 : {
4646 0 : gfc_error ("Redundant STAT tag found at %L", &tmp->where);
4647 0 : goto cleanup;
4648 : }
4649 42 : stat = tmp;
4650 42 : saw_stat = true;
4651 :
4652 42 : m = gfc_match_char (',');
4653 42 : if (m == MATCH_YES)
4654 2 : continue;
4655 :
4656 40 : tmp = NULL;
4657 40 : break;
4658 : }
4659 :
4660 24 : m = gfc_match (" errmsg = %v", &tmp);
4661 24 : if (m == MATCH_ERROR)
4662 0 : goto syntax;
4663 24 : if (m == MATCH_YES)
4664 : {
4665 2 : if (saw_errmsg)
4666 : {
4667 0 : gfc_error ("Redundant ERRMSG tag found at %L", &tmp->where);
4668 0 : goto cleanup;
4669 : }
4670 2 : errmsg = tmp;
4671 2 : saw_errmsg = true;
4672 :
4673 2 : m = gfc_match_char (',');
4674 2 : if (m == MATCH_YES)
4675 0 : continue;
4676 :
4677 2 : tmp = NULL;
4678 2 : break;
4679 : }
4680 :
4681 22 : m = gfc_match (" acquired_lock = %v", &tmp);
4682 22 : if (m == MATCH_ERROR || st == ST_UNLOCK)
4683 0 : goto syntax;
4684 22 : if (m == MATCH_YES)
4685 : {
4686 22 : if (saw_acq_lock)
4687 : {
4688 0 : gfc_error ("Redundant ACQUIRED_LOCK tag found at %L",
4689 0 : &tmp->where);
4690 0 : goto cleanup;
4691 : }
4692 22 : acq_lock = tmp;
4693 22 : saw_acq_lock = true;
4694 :
4695 22 : m = gfc_match_char (',');
4696 22 : if (m == MATCH_YES)
4697 2 : continue;
4698 :
4699 20 : tmp = NULL;
4700 20 : break;
4701 : }
4702 :
4703 : break;
4704 : }
4705 :
4706 62 : if (m == MATCH_ERROR)
4707 0 : goto syntax;
4708 :
4709 62 : if (gfc_match (" )%t") != MATCH_YES)
4710 0 : goto syntax;
4711 :
4712 62 : done:
4713 139 : switch (st)
4714 : {
4715 74 : case ST_LOCK:
4716 74 : new_st.op = EXEC_LOCK;
4717 74 : break;
4718 65 : case ST_UNLOCK:
4719 65 : new_st.op = EXEC_UNLOCK;
4720 65 : break;
4721 0 : default:
4722 0 : gcc_unreachable ();
4723 : }
4724 :
4725 139 : new_st.expr1 = lockvar;
4726 139 : new_st.expr2 = stat;
4727 139 : new_st.expr3 = errmsg;
4728 139 : new_st.expr4 = acq_lock;
4729 :
4730 139 : return MATCH_YES;
4731 :
4732 1 : syntax:
4733 1 : gfc_syntax_error (st);
4734 :
4735 1 : cleanup:
4736 1 : if (acq_lock != tmp)
4737 0 : gfc_free_expr (acq_lock);
4738 1 : if (errmsg != tmp)
4739 0 : gfc_free_expr (errmsg);
4740 1 : if (stat != tmp)
4741 0 : gfc_free_expr (stat);
4742 :
4743 1 : gfc_free_expr (tmp);
4744 1 : gfc_free_expr (lockvar);
4745 :
4746 1 : return MATCH_ERROR;
4747 : }
4748 :
4749 :
4750 : match
4751 78 : gfc_match_lock (void)
4752 : {
4753 78 : if (!gfc_notify_std (GFC_STD_F2008, "LOCK statement at %C"))
4754 : return MATCH_ERROR;
4755 :
4756 77 : return lock_unlock_statement (ST_LOCK);
4757 : }
4758 :
4759 :
4760 : match
4761 68 : gfc_match_unlock (void)
4762 : {
4763 68 : if (!gfc_notify_std (GFC_STD_F2008, "UNLOCK statement at %C"))
4764 : return MATCH_ERROR;
4765 :
4766 67 : return lock_unlock_statement (ST_UNLOCK);
4767 : }
4768 :
4769 :
4770 : /* Match SYNC ALL/IMAGES/MEMORY statement. Syntax:
4771 : SYNC ALL [(sync-stat-list)]
4772 : SYNC MEMORY [(sync-stat-list)]
4773 : SYNC IMAGES (image-set [, sync-stat-list] )
4774 : with sync-stat is int-expr or *. */
4775 :
4776 : static match
4777 1324 : sync_statement (gfc_statement st)
4778 : {
4779 1324 : match m;
4780 1324 : gfc_expr *tmp, *imageset, *stat, *errmsg;
4781 1324 : bool saw_stat, saw_errmsg;
4782 :
4783 1324 : tmp = imageset = stat = errmsg = NULL;
4784 1324 : saw_stat = saw_errmsg = false;
4785 :
4786 1324 : if (gfc_pure (NULL))
4787 : {
4788 1 : gfc_error ("Image control statement SYNC at %C in PURE procedure");
4789 1 : return MATCH_ERROR;
4790 : }
4791 :
4792 1323 : gfc_unset_implicit_pure (NULL);
4793 :
4794 1323 : if (!gfc_notify_std (GFC_STD_F2008, "SYNC statement at %C"))
4795 : return MATCH_ERROR;
4796 :
4797 1320 : if (flag_coarray == GFC_FCOARRAY_NONE)
4798 : {
4799 0 : gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to "
4800 : "enable");
4801 : return MATCH_ERROR;
4802 : }
4803 :
4804 1320 : if (gfc_find_state (COMP_CRITICAL))
4805 : {
4806 1 : gfc_error ("Image control statement SYNC at %C in CRITICAL block");
4807 1 : return MATCH_ERROR;
4808 : }
4809 :
4810 1319 : if (gfc_find_state (COMP_DO_CONCURRENT))
4811 : {
4812 1 : gfc_error ("Image control statement SYNC at %C in DO CONCURRENT block");
4813 1 : return MATCH_ERROR;
4814 : }
4815 :
4816 1318 : if (gfc_match_eos () == MATCH_YES)
4817 : {
4818 1084 : if (st == ST_SYNC_IMAGES)
4819 0 : goto syntax;
4820 1084 : goto done;
4821 : }
4822 :
4823 234 : if (gfc_match_char ('(') != MATCH_YES)
4824 0 : goto syntax;
4825 :
4826 234 : if (st == ST_SYNC_IMAGES)
4827 : {
4828 : /* Denote '*' as imageset == NULL. */
4829 107 : m = gfc_match_char ('*');
4830 107 : if (m == MATCH_ERROR)
4831 0 : goto syntax;
4832 107 : if (m == MATCH_NO)
4833 : {
4834 71 : if (gfc_match ("%e", &imageset) != MATCH_YES)
4835 0 : goto syntax;
4836 : }
4837 107 : m = gfc_match_char (',');
4838 107 : if (m == MATCH_ERROR)
4839 0 : goto syntax;
4840 107 : if (m == MATCH_NO)
4841 : {
4842 53 : m = gfc_match_char (')');
4843 53 : if (m == MATCH_YES)
4844 53 : goto done;
4845 0 : goto syntax;
4846 : }
4847 : }
4848 :
4849 224 : for (;;)
4850 : {
4851 224 : m = gfc_match (" stat = %e", &tmp);
4852 224 : if (m == MATCH_ERROR)
4853 0 : goto syntax;
4854 224 : if (m == MATCH_YES)
4855 : {
4856 110 : if (saw_stat)
4857 : {
4858 1 : gfc_error ("Redundant STAT tag found at %L", &tmp->where);
4859 1 : goto cleanup;
4860 : }
4861 109 : stat = tmp;
4862 109 : saw_stat = true;
4863 :
4864 109 : if (gfc_match_char (',') == MATCH_YES)
4865 15 : continue;
4866 :
4867 94 : tmp = NULL;
4868 94 : break;
4869 : }
4870 :
4871 114 : m = gfc_match (" errmsg = %e", &tmp);
4872 114 : if (m == MATCH_ERROR)
4873 0 : goto syntax;
4874 114 : if (m == MATCH_YES)
4875 : {
4876 90 : if (saw_errmsg)
4877 : {
4878 0 : gfc_error ("Redundant ERRMSG tag found at %L", &tmp->where);
4879 0 : goto cleanup;
4880 : }
4881 90 : errmsg = tmp;
4882 90 : saw_errmsg = true;
4883 :
4884 90 : if (gfc_match_char (',') == MATCH_YES)
4885 28 : continue;
4886 :
4887 62 : tmp = NULL;
4888 62 : break;
4889 : }
4890 :
4891 : break;
4892 : }
4893 :
4894 180 : if (gfc_match (" )%t") != MATCH_YES)
4895 0 : goto syntax;
4896 :
4897 180 : done:
4898 1317 : switch (st)
4899 : {
4900 1136 : case ST_SYNC_ALL:
4901 1136 : new_st.op = EXEC_SYNC_ALL;
4902 1136 : break;
4903 107 : case ST_SYNC_IMAGES:
4904 107 : new_st.op = EXEC_SYNC_IMAGES;
4905 107 : break;
4906 74 : case ST_SYNC_MEMORY:
4907 74 : new_st.op = EXEC_SYNC_MEMORY;
4908 74 : break;
4909 0 : default:
4910 0 : gcc_unreachable ();
4911 : }
4912 :
4913 1317 : new_st.expr1 = imageset;
4914 1317 : new_st.expr2 = stat;
4915 1317 : new_st.expr3 = errmsg;
4916 :
4917 1317 : return MATCH_YES;
4918 :
4919 0 : syntax:
4920 0 : gfc_syntax_error (st);
4921 :
4922 1 : cleanup:
4923 1 : if (stat != tmp)
4924 1 : gfc_free_expr (stat);
4925 1 : if (errmsg != tmp)
4926 1 : gfc_free_expr (errmsg);
4927 :
4928 1 : gfc_free_expr (tmp);
4929 1 : gfc_free_expr (imageset);
4930 :
4931 1 : return MATCH_ERROR;
4932 : }
4933 :
4934 :
4935 : /* Match SYNC ALL statement. */
4936 :
4937 : match
4938 1141 : gfc_match_sync_all (void)
4939 : {
4940 1141 : return sync_statement (ST_SYNC_ALL);
4941 : }
4942 :
4943 :
4944 : /* Match SYNC IMAGES statement. */
4945 :
4946 : match
4947 108 : gfc_match_sync_images (void)
4948 : {
4949 108 : return sync_statement (ST_SYNC_IMAGES);
4950 : }
4951 :
4952 :
4953 : /* Match SYNC MEMORY statement. */
4954 :
4955 : match
4956 75 : gfc_match_sync_memory (void)
4957 : {
4958 75 : return sync_statement (ST_SYNC_MEMORY);
4959 : }
4960 :
4961 :
4962 : /* Match a CONTINUE statement. */
4963 :
4964 : match
4965 2817 : gfc_match_continue (void)
4966 : {
4967 2817 : if (gfc_match_eos () != MATCH_YES)
4968 : {
4969 0 : gfc_syntax_error (ST_CONTINUE);
4970 0 : return MATCH_ERROR;
4971 : }
4972 :
4973 2817 : new_st.op = EXEC_CONTINUE;
4974 2817 : return MATCH_YES;
4975 : }
4976 :
4977 :
4978 : /* Match the (deprecated) ASSIGN statement. */
4979 :
4980 : match
4981 126 : gfc_match_assign (void)
4982 : {
4983 126 : gfc_expr *expr;
4984 126 : gfc_st_label *label;
4985 :
4986 126 : if (gfc_match (" %l", &label) == MATCH_YES)
4987 : {
4988 126 : if (!gfc_reference_st_label (label, ST_LABEL_UNKNOWN))
4989 : return MATCH_ERROR;
4990 126 : if (gfc_match (" to %v%t", &expr) == MATCH_YES)
4991 : {
4992 126 : if (!gfc_notify_std (GFC_STD_F95_DEL, "ASSIGN statement at %C"))
4993 : return MATCH_ERROR;
4994 :
4995 126 : expr->symtree->n.sym->attr.assign = 1;
4996 :
4997 126 : new_st.op = EXEC_LABEL_ASSIGN;
4998 126 : new_st.label1 = label;
4999 126 : new_st.expr1 = expr;
5000 126 : return MATCH_YES;
5001 : }
5002 : }
5003 : return MATCH_NO;
5004 : }
5005 :
5006 :
5007 : /* Match the GO TO statement. As a computed GOTO statement is
5008 : matched, it is transformed into an equivalent SELECT block. No
5009 : tree is necessary, and the resulting jumps-to-jumps are
5010 : specifically optimized away by the back end. */
5011 :
5012 : match
5013 1002 : gfc_match_goto (void)
5014 : {
5015 1002 : gfc_code *head, *tail;
5016 1002 : gfc_expr *expr;
5017 1002 : gfc_case *cp;
5018 1002 : gfc_st_label *label;
5019 1002 : int i;
5020 1002 : match m;
5021 :
5022 1002 : if (gfc_match (" %l%t", &label) == MATCH_YES)
5023 : {
5024 919 : if (!gfc_reference_st_label (label, ST_LABEL_TARGET))
5025 : return MATCH_ERROR;
5026 :
5027 919 : new_st.op = EXEC_GOTO;
5028 919 : new_st.label1 = label;
5029 919 : return MATCH_YES;
5030 : }
5031 :
5032 : /* The assigned GO TO statement. */
5033 :
5034 83 : if (gfc_match_variable (&expr, 0) == MATCH_YES)
5035 : {
5036 78 : if (!gfc_notify_std (GFC_STD_F95_DEL, "Assigned GOTO statement at %C"))
5037 : return MATCH_ERROR;
5038 :
5039 78 : new_st.op = EXEC_GOTO;
5040 78 : new_st.expr1 = expr;
5041 :
5042 78 : if (gfc_match_eos () == MATCH_YES)
5043 : return MATCH_YES;
5044 :
5045 : /* Match label list. */
5046 27 : gfc_match_char (',');
5047 27 : if (gfc_match_char ('(') != MATCH_YES)
5048 : {
5049 0 : gfc_syntax_error (ST_GOTO);
5050 0 : return MATCH_ERROR;
5051 : }
5052 : head = tail = NULL;
5053 :
5054 76 : do
5055 : {
5056 76 : m = gfc_match_st_label (&label);
5057 76 : if (m != MATCH_YES)
5058 0 : goto syntax;
5059 :
5060 76 : if (!gfc_reference_st_label (label, ST_LABEL_TARGET))
5061 0 : goto cleanup;
5062 :
5063 76 : if (head == NULL)
5064 27 : head = tail = gfc_get_code (EXEC_GOTO);
5065 : else
5066 : {
5067 49 : tail->block = gfc_get_code (EXEC_GOTO);
5068 49 : tail = tail->block;
5069 : }
5070 :
5071 76 : tail->label1 = label;
5072 : }
5073 76 : while (gfc_match_char (',') == MATCH_YES);
5074 :
5075 27 : if (gfc_match (" )%t") != MATCH_YES)
5076 0 : goto syntax;
5077 :
5078 27 : if (head == NULL)
5079 : {
5080 0 : gfc_error ("Statement label list in GOTO at %C cannot be empty");
5081 0 : goto syntax;
5082 : }
5083 27 : new_st.block = head;
5084 :
5085 27 : return MATCH_YES;
5086 : }
5087 :
5088 : /* Last chance is a computed GO TO statement. */
5089 5 : if (gfc_match_char ('(') != MATCH_YES)
5090 : {
5091 0 : gfc_syntax_error (ST_GOTO);
5092 0 : return MATCH_ERROR;
5093 : }
5094 :
5095 : head = tail = NULL;
5096 : i = 1;
5097 :
5098 13 : do
5099 : {
5100 13 : m = gfc_match_st_label (&label);
5101 13 : if (m != MATCH_YES)
5102 0 : goto syntax;
5103 :
5104 13 : if (!gfc_reference_st_label (label, ST_LABEL_TARGET))
5105 0 : goto cleanup;
5106 :
5107 13 : if (head == NULL)
5108 5 : head = tail = gfc_get_code (EXEC_SELECT);
5109 : else
5110 : {
5111 8 : tail->block = gfc_get_code (EXEC_SELECT);
5112 8 : tail = tail->block;
5113 : }
5114 :
5115 13 : cp = gfc_get_case ();
5116 26 : cp->low = cp->high = gfc_get_int_expr (gfc_default_integer_kind,
5117 13 : NULL, i++);
5118 :
5119 13 : tail->ext.block.case_list = cp;
5120 :
5121 13 : tail->next = gfc_get_code (EXEC_GOTO);
5122 13 : tail->next->label1 = label;
5123 : }
5124 13 : while (gfc_match_char (',') == MATCH_YES);
5125 :
5126 5 : if (gfc_match_char (')') != MATCH_YES)
5127 0 : goto syntax;
5128 :
5129 5 : if (head == NULL)
5130 : {
5131 0 : gfc_error ("Statement label list in GOTO at %C cannot be empty");
5132 0 : goto syntax;
5133 : }
5134 :
5135 : /* Get the rest of the statement. */
5136 5 : gfc_match_char (',');
5137 :
5138 5 : if (gfc_match (" %e%t", &expr) != MATCH_YES)
5139 0 : goto syntax;
5140 :
5141 5 : if (!gfc_notify_std (GFC_STD_F95_OBS, "Computed GOTO at %C"))
5142 : return MATCH_ERROR;
5143 :
5144 : /* At this point, a computed GOTO has been fully matched and an
5145 : equivalent SELECT statement constructed. */
5146 :
5147 5 : new_st.op = EXEC_SELECT;
5148 5 : new_st.expr1 = NULL;
5149 :
5150 : /* Hack: For a "real" SELECT, the expression is in expr. We put
5151 : it in expr2 so we can distinguish then and produce the correct
5152 : diagnostics. */
5153 5 : new_st.expr2 = expr;
5154 5 : new_st.block = head;
5155 5 : return MATCH_YES;
5156 :
5157 0 : syntax:
5158 0 : gfc_syntax_error (ST_GOTO);
5159 0 : cleanup:
5160 0 : gfc_free_statements (head);
5161 0 : return MATCH_ERROR;
5162 : }
5163 :
5164 :
5165 : /* A reduced version of gfc_spec_list_type, which only looks for deferred
5166 : type spec list parameters. */
5167 :
5168 : static gfc_param_spec_type
5169 0 : spec_list_type (gfc_actual_arglist *param_list)
5170 : {
5171 580 : gfc_param_spec_type res = SPEC_EXPLICIT;
5172 :
5173 580 : for (; param_list; param_list = param_list->next)
5174 433 : if (param_list->spec_type == SPEC_DEFERRED)
5175 : {
5176 : res = param_list->spec_type;
5177 : break;
5178 : }
5179 :
5180 256 : return res;
5181 : }
5182 :
5183 :
5184 : /* Frees a list of gfc_alloc structures. */
5185 :
5186 : void
5187 23867 : gfc_free_alloc_list (gfc_alloc *p)
5188 : {
5189 23867 : gfc_alloc *q;
5190 :
5191 52968 : for (; p; p = q)
5192 : {
5193 29101 : q = p->next;
5194 29101 : gfc_free_expr (p->expr);
5195 29101 : free (p);
5196 : }
5197 23867 : }
5198 :
5199 :
5200 : /* Match an ALLOCATE statement. */
5201 :
5202 : match
5203 14492 : gfc_match_allocate (void)
5204 : {
5205 14492 : gfc_alloc *head, *tail;
5206 14492 : gfc_expr *stat, *errmsg, *tmp, *source, *mold;
5207 14492 : gfc_typespec ts;
5208 14492 : gfc_symbol *sym;
5209 14492 : gfc_ref *ref;
5210 14492 : match m;
5211 14492 : locus old_locus, deferred_locus, assumed_locus;
5212 14492 : bool saw_stat, saw_errmsg, saw_source, saw_mold, saw_deferred, b1, b2, b3;
5213 14492 : bool saw_unlimited = false, saw_assumed = false;
5214 :
5215 14492 : head = tail = NULL;
5216 14492 : stat = errmsg = source = mold = tmp = NULL;
5217 14492 : saw_stat = saw_errmsg = saw_source = saw_mold = saw_deferred = false;
5218 :
5219 14492 : if (gfc_match_char ('(') != MATCH_YES)
5220 : {
5221 1 : gfc_syntax_error (ST_ALLOCATE);
5222 1 : return MATCH_ERROR;
5223 : }
5224 :
5225 : /* Match an optional type-spec. */
5226 14491 : old_locus = gfc_current_locus;
5227 14491 : m = gfc_match_type_spec (&ts);
5228 14491 : if (m == MATCH_ERROR)
5229 7 : goto cleanup;
5230 14484 : else if (m == MATCH_NO)
5231 : {
5232 12943 : char name[GFC_MAX_SYMBOL_LEN + 3];
5233 :
5234 12943 : if (gfc_match ("%n :: ", name) == MATCH_YES)
5235 : {
5236 7 : gfc_error ("Error in type-spec at %L", &old_locus);
5237 7 : goto cleanup;
5238 : }
5239 :
5240 12936 : ts.type = BT_UNKNOWN;
5241 : }
5242 : else
5243 : {
5244 : /* Needed for the F2008:C631 check below. */
5245 1541 : assumed_locus = gfc_current_locus;
5246 :
5247 1541 : if (gfc_match (" :: ") == MATCH_YES)
5248 : {
5249 1529 : if (!gfc_notify_std (GFC_STD_F2003, "typespec in ALLOCATE at %L",
5250 : &old_locus))
5251 0 : goto cleanup;
5252 :
5253 1529 : if (ts.deferred)
5254 : {
5255 5 : gfc_error ("Type-spec at %L cannot contain a deferred "
5256 : "type parameter", &old_locus);
5257 5 : goto cleanup;
5258 : }
5259 :
5260 1524 : if (ts.type == BT_CHARACTER)
5261 : {
5262 475 : if (!ts.u.cl->length)
5263 : saw_assumed = true;
5264 : else
5265 462 : ts.u.cl->length_from_typespec = true;
5266 : }
5267 :
5268 1524 : if (type_param_spec_list
5269 1601 : && spec_list_type (type_param_spec_list) == SPEC_DEFERRED)
5270 : {
5271 0 : gfc_error ("The type parameter spec list in the type-spec at "
5272 : "%L cannot contain DEFERRED parameters", &old_locus);
5273 0 : goto cleanup;
5274 : }
5275 : }
5276 : else
5277 : {
5278 12 : ts.type = BT_UNKNOWN;
5279 12 : gfc_current_locus = old_locus;
5280 : }
5281 : }
5282 :
5283 17515 : for (;;)
5284 : {
5285 17515 : if (head == NULL)
5286 14472 : head = tail = gfc_get_alloc ();
5287 : else
5288 : {
5289 3043 : tail->next = gfc_get_alloc ();
5290 3043 : tail = tail->next;
5291 : }
5292 :
5293 17515 : m = gfc_match_variable (&tail->expr, 0);
5294 17515 : if (m == MATCH_NO)
5295 0 : goto syntax;
5296 17515 : if (m == MATCH_ERROR)
5297 11 : goto cleanup;
5298 :
5299 17504 : if (tail->expr->expr_type == EXPR_CONSTANT)
5300 : {
5301 1 : gfc_error ("Unexpected constant at %C");
5302 1 : goto cleanup;
5303 : }
5304 :
5305 17503 : if (gfc_check_do_variable (tail->expr->symtree))
5306 0 : goto cleanup;
5307 :
5308 17503 : bool impure = gfc_impure_variable (tail->expr->symtree->n.sym);
5309 17503 : if (impure && gfc_pure (NULL))
5310 : {
5311 0 : gfc_error ("Bad allocate-object at %C for a PURE procedure");
5312 0 : goto cleanup;
5313 : }
5314 :
5315 17503 : if (impure)
5316 523 : gfc_unset_implicit_pure (NULL);
5317 :
5318 : /* F2008:C631 (R626) A type-param-value in a type-spec shall be an
5319 : asterisk if and only if each allocate-object is a dummy argument
5320 : for which the corresponding type parameter is assumed. */
5321 17503 : if (saw_assumed
5322 20 : && (tail->expr->ts.deferred
5323 19 : || (tail->expr->ts.u.cl && tail->expr->ts.u.cl->length)
5324 17 : || tail->expr->symtree->n.sym->attr.dummy == 0))
5325 : {
5326 4 : gfc_error ("Incompatible allocate-object at %C for CHARACTER "
5327 : "type-spec at %L", &assumed_locus);
5328 4 : goto cleanup;
5329 : }
5330 :
5331 17499 : if (tail->expr->ts.deferred
5332 17499 : || (tail->expr->symtree->n.sym->param_list
5333 161 : && spec_list_type (tail->expr->symtree->n.sym->param_list)
5334 : == SPEC_DEFERRED))
5335 : {
5336 1216 : saw_deferred = true;
5337 1216 : deferred_locus = tail->expr->where;
5338 : }
5339 16283 : else if ((tail->expr->ts.type == BT_DERIVED
5340 13606 : || tail->expr->ts.type == BT_CLASS)
5341 6264 : && tail->expr->ref)
5342 : {
5343 9834 : for (ref = tail->expr->ref; ref; ref = ref->next)
5344 5842 : if (ref->type == REF_COMPONENT
5345 1977 : && ref->u.c.component->param_list
5346 5860 : && spec_list_type (ref->u.c.component->param_list)
5347 : == SPEC_DEFERRED)
5348 : {
5349 4 : saw_deferred = true;
5350 4 : deferred_locus = tail->expr->where;
5351 : }
5352 : }
5353 :
5354 17499 : if (gfc_find_state (COMP_DO_CONCURRENT)
5355 17499 : || gfc_find_state (COMP_CRITICAL))
5356 : {
5357 2 : gfc_ref *ref;
5358 2 : bool coarray = tail->expr->symtree->n.sym->attr.codimension;
5359 4 : for (ref = tail->expr->ref; ref; ref = ref->next)
5360 2 : if (ref->type == REF_COMPONENT)
5361 0 : coarray = ref->u.c.component->attr.codimension;
5362 :
5363 2 : if (coarray && gfc_find_state (COMP_DO_CONCURRENT))
5364 : {
5365 1 : gfc_error ("ALLOCATE of coarray at %C in DO CONCURRENT block");
5366 1 : goto cleanup;
5367 : }
5368 1 : if (coarray && gfc_find_state (COMP_CRITICAL))
5369 : {
5370 1 : gfc_error ("ALLOCATE of coarray at %C in CRITICAL block");
5371 1 : goto cleanup;
5372 : }
5373 : }
5374 :
5375 : /* Check for F08:C628. */
5376 17497 : sym = tail->expr->symtree->n.sym;
5377 17497 : b1 = !(tail->expr->ref
5378 13282 : && (tail->expr->ref->type == REF_COMPONENT
5379 : || tail->expr->ref->type == REF_ARRAY));
5380 17497 : if (sym && sym->ts.type == BT_CLASS && sym->attr.class_ok)
5381 3424 : b2 = !(CLASS_DATA (sym)->attr.allocatable
5382 805 : || CLASS_DATA (sym)->attr.class_pointer);
5383 : else
5384 14073 : b2 = sym && !(sym->attr.allocatable || sym->attr.pointer
5385 2653 : || sym->attr.proc_pointer);
5386 17497 : b3 = sym && sym->ns && sym->ns->proc_name
5387 17497 : && (sym->ns->proc_name->attr.allocatable
5388 17436 : || sym->ns->proc_name->attr.pointer
5389 17399 : || sym->ns->proc_name->attr.proc_pointer);
5390 17497 : if (b1 && b2 && !b3)
5391 : {
5392 6 : gfc_error ("Allocate-object at %L is neither a data pointer "
5393 : "nor an allocatable variable", &tail->expr->where);
5394 6 : goto cleanup;
5395 : }
5396 :
5397 : /* The ALLOCATE statement had an optional typespec. Check the
5398 : constraints. */
5399 17491 : if (ts.type != BT_UNKNOWN)
5400 : {
5401 : /* Enforce F03:C624. */
5402 1759 : if (!gfc_type_compatible (&tail->expr->ts, &ts))
5403 : {
5404 13 : gfc_error ("Type of entity at %L is type incompatible with "
5405 13 : "typespec", &tail->expr->where);
5406 13 : goto cleanup;
5407 : }
5408 :
5409 : /* Enforce F03:C627. */
5410 1746 : if (ts.kind != tail->expr->ts.kind && !UNLIMITED_POLY (tail->expr))
5411 : {
5412 8 : gfc_error ("Kind type parameter for entity at %L differs from "
5413 : "the kind type parameter of the typespec",
5414 : &tail->expr->where);
5415 8 : goto cleanup;
5416 : }
5417 : }
5418 :
5419 17470 : if (tail->expr->ts.type == BT_DERIVED)
5420 2753 : tail->expr->ts.u.derived = gfc_use_derived (tail->expr->ts.u.derived);
5421 :
5422 17470 : if (type_param_spec_list)
5423 80 : tail->expr->param_list = gfc_copy_actual_arglist (type_param_spec_list);
5424 :
5425 17470 : saw_unlimited = saw_unlimited | UNLIMITED_POLY (tail->expr);
5426 :
5427 17470 : if (gfc_peek_ascii_char () == '(' && !sym->attr.dimension)
5428 : {
5429 2 : gfc_error ("Shape specification for allocatable scalar at %C");
5430 2 : goto cleanup;
5431 : }
5432 :
5433 17468 : if (gfc_match_char (',') != MATCH_YES)
5434 : break;
5435 :
5436 7120 : alloc_opt_list:
5437 :
5438 7252 : m = gfc_match (" stat = %e", &tmp);
5439 7252 : if (m == MATCH_ERROR)
5440 7 : goto cleanup;
5441 7245 : if (m == MATCH_YES)
5442 : {
5443 : /* Enforce C630. */
5444 336 : if (saw_stat)
5445 : {
5446 1 : gfc_error ("Redundant STAT tag found at %L", &tmp->where);
5447 1 : goto cleanup;
5448 : }
5449 :
5450 335 : stat = tmp;
5451 335 : tmp = NULL;
5452 335 : saw_stat = true;
5453 :
5454 335 : if (stat->expr_type == EXPR_CONSTANT)
5455 : {
5456 5 : gfc_error ("STAT tag at %L cannot be a constant", &stat->where);
5457 5 : goto cleanup;
5458 : }
5459 :
5460 330 : if (gfc_check_do_variable (stat->symtree))
5461 0 : goto cleanup;
5462 :
5463 330 : if (gfc_match_char (',') == MATCH_YES)
5464 84 : goto alloc_opt_list;
5465 : }
5466 :
5467 7155 : m = gfc_match (" errmsg = %e", &tmp);
5468 7155 : if (m == MATCH_ERROR)
5469 0 : goto cleanup;
5470 7155 : if (m == MATCH_YES)
5471 : {
5472 89 : if (!gfc_notify_std (GFC_STD_F2003, "ERRMSG tag at %L", &tmp->where))
5473 1 : goto cleanup;
5474 :
5475 : /* Enforce C630. */
5476 88 : if (saw_errmsg)
5477 : {
5478 1 : gfc_error ("Redundant ERRMSG tag found at %L", &tmp->where);
5479 1 : goto cleanup;
5480 : }
5481 :
5482 87 : errmsg = tmp;
5483 87 : tmp = NULL;
5484 87 : saw_errmsg = true;
5485 :
5486 87 : if (gfc_match_char (',') == MATCH_YES)
5487 4 : goto alloc_opt_list;
5488 : }
5489 :
5490 7149 : m = gfc_match (" source = %e", &tmp);
5491 7149 : if (m == MATCH_ERROR)
5492 2 : goto cleanup;
5493 7147 : if (m == MATCH_YES)
5494 : {
5495 3417 : if (!gfc_notify_std (GFC_STD_F2003, "SOURCE tag at %L", &tmp->where))
5496 1 : goto cleanup;
5497 :
5498 : /* Enforce C630. */
5499 3416 : if (saw_source)
5500 : {
5501 1 : gfc_error ("Redundant SOURCE tag found at %L", &tmp->where);
5502 1 : goto cleanup;
5503 : }
5504 :
5505 : /* The next 2 conditionals check C631. */
5506 3415 : if (ts.type != BT_UNKNOWN)
5507 : {
5508 1 : gfc_error ("SOURCE tag at %L conflicts with the typespec at %L",
5509 1 : &tmp->where, &old_locus);
5510 1 : goto cleanup;
5511 : }
5512 :
5513 3414 : if (head->next
5514 3440 : && !gfc_notify_std (GFC_STD_F2008, "SOURCE tag at %L"
5515 : " with more than a single allocate object",
5516 26 : &tmp->where))
5517 1 : goto cleanup;
5518 :
5519 3413 : source = tmp;
5520 3413 : tmp = NULL;
5521 3413 : saw_source = true;
5522 :
5523 3413 : if (gfc_match_char (',') == MATCH_YES)
5524 41 : goto alloc_opt_list;
5525 : }
5526 :
5527 7102 : m = gfc_match (" mold = %e", &tmp);
5528 7102 : if (m == MATCH_ERROR)
5529 0 : goto cleanup;
5530 7102 : if (m == MATCH_YES)
5531 : {
5532 358 : if (!gfc_notify_std (GFC_STD_F2008, "MOLD tag at %L", &tmp->where))
5533 1 : goto cleanup;
5534 :
5535 : /* Check F08:C636. */
5536 357 : if (saw_mold)
5537 : {
5538 1 : gfc_error ("Redundant MOLD tag found at %L", &tmp->where);
5539 1 : goto cleanup;
5540 : }
5541 :
5542 : /* Check F08:C637. */
5543 356 : if (ts.type != BT_UNKNOWN)
5544 : {
5545 1 : gfc_error ("MOLD tag at %L conflicts with the typespec at %L",
5546 1 : &tmp->where, &old_locus);
5547 1 : goto cleanup;
5548 : }
5549 :
5550 355 : mold = tmp;
5551 355 : tmp = NULL;
5552 355 : saw_mold = true;
5553 355 : mold->mold = 1;
5554 :
5555 355 : if (gfc_match_char (',') == MATCH_YES)
5556 3 : goto alloc_opt_list;
5557 : }
5558 :
5559 7096 : gfc_gobble_whitespace ();
5560 :
5561 7096 : if (gfc_peek_char () == ')')
5562 : break;
5563 : }
5564 :
5565 14401 : if (gfc_match (" )%t") != MATCH_YES)
5566 1 : goto syntax;
5567 :
5568 : /* Check F08:C637. */
5569 14400 : if (source && mold)
5570 : {
5571 1 : gfc_error ("MOLD tag at %L conflicts with SOURCE tag at %L",
5572 : &mold->where, &source->where);
5573 1 : goto cleanup;
5574 : }
5575 :
5576 : /* Check F03:C623, */
5577 14399 : if (saw_deferred && ts.type == BT_UNKNOWN && !source && !mold)
5578 : {
5579 15 : gfc_error ("Allocate-object at %L with a deferred type parameter "
5580 : "requires either a type-spec or SOURCE tag or a MOLD tag",
5581 : &deferred_locus);
5582 15 : goto cleanup;
5583 : }
5584 :
5585 : /* Check F03:C625, */
5586 14384 : if (saw_unlimited && ts.type == BT_UNKNOWN && !source && !mold)
5587 : {
5588 2 : for (tail = head; tail; tail = tail->next)
5589 : {
5590 1 : if (UNLIMITED_POLY (tail->expr))
5591 1 : gfc_error ("Unlimited polymorphic allocate-object at %L "
5592 : "requires either a type-spec or SOURCE tag "
5593 : "or a MOLD tag", &tail->expr->where);
5594 : }
5595 1 : goto cleanup;
5596 : }
5597 :
5598 14383 : new_st.op = EXEC_ALLOCATE;
5599 14383 : new_st.expr1 = stat;
5600 14383 : new_st.expr2 = errmsg;
5601 14383 : if (source)
5602 3411 : new_st.expr3 = source;
5603 : else
5604 10972 : new_st.expr3 = mold;
5605 14383 : new_st.ext.alloc.list = head;
5606 14383 : new_st.ext.alloc.ts = ts;
5607 :
5608 14383 : if (type_param_spec_list)
5609 77 : gfc_free_actual_arglist (type_param_spec_list);
5610 :
5611 : return MATCH_YES;
5612 :
5613 1 : syntax:
5614 1 : gfc_syntax_error (ST_ALLOCATE);
5615 :
5616 108 : cleanup:
5617 108 : gfc_free_expr (errmsg);
5618 108 : gfc_free_expr (source);
5619 108 : gfc_free_expr (stat);
5620 108 : gfc_free_expr (mold);
5621 108 : if (tmp && tmp->expr_type) gfc_free_expr (tmp);
5622 108 : gfc_free_alloc_list (head);
5623 108 : if (type_param_spec_list)
5624 0 : gfc_free_actual_arglist (type_param_spec_list);
5625 : return MATCH_ERROR;
5626 : }
5627 :
5628 :
5629 : /* Match a NULLIFY statement. A NULLIFY statement is transformed into
5630 : a set of pointer assignments to intrinsic NULL(). */
5631 :
5632 : match
5633 582 : gfc_match_nullify (void)
5634 : {
5635 582 : gfc_code *tail;
5636 582 : gfc_expr *e, *p = NULL;
5637 582 : match m;
5638 :
5639 582 : tail = NULL;
5640 :
5641 582 : if (gfc_match_char ('(') != MATCH_YES)
5642 0 : goto syntax;
5643 :
5644 986 : for (;;)
5645 : {
5646 986 : m = gfc_match_variable (&p, 0);
5647 986 : if (m == MATCH_ERROR)
5648 2 : goto cleanup;
5649 984 : if (m == MATCH_NO)
5650 0 : goto syntax;
5651 :
5652 984 : if (gfc_check_do_variable (p->symtree))
5653 0 : goto cleanup;
5654 :
5655 : /* F2008, C1242. */
5656 984 : if (gfc_is_coindexed (p))
5657 : {
5658 1 : gfc_error ("Pointer object at %C shall not be coindexed");
5659 1 : goto cleanup;
5660 : }
5661 :
5662 : /* Check for valid array pointer object. Bounds remapping is not
5663 : allowed with NULLIFY. */
5664 983 : if (p->ref)
5665 : {
5666 : gfc_ref *remap = p->ref;
5667 943 : for (; remap; remap = remap->next)
5668 492 : if (!remap->next && remap->type == REF_ARRAY
5669 320 : && remap->u.ar.type != AR_FULL)
5670 : break;
5671 : if (remap)
5672 : {
5673 2 : gfc_error ("NULLIFY does not allow bounds remapping for "
5674 : "pointer object at %C");
5675 2 : goto cleanup;
5676 : }
5677 : }
5678 :
5679 : /* build ' => NULL() '. */
5680 981 : e = gfc_get_null_expr (&gfc_current_locus);
5681 :
5682 : /* Chain to list. */
5683 981 : if (tail == NULL)
5684 : {
5685 578 : tail = &new_st;
5686 578 : tail->op = EXEC_POINTER_ASSIGN;
5687 : }
5688 : else
5689 : {
5690 403 : tail->next = gfc_get_code (EXEC_POINTER_ASSIGN);
5691 403 : tail = tail->next;
5692 : }
5693 :
5694 981 : tail->expr1 = p;
5695 981 : tail->expr2 = e;
5696 :
5697 981 : if (gfc_match (" )%t") == MATCH_YES)
5698 : break;
5699 404 : if (gfc_match_char (',') != MATCH_YES)
5700 0 : goto syntax;
5701 : }
5702 :
5703 : return MATCH_YES;
5704 :
5705 0 : syntax:
5706 0 : gfc_syntax_error (ST_NULLIFY);
5707 :
5708 5 : cleanup:
5709 5 : gfc_free_statements (new_st.next);
5710 5 : new_st.next = NULL;
5711 5 : gfc_free_expr (new_st.expr1);
5712 5 : new_st.expr1 = NULL;
5713 5 : gfc_free_expr (new_st.expr2);
5714 5 : new_st.expr2 = NULL;
5715 5 : gfc_free_expr (p);
5716 5 : return MATCH_ERROR;
5717 : }
5718 :
5719 :
5720 : /* Match a DEALLOCATE statement. */
5721 :
5722 : match
5723 6110 : gfc_match_deallocate (void)
5724 : {
5725 6110 : gfc_alloc *head, *tail;
5726 6110 : gfc_expr *stat, *errmsg, *tmp;
5727 6110 : gfc_symbol *sym;
5728 6110 : match m;
5729 6110 : bool saw_stat, saw_errmsg, b1, b2;
5730 :
5731 6110 : head = tail = NULL;
5732 6110 : stat = errmsg = tmp = NULL;
5733 6110 : saw_stat = saw_errmsg = false;
5734 :
5735 6110 : if (gfc_match_char ('(') != MATCH_YES)
5736 0 : goto syntax;
5737 :
5738 8387 : for (;;)
5739 : {
5740 8387 : if (head == NULL)
5741 6110 : head = tail = gfc_get_alloc ();
5742 : else
5743 : {
5744 2277 : tail->next = gfc_get_alloc ();
5745 2277 : tail = tail->next;
5746 : }
5747 :
5748 8387 : m = gfc_match_variable (&tail->expr, 0);
5749 8387 : if (m == MATCH_ERROR)
5750 0 : goto cleanup;
5751 8387 : if (m == MATCH_NO)
5752 0 : goto syntax;
5753 :
5754 8387 : if (tail->expr->expr_type == EXPR_CONSTANT)
5755 : {
5756 1 : gfc_error ("Unexpected constant at %C");
5757 1 : goto cleanup;
5758 : }
5759 :
5760 8386 : if (gfc_check_do_variable (tail->expr->symtree))
5761 0 : goto cleanup;
5762 :
5763 8386 : sym = tail->expr->symtree->n.sym;
5764 :
5765 8386 : bool impure = gfc_impure_variable (sym);
5766 8386 : if (impure && gfc_pure (NULL))
5767 : {
5768 0 : gfc_error ("Illegal allocate-object at %C for a PURE procedure");
5769 0 : goto cleanup;
5770 : }
5771 :
5772 8386 : if (impure)
5773 429 : gfc_unset_implicit_pure (NULL);
5774 :
5775 8386 : if (gfc_is_coarray (tail->expr)
5776 8386 : && gfc_find_state (COMP_DO_CONCURRENT))
5777 : {
5778 1 : gfc_error ("DEALLOCATE of coarray at %C in DO CONCURRENT block");
5779 1 : goto cleanup;
5780 : }
5781 :
5782 8385 : if (gfc_is_coarray (tail->expr)
5783 8385 : && gfc_find_state (COMP_CRITICAL))
5784 : {
5785 1 : gfc_error ("DEALLOCATE of coarray at %C in CRITICAL block");
5786 1 : goto cleanup;
5787 : }
5788 :
5789 : /* FIXME: disable the checking on derived types. */
5790 8384 : b1 = !(tail->expr->ref
5791 6365 : && (tail->expr->ref->type == REF_COMPONENT
5792 : || tail->expr->ref->type == REF_ARRAY));
5793 8384 : if (sym && sym->ts.type == BT_CLASS)
5794 1577 : b2 = !(CLASS_DATA (sym) && (CLASS_DATA (sym)->attr.allocatable
5795 391 : || CLASS_DATA (sym)->attr.class_pointer));
5796 : else
5797 6807 : b2 = sym && !(sym->attr.allocatable || sym->attr.pointer
5798 1362 : || sym->attr.proc_pointer);
5799 1432 : if (b1 && b2)
5800 : {
5801 3 : gfc_error ("Allocate-object at %C is not a nonprocedure pointer "
5802 : "nor an allocatable variable");
5803 3 : goto cleanup;
5804 : }
5805 :
5806 8381 : if (gfc_match_char (',') != MATCH_YES)
5807 : break;
5808 :
5809 2615 : dealloc_opt_list:
5810 :
5811 2680 : m = gfc_match (" stat = %e", &tmp);
5812 2680 : if (m == MATCH_ERROR)
5813 2 : goto cleanup;
5814 2678 : if (m == MATCH_YES)
5815 : {
5816 335 : if (saw_stat)
5817 : {
5818 1 : gfc_error ("Redundant STAT tag found at %L", &tmp->where);
5819 1 : gfc_free_expr (tmp);
5820 1 : goto cleanup;
5821 : }
5822 :
5823 334 : stat = tmp;
5824 334 : saw_stat = true;
5825 :
5826 334 : if (gfc_check_do_variable (stat->symtree))
5827 0 : goto cleanup;
5828 :
5829 334 : if (gfc_match_char (',') == MATCH_YES)
5830 61 : goto dealloc_opt_list;
5831 : }
5832 :
5833 2616 : m = gfc_match (" errmsg = %e", &tmp);
5834 2616 : if (m == MATCH_ERROR)
5835 0 : goto cleanup;
5836 2616 : if (m == MATCH_YES)
5837 : {
5838 66 : if (!gfc_notify_std (GFC_STD_F2003, "ERRMSG at %L", &tmp->where))
5839 0 : goto cleanup;
5840 :
5841 66 : if (saw_errmsg)
5842 : {
5843 1 : gfc_error ("Redundant ERRMSG tag found at %L", &tmp->where);
5844 1 : gfc_free_expr (tmp);
5845 1 : goto cleanup;
5846 : }
5847 :
5848 65 : errmsg = tmp;
5849 65 : saw_errmsg = true;
5850 :
5851 65 : if (gfc_match_char (',') == MATCH_YES)
5852 4 : goto dealloc_opt_list;
5853 : }
5854 :
5855 2611 : gfc_gobble_whitespace ();
5856 :
5857 2611 : if (gfc_peek_char () == ')')
5858 : break;
5859 : }
5860 :
5861 6100 : if (gfc_match (" )%t") != MATCH_YES)
5862 1 : goto syntax;
5863 :
5864 6099 : new_st.op = EXEC_DEALLOCATE;
5865 6099 : new_st.expr1 = stat;
5866 6099 : new_st.expr2 = errmsg;
5867 6099 : new_st.ext.alloc.list = head;
5868 :
5869 6099 : return MATCH_YES;
5870 :
5871 1 : syntax:
5872 1 : gfc_syntax_error (ST_DEALLOCATE);
5873 :
5874 11 : cleanup:
5875 11 : gfc_free_expr (errmsg);
5876 11 : gfc_free_expr (stat);
5877 11 : gfc_free_alloc_list (head);
5878 11 : return MATCH_ERROR;
5879 : }
5880 :
5881 :
5882 : /* Match a RETURN statement. */
5883 :
5884 : match
5885 3209 : gfc_match_return (void)
5886 : {
5887 3209 : gfc_expr *e;
5888 3209 : match m;
5889 3209 : gfc_compile_state s;
5890 :
5891 3209 : e = NULL;
5892 :
5893 3209 : if (gfc_find_state (COMP_CRITICAL))
5894 : {
5895 1 : gfc_error ("Image control statement RETURN at %C in CRITICAL block");
5896 1 : return MATCH_ERROR;
5897 : }
5898 :
5899 3208 : if (gfc_find_state (COMP_DO_CONCURRENT))
5900 : {
5901 1 : gfc_error ("Image control statement RETURN at %C in DO CONCURRENT block");
5902 1 : return MATCH_ERROR;
5903 : }
5904 :
5905 3207 : if (gfc_find_state (COMP_CHANGE_TEAM))
5906 : {
5907 : /* F2018, C1111: A RETURN statement shall not appear within a CHANGE TEAM
5908 : construct. */
5909 1 : gfc_error (
5910 : "Image control statement RETURN at %C in CHANGE TEAM-END TEAM block");
5911 1 : return MATCH_ERROR;
5912 : }
5913 :
5914 3206 : if (gfc_match_eos () == MATCH_YES)
5915 3152 : goto done;
5916 :
5917 54 : if (!gfc_find_state (COMP_SUBROUTINE))
5918 : {
5919 0 : gfc_error ("Alternate RETURN statement at %C is only allowed within "
5920 : "a SUBROUTINE");
5921 0 : goto cleanup;
5922 : }
5923 :
5924 54 : if (gfc_current_form == FORM_FREE)
5925 : {
5926 : /* The following are valid, so we can't require a blank after the
5927 : RETURN keyword:
5928 : return+1
5929 : return(1) */
5930 54 : char c = gfc_peek_ascii_char ();
5931 54 : if (ISALPHA (c) || ISDIGIT (c))
5932 : return MATCH_NO;
5933 : }
5934 :
5935 53 : m = gfc_match (" %e%t", &e);
5936 53 : if (m == MATCH_YES)
5937 53 : goto done;
5938 0 : if (m == MATCH_ERROR)
5939 0 : goto cleanup;
5940 :
5941 0 : gfc_syntax_error (ST_RETURN);
5942 :
5943 0 : cleanup:
5944 0 : gfc_free_expr (e);
5945 0 : return MATCH_ERROR;
5946 :
5947 3205 : done:
5948 3205 : gfc_enclosing_unit (&s);
5949 3205 : if (s == COMP_PROGRAM
5950 3205 : && !gfc_notify_std (GFC_STD_GNU, "RETURN statement in "
5951 : "main program at %C"))
5952 : return MATCH_ERROR;
5953 :
5954 3205 : new_st.op = EXEC_RETURN;
5955 3205 : new_st.expr1 = e;
5956 :
5957 3205 : return MATCH_YES;
5958 : }
5959 :
5960 :
5961 : /* Match the call of a type-bound procedure, if CALL%var has already been
5962 : matched and var found to be a derived-type variable. */
5963 :
5964 : static match
5965 1438 : match_typebound_call (gfc_symtree* varst)
5966 : {
5967 1438 : gfc_expr* base;
5968 1438 : match m;
5969 :
5970 1438 : base = gfc_get_expr ();
5971 1438 : base->expr_type = EXPR_VARIABLE;
5972 1438 : base->symtree = varst;
5973 1438 : base->where = gfc_current_locus;
5974 1438 : gfc_set_sym_referenced (varst->n.sym);
5975 :
5976 1438 : m = gfc_match_varspec (base, 0, true, true);
5977 1438 : if (m == MATCH_NO)
5978 0 : gfc_error ("Expected component reference at %C");
5979 1438 : if (m != MATCH_YES)
5980 : {
5981 5 : gfc_free_expr (base);
5982 5 : return MATCH_ERROR;
5983 : }
5984 :
5985 1433 : if (gfc_match_eos () != MATCH_YES)
5986 : {
5987 1 : gfc_error ("Junk after CALL at %C");
5988 1 : gfc_free_expr (base);
5989 1 : return MATCH_ERROR;
5990 : }
5991 :
5992 1432 : if (base->expr_type == EXPR_COMPCALL)
5993 1307 : new_st.op = EXEC_COMPCALL;
5994 125 : else if (base->expr_type == EXPR_PPC)
5995 124 : new_st.op = EXEC_CALL_PPC;
5996 : else
5997 : {
5998 1 : gfc_error ("Expected type-bound procedure or procedure pointer component "
5999 : "at %C");
6000 1 : gfc_free_expr (base);
6001 1 : return MATCH_ERROR;
6002 : }
6003 1431 : new_st.expr1 = base;
6004 :
6005 1431 : return MATCH_YES;
6006 : }
6007 :
6008 :
6009 : /* Match a CALL statement. The tricky part here are possible
6010 : alternate return specifiers. We handle these by having all
6011 : "subroutines" actually return an integer via a register that gives
6012 : the return number. If the call specifies alternate returns, we
6013 : generate code for a SELECT statement whose case clauses contain
6014 : GOTOs to the various labels. */
6015 :
6016 : match
6017 80702 : gfc_match_call (void)
6018 : {
6019 80702 : char name[GFC_MAX_SYMBOL_LEN + 1];
6020 80702 : gfc_actual_arglist *a, *arglist;
6021 80702 : gfc_case *new_case;
6022 80702 : gfc_symbol *sym;
6023 80702 : gfc_symtree *st;
6024 80702 : gfc_code *c;
6025 80702 : match m;
6026 80702 : int i;
6027 :
6028 80702 : arglist = NULL;
6029 :
6030 80702 : m = gfc_match ("% %n", name);
6031 80702 : if (m == MATCH_NO)
6032 0 : goto syntax;
6033 80702 : if (m != MATCH_YES)
6034 : return m;
6035 :
6036 80702 : if (gfc_get_ha_sym_tree (name, &st))
6037 : return MATCH_ERROR;
6038 :
6039 80700 : sym = st->n.sym;
6040 :
6041 : /* If this is a variable of derived-type, it probably starts a type-bound
6042 : procedure call. Associate variable targets have to be resolved for the
6043 : target type. */
6044 80700 : if (((sym->attr.flavor != FL_PROCEDURE
6045 57491 : || gfc_is_function_return_value (sym, gfc_current_ns))
6046 23211 : && (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS))
6047 79276 : ||
6048 : /* Skip gfc_resolve_expr for ASSOCIATE names followed by '%'.
6049 : resolving a contained-function selector before CONTAINS is
6050 : parsed prematurely, marks it EXTERNAL, conflicting with its
6051 : later INTERNAL declaration. */
6052 79276 : (sym->assoc && sym->assoc->target && gfc_peek_ascii_char () == '%')
6053 80700 : ||
6054 79262 : (sym->assoc && sym->assoc->target
6055 0 : && gfc_resolve_expr (sym->assoc->target)
6056 0 : && (sym->assoc->target->ts.type == BT_DERIVED
6057 0 : || sym->assoc->target->ts.type == BT_CLASS)))
6058 1438 : return match_typebound_call (st);
6059 :
6060 : /* If it does not seem to be callable (include functions so that the
6061 : right association is made. They are thrown out in resolution.)
6062 : ... */
6063 79262 : if (!sym->attr.generic
6064 76450 : && !sym->attr.proc_pointer
6065 76217 : && !sym->attr.subroutine
6066 22548 : && !sym->attr.function)
6067 : {
6068 22543 : if (!(sym->attr.external && !sym->attr.referenced))
6069 : {
6070 : /* ...create a symbol in this scope... */
6071 21911 : if (sym->ns != gfc_current_ns
6072 21911 : && gfc_get_sym_tree (name, NULL, &st, false) == 1)
6073 : return MATCH_ERROR;
6074 :
6075 21911 : if (sym != st->n.sym)
6076 22543 : sym = st->n.sym;
6077 : }
6078 :
6079 : /* ...and then to try to make the symbol into a subroutine. */
6080 22543 : if (!gfc_add_subroutine (&sym->attr, sym->name, NULL))
6081 : return MATCH_ERROR;
6082 : }
6083 :
6084 79260 : gfc_set_sym_referenced (sym);
6085 :
6086 79260 : if (gfc_match_eos () != MATCH_YES)
6087 : {
6088 71955 : m = gfc_match_actual_arglist (1, &arglist);
6089 71955 : if (m == MATCH_NO)
6090 0 : goto syntax;
6091 71955 : if (m == MATCH_ERROR)
6092 10 : goto cleanup;
6093 :
6094 71945 : if (gfc_match_eos () != MATCH_YES)
6095 1 : goto syntax;
6096 : }
6097 :
6098 : /* Walk the argument list looking for invalid BOZ. */
6099 247989 : for (a = arglist; a; a = a->next)
6100 168741 : if (a->expr && a->expr->ts.type == BT_BOZ)
6101 : {
6102 1 : gfc_error ("A BOZ literal constant at %L cannot appear as an actual "
6103 : "argument in a subroutine reference", &a->expr->where);
6104 1 : goto cleanup;
6105 : }
6106 :
6107 :
6108 : /* If any alternate return labels were found, construct a SELECT
6109 : statement that will jump to the right place. */
6110 :
6111 247696 : i = 0;
6112 247696 : for (a = arglist; a; a = a->next)
6113 168598 : if (a->expr == NULL)
6114 : {
6115 : i = 1;
6116 : break;
6117 : }
6118 :
6119 79248 : if (i)
6120 : {
6121 150 : gfc_symtree *select_st;
6122 150 : gfc_symbol *select_sym;
6123 150 : char name[GFC_MAX_SYMBOL_LEN + 1];
6124 :
6125 150 : new_st.next = c = gfc_get_code (EXEC_SELECT);
6126 150 : sprintf (name, "_result_%s", sym->name);
6127 150 : gfc_get_ha_sym_tree (name, &select_st); /* Can't fail. */
6128 :
6129 150 : select_sym = select_st->n.sym;
6130 150 : select_sym->ts.type = BT_INTEGER;
6131 150 : select_sym->ts.kind = gfc_default_integer_kind;
6132 150 : gfc_set_sym_referenced (select_sym);
6133 150 : c->expr1 = gfc_get_expr ();
6134 150 : c->expr1->expr_type = EXPR_VARIABLE;
6135 150 : c->expr1->symtree = select_st;
6136 150 : c->expr1->ts = select_sym->ts;
6137 150 : c->expr1->where = gfc_current_locus;
6138 :
6139 150 : i = 0;
6140 618 : for (a = arglist; a; a = a->next)
6141 : {
6142 468 : if (a->expr != NULL)
6143 232 : continue;
6144 :
6145 236 : if (!gfc_reference_st_label (a->label, ST_LABEL_TARGET))
6146 0 : continue;
6147 :
6148 236 : i++;
6149 :
6150 236 : c->block = gfc_get_code (EXEC_SELECT);
6151 236 : c = c->block;
6152 :
6153 236 : new_case = gfc_get_case ();
6154 236 : new_case->high = gfc_get_int_expr (gfc_default_integer_kind, NULL, i);
6155 236 : new_case->low = new_case->high;
6156 236 : c->ext.block.case_list = new_case;
6157 :
6158 236 : c->next = gfc_get_code (EXEC_GOTO);
6159 236 : c->next->label1 = a->label;
6160 : }
6161 : }
6162 :
6163 79248 : new_st.op = EXEC_CALL;
6164 79248 : new_st.symtree = st;
6165 79248 : new_st.ext.actual = arglist;
6166 :
6167 79248 : return MATCH_YES;
6168 :
6169 1 : syntax:
6170 1 : gfc_syntax_error (ST_CALL);
6171 :
6172 12 : cleanup:
6173 12 : gfc_free_actual_arglist (arglist);
6174 12 : return MATCH_ERROR;
6175 : }
6176 :
6177 :
6178 : /* Given a name, return a pointer to the common head structure,
6179 : creating it if it does not exist. If FROM_MODULE is nonzero, we
6180 : mangle the name so that it doesn't interfere with commons defined
6181 : in the using namespace.
6182 : TODO: Add to global symbol tree. */
6183 :
6184 : gfc_common_head *
6185 2078 : gfc_get_common (const char *name, int from_module)
6186 : {
6187 2078 : gfc_symtree *st;
6188 2078 : static int serial = 0;
6189 2078 : char mangled_name[GFC_MAX_SYMBOL_LEN + 1];
6190 :
6191 2078 : if (from_module)
6192 : {
6193 : /* A use associated common block is only needed to correctly layout
6194 : the variables it contains. */
6195 170 : snprintf (mangled_name, GFC_MAX_SYMBOL_LEN, "_%d_%s", serial++, name);
6196 170 : st = gfc_new_symtree (&gfc_current_ns->common_root, mangled_name);
6197 : }
6198 : else
6199 : {
6200 1908 : st = gfc_find_symtree (gfc_current_ns->common_root, name);
6201 :
6202 1908 : if (st == NULL)
6203 1820 : st = gfc_new_symtree (&gfc_current_ns->common_root, name);
6204 : }
6205 :
6206 2078 : if (st->n.common == NULL)
6207 : {
6208 1990 : st->n.common = gfc_get_common_head ();
6209 1990 : st->n.common->where = gfc_current_locus;
6210 1990 : strcpy (st->n.common->name, name);
6211 : }
6212 :
6213 2078 : return st->n.common;
6214 : }
6215 :
6216 :
6217 : /* Match a common block name. */
6218 :
6219 : match
6220 2114 : gfc_match_common_name (char *name)
6221 : {
6222 2114 : match m;
6223 :
6224 2114 : if (gfc_match_char ('/') == MATCH_NO)
6225 : {
6226 122 : name[0] = '\0';
6227 122 : return MATCH_YES;
6228 : }
6229 :
6230 1992 : if (gfc_match_char ('/') == MATCH_YES)
6231 : {
6232 85 : name[0] = '\0';
6233 85 : return MATCH_YES;
6234 : }
6235 :
6236 1907 : m = gfc_match_name (name);
6237 :
6238 1907 : if (m == MATCH_ERROR)
6239 : return MATCH_ERROR;
6240 1907 : if (m == MATCH_YES && gfc_match_char ('/') == MATCH_YES)
6241 : return MATCH_YES;
6242 :
6243 0 : gfc_error ("Syntax error in common block name at %C");
6244 0 : return MATCH_ERROR;
6245 : }
6246 :
6247 :
6248 : /* Match a COMMON statement. */
6249 :
6250 : match
6251 2034 : gfc_match_common (void)
6252 : {
6253 2034 : gfc_symbol *sym, **head, *tail, *other;
6254 2034 : char name[GFC_MAX_SYMBOL_LEN + 1];
6255 2034 : gfc_common_head *t;
6256 2034 : gfc_array_spec *as;
6257 2034 : gfc_equiv *e1, *e2;
6258 2034 : match m;
6259 2034 : char c;
6260 :
6261 : /* COMMON has been matched. In free form source code, the next character
6262 : needs to be whitespace or '/'. Check that here. Fixed form source
6263 : code needs to be checked below. */
6264 2034 : c = gfc_peek_ascii_char ();
6265 2034 : if (gfc_current_form == FORM_FREE && !gfc_is_whitespace (c) && c != '/')
6266 : return MATCH_NO;
6267 :
6268 2033 : as = NULL;
6269 :
6270 2038 : for (;;)
6271 : {
6272 2038 : m = gfc_match_common_name (name);
6273 2038 : if (m == MATCH_ERROR)
6274 0 : goto cleanup;
6275 :
6276 2038 : if (name[0] == '\0')
6277 : {
6278 207 : t = &gfc_current_ns->blank_common;
6279 207 : if (t->head == NULL)
6280 205 : t->where = gfc_current_locus;
6281 : }
6282 : else
6283 : {
6284 1831 : t = gfc_get_common (name, 0);
6285 : }
6286 2038 : head = &t->head;
6287 :
6288 2038 : if (*head == NULL)
6289 : tail = NULL;
6290 : else
6291 : {
6292 : tail = *head;
6293 114 : while (tail->common_next)
6294 : tail = tail->common_next;
6295 : }
6296 :
6297 : /* Grab the list of symbols. */
6298 5877 : for (;;)
6299 : {
6300 5877 : m = gfc_match_symbol (&sym, 0);
6301 5877 : if (m == MATCH_ERROR)
6302 0 : goto cleanup;
6303 5877 : if (m == MATCH_NO)
6304 7 : goto syntax;
6305 :
6306 : /* See if we know the current common block is bind(c), and if
6307 : so, then see if we can check if the symbol is (which it'll
6308 : need to be). This can happen if the bind(c) attr stmt was
6309 : applied to the common block, and the variable(s) already
6310 : defined, before declaring the common block. */
6311 5870 : if (t->is_bind_c == 1)
6312 : {
6313 13 : if (sym->ts.type != BT_UNKNOWN && sym->ts.is_c_interop != 1)
6314 : {
6315 : /* If we find an error, just print it and continue,
6316 : cause it's just semantic, and we can see if there
6317 : are more errors. */
6318 0 : gfc_error_now ("Variable %qs at %L in common block %qs "
6319 : "at %C must be declared with a C "
6320 : "interoperable kind since common block "
6321 : "%qs is bind(c)",
6322 : sym->name, &(sym->declared_at), t->name,
6323 0 : t->name);
6324 : }
6325 :
6326 13 : if (sym->attr.is_bind_c == 1)
6327 0 : gfc_error_now ("Variable %qs in common block %qs at %C cannot "
6328 : "be bind(c) since it is not global", sym->name,
6329 0 : t->name);
6330 : }
6331 :
6332 5870 : if (sym->attr.in_common)
6333 : {
6334 2 : gfc_error ("Symbol %qs at %C is already in a COMMON block",
6335 : sym->name);
6336 2 : goto cleanup;
6337 : }
6338 :
6339 5868 : if (((sym->value != NULL && sym->value->expr_type != EXPR_NULL)
6340 5868 : || sym->attr.data) && gfc_current_state () != COMP_BLOCK_DATA)
6341 : {
6342 7 : if (!gfc_notify_std (GFC_STD_GNU, "Initialized symbol %qs at "
6343 : "%C can only be COMMON in BLOCK DATA",
6344 : sym->name))
6345 2 : goto cleanup;
6346 : }
6347 :
6348 : /* F2018:R874: common-block-object is variable-name [ (array-spec) ]
6349 : F2018:C8121: A variable-name shall not be a name made accessible
6350 : by use association. */
6351 5866 : if (sym->attr.use_assoc)
6352 : {
6353 2 : gfc_error ("Symbol %qs at %C is USE associated from module %qs "
6354 : "and cannot occur in COMMON", sym->name, sym->module);
6355 2 : goto cleanup;
6356 : }
6357 :
6358 : /* Deal with an optional array specification after the
6359 : symbol name. */
6360 5864 : m = gfc_match_array_spec (&as, true, true);
6361 5864 : if (m == MATCH_ERROR)
6362 2 : goto cleanup;
6363 :
6364 5862 : if (m == MATCH_YES)
6365 : {
6366 2127 : if (as->type != AS_EXPLICIT)
6367 : {
6368 0 : gfc_error ("Array specification for symbol %qs in COMMON "
6369 : "at %C must be explicit", sym->name);
6370 0 : goto cleanup;
6371 : }
6372 :
6373 2127 : if (as->corank)
6374 : {
6375 1 : gfc_error ("Symbol %qs in COMMON at %C cannot be a "
6376 : "coarray", sym->name);
6377 1 : goto cleanup;
6378 : }
6379 :
6380 2126 : if (!gfc_add_dimension (&sym->attr, sym->name, NULL))
6381 0 : goto cleanup;
6382 :
6383 2126 : if (sym->attr.pointer)
6384 : {
6385 0 : gfc_error ("Symbol %qs in COMMON at %C cannot be a "
6386 : "POINTER array", sym->name);
6387 0 : goto cleanup;
6388 : }
6389 :
6390 2126 : sym->as = as;
6391 2126 : as = NULL;
6392 :
6393 : }
6394 :
6395 : /* Add the in_common attribute, but ignore the reported errors
6396 : if any, and continue matching. */
6397 5861 : gfc_add_in_common (&sym->attr, sym->name, NULL);
6398 :
6399 5861 : sym->common_block = t;
6400 5861 : sym->common_block->refs++;
6401 :
6402 5861 : if (tail != NULL)
6403 3851 : tail->common_next = sym;
6404 : else
6405 2010 : *head = sym;
6406 :
6407 5861 : tail = sym;
6408 :
6409 5861 : sym->common_head = t;
6410 :
6411 : /* Check to see if the symbol is already in an equivalence group.
6412 : If it is, set the other members as being in common. */
6413 5861 : if (sym->attr.in_equivalence)
6414 : {
6415 20 : for (e1 = gfc_current_ns->equiv; e1; e1 = e1->next)
6416 : {
6417 29 : for (e2 = e1; e2; e2 = e2->eq)
6418 23 : if (e2->expr->symtree->n.sym == sym)
6419 8 : goto equiv_found;
6420 :
6421 6 : continue;
6422 :
6423 8 : equiv_found:
6424 :
6425 23 : for (e2 = e1; e2; e2 = e2->eq)
6426 : {
6427 16 : other = e2->expr->symtree->n.sym;
6428 16 : if (other->common_head
6429 9 : && other->common_head != sym->common_head)
6430 : {
6431 1 : gfc_error ("Symbol %qs, in COMMON block %qs at "
6432 : "%C is being indirectly equivalenced to "
6433 : "another COMMON block %qs",
6434 1 : sym->name, sym->common_head->name,
6435 1 : other->common_head->name);
6436 1 : goto cleanup;
6437 : }
6438 15 : other->attr.in_common = 1;
6439 15 : other->common_head = t;
6440 : }
6441 : }
6442 : }
6443 :
6444 :
6445 5860 : gfc_gobble_whitespace ();
6446 5860 : if (gfc_match_eos () == MATCH_YES)
6447 2015 : goto done;
6448 3845 : c = gfc_peek_ascii_char ();
6449 3845 : if (c == '/')
6450 : break;
6451 3842 : if (c != ',')
6452 : {
6453 : /* In Fixed form source code, gfortran can end up here for an
6454 : expression of the form COMMONI = RHS. This may not be an
6455 : error, so return MATCH_NO. */
6456 1 : if (gfc_current_form == FORM_FIXED && c == '=')
6457 : {
6458 1 : gfc_free_array_spec (as);
6459 1 : return MATCH_NO;
6460 : }
6461 0 : goto syntax;
6462 : }
6463 : else
6464 3841 : gfc_match_char (',');
6465 :
6466 3841 : gfc_gobble_whitespace ();
6467 3841 : if (gfc_peek_ascii_char () == '/')
6468 : break;
6469 : }
6470 : }
6471 :
6472 2015 : done:
6473 2015 : return MATCH_YES;
6474 :
6475 7 : syntax:
6476 7 : gfc_syntax_error (ST_COMMON);
6477 :
6478 17 : cleanup:
6479 17 : gfc_free_array_spec (as);
6480 17 : return MATCH_ERROR;
6481 : }
6482 :
6483 :
6484 : /* Match a BLOCK DATA program unit. */
6485 :
6486 : match
6487 88 : gfc_match_block_data (void)
6488 : {
6489 88 : char name[GFC_MAX_SYMBOL_LEN + 1];
6490 88 : gfc_symbol *sym;
6491 88 : match m;
6492 :
6493 88 : if (!gfc_notify_std (GFC_STD_F2018_OBS, "BLOCK DATA construct at %L",
6494 : &gfc_current_locus))
6495 : return MATCH_ERROR;
6496 :
6497 88 : if (gfc_match_eos () == MATCH_YES)
6498 : {
6499 50 : gfc_new_block = NULL;
6500 50 : return MATCH_YES;
6501 : }
6502 :
6503 38 : m = gfc_match ("% %n%t", name);
6504 38 : if (m != MATCH_YES)
6505 : return MATCH_ERROR;
6506 :
6507 38 : if (gfc_get_symbol (name, NULL, &sym))
6508 : return MATCH_ERROR;
6509 :
6510 38 : if (!gfc_add_flavor (&sym->attr, FL_BLOCK_DATA, sym->name, NULL))
6511 : return MATCH_ERROR;
6512 :
6513 38 : gfc_new_block = sym;
6514 :
6515 38 : return MATCH_YES;
6516 : }
6517 :
6518 :
6519 : /* Free a namelist structure. */
6520 :
6521 : void
6522 6246997 : gfc_free_namelist (gfc_namelist *name)
6523 : {
6524 6246997 : gfc_namelist *n;
6525 :
6526 6249169 : for (; name; name = n)
6527 : {
6528 2172 : n = name->next;
6529 2172 : free (name);
6530 : }
6531 6246997 : }
6532 :
6533 :
6534 : /* Free an OpenMP namelist structure. */
6535 :
6536 : void
6537 1352793 : gfc_free_omp_namelist (gfc_omp_namelist *name, enum gfc_omp_list_type list)
6538 : {
6539 2705586 : bool free_ns = (list == OMP_LIST_AFFINITY || list == OMP_LIST_DEPEND
6540 : || list == OMP_LIST_MAP
6541 1352793 : || list == OMP_LIST_TO || list == OMP_LIST_FROM);
6542 1352793 : bool free_align_allocator = (list == OMP_LIST_ALLOCATE);
6543 1352793 : bool free_mem_traits_space = (list == OMP_LIST_USES_ALLOCATORS);
6544 1352793 : bool free_init = (list == OMP_LIST_INIT);
6545 1352793 : bool free_mapper = (list == OMP_LIST_MAP
6546 : || list == OMP_LIST_TO
6547 1352793 : || list == OMP_LIST_FROM);
6548 :
6549 1352793 : gfc_omp_namelist *n;
6550 1352793 : gfc_expr *last_allocator = NULL;
6551 1352793 : char *last_init_interop = NULL;
6552 :
6553 1399413 : for (; name; name = n)
6554 : {
6555 46620 : gfc_free_expr (name->expr);
6556 46620 : if (free_align_allocator)
6557 523 : gfc_free_expr (name->u.align);
6558 : else if (free_mem_traits_space)
6559 : { } /* name->u.memspace_sym: shall not call gfc_free_symbol here. */
6560 :
6561 46620 : if (free_ns)
6562 21076 : gfc_free_namespace (name->u2.ns);
6563 25544 : else if (free_align_allocator)
6564 : {
6565 523 : if (last_allocator != name->u2.allocator)
6566 : {
6567 160 : last_allocator = name->u2.allocator;
6568 160 : gfc_free_expr (name->u2.allocator);
6569 : }
6570 : }
6571 25021 : else if (free_mem_traits_space)
6572 : { } /* name->u2.traits_sym: shall not call gfc_free_symbol here. */
6573 24917 : else if (free_init)
6574 : {
6575 84 : if (name->u2.init_interop != last_init_interop)
6576 : {
6577 31 : last_init_interop = name->u2.init_interop;
6578 31 : free (name->u2.init_interop);
6579 : }
6580 : }
6581 24833 : else if (free_mapper && name->u3.udm)
6582 0 : free (name->u3.udm);
6583 24833 : else if (!free_mapper && name->u2.udr)
6584 : {
6585 470 : if (name->u2.udr->combiner)
6586 470 : gfc_free_statement (name->u2.udr->combiner);
6587 470 : if (name->u2.udr->initializer)
6588 331 : gfc_free_statement (name->u2.udr->initializer);
6589 470 : free (name->u2.udr);
6590 : }
6591 46620 : n = name->next;
6592 46620 : free (name);
6593 : }
6594 1352793 : }
6595 :
6596 :
6597 : /* Match a NAMELIST statement. */
6598 :
6599 : match
6600 1030 : gfc_match_namelist (void)
6601 : {
6602 1030 : gfc_symbol *group_name, *sym;
6603 1030 : gfc_namelist *nl;
6604 1030 : match m, m2;
6605 :
6606 1030 : m = gfc_match (" / %s /", &group_name);
6607 1030 : if (m == MATCH_NO)
6608 0 : goto syntax;
6609 1030 : if (m == MATCH_ERROR)
6610 0 : goto error;
6611 :
6612 1030 : for (;;)
6613 : {
6614 1030 : if (group_name->ts.type != BT_UNKNOWN)
6615 : {
6616 0 : gfc_error ("Namelist group name %qs at %C already has a basic "
6617 : "type of %s", group_name->name,
6618 : gfc_typename (&group_name->ts));
6619 0 : return MATCH_ERROR;
6620 : }
6621 :
6622 : /* A use associated name shall not be used as a namelist group name
6623 : (e.g. F2003:C581). It is only supported as a legacy extension. */
6624 1030 : if (group_name->attr.flavor == FL_NAMELIST
6625 220 : && group_name->attr.use_assoc
6626 1039 : && !gfc_notify_std (GFC_STD_LEGACY, "Namelist group name %qs "
6627 : "at %C already is USE associated and can"
6628 : "not be respecified.", group_name->name))
6629 : return MATCH_ERROR;
6630 :
6631 1028 : if (group_name->attr.flavor != FL_NAMELIST
6632 1028 : && !gfc_add_flavor (&group_name->attr, FL_NAMELIST,
6633 : group_name->name, NULL))
6634 : return MATCH_ERROR;
6635 :
6636 2094 : for (;;)
6637 : {
6638 2094 : m = gfc_match_symbol (&sym, 1);
6639 2094 : if (m == MATCH_NO)
6640 1 : goto syntax;
6641 2093 : if (m == MATCH_ERROR)
6642 0 : goto error;
6643 :
6644 2093 : if (sym->ts.type == BT_UNKNOWN)
6645 : {
6646 50 : if (gfc_current_ns->seen_implicit_none)
6647 : {
6648 : /* It is required that members of a namelist be declared
6649 : before the namelist. We check this by checking if the
6650 : symbol has a defined type for IMPLICIT NONE. */
6651 1 : gfc_error ("Symbol %qs in namelist %qs at %C must be "
6652 : "declared before the namelist is declared.",
6653 : sym->name, group_name->name);
6654 1 : gfc_error_check ();
6655 : }
6656 : else
6657 : {
6658 : /* Before the symbol is given an implicit type, check to
6659 : see if the symbol is already available in the namespace,
6660 : possibly through host association. Importantly, the
6661 : symbol may be a user defined type. */
6662 :
6663 49 : gfc_symbol *tmp;
6664 :
6665 49 : gfc_find_symbol (sym->name, NULL, 1, &tmp);
6666 49 : if (tmp && tmp->attr.generic
6667 51 : && (tmp = gfc_find_dt_in_generic (tmp)))
6668 : {
6669 2 : if (tmp->attr.flavor == FL_DERIVED)
6670 : {
6671 2 : gfc_error ("Derived type %qs at %L conflicts with "
6672 : "namelist object %qs at %C",
6673 : tmp->name, &tmp->declared_at, sym->name);
6674 2 : goto error;
6675 : }
6676 : }
6677 :
6678 : /* Set type of the symbol to its implicit default type. It is
6679 : not allowed to set it later to any other type. */
6680 47 : gfc_set_default_type (sym, 0, gfc_current_ns);
6681 : }
6682 : }
6683 2091 : if (sym->attr.in_namelist == 0
6684 2091 : && !gfc_add_in_namelist (&sym->attr, sym->name, NULL))
6685 2 : goto error;
6686 :
6687 : /* Use gfc_error_check here, rather than goto error, so that
6688 : these are the only errors for the next two lines. */
6689 2089 : if (sym->as && sym->as->type == AS_ASSUMED_SIZE)
6690 : {
6691 1 : gfc_error ("Assumed size array %qs in namelist %qs at "
6692 : "%C is not allowed", sym->name, group_name->name);
6693 1 : gfc_error_check ();
6694 : }
6695 :
6696 2089 : nl = gfc_get_namelist ();
6697 2089 : nl->sym = sym;
6698 2089 : sym->refs++;
6699 :
6700 2089 : if (group_name->namelist == NULL)
6701 804 : group_name->namelist = group_name->namelist_tail = nl;
6702 : else
6703 : {
6704 1285 : group_name->namelist_tail->next = nl;
6705 1285 : group_name->namelist_tail = nl;
6706 : }
6707 :
6708 2089 : if (gfc_match_eos () == MATCH_YES)
6709 1021 : goto done;
6710 :
6711 1068 : m = gfc_match_char (',');
6712 :
6713 1068 : if (gfc_match_char ('/') == MATCH_YES)
6714 : {
6715 0 : m2 = gfc_match (" %s /", &group_name);
6716 0 : if (m2 == MATCH_YES)
6717 : break;
6718 0 : if (m2 == MATCH_ERROR)
6719 0 : goto error;
6720 0 : goto syntax;
6721 : }
6722 :
6723 1068 : if (m != MATCH_YES)
6724 0 : goto syntax;
6725 : }
6726 : }
6727 :
6728 1021 : done:
6729 1021 : return MATCH_YES;
6730 :
6731 1 : syntax:
6732 1 : gfc_syntax_error (ST_NAMELIST);
6733 :
6734 : error:
6735 : return MATCH_ERROR;
6736 : }
6737 :
6738 :
6739 : /* Match a MODULE statement. */
6740 :
6741 : match
6742 9847 : gfc_match_module (void)
6743 : {
6744 9847 : match m;
6745 :
6746 9847 : m = gfc_match (" %s%t", &gfc_new_block);
6747 9847 : if (m != MATCH_YES)
6748 : return m;
6749 :
6750 9821 : if (!gfc_add_flavor (&gfc_new_block->attr, FL_MODULE,
6751 : gfc_new_block->name, NULL))
6752 0 : return MATCH_ERROR;
6753 :
6754 : return MATCH_YES;
6755 : }
6756 :
6757 :
6758 : /* Free equivalence sets and lists. Recursively is the easiest way to
6759 : do this. */
6760 :
6761 : void
6762 9597422 : gfc_free_equiv_until (gfc_equiv *eq, gfc_equiv *stop)
6763 : {
6764 9597422 : if (eq == stop)
6765 : return;
6766 :
6767 3201 : gfc_free_equiv (eq->eq);
6768 3201 : gfc_free_equiv_until (eq->next, stop);
6769 3201 : gfc_free_expr (eq->expr);
6770 3201 : free (eq);
6771 : }
6772 :
6773 :
6774 : void
6775 532053 : gfc_free_equiv (gfc_equiv *eq)
6776 : {
6777 532053 : gfc_free_equiv_until (eq, NULL);
6778 532053 : }
6779 :
6780 :
6781 : /* Match an EQUIVALENCE statement. */
6782 :
6783 : match
6784 1021 : gfc_match_equivalence (void)
6785 : {
6786 1021 : gfc_equiv *eq, *set, *tail;
6787 1021 : gfc_ref *ref;
6788 1021 : gfc_symbol *sym;
6789 1021 : match m;
6790 1021 : gfc_common_head *common_head = NULL;
6791 1021 : bool common_flag;
6792 1021 : int cnt;
6793 1021 : char c;
6794 :
6795 : /* EQUIVALENCE has been matched. After gobbling any possible whitespace,
6796 : the next character needs to be '('. Check that here, and return
6797 : MATCH_NO for a variable of the form equivalence. */
6798 1021 : gfc_gobble_whitespace ();
6799 1021 : c = gfc_peek_ascii_char ();
6800 1021 : if (c != '(')
6801 : return MATCH_NO;
6802 :
6803 : tail = NULL;
6804 :
6805 1453 : for (;;)
6806 : {
6807 1453 : eq = gfc_get_equiv ();
6808 1453 : if (tail == NULL)
6809 1020 : tail = eq;
6810 :
6811 1453 : eq->next = gfc_current_ns->equiv;
6812 1453 : gfc_current_ns->equiv = eq;
6813 :
6814 1453 : if (gfc_match_char ('(') != MATCH_YES)
6815 0 : goto syntax;
6816 :
6817 : set = eq;
6818 : common_flag = false;
6819 : cnt = 0;
6820 :
6821 4441 : for (;;)
6822 : {
6823 2947 : m = gfc_match_equiv_variable (&set->expr);
6824 2947 : if (m == MATCH_ERROR)
6825 1 : goto cleanup;
6826 2946 : if (m == MATCH_NO)
6827 0 : goto syntax;
6828 :
6829 : /* count the number of objects. */
6830 2946 : cnt++;
6831 :
6832 2946 : if (gfc_match_char ('%') == MATCH_YES)
6833 : {
6834 0 : gfc_error ("Derived type component %C is not a "
6835 : "permitted EQUIVALENCE member");
6836 0 : goto cleanup;
6837 : }
6838 :
6839 5020 : for (ref = set->expr->ref; ref; ref = ref->next)
6840 2074 : if (ref->type == REF_ARRAY && ref->u.ar.type == AR_SECTION)
6841 : {
6842 0 : gfc_error ("Array reference in EQUIVALENCE at %C cannot "
6843 : "be an array section");
6844 0 : goto cleanup;
6845 : }
6846 :
6847 2946 : sym = set->expr->symtree->n.sym;
6848 :
6849 2946 : if (!gfc_add_in_equivalence (&sym->attr, sym->name, NULL))
6850 6 : goto cleanup;
6851 2940 : if (sym->ts.type == BT_CLASS
6852 3 : && CLASS_DATA (sym)
6853 2943 : && !gfc_add_in_equivalence (&CLASS_DATA (sym)->attr,
6854 : sym->name, NULL))
6855 3 : goto cleanup;
6856 :
6857 2937 : if (sym->attr.in_common)
6858 : {
6859 301 : common_flag = true;
6860 301 : common_head = sym->common_head;
6861 : }
6862 :
6863 2937 : if (gfc_match_char (')') == MATCH_YES)
6864 : break;
6865 :
6866 1494 : if (gfc_match_char (',') != MATCH_YES)
6867 0 : goto syntax;
6868 :
6869 1494 : set->eq = gfc_get_equiv ();
6870 1494 : set = set->eq;
6871 : }
6872 :
6873 1443 : if (cnt < 2)
6874 : {
6875 1 : gfc_error ("EQUIVALENCE at %C requires two or more objects");
6876 1 : goto cleanup;
6877 : }
6878 :
6879 : /* If one of the members of an equivalence is in common, then
6880 : mark them all as being in common. Before doing this, check
6881 : that members of the equivalence group are not in different
6882 : common blocks. */
6883 1442 : if (common_flag)
6884 901 : for (set = eq; set; set = set->eq)
6885 : {
6886 609 : sym = set->expr->symtree->n.sym;
6887 609 : if (sym->common_head && sym->common_head != common_head)
6888 : {
6889 1 : gfc_error ("Attempt to indirectly overlap COMMON "
6890 : "blocks %s and %s by EQUIVALENCE at %C",
6891 1 : sym->common_head->name, common_head->name);
6892 1 : goto cleanup;
6893 : }
6894 608 : sym->attr.in_common = 1;
6895 608 : sym->common_head = common_head;
6896 : }
6897 :
6898 1441 : if (gfc_match_eos () == MATCH_YES)
6899 : break;
6900 434 : if (gfc_match_char (',') != MATCH_YES)
6901 : {
6902 1 : gfc_error ("Expecting a comma in EQUIVALENCE at %C");
6903 1 : goto cleanup;
6904 : }
6905 : }
6906 :
6907 1007 : if (!gfc_notify_std (GFC_STD_F2018_OBS, "EQUIVALENCE statement at %C"))
6908 : return MATCH_ERROR;
6909 :
6910 : return MATCH_YES;
6911 :
6912 0 : syntax:
6913 0 : gfc_syntax_error (ST_EQUIVALENCE);
6914 :
6915 13 : cleanup:
6916 13 : eq = tail->next;
6917 13 : tail->next = NULL;
6918 :
6919 13 : gfc_free_equiv (gfc_current_ns->equiv);
6920 13 : gfc_current_ns->equiv = eq;
6921 :
6922 13 : return MATCH_ERROR;
6923 : }
6924 :
6925 :
6926 : /* Check that a statement function is not recursive. This is done by looking
6927 : for the statement function symbol(sym) by looking recursively through its
6928 : expression(e). If a reference to sym is found, true is returned.
6929 : 12.5.4 requires that any variable of function that is implicitly typed
6930 : shall have that type confirmed by any subsequent type declaration. The
6931 : implicit typing is conveniently done here. */
6932 : static bool
6933 : recursive_stmt_fcn (gfc_expr *, gfc_symbol *);
6934 :
6935 : static bool
6936 908 : check_stmt_fcn (gfc_expr *e, gfc_symbol *sym, int *f ATTRIBUTE_UNUSED)
6937 : {
6938 :
6939 908 : if (e == NULL)
6940 : return false;
6941 :
6942 908 : switch (e->expr_type)
6943 : {
6944 118 : case EXPR_FUNCTION:
6945 118 : if (e->symtree == NULL)
6946 : return false;
6947 :
6948 : /* Check the name before testing for nested recursion! */
6949 118 : if (sym->name == e->symtree->n.sym->name)
6950 : return true;
6951 :
6952 : /* Catch recursion via other statement functions. */
6953 117 : if (e->symtree->n.sym->attr.proc == PROC_ST_FUNCTION
6954 4 : && e->symtree->n.sym->value
6955 121 : && recursive_stmt_fcn (e->symtree->n.sym->value, sym))
6956 : return true;
6957 :
6958 115 : if (e->symtree->n.sym->ts.type == BT_UNKNOWN)
6959 65 : gfc_set_default_type (e->symtree->n.sym, 0, NULL);
6960 :
6961 : break;
6962 :
6963 418 : case EXPR_VARIABLE:
6964 418 : if (e->symtree && sym->name == e->symtree->n.sym->name)
6965 : return true;
6966 :
6967 418 : if (e->symtree->n.sym->ts.type == BT_UNKNOWN)
6968 152 : gfc_set_default_type (e->symtree->n.sym, 0, NULL);
6969 : break;
6970 :
6971 : default:
6972 : break;
6973 : }
6974 :
6975 : return false;
6976 : }
6977 :
6978 :
6979 : static bool
6980 239 : recursive_stmt_fcn (gfc_expr *e, gfc_symbol *sym)
6981 : {
6982 4 : return gfc_traverse_expr (e, sym, check_stmt_fcn, 0);
6983 : }
6984 :
6985 :
6986 : /* Check for invalid uses of statement function dummy arguments in body. */
6987 :
6988 : static bool
6989 879 : chk_stmt_fcn_body (gfc_expr *e, gfc_symbol *sym, int *f ATTRIBUTE_UNUSED)
6990 : {
6991 879 : gfc_formal_arglist *formal;
6992 :
6993 879 : if (e == NULL || e->symtree == NULL || e->expr_type != EXPR_FUNCTION)
6994 : return false;
6995 :
6996 275 : for (formal = sym->formal; formal; formal = formal->next)
6997 : {
6998 165 : if (formal->sym == e->symtree->n.sym)
6999 : {
7000 2 : gfc_error ("Invalid use of statement function argument at %L",
7001 : &e->where);
7002 2 : return true;
7003 : }
7004 : }
7005 :
7006 : return false;
7007 : }
7008 :
7009 :
7010 : /* Match a statement function declaration. It is so easy to match
7011 : non-statement function statements with a MATCH_ERROR as opposed to
7012 : MATCH_NO that we suppress error message in most cases. */
7013 :
7014 : match
7015 419624 : gfc_match_st_function (void)
7016 : {
7017 419624 : gfc_error_buffer old_error;
7018 419624 : gfc_symbol *sym;
7019 419624 : gfc_expr *expr;
7020 419624 : match m;
7021 419624 : char name[GFC_MAX_SYMBOL_LEN + 1];
7022 419624 : locus old_locus;
7023 419624 : bool fcn;
7024 419624 : gfc_formal_arglist *ptr;
7025 :
7026 : /* Read the possible statement function name, and then check to see if
7027 : a symbol is already present in the namespace. Record if it is a
7028 : function and whether it has been referenced. */
7029 419624 : fcn = false;
7030 419624 : ptr = NULL;
7031 419624 : old_locus = gfc_current_locus;
7032 419624 : m = gfc_match_name (name);
7033 419624 : if (m == MATCH_YES)
7034 : {
7035 419624 : gfc_find_symbol (name, NULL, 1, &sym);
7036 419624 : if (sym && sym->attr.function && !sym->attr.referenced)
7037 : {
7038 138 : fcn = true;
7039 138 : ptr = sym->formal;
7040 : }
7041 : }
7042 :
7043 419624 : gfc_current_locus = old_locus;
7044 419624 : m = gfc_match_symbol (&sym, 0);
7045 419624 : if (m != MATCH_YES)
7046 : return m;
7047 :
7048 419611 : gfc_push_error (&old_error);
7049 :
7050 419611 : if (!gfc_add_procedure (&sym->attr, PROC_ST_FUNCTION, sym->name, NULL))
7051 422 : goto undo_error;
7052 :
7053 419189 : if (gfc_match_formal_arglist (sym, 1, 0) != MATCH_YES)
7054 343312 : goto undo_error;
7055 :
7056 75877 : m = gfc_match (" = %e%t", &expr);
7057 75877 : if (m == MATCH_NO)
7058 75642 : goto undo_error;
7059 :
7060 235 : gfc_free_error (&old_error);
7061 :
7062 235 : if (m == MATCH_ERROR)
7063 : return m;
7064 :
7065 235 : if (recursive_stmt_fcn (expr, sym))
7066 : {
7067 1 : gfc_error ("Statement function at %L is recursive", &expr->where);
7068 1 : return MATCH_ERROR;
7069 : }
7070 :
7071 234 : if (fcn && ptr != sym->formal)
7072 : {
7073 4 : gfc_error ("Statement function %qs at %L conflicts with function name",
7074 4 : sym->name, &expr->where);
7075 4 : return MATCH_ERROR;
7076 : }
7077 :
7078 230 : if (gfc_traverse_expr (expr, sym, chk_stmt_fcn_body, 0))
7079 : return MATCH_ERROR;
7080 :
7081 228 : sym->value = expr;
7082 :
7083 228 : if ((gfc_current_state () == COMP_FUNCTION
7084 228 : || gfc_current_state () == COMP_SUBROUTINE)
7085 138 : && gfc_state_stack->previous->state == COMP_INTERFACE)
7086 : {
7087 1 : gfc_error ("Statement function at %L cannot appear within an INTERFACE",
7088 : &expr->where);
7089 1 : return MATCH_ERROR;
7090 : }
7091 :
7092 227 : if (!gfc_notify_std (GFC_STD_F95_OBS, "Statement function at %C"))
7093 : return MATCH_ERROR;
7094 :
7095 : return MATCH_YES;
7096 :
7097 419376 : undo_error:
7098 419376 : gfc_pop_error (&old_error);
7099 419376 : return MATCH_NO;
7100 419624 : }
7101 :
7102 :
7103 : /* Match an assignment to a pointer function (F2008). This could, in
7104 : general be ambiguous with a statement function. In this implementation
7105 : it remains so if it is the first statement after the specification
7106 : block. */
7107 :
7108 : match
7109 1016485 : gfc_match_ptr_fcn_assign (void)
7110 : {
7111 1016485 : gfc_error_buffer old_error;
7112 1016485 : locus old_loc;
7113 1016485 : gfc_symbol *sym;
7114 1016485 : gfc_expr *expr;
7115 1016485 : match m;
7116 1016485 : char name[GFC_MAX_SYMBOL_LEN + 1];
7117 :
7118 1016485 : old_loc = gfc_current_locus;
7119 1016485 : m = gfc_match_name (name);
7120 1016485 : if (m != MATCH_YES)
7121 : return m;
7122 :
7123 1016482 : gfc_find_symbol (name, NULL, 1, &sym);
7124 1016482 : if (sym && sym->attr.flavor != FL_PROCEDURE)
7125 : return MATCH_NO;
7126 :
7127 1016206 : gfc_push_error (&old_error);
7128 :
7129 1016206 : if (sym && sym->attr.function)
7130 924 : goto match_actual_arglist;
7131 :
7132 1015282 : gfc_current_locus = old_loc;
7133 1015282 : m = gfc_match_symbol (&sym, 0);
7134 1015282 : if (m != MATCH_YES)
7135 : return m;
7136 :
7137 1015269 : if (!gfc_add_procedure (&sym->attr, PROC_UNKNOWN, sym->name, NULL))
7138 1 : goto undo_error;
7139 :
7140 1015268 : match_actual_arglist:
7141 1016192 : gfc_current_locus = old_loc;
7142 1016192 : m = gfc_match (" %e", &expr);
7143 1016191 : if (m != MATCH_YES)
7144 631116 : goto undo_error;
7145 :
7146 385075 : new_st.op = EXEC_ASSIGN;
7147 385075 : new_st.expr1 = expr;
7148 385075 : expr = NULL;
7149 :
7150 385075 : m = gfc_match (" = %e%t", &expr);
7151 385075 : if (m != MATCH_YES)
7152 384925 : goto undo_error;
7153 :
7154 150 : new_st.expr2 = expr;
7155 150 : return MATCH_YES;
7156 :
7157 1016042 : undo_error:
7158 1016042 : gfc_pop_error (&old_error);
7159 1016042 : return MATCH_NO;
7160 1016484 : }
7161 :
7162 :
7163 : /***************** SELECT CASE subroutines ******************/
7164 :
7165 : /* Free a single case structure. */
7166 :
7167 : static void
7168 10168 : free_case (gfc_case *p)
7169 : {
7170 10168 : if (p->low == p->high)
7171 4748 : p->high = NULL;
7172 10168 : gfc_free_expr (p->low);
7173 10168 : gfc_free_expr (p->high);
7174 10168 : free (p);
7175 10168 : }
7176 :
7177 :
7178 : /* Free a list of case structures. */
7179 :
7180 : void
7181 9972 : gfc_free_case_list (gfc_case *p)
7182 : {
7183 9972 : gfc_case *q;
7184 :
7185 20130 : for (; p; p = q)
7186 : {
7187 10158 : q = p->next;
7188 10158 : free_case (p);
7189 : }
7190 9972 : }
7191 :
7192 :
7193 : /* Match a single case selector. Combining the requirements of F08:C830
7194 : and F08:C832 (R838) means that the case-value must have either CHARACTER,
7195 : INTEGER, or LOGICAL type. */
7196 :
7197 : static match
7198 1434 : match_case_selector (gfc_case **cp)
7199 : {
7200 1434 : gfc_case *c;
7201 1434 : match m;
7202 :
7203 1434 : c = gfc_get_case ();
7204 1434 : c->where = gfc_current_locus;
7205 :
7206 1434 : if (gfc_match_char (':') == MATCH_YES)
7207 : {
7208 48 : m = gfc_match_init_expr (&c->high);
7209 48 : if (m == MATCH_NO)
7210 0 : goto need_expr;
7211 48 : if (m == MATCH_ERROR)
7212 0 : goto cleanup;
7213 :
7214 48 : if (c->high->ts.type != BT_LOGICAL && c->high->ts.type != BT_INTEGER
7215 2 : && c->high->ts.type != BT_CHARACTER
7216 2 : && (!flag_unsigned
7217 0 : || (flag_unsigned && c->high->ts.type != BT_UNSIGNED)))
7218 : {
7219 2 : gfc_error ("Expression in CASE selector at %L cannot be %s",
7220 2 : &c->high->where, gfc_typename (&c->high->ts));
7221 2 : goto cleanup;
7222 : }
7223 : }
7224 : else
7225 : {
7226 1386 : m = gfc_match_init_expr (&c->low);
7227 1386 : if (m == MATCH_ERROR)
7228 0 : goto cleanup;
7229 1386 : if (m == MATCH_NO)
7230 0 : goto need_expr;
7231 :
7232 1386 : if (c->low->ts.type != BT_LOGICAL && c->low->ts.type != BT_INTEGER
7233 357 : && c->low->ts.type != BT_CHARACTER
7234 43 : && (!flag_unsigned
7235 42 : || (flag_unsigned && c->low->ts.type != BT_UNSIGNED)))
7236 : {
7237 1 : gfc_error ("Expression in CASE selector at %L cannot be %s",
7238 1 : &c->low->where, gfc_typename (&c->low->ts));
7239 1 : goto cleanup;
7240 : }
7241 :
7242 : /* If we're not looking at a ':' now, make a range out of a single
7243 : target. Else get the upper bound for the case range. */
7244 1385 : if (gfc_match_char (':') != MATCH_YES)
7245 1218 : c->high = c->low;
7246 : else
7247 : {
7248 167 : m = gfc_match_init_expr (&c->high);
7249 167 : if (m == MATCH_ERROR)
7250 0 : goto cleanup;
7251 167 : if (m == MATCH_YES
7252 119 : && c->high->ts.type != BT_LOGICAL
7253 : && c->high->ts.type != BT_INTEGER
7254 : && c->high->ts.type != BT_CHARACTER
7255 1 : && (!flag_unsigned
7256 0 : || (flag_unsigned && c->high->ts.type != BT_UNSIGNED)))
7257 : {
7258 1 : gfc_error ("Expression in CASE selector at %L cannot be %s",
7259 1 : &c->high->where, gfc_typename (c->high));
7260 1 : goto cleanup;
7261 : }
7262 : /* MATCH_NO is fine. It's OK if nothing is there! */
7263 : }
7264 : }
7265 :
7266 1430 : if (c->low && c->low->rank != 0)
7267 : {
7268 4 : gfc_error ("Expression in CASE selector at %L must be scalar",
7269 : &c->low->where);
7270 4 : goto cleanup;
7271 : }
7272 1426 : if (c->high && c->high->rank != 0)
7273 : {
7274 2 : gfc_error ("Expression in CASE selector at %L must be scalar",
7275 : &c->high->where);
7276 2 : goto cleanup;
7277 : }
7278 :
7279 1424 : *cp = c;
7280 1424 : return MATCH_YES;
7281 :
7282 0 : need_expr:
7283 0 : gfc_error ("Expected initialization expression in CASE at %C");
7284 :
7285 10 : cleanup:
7286 10 : free_case (c);
7287 10 : return MATCH_ERROR;
7288 : }
7289 :
7290 :
7291 : /* Match the end of a case statement. */
7292 :
7293 : static match
7294 9330 : match_case_eos (void)
7295 : {
7296 9330 : char name[GFC_MAX_SYMBOL_LEN + 1];
7297 9330 : match m;
7298 :
7299 9330 : if (gfc_match_eos () == MATCH_YES)
7300 : return MATCH_YES;
7301 :
7302 : /* If the case construct doesn't have a case-construct-name, we
7303 : should have matched the EOS. */
7304 21 : if (!gfc_current_block ())
7305 : return MATCH_NO;
7306 :
7307 17 : gfc_gobble_whitespace ();
7308 :
7309 17 : m = gfc_match_name (name);
7310 17 : if (m != MATCH_YES)
7311 : return m;
7312 :
7313 17 : if (strcmp (name, gfc_current_block ()->name) != 0)
7314 : {
7315 1 : gfc_error ("Expected block name %qs of SELECT construct at %C",
7316 : gfc_current_block ()->name);
7317 1 : return MATCH_ERROR;
7318 : }
7319 :
7320 16 : return gfc_match_eos ();
7321 : }
7322 :
7323 :
7324 : /* Match a SELECT statement. */
7325 :
7326 : match
7327 491357 : gfc_match_select (void)
7328 : {
7329 491357 : gfc_expr *expr;
7330 491357 : match m;
7331 :
7332 491357 : m = gfc_match_label ();
7333 491357 : if (m == MATCH_ERROR)
7334 : return m;
7335 :
7336 491349 : m = gfc_match (" select case ( %e )%t", &expr);
7337 491349 : if (m != MATCH_YES)
7338 : return m;
7339 :
7340 532 : new_st.op = EXEC_SELECT;
7341 532 : new_st.expr1 = expr;
7342 :
7343 532 : return MATCH_YES;
7344 : }
7345 :
7346 :
7347 : /* Transfer the selector typespec to the associate name. */
7348 :
7349 : static void
7350 641 : copy_ts_from_selector_to_associate (gfc_expr *associate, gfc_expr *selector,
7351 : bool select_type = false)
7352 : {
7353 641 : gfc_ref *ref;
7354 641 : gfc_symbol *assoc_sym;
7355 641 : int rank = 0, corank = 0;
7356 :
7357 641 : assoc_sym = associate->symtree->n.sym;
7358 :
7359 : /* At this stage the expression rank and arrayspec dimensions have
7360 : not been completely sorted out. We must get the expr2->rank
7361 : right here, so that the correct class container is obtained. */
7362 641 : ref = selector->ref;
7363 895 : while (ref && ref->next)
7364 : ref = ref->next;
7365 :
7366 641 : if (selector->ts.type == BT_CLASS
7367 626 : && CLASS_DATA (selector)
7368 624 : && CLASS_DATA (selector)->as
7369 382 : && CLASS_DATA (selector)->as->type == AS_ASSUMED_RANK)
7370 : {
7371 12 : assoc_sym->attr.dimension = 1;
7372 12 : assoc_sym->as = gfc_copy_array_spec (CLASS_DATA (selector)->as);
7373 12 : corank = assoc_sym->as->corank;
7374 12 : goto build_class_sym;
7375 : }
7376 629 : else if (selector->ts.type == BT_CLASS
7377 614 : && CLASS_DATA (selector)
7378 612 : && CLASS_DATA (selector)->as
7379 370 : && ((ref && ref->type == REF_ARRAY)
7380 2 : || selector->expr_type == EXPR_OP))
7381 : {
7382 : /* Ensure that the array reference type is set. We cannot use
7383 : gfc_resolve_expr at this point, so the usable parts of
7384 : resolve.cc(resolve_array_ref) are employed to do it. */
7385 370 : if (ref && ref->u.ar.type == AR_UNKNOWN)
7386 : {
7387 108 : ref->u.ar.type = AR_ELEMENT;
7388 185 : for (int i = 0; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
7389 114 : if (ref->u.ar.dimen_type[i] == DIMEN_RANGE
7390 114 : || ref->u.ar.dimen_type[i] == DIMEN_VECTOR
7391 78 : || (ref->u.ar.dimen_type[i] == DIMEN_UNKNOWN
7392 78 : && ref->u.ar.start[i] && ref->u.ar.start[i]->rank))
7393 : {
7394 37 : ref->u.ar.type = AR_SECTION;
7395 37 : break;
7396 : }
7397 : }
7398 :
7399 368 : if (!ref || ref->u.ar.type == AR_FULL)
7400 : {
7401 262 : selector->rank = CLASS_DATA (selector)->as->rank;
7402 262 : selector->corank = CLASS_DATA (selector)->as->corank;
7403 : }
7404 108 : else if (ref->u.ar.type == AR_SECTION)
7405 : {
7406 37 : selector->rank = ref->u.ar.dimen;
7407 37 : selector->corank = ref->u.ar.codimen;
7408 : }
7409 : else
7410 71 : selector->rank = 0;
7411 :
7412 370 : rank = selector->rank;
7413 370 : corank = selector->corank;
7414 : }
7415 :
7416 370 : if (rank)
7417 : {
7418 290 : if (ref)
7419 : {
7420 337 : for (int i = 0; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
7421 49 : if (ref->u.ar.dimen_type[i] == DIMEN_ELEMENT
7422 49 : || (ref->u.ar.dimen_type[i] == DIMEN_UNKNOWN
7423 7 : && ref->u.ar.end[i] == NULL
7424 7 : && ref->u.ar.stride[i] == NULL))
7425 7 : rank--;
7426 : }
7427 :
7428 290 : if (rank)
7429 : {
7430 289 : assoc_sym->attr.dimension = 1;
7431 289 : assoc_sym->as = gfc_get_array_spec ();
7432 289 : assoc_sym->as->rank = rank;
7433 289 : assoc_sym->as->type = AS_DEFERRED;
7434 : }
7435 : }
7436 :
7437 629 : if (corank != 0 && rank == 0)
7438 : {
7439 9 : if (!assoc_sym->as)
7440 9 : assoc_sym->as = gfc_get_array_spec ();
7441 9 : assoc_sym->as->corank = corank;
7442 9 : assoc_sym->attr.codimension = 1;
7443 : }
7444 620 : else if (corank == 0 && rank == 0 && assoc_sym->as)
7445 : {
7446 0 : free (assoc_sym->as);
7447 0 : assoc_sym->as = NULL;
7448 : }
7449 620 : build_class_sym:
7450 : /* Deal with the very specific case of a SELECT_TYPE selector being an
7451 : associate_name whose type has been identified by component references.
7452 : It must be assumed that it will be identified as a CLASS expression,
7453 : so convert it now. */
7454 641 : if (select_type
7455 629 : && IS_INFERRED_TYPE (selector)
7456 13 : && selector->ts.type == BT_DERIVED)
7457 : {
7458 13 : gfc_find_derived_vtab (selector->ts.u.derived);
7459 : /* The correct class container has to be available. */
7460 13 : assoc_sym->ts.u.derived = selector->ts.u.derived;
7461 13 : assoc_sym->ts.type = BT_CLASS;
7462 13 : assoc_sym->attr.pointer = 1;
7463 13 : if (!selector->ts.u.derived->attr.is_class)
7464 13 : gfc_build_class_symbol (&assoc_sym->ts, &assoc_sym->attr, &assoc_sym->as);
7465 13 : associate->ts = assoc_sym->ts;
7466 : }
7467 628 : else if (selector->ts.type == BT_CLASS)
7468 : {
7469 : /* The correct class container has to be available. */
7470 626 : assoc_sym->ts.type = BT_CLASS;
7471 1252 : assoc_sym->ts.u.derived = CLASS_DATA (selector)
7472 626 : ? CLASS_DATA (selector)->ts.u.derived
7473 : : selector->ts.u.derived;
7474 626 : assoc_sym->attr.pointer = 1;
7475 626 : gfc_build_class_symbol (&assoc_sym->ts, &assoc_sym->attr, &assoc_sym->as);
7476 : }
7477 641 : }
7478 :
7479 :
7480 : /* Build the associate name */
7481 : static int
7482 660 : build_associate_name (const char *name, gfc_expr **e1, gfc_expr **e2)
7483 : {
7484 660 : gfc_expr *expr1 = *e1;
7485 660 : gfc_expr *expr2 = *e2;
7486 660 : gfc_symbol *sym;
7487 :
7488 : /* For the case where the associate name is already an associate name. */
7489 660 : if (!expr2)
7490 63 : expr2 = expr1;
7491 660 : expr1 = gfc_get_expr ();
7492 660 : expr1->expr_type = EXPR_VARIABLE;
7493 660 : expr1->where = expr2->where;
7494 660 : if (gfc_get_sym_tree (name, NULL, &expr1->symtree, false))
7495 : return 1;
7496 :
7497 660 : sym = expr1->symtree->n.sym;
7498 660 : if (expr2->ts.type == BT_UNKNOWN)
7499 31 : sym->attr.untyped = 1;
7500 : else
7501 629 : copy_ts_from_selector_to_associate (expr1, expr2, true);
7502 :
7503 660 : sym->attr.flavor = FL_VARIABLE;
7504 660 : sym->attr.referenced = 1;
7505 660 : sym->attr.class_ok = 1;
7506 :
7507 660 : *e1 = expr1;
7508 660 : *e2 = expr2;
7509 660 : return 0;
7510 : }
7511 :
7512 :
7513 : /* Push the current selector onto the SELECT TYPE stack. */
7514 :
7515 : static void
7516 4078 : select_type_push (gfc_symbol *sel)
7517 : {
7518 4078 : gfc_select_type_stack *top = gfc_get_select_type_stack ();
7519 4078 : top->selector = sel;
7520 4078 : top->tmp = NULL;
7521 4078 : top->prev = select_type_stack;
7522 :
7523 4078 : select_type_stack = top;
7524 4078 : }
7525 :
7526 :
7527 : /* Set the temporary for the current intrinsic SELECT TYPE selector. */
7528 :
7529 : static gfc_symtree *
7530 3798 : select_intrinsic_set_tmp (gfc_typespec *ts, const char *var_name)
7531 : {
7532 : /* Keep size in sync with the buffer size in resolve_select_type as it
7533 : determines the final name through truncation. */
7534 3798 : char name[GFC_MAX_SYMBOL_LEN + 12 + 1];
7535 3798 : gfc_symtree *tmp;
7536 3798 : HOST_WIDE_INT charlen = 0;
7537 3798 : gfc_symbol *selector = select_type_stack->selector;
7538 3798 : gfc_symbol *sym;
7539 :
7540 3798 : if (ts->type == BT_CLASS || ts->type == BT_DERIVED)
7541 : return NULL;
7542 :
7543 1449 : if (selector->ts.type == BT_CLASS && !selector->attr.class_ok)
7544 : return NULL;
7545 :
7546 : /* Case value == NULL corresponds to SELECT TYPE cases otherwise
7547 : the values correspond to SELECT rank cases. */
7548 1448 : if (ts->type == BT_CHARACTER && ts->u.cl && ts->u.cl->length
7549 0 : && ts->u.cl->length->expr_type == EXPR_CONSTANT)
7550 0 : charlen = gfc_mpz_get_hwi (ts->u.cl->length->value.integer);
7551 :
7552 1448 : if (ts->type != BT_CHARACTER)
7553 711 : snprintf (name, sizeof (name), "__tmp_%s_%d_%s",
7554 : gfc_basic_typename (ts->type), ts->kind, var_name);
7555 : else
7556 737 : snprintf (name, sizeof (name),
7557 : "__tmp_%s_" HOST_WIDE_INT_PRINT_DEC "_%d_%s",
7558 : gfc_basic_typename (ts->type), charlen, ts->kind, var_name);
7559 :
7560 1448 : gfc_get_sym_tree (name, gfc_current_ns, &tmp, false);
7561 1448 : sym = tmp->n.sym;
7562 1448 : gfc_add_type (sym, ts, NULL);
7563 :
7564 : /* Copy across the array spec to the selector. */
7565 1448 : if (selector->ts.type == BT_CLASS
7566 1446 : && (CLASS_DATA (selector)->attr.dimension
7567 730 : || CLASS_DATA (selector)->attr.codimension))
7568 : {
7569 728 : sym->attr.pointer = 1;
7570 728 : sym->attr.dimension = CLASS_DATA (selector)->attr.dimension;
7571 728 : sym->attr.codimension = CLASS_DATA (selector)->attr.codimension;
7572 728 : sym->as = gfc_copy_array_spec (CLASS_DATA (selector)->as);
7573 : }
7574 :
7575 1448 : gfc_set_sym_referenced (sym);
7576 1448 : gfc_add_flavor (&sym->attr, FL_VARIABLE, name, NULL);
7577 1448 : sym->attr.select_type_temporary = 1;
7578 :
7579 1448 : return tmp;
7580 : }
7581 :
7582 :
7583 : /* Set up a temporary for the current TYPE IS / CLASS IS branch . */
7584 :
7585 : static void
7586 5429 : select_type_set_tmp (gfc_typespec *ts)
7587 : {
7588 5429 : char name[GFC_MAX_SYMBOL_LEN + 12 + 1];
7589 5429 : gfc_symtree *tmp = NULL;
7590 5429 : gfc_symbol *selector = select_type_stack->selector;
7591 5429 : gfc_symbol *sym;
7592 5429 : gfc_expr *expr2;
7593 :
7594 5429 : if (!ts)
7595 : {
7596 1631 : select_type_stack->tmp = NULL;
7597 1632 : return;
7598 : }
7599 :
7600 3798 : gfc_expr *select_type_expr = gfc_state_stack->construct->expr1;
7601 3798 : const char *var_name = gfc_var_name_for_select_type_temp (select_type_expr);
7602 3798 : tmp = select_intrinsic_set_tmp (ts, var_name);
7603 :
7604 3798 : if (tmp == NULL)
7605 : {
7606 2350 : if (!ts->u.derived)
7607 : return;
7608 :
7609 2349 : if (ts->type == BT_CLASS)
7610 352 : snprintf (name, sizeof (name), "__tmp_class_%s_%s", ts->u.derived->name,
7611 : var_name);
7612 : else
7613 1997 : snprintf (name, sizeof (name), "__tmp_type_%s_%s", ts->u.derived->name,
7614 : var_name);
7615 :
7616 2349 : gfc_get_sym_tree (name, gfc_current_ns, &tmp, false);
7617 2349 : sym = tmp->n.sym;
7618 2349 : gfc_add_type (sym, ts, NULL);
7619 :
7620 : /* If the SELECT TYPE selector is a function we might be able to obtain
7621 : a typespec from the result. Since the function might not have been
7622 : parsed yet we have to check that there is indeed a result symbol. */
7623 2349 : if (selector->ts.type == BT_UNKNOWN
7624 46 : && gfc_state_stack->construct
7625 :
7626 46 : && (expr2 = gfc_state_stack->construct->expr2)
7627 33 : && expr2->expr_type == EXPR_FUNCTION
7628 14 : && expr2->symtree
7629 2363 : && expr2->symtree->n.sym && expr2->symtree->n.sym->result)
7630 14 : selector->ts = expr2->symtree->n.sym->result->ts;
7631 :
7632 2349 : if (selector->ts.type == BT_CLASS
7633 2309 : && selector->attr.class_ok
7634 2307 : && selector->ts.u.derived && CLASS_DATA (selector))
7635 : {
7636 2305 : sym->attr.pointer
7637 2305 : = CLASS_DATA (selector)->attr.class_pointer;
7638 :
7639 : /* Copy across the array spec to the selector. */
7640 2305 : if (CLASS_DATA (selector)->attr.dimension
7641 1571 : || CLASS_DATA (selector)->attr.codimension)
7642 : {
7643 741 : sym->attr.dimension
7644 741 : = CLASS_DATA (selector)->attr.dimension;
7645 741 : sym->attr.codimension
7646 741 : = CLASS_DATA (selector)->attr.codimension;
7647 741 : if (CLASS_DATA (selector)->as->type != AS_EXPLICIT)
7648 698 : sym->as = gfc_copy_array_spec (CLASS_DATA (selector)->as);
7649 : else
7650 : {
7651 43 : sym->as = gfc_get_array_spec();
7652 43 : sym->as->rank = CLASS_DATA (selector)->as->rank;
7653 43 : sym->as->type = AS_DEFERRED;
7654 : }
7655 : }
7656 : }
7657 :
7658 2349 : gfc_set_sym_referenced (sym);
7659 2349 : gfc_add_flavor (&sym->attr, FL_VARIABLE, name, NULL);
7660 2349 : sym->attr.select_type_temporary = 1;
7661 :
7662 2349 : if (ts->type == BT_CLASS)
7663 352 : gfc_build_class_symbol (&sym->ts, &sym->attr, &sym->as);
7664 : }
7665 : else
7666 1448 : sym = tmp->n.sym;
7667 :
7668 :
7669 : /* Add an association for it, so the rest of the parser knows it is
7670 : an associate-name. The target will be set during resolution. */
7671 3797 : sym->assoc = gfc_get_association_list ();
7672 3797 : sym->assoc->dangling = 1;
7673 3797 : sym->assoc->st = tmp;
7674 :
7675 3797 : select_type_stack->tmp = tmp;
7676 : }
7677 :
7678 :
7679 : /* Match a SELECT TYPE statement. */
7680 :
7681 : match
7682 490825 : gfc_match_select_type (void)
7683 : {
7684 490825 : gfc_expr *expr1, *expr2 = NULL;
7685 490825 : match m;
7686 490825 : char name[GFC_MAX_SYMBOL_LEN + 1];
7687 490825 : bool class_array;
7688 490825 : gfc_namespace *ns = gfc_current_ns;
7689 :
7690 490825 : m = gfc_match_label ();
7691 490825 : if (m == MATCH_ERROR)
7692 : return m;
7693 :
7694 490817 : m = gfc_match (" select type ( ");
7695 490817 : if (m != MATCH_YES)
7696 : return m;
7697 :
7698 3063 : if (gfc_current_state() == COMP_MODULE
7699 3063 : || gfc_current_state() == COMP_SUBMODULE)
7700 : {
7701 2 : gfc_error ("SELECT TYPE at %C cannot appear in this scope");
7702 2 : return MATCH_ERROR;
7703 : }
7704 :
7705 3061 : gfc_current_ns = gfc_build_block_ns (ns);
7706 3061 : m = gfc_match (" %n => %e", name, &expr2);
7707 3061 : if (m == MATCH_YES)
7708 : {
7709 597 : if (build_associate_name (name, &expr1, &expr2))
7710 : {
7711 0 : m = MATCH_ERROR;
7712 0 : goto cleanup;
7713 : }
7714 : }
7715 : else
7716 : {
7717 2464 : m = gfc_match (" %e ", &expr1);
7718 2464 : if (m == MATCH_NO)
7719 : {
7720 0 : std::swap (ns, gfc_current_ns);
7721 0 : gfc_free_namespace (ns);
7722 0 : return m;
7723 : }
7724 : /* On MATCH_ERROR, the temporary block namespace may already contain
7725 : broken state from the failed expression match. Avoid freeing it
7726 : through the normal rollback path. */
7727 2464 : else if (m == MATCH_ERROR)
7728 : return m;
7729 : }
7730 :
7731 3060 : m = gfc_match (" )%t");
7732 3060 : if (m != MATCH_YES)
7733 : {
7734 2 : gfc_error ("parse error in SELECT TYPE statement at %C");
7735 2 : goto cleanup;
7736 : }
7737 :
7738 : /* This ghastly expression seems to be needed to distinguish a CLASS
7739 : array, which can have a reference, from other expressions that
7740 : have references, such as derived type components, and are not
7741 : allowed by the standard.
7742 : TODO: see if it is sufficient to exclude component and substring
7743 : references. */
7744 6116 : class_array = (expr1->expr_type == EXPR_VARIABLE
7745 3057 : && expr1->ts.type == BT_CLASS
7746 2450 : && CLASS_DATA (expr1)
7747 2448 : && (strcmp (CLASS_DATA (expr1)->name, "_data") == 0)
7748 2448 : && (CLASS_DATA (expr1)->attr.dimension
7749 1541 : || CLASS_DATA (expr1)->attr.codimension)
7750 917 : && expr1->ref
7751 917 : && expr1->ref->type == REF_ARRAY
7752 917 : && expr1->ref->u.ar.type == AR_FULL
7753 3974 : && expr1->ref->next == NULL);
7754 :
7755 : /* Check for F03:C811 (F08:C835). */
7756 3058 : if (!expr2 && (expr1->expr_type != EXPR_VARIABLE
7757 2461 : || (!class_array && expr1->ref != NULL)))
7758 : {
7759 4 : gfc_error ("Selector in SELECT TYPE at %C is not a named variable; "
7760 : "use associate-name=>");
7761 4 : m = MATCH_ERROR;
7762 4 : goto cleanup;
7763 : }
7764 :
7765 : /* Prevent an existing associate name from reuse here by pushing expr1 to
7766 : expr2 and building a new associate name. */
7767 2458 : if (!expr2 && expr1->symtree->n.sym->assoc
7768 131 : && !expr1->symtree->n.sym->attr.select_type_temporary
7769 63 : && !expr1->symtree->n.sym->attr.select_rank_temporary
7770 3117 : && build_associate_name (expr1->symtree->n.sym->name, &expr1, &expr2))
7771 : {
7772 0 : m = MATCH_ERROR;
7773 0 : goto cleanup;
7774 : }
7775 :
7776 : /* Select type namespaces are not filled until resolution. Therefore, the
7777 : namespace must be marked as having an inferred type associate name if
7778 : either expr1 is an inferred type variable or expr2 is. In the latter
7779 : case, as well as the symbol being marked as inferred type, it might be
7780 : that it has not been detected to be so. In this case the target has
7781 : unknown type. Once the namespace is marked, the fixups in resolution can
7782 : be triggered. */
7783 3054 : if (!expr2
7784 2395 : && expr1->symtree->n.sym->assoc
7785 68 : && expr1->symtree->n.sym->assoc->inferred_type)
7786 0 : gfc_current_ns->assoc_name_inferred = 1;
7787 3054 : else if (expr2 && expr2->expr_type == EXPR_VARIABLE
7788 643 : && expr2->symtree->n.sym->assoc)
7789 : {
7790 184 : if (expr2->symtree->n.sym->assoc->inferred_type)
7791 13 : gfc_current_ns->assoc_name_inferred = 1;
7792 171 : else if (expr2->symtree->n.sym->assoc->target
7793 119 : && expr2->symtree->n.sym->assoc->target->ts.type == BT_UNKNOWN)
7794 36 : gfc_current_ns->assoc_name_inferred = 1;
7795 : }
7796 :
7797 3054 : new_st.op = EXEC_SELECT_TYPE;
7798 3054 : new_st.expr1 = expr1;
7799 3054 : new_st.expr2 = expr2;
7800 3054 : new_st.ext.block.ns = gfc_current_ns;
7801 :
7802 3054 : select_type_push (expr1->symtree->n.sym);
7803 3054 : gfc_current_ns = ns;
7804 :
7805 3054 : return MATCH_YES;
7806 :
7807 6 : cleanup:
7808 6 : gfc_free_expr (expr1);
7809 6 : gfc_free_expr (expr2);
7810 6 : gfc_undo_symbols ();
7811 6 : std::swap (ns, gfc_current_ns);
7812 6 : gfc_free_namespace (ns);
7813 6 : return m;
7814 : }
7815 :
7816 :
7817 : /* Set the temporary for the current intrinsic SELECT RANK selector. */
7818 :
7819 : static void
7820 1389 : select_rank_set_tmp (gfc_typespec *ts, int *case_value)
7821 : {
7822 1389 : char name[2 * GFC_MAX_SYMBOL_LEN];
7823 1389 : char tname[GFC_MAX_SYMBOL_LEN + 7];
7824 1389 : gfc_symtree *tmp;
7825 1389 : gfc_symbol *selector = select_type_stack->selector;
7826 1389 : gfc_symbol *sym;
7827 1389 : gfc_symtree *st;
7828 1389 : HOST_WIDE_INT charlen = 0;
7829 :
7830 1389 : if (case_value == NULL)
7831 2 : return;
7832 :
7833 1389 : if (ts->type == BT_CHARACTER && ts->u.cl && ts->u.cl->length
7834 265 : && ts->u.cl->length->expr_type == EXPR_CONSTANT)
7835 186 : charlen = gfc_mpz_get_hwi (ts->u.cl->length->value.integer);
7836 :
7837 1389 : if (ts->type == BT_CLASS)
7838 145 : sprintf (tname, "class_%s", ts->u.derived->name);
7839 1244 : else if (ts->type == BT_DERIVED)
7840 110 : sprintf (tname, "type_%s", ts->u.derived->name);
7841 1134 : else if (ts->type != BT_CHARACTER)
7842 575 : sprintf (tname, "%s_%d", gfc_basic_typename (ts->type), ts->kind);
7843 : else
7844 559 : sprintf (tname, "%s_" HOST_WIDE_INT_PRINT_DEC "_%d",
7845 : gfc_basic_typename (ts->type), charlen, ts->kind);
7846 :
7847 : /* Case value == NULL corresponds to SELECT TYPE cases otherwise
7848 : the values correspond to SELECT rank cases. */
7849 1389 : if (*case_value >=0)
7850 1356 : sprintf (name, "__tmp_%s_rank_%d", tname, *case_value);
7851 : else
7852 33 : sprintf (name, "__tmp_%s_rank_m%d", tname, -*case_value);
7853 :
7854 1389 : gfc_find_sym_tree (name, gfc_current_ns, 0, &st);
7855 1389 : if (st)
7856 : return;
7857 :
7858 1387 : gfc_get_sym_tree (name, gfc_current_ns, &tmp, false);
7859 1387 : sym = tmp->n.sym;
7860 1387 : gfc_add_type (sym, ts, NULL);
7861 :
7862 : /* Copy across the array spec to the selector. */
7863 1387 : if (selector->ts.type == BT_CLASS)
7864 : {
7865 145 : sym->ts.u.derived = CLASS_DATA (selector)->ts.u.derived;
7866 145 : sym->attr.pointer = CLASS_DATA (selector)->attr.pointer;
7867 145 : sym->attr.allocatable = CLASS_DATA (selector)->attr.allocatable;
7868 145 : sym->attr.target = CLASS_DATA (selector)->attr.target;
7869 145 : sym->attr.class_ok = 0;
7870 145 : if (case_value && *case_value != 0)
7871 : {
7872 114 : sym->attr.dimension = 1;
7873 114 : sym->as = gfc_copy_array_spec (CLASS_DATA (selector)->as);
7874 114 : if (*case_value > 0)
7875 : {
7876 114 : sym->as->type = AS_DEFERRED;
7877 114 : sym->as->rank = *case_value;
7878 : }
7879 0 : else if (*case_value == -1)
7880 : {
7881 0 : sym->as->type = AS_ASSUMED_SIZE;
7882 0 : sym->as->rank = 1;
7883 : }
7884 : }
7885 : }
7886 : else
7887 : {
7888 1242 : sym->attr.pointer = selector->attr.pointer;
7889 1242 : sym->attr.allocatable = selector->attr.allocatable;
7890 1242 : sym->attr.target = selector->attr.target;
7891 1242 : if (case_value && *case_value != 0)
7892 : {
7893 1193 : sym->attr.dimension = 1;
7894 1193 : sym->as = gfc_copy_array_spec (selector->as);
7895 1193 : if (*case_value > 0)
7896 : {
7897 1161 : sym->as->type = AS_DEFERRED;
7898 1161 : sym->as->rank = *case_value;
7899 : }
7900 32 : else if (*case_value == -1)
7901 : {
7902 32 : sym->as->type = AS_ASSUMED_SIZE;
7903 32 : sym->as->rank = 1;
7904 : }
7905 : }
7906 : }
7907 :
7908 1387 : gfc_set_sym_referenced (sym);
7909 1387 : gfc_add_flavor (&sym->attr, FL_VARIABLE, name, NULL);
7910 1387 : sym->attr.select_type_temporary = 1;
7911 1387 : if (case_value)
7912 1387 : sym->attr.select_rank_temporary = 1;
7913 :
7914 1387 : if (ts->type == BT_CLASS)
7915 145 : gfc_build_class_symbol (&sym->ts, &sym->attr, &sym->as);
7916 :
7917 : /* Add an association for it, so the rest of the parser knows it is
7918 : an associate-name. The target will be set during resolution. */
7919 1387 : sym->assoc = gfc_get_association_list ();
7920 1387 : sym->assoc->dangling = 1;
7921 1387 : sym->assoc->st = tmp;
7922 :
7923 1387 : select_type_stack->tmp = tmp;
7924 : }
7925 :
7926 :
7927 : /* Match a SELECT RANK statement. */
7928 :
7929 : match
7930 487771 : gfc_match_select_rank (void)
7931 : {
7932 487771 : gfc_expr *expr1, *expr2 = NULL;
7933 487771 : match m;
7934 487771 : char name[GFC_MAX_SYMBOL_LEN + 1];
7935 487771 : gfc_symbol *sym, *sym2;
7936 487771 : gfc_namespace *ns = gfc_current_ns;
7937 487771 : gfc_array_spec *as = NULL;
7938 :
7939 487771 : m = gfc_match_label ();
7940 487771 : if (m == MATCH_ERROR)
7941 : return m;
7942 :
7943 487763 : m = gfc_match (" select% rank ( ");
7944 487763 : if (m != MATCH_YES)
7945 : return m;
7946 :
7947 1029 : if (!gfc_notify_std (GFC_STD_F2018, "SELECT RANK statement at %C"))
7948 : return MATCH_NO;
7949 :
7950 1029 : gfc_current_ns = gfc_build_block_ns (ns);
7951 1029 : m = gfc_match (" %n => %e", name, &expr2);
7952 :
7953 1029 : if (m == MATCH_YES)
7954 : {
7955 : /* If expr2 corresponds to an implicitly typed variable, then the
7956 : actual type of the variable may not have been set. Set it here. */
7957 43 : if (!gfc_current_ns->seen_implicit_none
7958 43 : && expr2->expr_type == EXPR_VARIABLE
7959 42 : && expr2->ts.type == BT_UNKNOWN
7960 1 : && expr2->symtree && expr2->symtree->n.sym)
7961 : {
7962 1 : gfc_set_default_type (expr2->symtree->n.sym, 0, gfc_current_ns);
7963 1 : expr2->ts.type = expr2->symtree->n.sym->ts.type;
7964 : }
7965 :
7966 43 : expr1 = gfc_get_expr ();
7967 43 : expr1->expr_type = EXPR_VARIABLE;
7968 43 : expr1->where = expr2->where;
7969 43 : expr1->ref = gfc_copy_ref (expr2->ref);
7970 43 : if (gfc_get_sym_tree (name, NULL, &expr1->symtree, false))
7971 : {
7972 0 : m = MATCH_ERROR;
7973 0 : goto cleanup;
7974 : }
7975 :
7976 43 : sym = expr1->symtree->n.sym;
7977 :
7978 43 : if (expr2->symtree)
7979 : {
7980 42 : sym2 = expr2->symtree->n.sym;
7981 42 : as = (sym2->ts.type == BT_CLASS
7982 42 : && CLASS_DATA (sym2)) ? CLASS_DATA (sym2)->as : sym2->as;
7983 : }
7984 :
7985 43 : if (expr2->expr_type != EXPR_VARIABLE
7986 42 : || !(as && as->type == AS_ASSUMED_RANK))
7987 : {
7988 1 : gfc_error ("The SELECT RANK selector at %C must be an assumed "
7989 : "rank variable");
7990 1 : m = MATCH_ERROR;
7991 1 : goto cleanup;
7992 : }
7993 :
7994 42 : if (expr2->ts.type == BT_CLASS && CLASS_DATA (sym2))
7995 : {
7996 12 : copy_ts_from_selector_to_associate (expr1, expr2);
7997 :
7998 12 : sym->attr.flavor = FL_VARIABLE;
7999 12 : sym->attr.referenced = 1;
8000 12 : sym->attr.class_ok = 1;
8001 12 : CLASS_DATA (sym)->attr.allocatable = CLASS_DATA (sym2)->attr.allocatable;
8002 12 : CLASS_DATA (sym)->attr.pointer = CLASS_DATA (sym2)->attr.pointer;
8003 12 : CLASS_DATA (sym)->attr.target = CLASS_DATA (sym2)->attr.target;
8004 12 : sym->attr.pointer = 1;
8005 : }
8006 : else
8007 : {
8008 30 : sym->ts = sym2->ts;
8009 30 : sym->as = gfc_copy_array_spec (sym2->as);
8010 30 : sym->attr.dimension = 1;
8011 :
8012 30 : sym->attr.flavor = FL_VARIABLE;
8013 30 : sym->attr.referenced = 1;
8014 30 : sym->attr.class_ok = sym2->attr.class_ok;
8015 30 : sym->attr.allocatable = sym2->attr.allocatable;
8016 30 : sym->attr.pointer = sym2->attr.pointer;
8017 30 : sym->attr.target = sym2->attr.target;
8018 : }
8019 : }
8020 : else
8021 : {
8022 986 : m = gfc_match (" %e ", &expr1);
8023 :
8024 986 : if (m != MATCH_YES)
8025 : {
8026 1 : gfc_undo_symbols ();
8027 1 : std::swap (ns, gfc_current_ns);
8028 1 : gfc_free_namespace (ns);
8029 1 : return m;
8030 : }
8031 :
8032 985 : if (expr1->symtree)
8033 : {
8034 984 : sym = expr1->symtree->n.sym;
8035 984 : as = (sym->ts.type == BT_CLASS
8036 984 : && CLASS_DATA (sym)) ? CLASS_DATA (sym)->as : sym->as;
8037 : }
8038 :
8039 985 : if (expr1->expr_type != EXPR_VARIABLE
8040 984 : || !(as && as->type == AS_ASSUMED_RANK))
8041 : {
8042 3 : gfc_error("The SELECT RANK selector at %C must be an assumed "
8043 : "rank variable");
8044 3 : m = MATCH_ERROR;
8045 3 : goto cleanup;
8046 : }
8047 : }
8048 :
8049 1024 : m = gfc_match (" )%t");
8050 1024 : if (m != MATCH_YES)
8051 : {
8052 0 : gfc_error ("parse error in SELECT RANK statement at %C");
8053 0 : goto cleanup;
8054 : }
8055 :
8056 1024 : new_st.op = EXEC_SELECT_RANK;
8057 1024 : new_st.expr1 = expr1;
8058 1024 : new_st.expr2 = expr2;
8059 1024 : new_st.ext.block.ns = gfc_current_ns;
8060 :
8061 1024 : select_type_push (expr1->symtree->n.sym);
8062 1024 : gfc_current_ns = ns;
8063 :
8064 1024 : return MATCH_YES;
8065 :
8066 4 : cleanup:
8067 4 : gfc_free_expr (expr1);
8068 4 : gfc_free_expr (expr2);
8069 4 : gfc_undo_symbols ();
8070 4 : std::swap (ns, gfc_current_ns);
8071 4 : gfc_free_namespace (ns);
8072 4 : return m;
8073 : }
8074 :
8075 :
8076 : /* Match a CASE statement. */
8077 :
8078 : match
8079 1602 : gfc_match_case (void)
8080 : {
8081 1602 : gfc_case *c, *head, *tail;
8082 1602 : match m;
8083 :
8084 1602 : head = tail = NULL;
8085 :
8086 1602 : if (gfc_current_state () != COMP_SELECT)
8087 : {
8088 3 : gfc_error ("Unexpected CASE statement at %C");
8089 3 : return MATCH_ERROR;
8090 : }
8091 :
8092 1599 : if (gfc_match ("% default") == MATCH_YES)
8093 : {
8094 363 : m = match_case_eos ();
8095 363 : if (m == MATCH_NO)
8096 1 : goto syntax;
8097 362 : if (m == MATCH_ERROR)
8098 0 : goto cleanup;
8099 :
8100 362 : new_st.op = EXEC_SELECT;
8101 362 : c = gfc_get_case ();
8102 362 : c->where = gfc_current_locus;
8103 362 : new_st.ext.block.case_list = c;
8104 362 : return MATCH_YES;
8105 : }
8106 :
8107 1236 : if (gfc_match_char ('(') != MATCH_YES)
8108 0 : goto syntax;
8109 :
8110 1434 : for (;;)
8111 : {
8112 1434 : if (match_case_selector (&c) == MATCH_ERROR)
8113 10 : goto cleanup;
8114 :
8115 1424 : if (head == NULL)
8116 1226 : head = c;
8117 : else
8118 198 : tail->next = c;
8119 :
8120 1424 : tail = c;
8121 :
8122 1424 : if (gfc_match_char (')') == MATCH_YES)
8123 : break;
8124 198 : if (gfc_match_char (',') != MATCH_YES)
8125 0 : goto syntax;
8126 : }
8127 :
8128 1226 : m = match_case_eos ();
8129 1226 : if (m == MATCH_NO)
8130 2 : goto syntax;
8131 1224 : if (m == MATCH_ERROR)
8132 0 : goto cleanup;
8133 :
8134 1224 : new_st.op = EXEC_SELECT;
8135 1224 : new_st.ext.block.case_list = head;
8136 :
8137 1224 : return MATCH_YES;
8138 :
8139 3 : syntax:
8140 3 : gfc_error ("Syntax error in CASE specification at %C");
8141 :
8142 13 : cleanup:
8143 13 : gfc_free_case_list (head); /* new_st is cleaned up in parse.cc. */
8144 13 : return MATCH_ERROR;
8145 : }
8146 :
8147 :
8148 : /* Match a TYPE IS statement. */
8149 :
8150 : match
8151 3455 : gfc_match_type_is (void)
8152 : {
8153 3455 : gfc_case *c = NULL;
8154 3455 : match m;
8155 :
8156 3455 : if (gfc_current_state () != COMP_SELECT_TYPE)
8157 : {
8158 2 : gfc_error ("Unexpected TYPE IS statement at %C");
8159 2 : return MATCH_ERROR;
8160 : }
8161 :
8162 3453 : if (gfc_match_char ('(') != MATCH_YES)
8163 1 : goto syntax;
8164 :
8165 3452 : c = gfc_get_case ();
8166 3452 : c->where = gfc_current_locus;
8167 :
8168 3452 : m = gfc_match_type_spec (&c->ts);
8169 3452 : if (m == MATCH_NO)
8170 4 : goto syntax;
8171 3448 : if (m == MATCH_ERROR)
8172 0 : goto cleanup;
8173 :
8174 3448 : if (gfc_match_char (')') != MATCH_YES)
8175 0 : goto syntax;
8176 :
8177 3448 : m = match_case_eos ();
8178 3448 : if (m == MATCH_NO)
8179 0 : goto syntax;
8180 3448 : if (m == MATCH_ERROR)
8181 0 : goto cleanup;
8182 :
8183 3448 : new_st.op = EXEC_SELECT_TYPE;
8184 3448 : new_st.ext.block.case_list = c;
8185 :
8186 3448 : if (c->ts.type == BT_DERIVED && c->ts.u.derived
8187 1999 : && (c->ts.u.derived->attr.sequence
8188 1998 : || c->ts.u.derived->attr.is_bind_c))
8189 : {
8190 1 : gfc_error ("The type-spec shall not specify a sequence derived "
8191 : "type or a type with the BIND attribute in SELECT "
8192 : "TYPE at %C [F2003:C815]");
8193 1 : return MATCH_ERROR;
8194 : }
8195 :
8196 3447 : if (IS_PDT (c) && gfc_spec_list_type (type_param_spec_list,
8197 : c->ts.u.derived) != SPEC_ASSUMED)
8198 : {
8199 1 : gfc_error ("All the LEN type parameters in the TYPE IS statement "
8200 : "at %C must be ASSUMED");
8201 1 : return MATCH_ERROR;
8202 : }
8203 :
8204 : /* Create temporary variable. */
8205 3446 : select_type_set_tmp (&c->ts);
8206 :
8207 3446 : return MATCH_YES;
8208 :
8209 5 : syntax:
8210 :
8211 5 : if (!gfc_error_check ())
8212 3 : gfc_error ("Syntax error in TYPE IS specification at %C");
8213 :
8214 2 : cleanup:
8215 5 : if (c != NULL)
8216 4 : gfc_free_case_list (c); /* new_st is cleaned up in parse.cc. */
8217 : return MATCH_ERROR;
8218 : }
8219 :
8220 :
8221 : /* Match a CLASS IS or CLASS DEFAULT statement. */
8222 :
8223 : match
8224 2017 : gfc_match_class_is (void)
8225 : {
8226 2017 : gfc_case *c = NULL;
8227 2017 : match m;
8228 :
8229 2017 : if (gfc_current_state () != COMP_SELECT_TYPE)
8230 : return MATCH_NO;
8231 :
8232 1989 : if (gfc_match ("% default") == MATCH_YES)
8233 : {
8234 1631 : m = match_case_eos ();
8235 1631 : if (m == MATCH_NO)
8236 0 : goto syntax;
8237 1631 : if (m == MATCH_ERROR)
8238 0 : goto cleanup;
8239 :
8240 1631 : new_st.op = EXEC_SELECT_TYPE;
8241 1631 : c = gfc_get_case ();
8242 1631 : c->where = gfc_current_locus;
8243 1631 : c->ts.type = BT_UNKNOWN;
8244 1631 : new_st.ext.block.case_list = c;
8245 1631 : select_type_set_tmp (NULL);
8246 1631 : return MATCH_YES;
8247 : }
8248 :
8249 358 : m = gfc_match ("% is");
8250 358 : if (m == MATCH_NO)
8251 0 : goto syntax;
8252 358 : if (m == MATCH_ERROR)
8253 0 : goto cleanup;
8254 :
8255 358 : if (gfc_match_char ('(') != MATCH_YES)
8256 0 : goto syntax;
8257 :
8258 358 : c = gfc_get_case ();
8259 358 : c->where = gfc_current_locus;
8260 :
8261 358 : m = match_derived_type_spec (&c->ts);
8262 358 : if (m == MATCH_NO)
8263 4 : goto syntax;
8264 354 : if (m == MATCH_ERROR)
8265 0 : goto cleanup;
8266 :
8267 354 : if (c->ts.type == BT_DERIVED)
8268 354 : c->ts.type = BT_CLASS;
8269 :
8270 354 : if (gfc_match_char (')') != MATCH_YES)
8271 0 : goto syntax;
8272 :
8273 354 : m = match_case_eos ();
8274 354 : if (m == MATCH_NO)
8275 1 : goto syntax;
8276 353 : if (m == MATCH_ERROR)
8277 1 : goto cleanup;
8278 :
8279 352 : new_st.op = EXEC_SELECT_TYPE;
8280 352 : new_st.ext.block.case_list = c;
8281 :
8282 : /* Create temporary variable. */
8283 352 : select_type_set_tmp (&c->ts);
8284 :
8285 352 : return MATCH_YES;
8286 :
8287 5 : syntax:
8288 5 : gfc_error ("Syntax error in CLASS IS specification at %C");
8289 :
8290 6 : cleanup:
8291 6 : if (c != NULL)
8292 6 : gfc_free_case_list (c); /* new_st is cleaned up in parse.cc. */
8293 : return MATCH_ERROR;
8294 : }
8295 :
8296 :
8297 : /* Match a RANK statement. */
8298 :
8299 : match
8300 2316 : gfc_match_rank_is (void)
8301 : {
8302 2316 : gfc_case *c = NULL;
8303 2316 : match m;
8304 2316 : int case_value;
8305 :
8306 2316 : if (gfc_current_state () != COMP_SELECT_RANK)
8307 : {
8308 5 : gfc_error ("Unexpected RANK statement at %C");
8309 5 : return MATCH_ERROR;
8310 : }
8311 :
8312 2311 : if (gfc_match ("% default") == MATCH_YES)
8313 : {
8314 919 : m = match_case_eos ();
8315 919 : if (m == MATCH_NO)
8316 0 : goto syntax;
8317 919 : if (m == MATCH_ERROR)
8318 0 : goto cleanup;
8319 :
8320 919 : new_st.op = EXEC_SELECT_RANK;
8321 919 : c = gfc_get_case ();
8322 919 : c->ts.type = BT_UNKNOWN;
8323 919 : c->where = gfc_current_locus;
8324 919 : new_st.ext.block.case_list = c;
8325 919 : select_type_stack->tmp = NULL;
8326 919 : return MATCH_YES;
8327 : }
8328 :
8329 1392 : if (gfc_match_char ('(') != MATCH_YES)
8330 0 : goto syntax;
8331 :
8332 1392 : c = gfc_get_case ();
8333 1392 : c->where = gfc_current_locus;
8334 1392 : c->ts = select_type_stack->selector->ts;
8335 :
8336 1392 : m = gfc_match_expr (&c->low);
8337 1392 : if (m == MATCH_NO)
8338 : {
8339 33 : if (gfc_match_char ('*') == MATCH_YES)
8340 33 : c->low = gfc_get_int_expr (gfc_default_integer_kind,
8341 : NULL, -1);
8342 : else
8343 0 : goto syntax;
8344 :
8345 33 : case_value = -1;
8346 : }
8347 1359 : else if (m == MATCH_YES)
8348 : {
8349 : /* F2018: R1150 */
8350 1359 : if (c->low->expr_type != EXPR_CONSTANT
8351 1358 : || c->low->ts.type != BT_INTEGER
8352 1358 : || c->low->rank)
8353 : {
8354 1 : gfc_error ("The SELECT RANK CASE expression at %C must be a "
8355 : "scalar, integer constant");
8356 1 : goto cleanup;
8357 : }
8358 :
8359 1358 : case_value = (int) mpz_get_si (c->low->value.integer);
8360 : /* F2018: C1151 */
8361 1358 : if ((case_value < 0) || (case_value > GFC_MAX_DIMENSIONS))
8362 : {
8363 2 : gfc_error ("The value of the SELECT RANK CASE expression at "
8364 : "%C must not be less than zero or greater than %d",
8365 : GFC_MAX_DIMENSIONS);
8366 2 : goto cleanup;
8367 : }
8368 : }
8369 : else
8370 0 : goto cleanup;
8371 :
8372 1389 : if (gfc_match_char (')') != MATCH_YES)
8373 0 : goto syntax;
8374 :
8375 1389 : m = match_case_eos ();
8376 1389 : if (m == MATCH_NO)
8377 0 : goto syntax;
8378 1389 : if (m == MATCH_ERROR)
8379 0 : goto cleanup;
8380 :
8381 1389 : new_st.op = EXEC_SELECT_RANK;
8382 1389 : new_st.ext.block.case_list = c;
8383 :
8384 : /* Create temporary variable. Recycle the select type code. */
8385 1389 : select_rank_set_tmp (&c->ts, &case_value);
8386 :
8387 1389 : return MATCH_YES;
8388 :
8389 0 : syntax:
8390 0 : gfc_error ("Syntax error in RANK specification at %C");
8391 :
8392 3 : cleanup:
8393 3 : if (c != NULL)
8394 3 : gfc_free_case_list (c); /* new_st is cleaned up in parse.cc. */
8395 : return MATCH_ERROR;
8396 : }
8397 :
8398 : /********************* WHERE subroutines ********************/
8399 :
8400 : /* Match the rest of a simple WHERE statement that follows an IF statement.
8401 : */
8402 :
8403 : static match
8404 7 : match_simple_where (void)
8405 : {
8406 7 : gfc_expr *expr;
8407 7 : gfc_code *c;
8408 7 : match m;
8409 :
8410 7 : m = gfc_match (" ( %e )", &expr);
8411 7 : if (m != MATCH_YES)
8412 : return m;
8413 :
8414 7 : m = gfc_match_assignment ();
8415 7 : if (m == MATCH_NO)
8416 0 : goto syntax;
8417 7 : if (m == MATCH_ERROR)
8418 0 : goto cleanup;
8419 :
8420 7 : if (gfc_match_eos () != MATCH_YES)
8421 0 : goto syntax;
8422 :
8423 7 : c = gfc_get_code (EXEC_WHERE);
8424 7 : c->expr1 = expr;
8425 :
8426 7 : c->next = XCNEW (gfc_code);
8427 7 : *c->next = new_st;
8428 7 : c->next->loc = gfc_current_locus;
8429 7 : gfc_clear_new_st ();
8430 :
8431 7 : new_st.op = EXEC_WHERE;
8432 7 : new_st.block = c;
8433 :
8434 7 : return MATCH_YES;
8435 :
8436 0 : syntax:
8437 0 : gfc_syntax_error (ST_WHERE);
8438 :
8439 0 : cleanup:
8440 0 : gfc_free_expr (expr);
8441 0 : return MATCH_ERROR;
8442 : }
8443 :
8444 :
8445 : /* Match a WHERE statement. */
8446 :
8447 : match
8448 529675 : gfc_match_where (gfc_statement *st)
8449 : {
8450 529675 : gfc_expr *expr;
8451 529675 : match m0, m;
8452 529675 : gfc_code *c;
8453 :
8454 529675 : m0 = gfc_match_label ();
8455 529675 : if (m0 == MATCH_ERROR)
8456 : return m0;
8457 :
8458 529667 : m = gfc_match (" where ( %e )", &expr);
8459 529667 : if (m != MATCH_YES)
8460 : return m;
8461 :
8462 446 : if (gfc_match_eos () == MATCH_YES)
8463 : {
8464 371 : *st = ST_WHERE_BLOCK;
8465 371 : new_st.op = EXEC_WHERE;
8466 371 : new_st.expr1 = expr;
8467 371 : return MATCH_YES;
8468 : }
8469 :
8470 75 : m = gfc_match_assignment ();
8471 75 : if (m == MATCH_NO)
8472 0 : gfc_syntax_error (ST_WHERE);
8473 :
8474 75 : if (m != MATCH_YES)
8475 : {
8476 0 : gfc_free_expr (expr);
8477 0 : return MATCH_ERROR;
8478 : }
8479 :
8480 : /* We've got a simple WHERE statement. */
8481 75 : *st = ST_WHERE;
8482 75 : c = gfc_get_code (EXEC_WHERE);
8483 75 : c->expr1 = expr;
8484 :
8485 : /* Put in the assignment. It will not be processed by add_statement, so we
8486 : need to copy the location here. */
8487 :
8488 75 : c->next = XCNEW (gfc_code);
8489 75 : *c->next = new_st;
8490 75 : c->next->loc = gfc_current_locus;
8491 75 : gfc_clear_new_st ();
8492 :
8493 75 : new_st.op = EXEC_WHERE;
8494 75 : new_st.block = c;
8495 :
8496 75 : return MATCH_YES;
8497 : }
8498 :
8499 :
8500 : /* Match an ELSEWHERE statement. We leave behind a WHERE node in
8501 : new_st if successful. */
8502 :
8503 : match
8504 313 : gfc_match_elsewhere (void)
8505 : {
8506 313 : char name[GFC_MAX_SYMBOL_LEN + 1];
8507 313 : gfc_expr *expr;
8508 313 : match m;
8509 :
8510 313 : if (gfc_current_state () != COMP_WHERE)
8511 : {
8512 0 : gfc_error ("ELSEWHERE statement at %C not enclosed in WHERE block");
8513 0 : return MATCH_ERROR;
8514 : }
8515 :
8516 313 : expr = NULL;
8517 :
8518 313 : if (gfc_match_char ('(') == MATCH_YES)
8519 : {
8520 179 : m = gfc_match_expr (&expr);
8521 179 : if (m == MATCH_NO)
8522 0 : goto syntax;
8523 179 : if (m == MATCH_ERROR)
8524 : return MATCH_ERROR;
8525 :
8526 179 : if (gfc_match_char (')') != MATCH_YES)
8527 0 : goto syntax;
8528 : }
8529 :
8530 313 : if (gfc_match_eos () != MATCH_YES)
8531 : {
8532 : /* Only makes sense if we have a where-construct-name. */
8533 2 : if (!gfc_current_block ())
8534 : {
8535 1 : m = MATCH_ERROR;
8536 1 : goto cleanup;
8537 : }
8538 : /* Better be a name at this point. */
8539 1 : m = gfc_match_name (name);
8540 1 : if (m == MATCH_NO)
8541 0 : goto syntax;
8542 1 : if (m == MATCH_ERROR)
8543 0 : goto cleanup;
8544 :
8545 1 : if (gfc_match_eos () != MATCH_YES)
8546 0 : goto syntax;
8547 :
8548 1 : if (strcmp (name, gfc_current_block ()->name) != 0)
8549 : {
8550 0 : gfc_error ("Label %qs at %C doesn't match WHERE label %qs",
8551 : name, gfc_current_block ()->name);
8552 0 : goto cleanup;
8553 : }
8554 : }
8555 :
8556 312 : new_st.op = EXEC_WHERE;
8557 312 : new_st.expr1 = expr;
8558 312 : return MATCH_YES;
8559 :
8560 0 : syntax:
8561 0 : gfc_syntax_error (ST_ELSEWHERE);
8562 :
8563 1 : cleanup:
8564 1 : gfc_free_expr (expr);
8565 1 : return MATCH_ERROR;
8566 : }
|