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