Branch data Line data Source code
1 : : /* Matching subroutines in all sizes, shapes and colors.
2 : : Copyright (C) 2000-2023 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 : 7316029 : gfc_op2string (gfc_intrinsic_op op)
43 : : {
44 : 7316029 : switch (op)
45 : : {
46 : : case INTRINSIC_UPLUS:
47 : : case INTRINSIC_PLUS:
48 : : return "+";
49 : :
50 : 562498 : case INTRINSIC_UMINUS:
51 : 562498 : case INTRINSIC_MINUS:
52 : 562498 : return "-";
53 : :
54 : 281143 : case INTRINSIC_POWER:
55 : 281143 : return "**";
56 : 281143 : case INTRINSIC_CONCAT:
57 : 281143 : return "//";
58 : 281774 : case INTRINSIC_TIMES:
59 : 281774 : return "*";
60 : 281147 : case INTRINSIC_DIVIDE:
61 : 281147 : return "/";
62 : :
63 : 281261 : case INTRINSIC_AND:
64 : 281261 : return ".and.";
65 : 281964 : case INTRINSIC_OR:
66 : 281964 : return ".or.";
67 : 281252 : case INTRINSIC_EQV:
68 : 281252 : return ".eqv.";
69 : 281251 : case INTRINSIC_NEQV:
70 : 281251 : return ".neqv.";
71 : :
72 : 281206 : case INTRINSIC_EQ_OS:
73 : 281206 : return ".eq.";
74 : 281201 : case INTRINSIC_EQ:
75 : 281201 : return "==";
76 : 281222 : case INTRINSIC_NE_OS:
77 : 281222 : return ".ne.";
78 : 281896 : case INTRINSIC_NE:
79 : 281896 : return "/=";
80 : 281167 : case INTRINSIC_GE_OS:
81 : 281167 : return ".ge.";
82 : 281161 : case INTRINSIC_GE:
83 : 281161 : return ">=";
84 : 281168 : case INTRINSIC_LE_OS:
85 : 281168 : return ".le.";
86 : 281161 : case INTRINSIC_LE:
87 : 281161 : return "<=";
88 : 281226 : case INTRINSIC_LT_OS:
89 : 281226 : return ".lt.";
90 : 281185 : case INTRINSIC_LT:
91 : 281185 : return "<";
92 : 281176 : case INTRINSIC_GT_OS:
93 : 281176 : return ".gt.";
94 : 281162 : case INTRINSIC_GT:
95 : 281162 : return ">";
96 : 281142 : case INTRINSIC_NOT:
97 : 281142 : return ".not.";
98 : :
99 : 730 : case INTRINSIC_ASSIGN:
100 : 730 : return "=";
101 : :
102 : 281142 : case INTRINSIC_PARENTHESES:
103 : 281142 : 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 : 6420034 : gfc_match_member_sep(gfc_symbol *sym)
152 : : {
153 : 6420034 : char name[GFC_MAX_SYMBOL_LEN + 1];
154 : 6420034 : locus dot_loc, start_loc;
155 : 6420034 : gfc_intrinsic_op iop;
156 : 6420034 : match m;
157 : 6420034 : gfc_symbol *tsym;
158 : 6420034 : gfc_component *c = NULL;
159 : :
160 : : /* What a relief: '%' is an unambiguous member separator. */
161 : 6420034 : if (gfc_match_char ('%') == MATCH_YES)
162 : : return MATCH_YES;
163 : :
164 : : /* Beware ye who enter here. */
165 : 6275590 : if (!flag_dec_structure || !sym)
166 : : return MATCH_NO;
167 : :
168 : 66707 : tsym = NULL;
169 : :
170 : : /* We may be given either a derived type variable or the derived type
171 : : declaration itself (which actually contains the components);
172 : : we need the latter to search for components. */
173 : 66707 : if (gfc_fl_struct (sym->attr.flavor))
174 : : tsym = sym;
175 : 66307 : else if (gfc_bt_struct (sym->ts.type))
176 : 2726 : tsym = sym->ts.u.derived;
177 : :
178 : 66707 : iop = INTRINSIC_NONE;
179 : 66707 : name[0] = '\0';
180 : 66707 : m = MATCH_NO;
181 : :
182 : : /* If we have to reject come back here later. */
183 : 66707 : start_loc = gfc_current_locus;
184 : :
185 : : /* Look for a component access next. */
186 : 66707 : if (gfc_match_char ('.') != MATCH_YES)
187 : : return MATCH_NO;
188 : :
189 : : /* If we accept, come back here. */
190 : 7865 : dot_loc = gfc_current_locus;
191 : :
192 : : /* Try to match a symbol name following the dot. */
193 : 7865 : if (gfc_match_name (name) != MATCH_YES)
194 : : {
195 : 1 : gfc_error ("Expected structure component or operator name "
196 : : "after %<.%> at %C");
197 : 1 : goto error;
198 : : }
199 : :
200 : : /* If no dot follows we have "x.y" which should be a component access. */
201 : 7864 : if (gfc_match_char ('.') != MATCH_YES)
202 : 1658 : goto yes;
203 : :
204 : : /* Now we have a string "x.y.z" which could be a nested member access
205 : : (x->y)->z or a binary operation y on x and z. */
206 : :
207 : : /* First use any user-defined operators ".y." */
208 : 6206 : if (gfc_find_uop (name, sym->ns) != NULL)
209 : 6 : goto no;
210 : :
211 : : /* Match accesses to existing derived-type components for
212 : : derived-type vars: "x.y.z" = (x->y)->z */
213 : 6200 : c = gfc_find_component(tsym, name, false, true, NULL);
214 : 6200 : if (c && (gfc_bt_struct (c->ts.type) || c->ts.type == BT_CLASS))
215 : 314 : goto yes;
216 : :
217 : : /* If y is not a component or has no members, try intrinsic operators. */
218 : 5886 : gfc_current_locus = start_loc;
219 : 5886 : if (gfc_match_intrinsic_op (&iop) != MATCH_YES)
220 : : {
221 : : /* If ".y." is not an intrinsic operator but y was a valid non-
222 : : structure component, match and leave the trailing dot to be
223 : : dealt with later. */
224 : 877 : if (c)
225 : 877 : goto yes;
226 : :
227 : 0 : gfc_error ("%qs is neither a defined operator nor a "
228 : : "structure component in dotted string at %C", name);
229 : 0 : goto error;
230 : : }
231 : :
232 : : /* .y. is an intrinsic operator, overriding any possible member access. */
233 : 5009 : goto no;
234 : :
235 : : /* Return keeping the current locus consistent with the match result. */
236 : : error:
237 : : m = MATCH_ERROR;
238 : 5016 : no:
239 : 5016 : gfc_current_locus = start_loc;
240 : 5016 : return m;
241 : 2849 : yes:
242 : 2849 : gfc_current_locus = dot_loc;
243 : 2849 : return MATCH_YES;
244 : : }
245 : :
246 : :
247 : : /* This function scans the current statement counting the opened and closed
248 : : parenthesis to make sure they are balanced. */
249 : :
250 : : match
251 : 310552 : gfc_match_parens (void)
252 : : {
253 : 310552 : locus old_loc, where;
254 : 310552 : int count;
255 : 310552 : gfc_instring instring;
256 : 310552 : gfc_char_t c, quote;
257 : :
258 : 310552 : old_loc = gfc_current_locus;
259 : 310552 : count = 0;
260 : 310552 : instring = NONSTRING;
261 : 310552 : quote = ' ';
262 : :
263 : 11946731 : for (;;)
264 : : {
265 : 11946731 : if (count > 0)
266 : 6614951 : where = gfc_current_locus;
267 : 11946731 : c = gfc_next_char_literal (instring);
268 : 11946731 : if (c == '\n')
269 : : break;
270 : 11636179 : if (quote == ' ' && ((c == '\'') || (c == '"')))
271 : : {
272 : 54845 : quote = c;
273 : 54845 : instring = INSTRING_WARN;
274 : 54845 : continue;
275 : : }
276 : 11581334 : if (quote != ' ' && c == quote)
277 : : {
278 : 54845 : quote = ' ';
279 : 54845 : instring = NONSTRING;
280 : 54845 : continue;
281 : : }
282 : :
283 : 11526489 : if (c == '(' && quote == ' ')
284 : : {
285 : 581594 : count++;
286 : : }
287 : 11526489 : if (c == ')' && quote == ' ')
288 : : {
289 : 581588 : count--;
290 : 581588 : where = gfc_current_locus;
291 : : }
292 : : }
293 : :
294 : 310552 : gfc_current_locus = old_loc;
295 : :
296 : 310552 : 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 : 371641 : gfc_match_space (void)
386 : : {
387 : 371641 : locus old_loc;
388 : 371641 : char c;
389 : :
390 : 371641 : if (gfc_current_form == FORM_FIXED)
391 : : return MATCH_YES;
392 : :
393 : 356178 : old_loc = gfc_current_locus;
394 : :
395 : 356178 : c = gfc_next_ascii_char ();
396 : 356178 : if (!gfc_is_whitespace (c))
397 : : {
398 : 14616 : gfc_current_locus = old_loc;
399 : 14616 : return MATCH_NO;
400 : : }
401 : :
402 : 341562 : gfc_gobble_whitespace ();
403 : :
404 : 341562 : 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 : 2862611 : gfc_match_eos (void)
414 : : {
415 : 2862611 : locus old_loc;
416 : 2862611 : int flag;
417 : 2862611 : char c;
418 : :
419 : 2862611 : flag = 0;
420 : :
421 : 2926225 : for (;;)
422 : : {
423 : 2894418 : old_loc = gfc_current_locus;
424 : 2894418 : gfc_gobble_whitespace ();
425 : :
426 : 2894418 : c = gfc_next_ascii_char ();
427 : 2894418 : 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 : 31807 : case ';':
442 : 31807 : flag = 1;
443 : 31807 : continue;
444 : : }
445 : :
446 : 1826789 : break;
447 : : }
448 : :
449 : 1826789 : gfc_current_locus = old_loc;
450 : 1826789 : 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 : 641164 : gfc_match_small_literal_int (int *value, int *cnt, bool gobble_ws)
462 : : {
463 : 641164 : locus old_loc;
464 : 641164 : char c;
465 : 641164 : int i, j;
466 : :
467 : 641164 : old_loc = gfc_current_locus;
468 : :
469 : 641164 : *value = -1;
470 : 641164 : if (gobble_ws)
471 : 266597 : gfc_gobble_whitespace ();
472 : 641164 : c = gfc_next_ascii_char ();
473 : 641164 : if (cnt)
474 : 262739 : *cnt = 0;
475 : :
476 : 641164 : if (!ISDIGIT (c))
477 : : {
478 : 344603 : gfc_current_locus = old_loc;
479 : 344603 : return MATCH_NO;
480 : : }
481 : :
482 : 296561 : i = c - '0';
483 : 296561 : j = 1;
484 : :
485 : 365313 : for (;;)
486 : : {
487 : 365313 : old_loc = gfc_current_locus;
488 : 365313 : c = gfc_next_ascii_char ();
489 : :
490 : 365313 : if (!ISDIGIT (c))
491 : : break;
492 : :
493 : 68752 : i = 10 * i + c - '0';
494 : 68752 : j++;
495 : :
496 : 68752 : if (i > 99999999)
497 : : {
498 : 0 : gfc_error ("Integer too large at %C");
499 : 0 : return MATCH_ERROR;
500 : : }
501 : : }
502 : :
503 : 296561 : gfc_current_locus = old_loc;
504 : :
505 : 296561 : *value = i;
506 : 296561 : if (cnt)
507 : 11017 : *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 : 169829 : gfc_match_small_int (int *value)
517 : : {
518 : 169829 : gfc_expr *expr;
519 : 169829 : match m;
520 : 169829 : int i;
521 : :
522 : 169829 : m = gfc_match_expr (&expr);
523 : 169829 : if (m != MATCH_YES)
524 : : return m;
525 : :
526 : 169829 : if (gfc_extract_int (expr, &i, 1))
527 : 756 : m = MATCH_ERROR;
528 : 169829 : gfc_free_expr (expr);
529 : :
530 : 169829 : *value = i;
531 : 169829 : 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 : 262735 : gfc_match_st_label (gfc_st_label **label)
540 : : {
541 : 262735 : locus old_loc;
542 : 262735 : match m;
543 : 262735 : int i, cnt;
544 : :
545 : 262735 : old_loc = gfc_current_locus;
546 : :
547 : 262735 : m = gfc_match_small_literal_int (&i, &cnt);
548 : 262735 : if (m != MATCH_YES)
549 : : return m;
550 : :
551 : 11015 : if (cnt > 5)
552 : : {
553 : 2 : gfc_error ("Too many digits in statement label at %C");
554 : 2 : goto cleanup;
555 : : }
556 : :
557 : 11013 : if (i == 0)
558 : : {
559 : 2 : gfc_error ("Statement label at %C is zero");
560 : 2 : goto cleanup;
561 : : }
562 : :
563 : 11011 : *label = gfc_get_st_label (i);
564 : 11011 : 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 : 4559964 : gfc_match_label (void)
580 : : {
581 : 4559964 : char name[GFC_MAX_SYMBOL_LEN + 1];
582 : 4559964 : match m;
583 : :
584 : 4559964 : gfc_new_block = NULL;
585 : :
586 : 4559964 : m = gfc_match (" %n :", name);
587 : 4559964 : if (m != MATCH_YES)
588 : : return m;
589 : :
590 : 91157 : 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 : 91157 : if (gfc_new_block->attr.flavor == FL_LABEL)
597 : : {
598 : 70 : gfc_error ("Duplicate construct label %qs at %C", name);
599 : 70 : return MATCH_ERROR;
600 : : }
601 : :
602 : 91087 : if (!gfc_add_flavor (&gfc_new_block->attr, FL_LABEL,
603 : : gfc_new_block->name, NULL))
604 : : return MATCH_ERROR;
605 : :
606 : : return MATCH_YES;
607 : : }
608 : :
609 : :
610 : : /* See if the current input looks like a name of some sort. Modifies
611 : : the passed buffer which must be GFC_MAX_SYMBOL_LEN+1 bytes long.
612 : : Note that options.cc restricts max_identifier_length to not more
613 : : than GFC_MAX_SYMBOL_LEN.
614 : : When gobble_ws is false, do not skip over leading blanks. */
615 : :
616 : : match
617 : 23592613 : gfc_match_name (char *buffer, bool gobble_ws)
618 : : {
619 : 23592613 : locus old_loc;
620 : 23592613 : int i;
621 : 23592613 : char c;
622 : :
623 : 23592613 : old_loc = gfc_current_locus;
624 : 23592613 : if (gobble_ws)
625 : 23500236 : gfc_gobble_whitespace ();
626 : :
627 : 23592613 : c = gfc_next_ascii_char ();
628 : 23592613 : 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 : 1430864 : if (!gfc_error_flag_test () && c != '(' && c != '-' && c != '+')
634 : 357060 : gfc_error ("Invalid character in name at %C");
635 : 1430864 : gfc_current_locus = old_loc;
636 : 1430864 : return MATCH_NO;
637 : : }
638 : :
639 : : i = 0;
640 : :
641 : 101455603 : do
642 : : {
643 : 101455603 : buffer[i++] = c;
644 : :
645 : 101455603 : 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 : 101455603 : old_loc = gfc_current_locus;
652 : 101455603 : c = gfc_next_ascii_char ();
653 : : }
654 : 101455603 : while (ISALNUM (c) || c == '_' || (flag_dollar_ok && c == '$'));
655 : :
656 : 22161749 : 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 : 22161747 : buffer[i] = '\0';
664 : 22161747 : gfc_current_locus = old_loc;
665 : :
666 : 22161747 : 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 : 3547007 : gfc_match_sym_tree (gfc_symtree **matched_symbol, int host_assoc)
675 : : {
676 : 3547007 : char buffer[GFC_MAX_SYMBOL_LEN + 1];
677 : 3547007 : match m;
678 : :
679 : 3547007 : m = gfc_match_name (buffer);
680 : 3547006 : if (m != MATCH_YES)
681 : : return m;
682 : :
683 : 3546866 : if (host_assoc)
684 : 2145701 : return (gfc_get_ha_sym_tree (buffer, matched_symbol))
685 : 2145701 : ? MATCH_ERROR : MATCH_YES;
686 : :
687 : 1401165 : if (gfc_get_sym_tree (buffer, NULL, matched_symbol, false))
688 : : return MATCH_ERROR;
689 : :
690 : : return MATCH_YES;
691 : : }
692 : :
693 : :
694 : : match
695 : 1242475 : gfc_match_symbol (gfc_symbol **matched_symbol, int host_assoc)
696 : : {
697 : 1242475 : gfc_symtree *st;
698 : 1242475 : match m;
699 : :
700 : 1242475 : m = gfc_match_sym_tree (&st, host_assoc);
701 : :
702 : 1242475 : if (m == MATCH_YES)
703 : : {
704 : 1242327 : if (st)
705 : 1242327 : *matched_symbol = st->n.sym;
706 : : else
707 : 0 : *matched_symbol = NULL;
708 : : }
709 : : else
710 : 148 : *matched_symbol = NULL;
711 : 1242475 : return m;
712 : : }
713 : :
714 : :
715 : : /* Match an intrinsic operator. Returns an INTRINSIC enum. While matching,
716 : : we always find INTRINSIC_PLUS before INTRINSIC_UPLUS. We work around this
717 : : in matchexp.cc. */
718 : :
719 : : match
720 : 65251447 : gfc_match_intrinsic_op (gfc_intrinsic_op *result)
721 : : {
722 : 65251447 : locus orig_loc = gfc_current_locus;
723 : 65251447 : char ch;
724 : :
725 : 65251447 : gfc_gobble_whitespace ();
726 : 65251447 : ch = gfc_next_ascii_char ();
727 : 65251447 : switch (ch)
728 : : {
729 : 292990 : case '+':
730 : : /* Matched "+". */
731 : 292990 : *result = INTRINSIC_PLUS;
732 : 292990 : return MATCH_YES;
733 : :
734 : 507213 : case '-':
735 : : /* Matched "-". */
736 : 507213 : *result = INTRINSIC_MINUS;
737 : 507213 : return MATCH_YES;
738 : :
739 : 246940 : case '=':
740 : 246940 : if (gfc_next_ascii_char () == '=')
741 : : {
742 : : /* Matched "==". */
743 : 143430 : *result = INTRINSIC_EQ;
744 : 143430 : return MATCH_YES;
745 : : }
746 : : break;
747 : :
748 : 73117 : case '<':
749 : 73117 : if (gfc_peek_ascii_char () == '=')
750 : : {
751 : : /* Matched "<=". */
752 : 31831 : gfc_next_ascii_char ();
753 : 31831 : *result = INTRINSIC_LE;
754 : 31831 : return MATCH_YES;
755 : : }
756 : : /* Matched "<". */
757 : 41286 : *result = INTRINSIC_LT;
758 : 41286 : return MATCH_YES;
759 : :
760 : 264702 : case '>':
761 : 264702 : if (gfc_peek_ascii_char () == '=')
762 : : {
763 : : /* Matched ">=". */
764 : 13505 : gfc_next_ascii_char ();
765 : 13505 : *result = INTRINSIC_GE;
766 : 13505 : return MATCH_YES;
767 : : }
768 : : /* Matched ">". */
769 : 251197 : *result = INTRINSIC_GT;
770 : 251197 : return MATCH_YES;
771 : :
772 : 190734 : case '*':
773 : 190734 : if (gfc_peek_ascii_char () == '*')
774 : : {
775 : : /* Matched "**". */
776 : 6885 : gfc_next_ascii_char ();
777 : 6885 : *result = INTRINSIC_POWER;
778 : 6885 : return MATCH_YES;
779 : : }
780 : : /* Matched "*". */
781 : 183849 : *result = INTRINSIC_TIMES;
782 : 183849 : return MATCH_YES;
783 : :
784 : 3158929 : case '/':
785 : 3158929 : ch = gfc_peek_ascii_char ();
786 : 3158929 : if (ch == '=')
787 : : {
788 : : /* Matched "/=". */
789 : 2683390 : gfc_next_ascii_char ();
790 : 2683390 : *result = INTRINSIC_NE;
791 : 2683390 : return MATCH_YES;
792 : : }
793 : 475539 : else if (ch == '/')
794 : : {
795 : : /* Matched "//". */
796 : 26625 : gfc_next_ascii_char ();
797 : 26625 : *result = INTRINSIC_CONCAT;
798 : 26625 : return MATCH_YES;
799 : : }
800 : : /* Matched "/". */
801 : 448914 : *result = INTRINSIC_DIVIDE;
802 : 448914 : return MATCH_YES;
803 : :
804 : 2714368 : case '.':
805 : 2714368 : ch = gfc_next_ascii_char ();
806 : 2714368 : switch (ch)
807 : : {
808 : 124268 : case 'a':
809 : 124268 : if (gfc_next_ascii_char () == 'n'
810 : 123358 : && gfc_next_ascii_char () == 'd'
811 : 247626 : && gfc_next_ascii_char () == '.')
812 : : {
813 : : /* Matched ".and.". */
814 : 123358 : *result = INTRINSIC_AND;
815 : 123358 : return MATCH_YES;
816 : : }
817 : : break;
818 : :
819 : 96080 : case 'e':
820 : 96080 : if (gfc_next_ascii_char () == 'q')
821 : : {
822 : 95996 : ch = gfc_next_ascii_char ();
823 : 95996 : if (ch == '.')
824 : : {
825 : : /* Matched ".eq.". */
826 : 79517 : *result = INTRINSIC_EQ_OS;
827 : 79517 : return MATCH_YES;
828 : : }
829 : 16479 : else if (ch == 'v')
830 : : {
831 : 16477 : if (gfc_next_ascii_char () == '.')
832 : : {
833 : : /* Matched ".eqv.". */
834 : 16477 : *result = INTRINSIC_EQV;
835 : 16477 : return MATCH_YES;
836 : : }
837 : : }
838 : : }
839 : : break;
840 : :
841 : 76959 : case 'g':
842 : 76959 : ch = gfc_next_ascii_char ();
843 : 76959 : if (ch == 'e')
844 : : {
845 : 20232 : if (gfc_next_ascii_char () == '.')
846 : : {
847 : : /* Matched ".ge.". */
848 : 20154 : *result = INTRINSIC_GE_OS;
849 : 20154 : return MATCH_YES;
850 : : }
851 : : }
852 : 56727 : else if (ch == 't')
853 : : {
854 : 56727 : if (gfc_next_ascii_char () == '.')
855 : : {
856 : : /* Matched ".gt.". */
857 : 56727 : *result = INTRINSIC_GT_OS;
858 : 56727 : return MATCH_YES;
859 : : }
860 : : }
861 : : break;
862 : :
863 : 52952 : case 'l':
864 : 52952 : ch = gfc_next_ascii_char ();
865 : 52952 : if (ch == 'e')
866 : : {
867 : 18568 : if (gfc_next_ascii_char () == '.')
868 : : {
869 : : /* Matched ".le.". */
870 : 18568 : *result = INTRINSIC_LE_OS;
871 : 18568 : return MATCH_YES;
872 : : }
873 : : }
874 : 34384 : else if (ch == 't')
875 : : {
876 : 34198 : if (gfc_next_ascii_char () == '.')
877 : : {
878 : : /* Matched ".lt.". */
879 : 34198 : *result = INTRINSIC_LT_OS;
880 : 34198 : return MATCH_YES;
881 : : }
882 : : }
883 : : break;
884 : :
885 : 1628588 : case 'n':
886 : 1628588 : ch = gfc_next_ascii_char ();
887 : 1628588 : if (ch == 'e')
888 : : {
889 : 1557925 : ch = gfc_next_ascii_char ();
890 : 1557925 : if (ch == '.')
891 : : {
892 : : /* Matched ".ne.". */
893 : 1335415 : *result = INTRINSIC_NE_OS;
894 : 1335415 : return MATCH_YES;
895 : : }
896 : 222510 : else if (ch == 'q')
897 : : {
898 : 222510 : if (gfc_next_ascii_char () == 'v'
899 : 222510 : && gfc_next_ascii_char () == '.')
900 : : {
901 : : /* Matched ".neqv.". */
902 : 222510 : *result = INTRINSIC_NEQV;
903 : 222510 : return MATCH_YES;
904 : : }
905 : : }
906 : : }
907 : 70663 : else if (ch == 'o')
908 : : {
909 : 70660 : if (gfc_next_ascii_char () == 't'
910 : 70660 : && gfc_next_ascii_char () == '.')
911 : : {
912 : : /* Matched ".not.". */
913 : 70615 : *result = INTRINSIC_NOT;
914 : 70615 : return MATCH_YES;
915 : : }
916 : : }
917 : : break;
918 : :
919 : 617184 : case 'o':
920 : 617184 : if (gfc_next_ascii_char () == 'r'
921 : 617184 : && gfc_next_ascii_char () == '.')
922 : : {
923 : : /* Matched ".or.". */
924 : 616959 : *result = INTRINSIC_OR;
925 : 616959 : return MATCH_YES;
926 : : }
927 : : break;
928 : :
929 : 449 : case 'x':
930 : 449 : if (gfc_next_ascii_char () == 'o'
931 : 327 : && gfc_next_ascii_char () == 'r'
932 : 776 : && gfc_next_ascii_char () == '.')
933 : : {
934 : 327 : if (!gfc_notify_std (GFC_STD_LEGACY, ".XOR. operator at %C"))
935 : : return MATCH_ERROR;
936 : : /* Matched ".xor." - equivalent to ".neqv.". */
937 : 320 : *result = INTRINSIC_NEQV;
938 : 320 : return MATCH_YES;
939 : : }
940 : : break;
941 : :
942 : : default:
943 : : break;
944 : : }
945 : : break;
946 : :
947 : : default:
948 : : break;
949 : : }
950 : :
951 : 58025507 : gfc_current_locus = orig_loc;
952 : 58025507 : return MATCH_NO;
953 : : }
954 : :
955 : :
956 : : /* Match a loop control phrase:
957 : :
958 : : <LVALUE> = <EXPR>, <EXPR> [, <EXPR> ]
959 : :
960 : : If the final integer expression is not present, a constant unity
961 : : expression is returned. We don't return MATCH_ERROR until after
962 : : the equals sign is seen. */
963 : :
964 : : match
965 : 37890 : gfc_match_iterator (gfc_iterator *iter, int init_flag)
966 : : {
967 : 37890 : char name[GFC_MAX_SYMBOL_LEN + 1];
968 : 37890 : gfc_expr *var, *e1, *e2, *e3;
969 : 37890 : locus start;
970 : 37890 : match m;
971 : :
972 : 37890 : e1 = e2 = e3 = NULL;
973 : :
974 : : /* Match the start of an iterator without affecting the symbol table. */
975 : :
976 : 37890 : start = gfc_current_locus;
977 : 37890 : m = gfc_match (" %n =", name);
978 : 37890 : gfc_current_locus = start;
979 : :
980 : 37890 : if (m != MATCH_YES)
981 : : return MATCH_NO;
982 : :
983 : 36250 : m = gfc_match_variable (&var, 0);
984 : 36250 : if (m != MATCH_YES)
985 : : return MATCH_NO;
986 : :
987 : 36250 : if (var->symtree->n.sym->attr.dimension)
988 : : {
989 : 4 : gfc_error ("Loop variable at %C cannot be an array");
990 : 4 : goto cleanup;
991 : : }
992 : :
993 : : /* F2008, C617 & C565. */
994 : 36246 : if (var->symtree->n.sym->attr.codimension)
995 : : {
996 : 1 : gfc_error ("Loop variable at %C cannot be a coarray");
997 : 1 : goto cleanup;
998 : : }
999 : :
1000 : 36245 : if (var->ref != NULL)
1001 : : {
1002 : 0 : gfc_error ("Loop variable at %C cannot be a sub-component");
1003 : 0 : goto cleanup;
1004 : : }
1005 : :
1006 : 36245 : gfc_match_char ('=');
1007 : :
1008 : 36245 : var->symtree->n.sym->attr.implied_index = 1;
1009 : :
1010 : 36245 : m = init_flag ? gfc_match_init_expr (&e1) : gfc_match_expr (&e1);
1011 : 36245 : if (m == MATCH_NO)
1012 : 0 : goto syntax;
1013 : 36245 : if (m == MATCH_ERROR)
1014 : 0 : goto cleanup;
1015 : :
1016 : 36245 : if (gfc_match_char (',') != MATCH_YES)
1017 : 1 : goto syntax;
1018 : :
1019 : 36244 : m = init_flag ? gfc_match_init_expr (&e2) : gfc_match_expr (&e2);
1020 : 36244 : if (m == MATCH_NO)
1021 : 0 : goto syntax;
1022 : 36244 : if (m == MATCH_ERROR)
1023 : 0 : goto cleanup;
1024 : :
1025 : 36244 : if (gfc_match_char (',') != MATCH_YES)
1026 : : {
1027 : 33106 : e3 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
1028 : 33106 : goto done;
1029 : : }
1030 : :
1031 : 3138 : m = init_flag ? gfc_match_init_expr (&e3) : gfc_match_expr (&e3);
1032 : 3138 : if (m == MATCH_ERROR)
1033 : 0 : goto cleanup;
1034 : 3138 : if (m == MATCH_NO)
1035 : : {
1036 : 0 : gfc_error ("Expected a step value in iterator at %C");
1037 : 0 : goto cleanup;
1038 : : }
1039 : :
1040 : 3138 : done:
1041 : 36244 : iter->var = var;
1042 : 36244 : iter->start = e1;
1043 : 36244 : iter->end = e2;
1044 : 36244 : iter->step = e3;
1045 : 36244 : return MATCH_YES;
1046 : :
1047 : 1 : syntax:
1048 : 1 : gfc_error ("Syntax error in iterator at %C");
1049 : :
1050 : 6 : cleanup:
1051 : 6 : gfc_free_expr (e1);
1052 : 6 : gfc_free_expr (e2);
1053 : 6 : gfc_free_expr (e3);
1054 : :
1055 : 6 : return MATCH_ERROR;
1056 : : }
1057 : :
1058 : :
1059 : : /* Tries to match the next non-whitespace character on the input.
1060 : : This subroutine does not return MATCH_ERROR.
1061 : : When gobble_ws is false, do not skip over leading blanks. */
1062 : :
1063 : : match
1064 : 33549486 : gfc_match_char (char c, bool gobble_ws)
1065 : : {
1066 : 33549486 : locus where;
1067 : :
1068 : 33549486 : where = gfc_current_locus;
1069 : 33549486 : if (gobble_ws)
1070 : 29831000 : gfc_gobble_whitespace ();
1071 : :
1072 : 33549486 : if (gfc_next_ascii_char () == c)
1073 : : return MATCH_YES;
1074 : :
1075 : 27284535 : gfc_current_locus = where;
1076 : 27284535 : return MATCH_NO;
1077 : : }
1078 : :
1079 : :
1080 : : /* General purpose matching subroutine. The target string is a
1081 : : scanf-like format string in which spaces correspond to arbitrary
1082 : : whitespace (including no whitespace), characters correspond to
1083 : : themselves. The %-codes are:
1084 : :
1085 : : %% Literal percent sign
1086 : : %e Expression, pointer to a pointer is set
1087 : : %s Symbol, pointer to the symbol is set (host_assoc = 0)
1088 : : %S Symbol, pointer to the symbol is set (host_assoc = 1)
1089 : : %n Name, character buffer is set to name
1090 : : %t Matches end of statement.
1091 : : %o Matches an intrinsic operator, returned as an INTRINSIC enum.
1092 : : %l Matches a statement label
1093 : : %v Matches a variable expression (an lvalue, except function references
1094 : : having a data pointer result)
1095 : : % Matches a required space (in free form) and optional spaces. */
1096 : :
1097 : : match
1098 : 76058802 : gfc_match (const char *target, ...)
1099 : : {
1100 : 76058802 : gfc_st_label **label;
1101 : 76058802 : int matches, *ip;
1102 : 76058802 : locus old_loc;
1103 : 76058802 : va_list argp;
1104 : 76058802 : char c, *np;
1105 : 76058802 : match m, n;
1106 : 76058802 : void **vp;
1107 : 76058802 : const char *p;
1108 : :
1109 : 76058802 : old_loc = gfc_current_locus;
1110 : 76058802 : va_start (argp, target);
1111 : 76058802 : m = MATCH_NO;
1112 : 76058802 : matches = 0;
1113 : 76058802 : p = target;
1114 : :
1115 : 337193697 : loop:
1116 : 337193697 : c = *p++;
1117 : 337193697 : switch (c)
1118 : : {
1119 : 97258759 : case ' ':
1120 : 97258759 : gfc_gobble_whitespace ();
1121 : 97258759 : goto loop;
1122 : : case '\0':
1123 : : m = MATCH_YES;
1124 : : break;
1125 : :
1126 : 19092292 : case '%':
1127 : 19092292 : c = *p++;
1128 : 19092292 : switch (c)
1129 : : {
1130 : 1596174 : case 'e':
1131 : 1596174 : vp = va_arg (argp, void **);
1132 : 1596174 : n = gfc_match_expr ((gfc_expr **) vp);
1133 : 1596174 : if (n != MATCH_YES)
1134 : : {
1135 : 541620 : m = n;
1136 : 541620 : goto not_yes;
1137 : : }
1138 : :
1139 : 1054554 : matches++;
1140 : 1054554 : goto loop;
1141 : :
1142 : 2229034 : case 'v':
1143 : 2229034 : vp = va_arg (argp, void **);
1144 : 2229034 : n = gfc_match_variable ((gfc_expr **) vp, 0);
1145 : 2229033 : if (n != MATCH_YES)
1146 : : {
1147 : 2221 : m = n;
1148 : 2221 : goto not_yes;
1149 : : }
1150 : :
1151 : 2226812 : matches++;
1152 : 2226812 : goto loop;
1153 : :
1154 : 27204 : case 's':
1155 : 27204 : case 'S':
1156 : 27204 : vp = va_arg (argp, void **);
1157 : 27204 : n = gfc_match_symbol ((gfc_symbol **) vp, c == 'S');
1158 : 27204 : if (n != MATCH_YES)
1159 : : {
1160 : 3 : m = n;
1161 : 3 : goto not_yes;
1162 : : }
1163 : :
1164 : 27201 : matches++;
1165 : 27201 : goto loop;
1166 : :
1167 : 11279019 : case 'n':
1168 : 11279019 : np = va_arg (argp, char *);
1169 : 11279019 : n = gfc_match_name (np);
1170 : 11279019 : if (n != MATCH_YES)
1171 : : {
1172 : 23045 : m = n;
1173 : 23045 : goto not_yes;
1174 : : }
1175 : :
1176 : 11255974 : matches++;
1177 : 11255974 : goto loop;
1178 : :
1179 : 189073 : case 'l':
1180 : 189073 : label = va_arg (argp, gfc_st_label **);
1181 : 189073 : n = gfc_match_st_label (label);
1182 : 189073 : if (n != MATCH_YES)
1183 : : {
1184 : 186814 : m = n;
1185 : 186814 : goto not_yes;
1186 : : }
1187 : :
1188 : 2259 : matches++;
1189 : 2259 : goto loop;
1190 : :
1191 : 1585 : case 'o':
1192 : 1585 : ip = va_arg (argp, int *);
1193 : 1585 : n = gfc_match_intrinsic_op ((gfc_intrinsic_op *) ip);
1194 : 1585 : if (n != MATCH_YES)
1195 : : {
1196 : 729 : m = n;
1197 : 729 : goto not_yes;
1198 : : }
1199 : :
1200 : 856 : matches++;
1201 : 856 : goto loop;
1202 : :
1203 : 246764 : case 't':
1204 : 246764 : if (gfc_match_eos () != MATCH_YES)
1205 : : {
1206 : 2227 : m = MATCH_NO;
1207 : 2227 : goto not_yes;
1208 : : }
1209 : 244537 : goto loop;
1210 : :
1211 : 278014 : case ' ':
1212 : 278014 : if (gfc_match_space () == MATCH_YES)
1213 : 274642 : goto loop;
1214 : 3372 : m = MATCH_NO;
1215 : 3372 : goto not_yes;
1216 : :
1217 : : case '%':
1218 : : break; /* Fall through to character matcher. */
1219 : :
1220 : 0 : default:
1221 : 0 : gfc_internal_error ("gfc_match(): Bad match code %c", c);
1222 : : }
1223 : : /* FALLTHRU */
1224 : :
1225 : 208089187 : default:
1226 : :
1227 : : /* gfc_next_ascii_char converts characters to lower-case, so we shouldn't
1228 : : expect an upper case character here! */
1229 : 208089187 : gcc_assert (TOLOWER (c) == c);
1230 : :
1231 : 208089187 : if (c == gfc_next_ascii_char ())
1232 : 148789301 : goto loop;
1233 : : break;
1234 : : }
1235 : :
1236 : 76058801 : not_yes:
1237 : 76058801 : va_end (argp);
1238 : :
1239 : 76058801 : if (m != MATCH_YES)
1240 : : {
1241 : : /* Clean up after a failed match. */
1242 : 60059917 : gfc_current_locus = old_loc;
1243 : 60059917 : va_start (argp, target);
1244 : :
1245 : 60059917 : p = target;
1246 : 66697831 : for (; matches > 0; matches--)
1247 : : {
1248 : 13502453 : while (*p++ != '%');
1249 : :
1250 : 6637914 : switch (*p++)
1251 : : {
1252 : 0 : case '%':
1253 : 0 : matches++;
1254 : 0 : break; /* Skip. */
1255 : :
1256 : : /* Matches that don't have to be undone */
1257 : 4600717 : case 'o':
1258 : 4600717 : case 'l':
1259 : 4600717 : case 'n':
1260 : 4600717 : case 's':
1261 : 4600717 : (void) va_arg (argp, void **);
1262 : 4600717 : break;
1263 : :
1264 : 2037197 : case 'e':
1265 : 2037197 : case 'v':
1266 : 2037197 : vp = va_arg (argp, void **);
1267 : 2037197 : gfc_free_expr ((struct gfc_expr *)*vp);
1268 : 2037197 : *vp = NULL;
1269 : 2037197 : break;
1270 : : }
1271 : : }
1272 : :
1273 : 60059917 : va_end (argp);
1274 : : }
1275 : :
1276 : 76058801 : return m;
1277 : : }
1278 : :
1279 : :
1280 : : /*********************** Statement level matching **********************/
1281 : :
1282 : : /* Matches the start of a program unit, which is the program keyword
1283 : : followed by an obligatory symbol. */
1284 : :
1285 : : match
1286 : 17324 : gfc_match_program (void)
1287 : : {
1288 : 17324 : gfc_symbol *sym;
1289 : 17324 : match m;
1290 : :
1291 : 17324 : m = gfc_match ("% %s%t", &sym);
1292 : :
1293 : 17324 : if (m == MATCH_NO)
1294 : : {
1295 : 0 : gfc_error ("Invalid form of PROGRAM statement at %C");
1296 : 0 : m = MATCH_ERROR;
1297 : : }
1298 : :
1299 : 17324 : if (m == MATCH_ERROR)
1300 : 0 : return m;
1301 : :
1302 : 17324 : if (!gfc_add_flavor (&sym->attr, FL_PROGRAM, sym->name, NULL))
1303 : : return MATCH_ERROR;
1304 : :
1305 : 17324 : gfc_new_block = sym;
1306 : :
1307 : 17324 : return MATCH_YES;
1308 : : }
1309 : :
1310 : :
1311 : : /* Match a simple assignment statement. */
1312 : :
1313 : : match
1314 : 1196678 : gfc_match_assignment (void)
1315 : : {
1316 : 1196678 : gfc_expr *lvalue, *rvalue;
1317 : 1196678 : locus old_loc;
1318 : 1196678 : match m;
1319 : :
1320 : 1196678 : old_loc = gfc_current_locus;
1321 : :
1322 : 1196678 : lvalue = NULL;
1323 : 1196678 : m = gfc_match (" %v =", &lvalue);
1324 : 1196677 : if (m != MATCH_YES)
1325 : : {
1326 : 1017360 : gfc_current_locus = old_loc;
1327 : 1017360 : gfc_free_expr (lvalue);
1328 : 1017360 : return MATCH_NO;
1329 : : }
1330 : :
1331 : 179317 : rvalue = NULL;
1332 : 179317 : m = gfc_match (" %e%t", &rvalue);
1333 : :
1334 : 179317 : if (m == MATCH_YES
1335 : 169141 : && rvalue->ts.type == BT_BOZ
1336 : 4 : && lvalue->ts.type == BT_CLASS)
1337 : : {
1338 : 1 : m = MATCH_ERROR;
1339 : 1 : gfc_error ("BOZ literal constant at %L is neither a DATA statement "
1340 : : "value nor an actual argument of INT/REAL/DBLE/CMPLX "
1341 : : "intrinsic subprogram", &rvalue->where);
1342 : : }
1343 : :
1344 : 179317 : if (lvalue->expr_type == EXPR_CONSTANT)
1345 : : {
1346 : : /* This clobbers %len and %kind. */
1347 : 6 : m = MATCH_ERROR;
1348 : 6 : gfc_error ("Assignment to a constant expression at %C");
1349 : : }
1350 : :
1351 : 179317 : if (m != MATCH_YES)
1352 : : {
1353 : 10182 : gfc_current_locus = old_loc;
1354 : 10182 : gfc_free_expr (lvalue);
1355 : 10182 : gfc_free_expr (rvalue);
1356 : 10182 : return m;
1357 : : }
1358 : :
1359 : 169135 : if (!lvalue->symtree)
1360 : : {
1361 : 0 : gfc_free_expr (lvalue);
1362 : 0 : gfc_free_expr (rvalue);
1363 : 0 : return MATCH_ERROR;
1364 : : }
1365 : :
1366 : :
1367 : 169135 : gfc_set_sym_referenced (lvalue->symtree->n.sym);
1368 : :
1369 : 169135 : new_st.op = EXEC_ASSIGN;
1370 : 169135 : new_st.expr1 = lvalue;
1371 : 169135 : new_st.expr2 = rvalue;
1372 : :
1373 : 169135 : gfc_check_do_variable (lvalue->symtree);
1374 : :
1375 : 169135 : return MATCH_YES;
1376 : : }
1377 : :
1378 : :
1379 : : /* Match a pointer assignment statement. */
1380 : :
1381 : : match
1382 : 1027542 : gfc_match_pointer_assignment (void)
1383 : : {
1384 : 1027542 : gfc_expr *lvalue, *rvalue;
1385 : 1027542 : locus old_loc;
1386 : 1027542 : match m;
1387 : :
1388 : 1027542 : old_loc = gfc_current_locus;
1389 : :
1390 : 1027542 : lvalue = rvalue = NULL;
1391 : 1027542 : gfc_matching_ptr_assignment = 0;
1392 : 1027542 : gfc_matching_procptr_assignment = 0;
1393 : :
1394 : 1027542 : m = gfc_match (" %v =>", &lvalue);
1395 : 1027542 : if (m != MATCH_YES || !lvalue->symtree)
1396 : : {
1397 : 1019628 : m = MATCH_NO;
1398 : 1019628 : goto cleanup;
1399 : : }
1400 : :
1401 : 7914 : if (lvalue->symtree->n.sym->attr.proc_pointer
1402 : 7914 : || gfc_is_proc_ptr_comp (lvalue))
1403 : 1196 : gfc_matching_procptr_assignment = 1;
1404 : : else
1405 : 6718 : gfc_matching_ptr_assignment = 1;
1406 : :
1407 : 7914 : m = gfc_match (" %e%t", &rvalue);
1408 : 7914 : gfc_matching_ptr_assignment = 0;
1409 : 7914 : gfc_matching_procptr_assignment = 0;
1410 : 7914 : if (m != MATCH_YES)
1411 : 1 : goto cleanup;
1412 : :
1413 : 7913 : new_st.op = EXEC_POINTER_ASSIGN;
1414 : 7913 : new_st.expr1 = lvalue;
1415 : 7913 : new_st.expr2 = rvalue;
1416 : :
1417 : 7913 : return MATCH_YES;
1418 : :
1419 : 1019629 : cleanup:
1420 : 1019629 : gfc_current_locus = old_loc;
1421 : 1019629 : gfc_free_expr (lvalue);
1422 : 1019629 : gfc_free_expr (rvalue);
1423 : 1019629 : return m;
1424 : : }
1425 : :
1426 : :
1427 : : /* We try to match an easy arithmetic IF statement. This only happens
1428 : : when just after having encountered a simple IF statement. This code
1429 : : is really duplicate with parts of the gfc_match_if code, but this is
1430 : : *much* easier. */
1431 : :
1432 : : static match
1433 : 24 : match_arithmetic_if (void)
1434 : : {
1435 : 24 : gfc_st_label *l1, *l2, *l3;
1436 : 24 : gfc_expr *expr;
1437 : 24 : match m;
1438 : :
1439 : 24 : m = gfc_match (" ( %e ) %l , %l , %l%t", &expr, &l1, &l2, &l3);
1440 : 24 : if (m != MATCH_YES)
1441 : : return m;
1442 : :
1443 : 24 : if (!gfc_reference_st_label (l1, ST_LABEL_TARGET)
1444 : 24 : || !gfc_reference_st_label (l2, ST_LABEL_TARGET)
1445 : 48 : || !gfc_reference_st_label (l3, ST_LABEL_TARGET))
1446 : : {
1447 : 0 : gfc_free_expr (expr);
1448 : 0 : return MATCH_ERROR;
1449 : : }
1450 : :
1451 : 24 : if (!gfc_notify_std (GFC_STD_F95_OBS | GFC_STD_F2018_DEL,
1452 : : "Arithmetic IF statement at %C"))
1453 : : return MATCH_ERROR;
1454 : :
1455 : 24 : new_st.op = EXEC_ARITHMETIC_IF;
1456 : 24 : new_st.expr1 = expr;
1457 : 24 : new_st.label1 = l1;
1458 : 24 : new_st.label2 = l2;
1459 : 24 : new_st.label3 = l3;
1460 : :
1461 : 24 : return MATCH_YES;
1462 : : }
1463 : :
1464 : :
1465 : : /* The IF statement is a bit of a pain. First of all, there are three
1466 : : forms of it, the simple IF, the IF that starts a block and the
1467 : : arithmetic IF.
1468 : :
1469 : : There is a problem with the simple IF and that is the fact that we
1470 : : only have a single level of undo information on symbols. What this
1471 : : means is for a simple IF, we must re-match the whole IF statement
1472 : : multiple times in order to guarantee that the symbol table ends up
1473 : : in the proper state. */
1474 : :
1475 : : static match match_simple_forall (void);
1476 : : static match match_simple_where (void);
1477 : :
1478 : : match
1479 : 641875 : gfc_match_if (gfc_statement *if_type)
1480 : : {
1481 : 641875 : gfc_expr *expr;
1482 : 641875 : gfc_st_label *l1, *l2, *l3;
1483 : 641875 : locus old_loc, old_loc2;
1484 : 641875 : gfc_code *p;
1485 : 641875 : match m, n;
1486 : :
1487 : 641875 : n = gfc_match_label ();
1488 : 641875 : if (n == MATCH_ERROR)
1489 : : return n;
1490 : :
1491 : 641867 : old_loc = gfc_current_locus;
1492 : :
1493 : 641867 : m = gfc_match (" if ", &expr);
1494 : 641867 : if (m != MATCH_YES)
1495 : : return m;
1496 : :
1497 : 186806 : if (gfc_match_char ('(') != MATCH_YES)
1498 : : {
1499 : 3 : gfc_error ("Missing %<(%> in IF-expression at %C");
1500 : 3 : return MATCH_ERROR;
1501 : : }
1502 : :
1503 : 186803 : m = gfc_match ("%e", &expr);
1504 : 186803 : if (m != MATCH_YES)
1505 : : return m;
1506 : :
1507 : 186782 : old_loc2 = gfc_current_locus;
1508 : 186782 : gfc_current_locus = old_loc;
1509 : :
1510 : 186782 : if (gfc_match_parens () == MATCH_ERROR)
1511 : : return MATCH_ERROR;
1512 : :
1513 : 186775 : gfc_current_locus = old_loc2;
1514 : :
1515 : 186775 : if (gfc_match_char (')') != MATCH_YES)
1516 : : {
1517 : 0 : gfc_error ("Syntax error in IF-expression at %C");
1518 : 0 : gfc_free_expr (expr);
1519 : 0 : return MATCH_ERROR;
1520 : : }
1521 : :
1522 : 186775 : m = gfc_match (" %l , %l , %l%t", &l1, &l2, &l3);
1523 : :
1524 : 186775 : if (m == MATCH_YES)
1525 : : {
1526 : 48 : if (n == MATCH_YES)
1527 : : {
1528 : 0 : gfc_error ("Block label not appropriate for arithmetic IF "
1529 : : "statement at %C");
1530 : 0 : gfc_free_expr (expr);
1531 : 0 : return MATCH_ERROR;
1532 : : }
1533 : :
1534 : 48 : if (!gfc_reference_st_label (l1, ST_LABEL_TARGET)
1535 : 48 : || !gfc_reference_st_label (l2, ST_LABEL_TARGET)
1536 : 96 : || !gfc_reference_st_label (l3, ST_LABEL_TARGET))
1537 : : {
1538 : 0 : gfc_free_expr (expr);
1539 : 0 : return MATCH_ERROR;
1540 : : }
1541 : :
1542 : 48 : if (!gfc_notify_std (GFC_STD_F95_OBS | GFC_STD_F2018_DEL,
1543 : : "Arithmetic IF statement at %C"))
1544 : : return MATCH_ERROR;
1545 : :
1546 : 48 : new_st.op = EXEC_ARITHMETIC_IF;
1547 : 48 : new_st.expr1 = expr;
1548 : 48 : new_st.label1 = l1;
1549 : 48 : new_st.label2 = l2;
1550 : 48 : new_st.label3 = l3;
1551 : :
1552 : 48 : *if_type = ST_ARITHMETIC_IF;
1553 : 48 : return MATCH_YES;
1554 : : }
1555 : :
1556 : 186727 : if (gfc_match (" then%t") == MATCH_YES)
1557 : : {
1558 : 13037 : new_st.op = EXEC_IF;
1559 : 13037 : new_st.expr1 = expr;
1560 : 13037 : *if_type = ST_IF_BLOCK;
1561 : 13037 : return MATCH_YES;
1562 : : }
1563 : :
1564 : 173690 : if (n == MATCH_YES)
1565 : : {
1566 : 0 : gfc_error ("Block label is not appropriate for IF statement at %C");
1567 : 0 : gfc_free_expr (expr);
1568 : 0 : return MATCH_ERROR;
1569 : : }
1570 : :
1571 : : /* At this point the only thing left is a simple IF statement. At
1572 : : this point, n has to be MATCH_NO, so we don't have to worry about
1573 : : re-matching a block label. From what we've got so far, try
1574 : : matching an assignment. */
1575 : :
1576 : 173690 : *if_type = ST_SIMPLE_IF;
1577 : :
1578 : 173690 : m = gfc_match_assignment ();
1579 : 173690 : if (m == MATCH_YES)
1580 : 4599 : goto got_match;
1581 : :
1582 : 169091 : gfc_free_expr (expr);
1583 : 169091 : gfc_undo_symbols ();
1584 : 169091 : gfc_current_locus = old_loc;
1585 : :
1586 : : /* m can be MATCH_NO or MATCH_ERROR, here. For MATCH_ERROR, a mangled
1587 : : assignment was found. For MATCH_NO, continue to call the various
1588 : : matchers. */
1589 : 169091 : if (m == MATCH_ERROR)
1590 : : return MATCH_ERROR;
1591 : :
1592 : 169091 : gfc_match (" if ( %e ) ", &expr); /* Guaranteed to match. */
1593 : :
1594 : 169091 : m = gfc_match_pointer_assignment ();
1595 : 169091 : if (m == MATCH_YES)
1596 : 38 : goto got_match;
1597 : :
1598 : 169053 : gfc_free_expr (expr);
1599 : 169053 : gfc_undo_symbols ();
1600 : 169053 : gfc_current_locus = old_loc;
1601 : :
1602 : 169053 : gfc_match (" if ( %e ) ", &expr); /* Guaranteed to match. */
1603 : :
1604 : : /* Look at the next keyword to see which matcher to call. Matching
1605 : : the keyword doesn't affect the symbol table, so we don't have to
1606 : : restore between tries. */
1607 : :
1608 : : #define match(string, subr, statement) \
1609 : : if (gfc_match (string) == MATCH_YES) { m = subr(); goto got_match; }
1610 : :
1611 : 169053 : gfc_clear_error ();
1612 : :
1613 : 169053 : match ("allocate", gfc_match_allocate, ST_ALLOCATE)
1614 : 169002 : match ("assign", gfc_match_assign, ST_LABEL_ASSIGNMENT)
1615 : 169000 : match ("backspace", gfc_match_backspace, ST_BACKSPACE)
1616 : 168994 : match ("call", gfc_match_call, ST_CALL)
1617 : 168274 : match ("change% team", gfc_match_change_team, ST_CHANGE_TEAM)
1618 : 168274 : match ("close", gfc_match_close, ST_CLOSE)
1619 : 168274 : match ("continue", gfc_match_continue, ST_CONTINUE)
1620 : 168274 : match ("cycle", gfc_match_cycle, ST_CYCLE)
1621 : 168185 : match ("deallocate", gfc_match_deallocate, ST_DEALLOCATE)
1622 : 167822 : match ("end file", gfc_match_endfile, ST_END_FILE)
1623 : 167822 : match ("end team", gfc_match_end_team, ST_END_TEAM)
1624 : 167822 : match ("error% stop", gfc_match_error_stop, ST_ERROR_STOP)
1625 : 150737 : match ("event% post", gfc_match_event_post, ST_EVENT_POST)
1626 : 150737 : match ("event% wait", gfc_match_event_wait, ST_EVENT_WAIT)
1627 : 150737 : match ("exit", gfc_match_exit, ST_EXIT)
1628 : 150437 : match ("fail% image", gfc_match_fail_image, ST_FAIL_IMAGE)
1629 : 150436 : match ("flush", gfc_match_flush, ST_FLUSH)
1630 : 150436 : match ("forall", match_simple_forall, ST_FORALL)
1631 : 150430 : match ("form% team", gfc_match_form_team, ST_FORM_TEAM)
1632 : 150430 : match ("go to", gfc_match_goto, ST_GOTO)
1633 : 150055 : match ("if", match_arithmetic_if, ST_ARITHMETIC_IF)
1634 : 150031 : match ("inquire", gfc_match_inquire, ST_INQUIRE)
1635 : 150031 : match ("lock", gfc_match_lock, ST_LOCK)
1636 : 150031 : match ("nullify", gfc_match_nullify, ST_NULLIFY)
1637 : 150031 : match ("open", gfc_match_open, ST_OPEN)
1638 : 150031 : match ("pause", gfc_match_pause, ST_NONE)
1639 : 150031 : match ("print", gfc_match_print, ST_WRITE)
1640 : 149567 : match ("read", gfc_match_read, ST_READ)
1641 : 149565 : match ("return", gfc_match_return, ST_RETURN)
1642 : 149271 : match ("rewind", gfc_match_rewind, ST_REWIND)
1643 : 149271 : match ("stop", gfc_match_stop, ST_STOP)
1644 : 377 : match ("wait", gfc_match_wait, ST_WAIT)
1645 : 377 : match ("sync% all", gfc_match_sync_all, ST_SYNC_CALL);
1646 : 377 : match ("sync% images", gfc_match_sync_images, ST_SYNC_IMAGES);
1647 : 377 : match ("sync% memory", gfc_match_sync_memory, ST_SYNC_MEMORY);
1648 : 377 : match ("sync% team", gfc_match_sync_team, ST_SYNC_TEAM)
1649 : 377 : match ("unlock", gfc_match_unlock, ST_UNLOCK)
1650 : 377 : match ("where", match_simple_where, ST_WHERE)
1651 : 370 : match ("write", gfc_match_write, ST_WRITE)
1652 : :
1653 : 6 : if (flag_dec)
1654 : 1 : match ("type", gfc_match_print, ST_WRITE)
1655 : :
1656 : : /* All else has failed, so give up. See if any of the matchers has
1657 : : stored an error message of some sort. */
1658 : 5 : if (!gfc_error_check ())
1659 : 5 : gfc_error ("Syntax error in IF-clause after %C");
1660 : :
1661 : 5 : gfc_free_expr (expr);
1662 : 5 : return MATCH_ERROR;
1663 : :
1664 : 173685 : got_match:
1665 : 173685 : if (m == MATCH_NO)
1666 : 0 : gfc_error ("Syntax error in IF-clause after %C");
1667 : 173685 : if (m != MATCH_YES)
1668 : : {
1669 : 77 : gfc_free_expr (expr);
1670 : 77 : return MATCH_ERROR;
1671 : : }
1672 : :
1673 : : /* At this point, we've matched the single IF and the action clause
1674 : : is in new_st. Rearrange things so that the IF statement appears
1675 : : in new_st. */
1676 : :
1677 : 173608 : p = gfc_get_code (EXEC_IF);
1678 : 173608 : p->next = XCNEW (gfc_code);
1679 : 173608 : *p->next = new_st;
1680 : 173608 : p->next->loc = gfc_current_locus;
1681 : :
1682 : 173608 : p->expr1 = expr;
1683 : :
1684 : 173608 : gfc_clear_new_st ();
1685 : :
1686 : 173608 : new_st.op = EXEC_IF;
1687 : 173608 : new_st.block = p;
1688 : :
1689 : 173608 : return MATCH_YES;
1690 : : }
1691 : :
1692 : : #undef match
1693 : :
1694 : :
1695 : : /* Match an ELSE statement. */
1696 : :
1697 : : match
1698 : 5862 : gfc_match_else (void)
1699 : : {
1700 : 5862 : char name[GFC_MAX_SYMBOL_LEN + 1];
1701 : :
1702 : 5862 : if (gfc_match_eos () == MATCH_YES)
1703 : : return MATCH_YES;
1704 : :
1705 : 2249 : if (gfc_match_name (name) != MATCH_YES
1706 : 2248 : || gfc_current_block () == NULL
1707 : 2266 : || gfc_match_eos () != MATCH_YES)
1708 : : {
1709 : 2247 : gfc_error ("Invalid character(s) in ELSE statement after %C");
1710 : 2247 : return MATCH_ERROR;
1711 : : }
1712 : :
1713 : 2 : if (strcmp (name, gfc_current_block ()->name) != 0)
1714 : : {
1715 : 1 : gfc_error ("Label %qs at %C doesn't match IF label %qs",
1716 : : name, gfc_current_block ()->name);
1717 : 1 : return MATCH_ERROR;
1718 : : }
1719 : :
1720 : : return MATCH_YES;
1721 : : }
1722 : :
1723 : :
1724 : : /* Match an ELSE IF statement. */
1725 : :
1726 : : match
1727 : 1922 : gfc_match_elseif (void)
1728 : : {
1729 : 1922 : char name[GFC_MAX_SYMBOL_LEN + 1];
1730 : 1922 : gfc_expr *expr, *then;
1731 : 1922 : locus where;
1732 : 1922 : match m;
1733 : :
1734 : 1922 : if (gfc_match_char ('(') != MATCH_YES)
1735 : : {
1736 : 1 : gfc_error ("Missing %<(%> in ELSE IF expression at %C");
1737 : 1 : return MATCH_ERROR;
1738 : : }
1739 : :
1740 : 1921 : m = gfc_match (" %e ", &expr);
1741 : 1921 : if (m != MATCH_YES)
1742 : : return m;
1743 : :
1744 : 1921 : if (gfc_match_char (')') != MATCH_YES)
1745 : : {
1746 : 1 : gfc_error ("Missing %<)%> in ELSE IF expression at %C");
1747 : 1 : goto cleanup;
1748 : : }
1749 : :
1750 : 1920 : m = gfc_match (" then ", &then);
1751 : :
1752 : 1920 : where = gfc_current_locus;
1753 : :
1754 : 1920 : if (m == MATCH_YES && (gfc_match_eos () == MATCH_YES
1755 : 3 : || (gfc_current_block ()
1756 : 2 : && gfc_match_name (name) == MATCH_YES)))
1757 : 1917 : goto done;
1758 : :
1759 : 3 : if (gfc_match_eos () == MATCH_YES)
1760 : : {
1761 : 1 : gfc_error ("Missing THEN in ELSE IF statement after %L", &where);
1762 : 1 : goto cleanup;
1763 : : }
1764 : :
1765 : 2 : if (gfc_match_name (name) != MATCH_YES
1766 : 2 : || gfc_current_block () == NULL
1767 : 3 : || gfc_match_eos () != MATCH_YES)
1768 : : {
1769 : 1 : gfc_error ("Syntax error in ELSE IF statement after %L", &where);
1770 : 1 : goto cleanup;
1771 : : }
1772 : :
1773 : 1 : if (strcmp (name, gfc_current_block ()->name) != 0)
1774 : : {
1775 : 1 : gfc_error ("Label %qs after %L doesn't match IF label %qs",
1776 : : name, &where, gfc_current_block ()->name);
1777 : 1 : goto cleanup;
1778 : : }
1779 : :
1780 : 0 : if (m != MATCH_YES)
1781 : : return m;
1782 : :
1783 : 0 : done:
1784 : 1917 : new_st.op = EXEC_IF;
1785 : 1917 : new_st.expr1 = expr;
1786 : 1917 : return MATCH_YES;
1787 : :
1788 : 4 : cleanup:
1789 : 4 : gfc_free_expr (expr);
1790 : 4 : return MATCH_ERROR;
1791 : : }
1792 : :
1793 : :
1794 : : /* Free a gfc_iterator structure. */
1795 : :
1796 : : void
1797 : 85375 : gfc_free_iterator (gfc_iterator *iter, int flag)
1798 : : {
1799 : :
1800 : 85375 : if (iter == NULL)
1801 : : return;
1802 : :
1803 : 48479 : gfc_free_expr (iter->var);
1804 : 48479 : gfc_free_expr (iter->start);
1805 : 48479 : gfc_free_expr (iter->end);
1806 : 48479 : gfc_free_expr (iter->step);
1807 : :
1808 : 48479 : if (flag)
1809 : 43312 : free (iter);
1810 : : }
1811 : :
1812 : :
1813 : : /* Match a CRITICAL statement. */
1814 : : match
1815 : 421228 : gfc_match_critical (void)
1816 : : {
1817 : 421228 : gfc_st_label *label = NULL;
1818 : :
1819 : 421228 : if (gfc_match_label () == MATCH_ERROR)
1820 : : return MATCH_ERROR;
1821 : :
1822 : 421220 : if (gfc_match (" critical") != MATCH_YES)
1823 : : return MATCH_NO;
1824 : :
1825 : 38 : if (gfc_match_st_label (&label) == MATCH_ERROR)
1826 : : return MATCH_ERROR;
1827 : :
1828 : 38 : if (gfc_match_eos () != MATCH_YES)
1829 : : {
1830 : 1 : gfc_syntax_error (ST_CRITICAL);
1831 : 1 : return MATCH_ERROR;
1832 : : }
1833 : :
1834 : 37 : if (gfc_pure (NULL))
1835 : : {
1836 : 1 : gfc_error ("Image control statement CRITICAL at %C in PURE procedure");
1837 : 1 : return MATCH_ERROR;
1838 : : }
1839 : :
1840 : 36 : if (gfc_find_state (COMP_DO_CONCURRENT))
1841 : : {
1842 : 1 : gfc_error ("Image control statement CRITICAL at %C in DO CONCURRENT "
1843 : : "block");
1844 : 1 : return MATCH_ERROR;
1845 : : }
1846 : :
1847 : 35 : gfc_unset_implicit_pure (NULL);
1848 : :
1849 : 35 : if (!gfc_notify_std (GFC_STD_F2008, "CRITICAL statement at %C"))
1850 : : return MATCH_ERROR;
1851 : :
1852 : 34 : if (flag_coarray == GFC_FCOARRAY_NONE)
1853 : : {
1854 : 0 : gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to "
1855 : : "enable");
1856 : : return MATCH_ERROR;
1857 : : }
1858 : :
1859 : 34 : if (gfc_find_state (COMP_CRITICAL))
1860 : : {
1861 : 1 : gfc_error ("Nested CRITICAL block at %C");
1862 : 1 : return MATCH_ERROR;
1863 : : }
1864 : :
1865 : 33 : new_st.op = EXEC_CRITICAL;
1866 : :
1867 : 33 : if (label != NULL
1868 : 33 : && !gfc_reference_st_label (label, ST_LABEL_TARGET))
1869 : : return MATCH_ERROR;
1870 : :
1871 : : return MATCH_YES;
1872 : : }
1873 : :
1874 : :
1875 : : /* Match a BLOCK statement. */
1876 : :
1877 : : match
1878 : 423273 : gfc_match_block (void)
1879 : : {
1880 : 423273 : match m;
1881 : :
1882 : 423273 : if (gfc_match_label () == MATCH_ERROR)
1883 : : return MATCH_ERROR;
1884 : :
1885 : 423265 : if (gfc_match (" block") != MATCH_YES)
1886 : : return MATCH_NO;
1887 : :
1888 : : /* For this to be a correct BLOCK statement, the line must end now. */
1889 : 1236 : m = gfc_match_eos ();
1890 : 1236 : if (m == MATCH_ERROR)
1891 : : return MATCH_ERROR;
1892 : 1236 : if (m == MATCH_NO)
1893 : : return MATCH_NO;
1894 : :
1895 : : return MATCH_YES;
1896 : : }
1897 : :
1898 : :
1899 : : /* Match an ASSOCIATE statement. */
1900 : :
1901 : : match
1902 : 422122 : gfc_match_associate (void)
1903 : : {
1904 : 422122 : if (gfc_match_label () == MATCH_ERROR)
1905 : : return MATCH_ERROR;
1906 : :
1907 : 422114 : if (gfc_match (" associate") != MATCH_YES)
1908 : : return MATCH_NO;
1909 : :
1910 : : /* Match the association list. */
1911 : 907 : if (gfc_match_char ('(') != MATCH_YES)
1912 : : {
1913 : 1 : gfc_error ("Expected association list at %C");
1914 : 1 : return MATCH_ERROR;
1915 : : }
1916 : 906 : new_st.ext.block.assoc = NULL;
1917 : 1114 : while (true)
1918 : : {
1919 : 1010 : gfc_association_list* newAssoc = gfc_get_association_list ();
1920 : 1010 : gfc_association_list* a;
1921 : :
1922 : : /* Match the next association. */
1923 : 1010 : if (gfc_match (" %n =>", newAssoc->name) != MATCH_YES)
1924 : : {
1925 : 3 : gfc_error ("Expected association at %C");
1926 : 3 : goto assocListError;
1927 : : }
1928 : :
1929 : 1007 : if (gfc_match (" %e", &newAssoc->target) != MATCH_YES)
1930 : : {
1931 : : /* Have another go, allowing for procedure pointer selectors. */
1932 : 18 : gfc_matching_procptr_assignment = 1;
1933 : 18 : if (gfc_match (" %e", &newAssoc->target) != MATCH_YES)
1934 : : {
1935 : 5 : gfc_error ("Invalid association target at %C");
1936 : 5 : goto assocListError;
1937 : : }
1938 : 13 : gfc_matching_procptr_assignment = 0;
1939 : : }
1940 : 1002 : newAssoc->where = gfc_current_locus;
1941 : :
1942 : : /* Check that the current name is not yet in the list. */
1943 : 1124 : for (a = new_st.ext.block.assoc; a; a = a->next)
1944 : 123 : if (!strcmp (a->name, newAssoc->name))
1945 : : {
1946 : 1 : gfc_error ("Duplicate name %qs in association at %C",
1947 : : newAssoc->name);
1948 : 1 : goto assocListError;
1949 : : }
1950 : :
1951 : : /* The target expression must not be coindexed. */
1952 : 1001 : if (gfc_is_coindexed (newAssoc->target))
1953 : : {
1954 : 1 : gfc_error ("Association target at %C must not be coindexed");
1955 : 1 : goto assocListError;
1956 : : }
1957 : :
1958 : : /* The target expression cannot be a BOZ literal constant. */
1959 : 1000 : if (newAssoc->target->ts.type == BT_BOZ)
1960 : : {
1961 : 1 : gfc_error ("Association target at %L cannot be a BOZ literal "
1962 : : "constant", &newAssoc->target->where);
1963 : 1 : goto assocListError;
1964 : : }
1965 : :
1966 : : /* The `variable' field is left blank for now; because the target is not
1967 : : yet resolved, we can't use gfc_has_vector_subscript to determine it
1968 : : for now. This is set during resolution. */
1969 : :
1970 : : /* Put it into the list. */
1971 : 999 : newAssoc->next = new_st.ext.block.assoc;
1972 : 999 : new_st.ext.block.assoc = newAssoc;
1973 : :
1974 : : /* Try next one or end if closing parenthesis is found. */
1975 : 999 : gfc_gobble_whitespace ();
1976 : 999 : if (gfc_peek_char () == ')')
1977 : : break;
1978 : 104 : if (gfc_match_char (',') != MATCH_YES)
1979 : : {
1980 : 0 : gfc_error ("Expected %<)%> or %<,%> at %C");
1981 : 0 : return MATCH_ERROR;
1982 : : }
1983 : :
1984 : 104 : continue;
1985 : :
1986 : 11 : assocListError:
1987 : 11 : free (newAssoc);
1988 : 11 : goto error;
1989 : 104 : }
1990 : 895 : if (gfc_match_char (')') != MATCH_YES)
1991 : : {
1992 : : /* This should never happen as we peek above. */
1993 : 0 : gcc_unreachable ();
1994 : : }
1995 : :
1996 : 895 : if (gfc_match_eos () != MATCH_YES)
1997 : : {
1998 : 1 : gfc_error ("Junk after ASSOCIATE statement at %C");
1999 : 1 : goto error;
2000 : : }
2001 : :
2002 : : return MATCH_YES;
2003 : :
2004 : 12 : error:
2005 : 12 : gfc_free_association_list (new_st.ext.block.assoc);
2006 : 12 : return MATCH_ERROR;
2007 : : }
2008 : :
2009 : :
2010 : : /* Match a Fortran 2003 derived-type-spec (F03:R455), which is just the name of
2011 : : an accessible derived type. */
2012 : :
2013 : : static match
2014 : 26258 : match_derived_type_spec (gfc_typespec *ts)
2015 : : {
2016 : 26258 : char name[GFC_MAX_SYMBOL_LEN + 1];
2017 : 26258 : locus old_locus;
2018 : 26258 : gfc_symbol *derived, *der_type;
2019 : 26258 : match m = MATCH_YES;
2020 : 26258 : gfc_actual_arglist *decl_type_param_list = NULL;
2021 : 26258 : bool is_pdt_template = false;
2022 : :
2023 : 26258 : old_locus = gfc_current_locus;
2024 : :
2025 : 26258 : if (gfc_match ("%n", name) != MATCH_YES)
2026 : : {
2027 : 1 : gfc_current_locus = old_locus;
2028 : 1 : return MATCH_NO;
2029 : : }
2030 : :
2031 : 26257 : gfc_find_symbol (name, NULL, 1, &derived);
2032 : :
2033 : : /* Match the PDT spec list, if there. */
2034 : 26257 : if (derived && derived->attr.flavor == FL_PROCEDURE)
2035 : : {
2036 : 6263 : gfc_find_symbol (gfc_dt_upper_string (name), NULL, 1, &der_type);
2037 : 6263 : is_pdt_template = der_type
2038 : : && der_type->attr.flavor == FL_DERIVED
2039 : 6263 : && der_type->attr.pdt_template;
2040 : : }
2041 : :
2042 : 70 : if (is_pdt_template)
2043 : 70 : m = gfc_match_actual_arglist (1, &decl_type_param_list, true);
2044 : :
2045 : 4947 : if (m == MATCH_ERROR)
2046 : : {
2047 : 0 : gfc_free_actual_arglist (decl_type_param_list);
2048 : 0 : return m;
2049 : : }
2050 : :
2051 : 26257 : if (derived && derived->attr.flavor == FL_PROCEDURE && derived->attr.generic)
2052 : 4252 : derived = gfc_find_dt_in_generic (derived);
2053 : :
2054 : : /* If this is a PDT, find the specific instance. */
2055 : 26257 : if (m == MATCH_YES && is_pdt_template)
2056 : : {
2057 : 70 : gfc_namespace *old_ns;
2058 : :
2059 : 70 : old_ns = gfc_current_ns;
2060 : 107 : while (gfc_current_ns && gfc_current_ns->parent)
2061 : 37 : gfc_current_ns = gfc_current_ns->parent;
2062 : :
2063 : 70 : if (type_param_spec_list)
2064 : 0 : gfc_free_actual_arglist (type_param_spec_list);
2065 : 70 : m = gfc_get_pdt_instance (decl_type_param_list, &der_type,
2066 : : &type_param_spec_list);
2067 : 70 : gfc_free_actual_arglist (decl_type_param_list);
2068 : :
2069 : 70 : if (m != MATCH_YES)
2070 : : return m;
2071 : 69 : derived = der_type;
2072 : 69 : gcc_assert (!derived->attr.pdt_template && derived->attr.pdt_type);
2073 : 69 : gfc_set_sym_referenced (derived);
2074 : :
2075 : 69 : gfc_current_ns = old_ns;
2076 : : }
2077 : :
2078 : 26256 : if (derived && derived->attr.flavor == FL_DERIVED)
2079 : : {
2080 : 4227 : ts->type = BT_DERIVED;
2081 : 4227 : ts->u.derived = derived;
2082 : 4227 : return MATCH_YES;
2083 : : }
2084 : :
2085 : 22029 : gfc_current_locus = old_locus;
2086 : 22029 : return MATCH_NO;
2087 : : }
2088 : :
2089 : :
2090 : : /* Match a Fortran 2003 type-spec (F03:R401). This is similar to
2091 : : gfc_match_decl_type_spec() from decl.cc, with the following exceptions:
2092 : : It only includes the intrinsic types from the Fortran 2003 standard
2093 : : (thus, neither BYTE nor forms like REAL*4 are allowed). Additionally,
2094 : : the implicit_flag is not needed, so it was removed. Derived types are
2095 : : identified by their name alone. */
2096 : :
2097 : : match
2098 : 110510 : gfc_match_type_spec (gfc_typespec *ts)
2099 : : {
2100 : 110510 : match m;
2101 : 110510 : locus old_locus;
2102 : 110510 : char c, name[GFC_MAX_SYMBOL_LEN + 1];
2103 : :
2104 : 110510 : gfc_clear_ts (ts);
2105 : 110510 : gfc_gobble_whitespace ();
2106 : 110510 : old_locus = gfc_current_locus;
2107 : :
2108 : : /* If c isn't [a-z], then return immediately. */
2109 : 110510 : c = gfc_peek_ascii_char ();
2110 : 110510 : if (!ISALPHA(c))
2111 : : return MATCH_NO;
2112 : :
2113 : 25964 : type_param_spec_list = NULL;
2114 : :
2115 : 25964 : if (match_derived_type_spec (ts) == MATCH_YES)
2116 : : {
2117 : : /* Enforce F03:C401. */
2118 : 3937 : if (ts->u.derived->attr.abstract)
2119 : : {
2120 : 1 : gfc_error ("Derived type %qs at %L may not be ABSTRACT",
2121 : : ts->u.derived->name, &old_locus);
2122 : 1 : return MATCH_ERROR;
2123 : : }
2124 : : return MATCH_YES;
2125 : : }
2126 : :
2127 : 22027 : if (gfc_match ("integer") == MATCH_YES)
2128 : : {
2129 : 1176 : ts->type = BT_INTEGER;
2130 : 1176 : ts->kind = gfc_default_integer_kind;
2131 : 1176 : goto kind_selector;
2132 : : }
2133 : :
2134 : 20851 : if (gfc_match ("double precision") == MATCH_YES)
2135 : : {
2136 : 53 : ts->type = BT_REAL;
2137 : 53 : ts->kind = gfc_default_double_kind;
2138 : 53 : return MATCH_YES;
2139 : : }
2140 : :
2141 : 20798 : if (gfc_match ("complex") == MATCH_YES)
2142 : : {
2143 : 91 : ts->type = BT_COMPLEX;
2144 : 91 : ts->kind = gfc_default_complex_kind;
2145 : 91 : goto kind_selector;
2146 : : }
2147 : :
2148 : 20707 : if (gfc_match ("character") == MATCH_YES)
2149 : : {
2150 : 1631 : ts->type = BT_CHARACTER;
2151 : :
2152 : 1631 : m = gfc_match_char_spec (ts);
2153 : :
2154 : 1631 : if (m == MATCH_NO)
2155 : 0 : m = MATCH_YES;
2156 : :
2157 : 1631 : return m;
2158 : : }
2159 : :
2160 : : /* REAL is a real pain because it can be a type, intrinsic subprogram,
2161 : : or list item in a type-list of an OpenMP reduction clause. Need to
2162 : : differentiate REAL([KIND]=scalar-int-initialization-expr) from
2163 : : REAL(A,[KIND]) and REAL(KIND,A). Logically, when this code was
2164 : : written the use of LOGICAL as a type-spec or intrinsic subprogram
2165 : : was overlooked. */
2166 : :
2167 : 19076 : m = gfc_match (" %n", name);
2168 : 19076 : if (m == MATCH_YES
2169 : 19075 : && (strcmp (name, "real") == 0 || strcmp (name, "logical") == 0))
2170 : : {
2171 : 1609 : char c;
2172 : 1609 : gfc_expr *e;
2173 : 1609 : locus where;
2174 : :
2175 : 1609 : if (*name == 'r')
2176 : : {
2177 : 1522 : ts->type = BT_REAL;
2178 : 1522 : ts->kind = gfc_default_real_kind;
2179 : : }
2180 : : else
2181 : : {
2182 : 87 : ts->type = BT_LOGICAL;
2183 : 87 : ts->kind = gfc_default_logical_kind;
2184 : : }
2185 : :
2186 : 1609 : gfc_gobble_whitespace ();
2187 : :
2188 : : /* Prevent REAL*4, etc. */
2189 : 1609 : c = gfc_peek_ascii_char ();
2190 : 1609 : if (c == '*')
2191 : : {
2192 : 4 : gfc_error ("Invalid type-spec at %C");
2193 : 1610 : return MATCH_ERROR;
2194 : : }
2195 : :
2196 : : /* Found leading colon in REAL::, a trailing ')' in for example
2197 : : TYPE IS (REAL), or REAL, for an OpenMP list-item. */
2198 : 1605 : if (c == ':' || c == ')' || (flag_openmp && c == ','))
2199 : : return MATCH_YES;
2200 : :
2201 : : /* Found something other than the opening '(' in REAL(... */
2202 : 422 : if (c != '(')
2203 : : return MATCH_NO;
2204 : : else
2205 : 422 : gfc_next_char (); /* Burn the '('. */
2206 : :
2207 : : /* Look for the optional KIND=. */
2208 : 422 : where = gfc_current_locus;
2209 : 422 : m = gfc_match ("%n", name);
2210 : 422 : if (m == MATCH_YES)
2211 : : {
2212 : 280 : gfc_gobble_whitespace ();
2213 : 280 : c = gfc_next_char ();
2214 : 280 : if (c == '=')
2215 : : {
2216 : 42 : if (strcmp(name, "a") == 0 || strcmp(name, "l") == 0)
2217 : : return MATCH_NO;
2218 : 38 : else if (strcmp(name, "kind") == 0)
2219 : 38 : goto found;
2220 : : else
2221 : : return MATCH_ERROR;
2222 : : }
2223 : : else
2224 : 238 : gfc_current_locus = where;
2225 : : }
2226 : : else
2227 : 142 : gfc_current_locus = where;
2228 : :
2229 : 418 : found:
2230 : :
2231 : 418 : m = gfc_match_expr (&e);
2232 : 418 : if (m == MATCH_NO || m == MATCH_ERROR)
2233 : : return m;
2234 : :
2235 : : /* If a comma appears, it is an intrinsic subprogram. */
2236 : 418 : gfc_gobble_whitespace ();
2237 : 418 : c = gfc_peek_ascii_char ();
2238 : 418 : if (c == ',')
2239 : : {
2240 : 11 : gfc_free_expr (e);
2241 : 11 : return MATCH_NO;
2242 : : }
2243 : :
2244 : : /* If ')' appears, we have REAL(initialization-expr), here check for
2245 : : a scalar integer initialization-expr and valid kind parameter. */
2246 : 407 : if (c == ')')
2247 : : {
2248 : 407 : bool ok = true;
2249 : 407 : if (e->expr_type != EXPR_CONSTANT && e->expr_type != EXPR_VARIABLE)
2250 : 6 : ok = gfc_reduce_init_expr (e);
2251 : 407 : if (!ok || e->ts.type != BT_INTEGER || e->rank > 0)
2252 : : {
2253 : 2 : gfc_free_expr (e);
2254 : 2 : return MATCH_NO;
2255 : : }
2256 : :
2257 : 405 : if (e->expr_type != EXPR_CONSTANT)
2258 : 3 : goto ohno;
2259 : :
2260 : 402 : gfc_next_char (); /* Burn the ')'. */
2261 : 402 : ts->kind = (int) mpz_get_si (e->value.integer);
2262 : 402 : if (gfc_validate_kind (ts->type, ts->kind , true) == -1)
2263 : : {
2264 : 1 : gfc_error ("Invalid type-spec at %C");
2265 : 1 : return MATCH_ERROR;
2266 : : }
2267 : :
2268 : 401 : gfc_free_expr (e);
2269 : :
2270 : 401 : return MATCH_YES;
2271 : : }
2272 : : }
2273 : :
2274 : 17467 : ohno:
2275 : :
2276 : : /* If a type is not matched, simply return MATCH_NO. */
2277 : 17470 : gfc_current_locus = old_locus;
2278 : 17470 : return MATCH_NO;
2279 : :
2280 : 1267 : kind_selector:
2281 : :
2282 : 1267 : gfc_gobble_whitespace ();
2283 : :
2284 : : /* This prevents INTEGER*4, etc. */
2285 : 1267 : if (gfc_peek_ascii_char () == '*')
2286 : : {
2287 : 0 : gfc_error ("Invalid type-spec at %C");
2288 : 0 : return MATCH_ERROR;
2289 : : }
2290 : :
2291 : 1267 : m = gfc_match_kind_spec (ts, false);
2292 : :
2293 : : /* No kind specifier found. */
2294 : 1267 : if (m == MATCH_NO)
2295 : 5027 : m = MATCH_YES;
2296 : :
2297 : : return m;
2298 : : }
2299 : :
2300 : :
2301 : : /******************** FORALL subroutines ********************/
2302 : :
2303 : : /* Free a list of FORALL iterators. */
2304 : :
2305 : : void
2306 : 4816 : gfc_free_forall_iterator (gfc_forall_iterator *iter)
2307 : : {
2308 : 4816 : gfc_forall_iterator *next;
2309 : :
2310 : 9558 : while (iter)
2311 : : {
2312 : 4742 : next = iter->next;
2313 : 4742 : gfc_free_expr (iter->var);
2314 : 4742 : gfc_free_expr (iter->start);
2315 : 4742 : gfc_free_expr (iter->end);
2316 : 4742 : gfc_free_expr (iter->stride);
2317 : 4742 : free (iter);
2318 : 4742 : iter = next;
2319 : : }
2320 : 4816 : }
2321 : :
2322 : :
2323 : : /* Match an iterator as part of a FORALL statement. The format is:
2324 : :
2325 : : <var> = <start>:<end>[:<stride>]
2326 : :
2327 : : On MATCH_NO, the caller tests for the possibility that there is a
2328 : : scalar mask expression. */
2329 : :
2330 : : static match
2331 : 4742 : match_forall_iterator (gfc_forall_iterator **result)
2332 : : {
2333 : 4742 : gfc_forall_iterator *iter;
2334 : 4742 : locus where;
2335 : 4742 : match m;
2336 : :
2337 : 4742 : where = gfc_current_locus;
2338 : 4742 : iter = XCNEW (gfc_forall_iterator);
2339 : :
2340 : 4742 : m = gfc_match_expr (&iter->var);
2341 : 4742 : if (m != MATCH_YES)
2342 : 0 : goto cleanup;
2343 : :
2344 : 4742 : if (gfc_match_char ('=') != MATCH_YES
2345 : 4742 : || iter->var->expr_type != EXPR_VARIABLE)
2346 : : {
2347 : 749 : m = MATCH_NO;
2348 : 749 : goto cleanup;
2349 : : }
2350 : :
2351 : 3993 : m = gfc_match_expr (&iter->start);
2352 : 3993 : if (m != MATCH_YES)
2353 : 0 : goto cleanup;
2354 : :
2355 : 3993 : if (gfc_match_char (':') != MATCH_YES)
2356 : 0 : goto syntax;
2357 : :
2358 : 3993 : m = gfc_match_expr (&iter->end);
2359 : 3993 : if (m == MATCH_NO)
2360 : 0 : goto syntax;
2361 : 3993 : if (m == MATCH_ERROR)
2362 : 0 : goto cleanup;
2363 : :
2364 : 3993 : if (gfc_match_char (':') == MATCH_NO)
2365 : 3943 : iter->stride = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
2366 : : else
2367 : : {
2368 : 50 : m = gfc_match_expr (&iter->stride);
2369 : 50 : if (m == MATCH_NO)
2370 : 0 : goto syntax;
2371 : 50 : if (m == MATCH_ERROR)
2372 : 0 : goto cleanup;
2373 : : }
2374 : :
2375 : : /* Mark the iteration variable's symbol as used as a FORALL index. */
2376 : 3993 : iter->var->symtree->n.sym->forall_index = true;
2377 : :
2378 : 3993 : *result = iter;
2379 : 3993 : return MATCH_YES;
2380 : :
2381 : 0 : syntax:
2382 : 0 : gfc_error ("Syntax error in FORALL iterator at %C");
2383 : 0 : m = MATCH_ERROR;
2384 : :
2385 : 749 : cleanup:
2386 : :
2387 : 749 : gfc_current_locus = where;
2388 : 749 : gfc_free_forall_iterator (iter);
2389 : 749 : return m;
2390 : : }
2391 : :
2392 : :
2393 : : /* Match the header of a FORALL statement. */
2394 : :
2395 : : static match
2396 : 2065 : match_forall_header (gfc_forall_iterator **phead, gfc_expr **mask)
2397 : : {
2398 : 2065 : gfc_forall_iterator *head, *tail, *new_iter;
2399 : 2065 : gfc_expr *msk;
2400 : 2065 : match m;
2401 : :
2402 : 2065 : gfc_gobble_whitespace ();
2403 : :
2404 : 2065 : head = tail = NULL;
2405 : 2065 : msk = NULL;
2406 : :
2407 : 2065 : if (gfc_match_char ('(') != MATCH_YES)
2408 : : return MATCH_NO;
2409 : :
2410 : 2065 : m = match_forall_iterator (&new_iter);
2411 : 2065 : if (m == MATCH_ERROR)
2412 : 0 : goto cleanup;
2413 : 2065 : if (m == MATCH_NO)
2414 : 0 : goto syntax;
2415 : :
2416 : 2065 : head = tail = new_iter;
2417 : :
2418 : 5921 : for (;;)
2419 : : {
2420 : 3993 : if (gfc_match_char (',') != MATCH_YES)
2421 : : break;
2422 : :
2423 : 2677 : m = match_forall_iterator (&new_iter);
2424 : 2677 : if (m == MATCH_ERROR)
2425 : 0 : goto cleanup;
2426 : :
2427 : 2677 : if (m == MATCH_YES)
2428 : : {
2429 : 1928 : tail->next = new_iter;
2430 : 1928 : tail = new_iter;
2431 : 1928 : continue;
2432 : : }
2433 : :
2434 : : /* Have to have a mask expression. */
2435 : :
2436 : 749 : m = gfc_match_expr (&msk);
2437 : 749 : if (m == MATCH_NO)
2438 : 0 : goto syntax;
2439 : 749 : if (m == MATCH_ERROR)
2440 : 0 : goto cleanup;
2441 : :
2442 : : break;
2443 : : }
2444 : :
2445 : 2065 : if (gfc_match_char (')') == MATCH_NO)
2446 : 0 : goto syntax;
2447 : :
2448 : 2065 : *phead = head;
2449 : 2065 : *mask = msk;
2450 : 2065 : return MATCH_YES;
2451 : :
2452 : 0 : syntax:
2453 : 0 : gfc_syntax_error (ST_FORALL);
2454 : :
2455 : 0 : cleanup:
2456 : 0 : gfc_free_expr (msk);
2457 : 0 : gfc_free_forall_iterator (head);
2458 : :
2459 : 0 : return MATCH_ERROR;
2460 : : }
2461 : :
2462 : : /* Match the rest of a simple FORALL statement that follows an
2463 : : IF statement. */
2464 : :
2465 : : static match
2466 : 6 : match_simple_forall (void)
2467 : : {
2468 : 6 : gfc_forall_iterator *head;
2469 : 6 : gfc_expr *mask;
2470 : 6 : gfc_code *c;
2471 : 6 : match m;
2472 : :
2473 : 6 : mask = NULL;
2474 : 6 : head = NULL;
2475 : 6 : c = NULL;
2476 : :
2477 : 6 : m = match_forall_header (&head, &mask);
2478 : :
2479 : 6 : if (m == MATCH_NO)
2480 : 0 : goto syntax;
2481 : 6 : if (m != MATCH_YES)
2482 : 0 : goto cleanup;
2483 : :
2484 : 6 : m = gfc_match_assignment ();
2485 : :
2486 : 6 : if (m == MATCH_ERROR)
2487 : 0 : goto cleanup;
2488 : 6 : if (m == MATCH_NO)
2489 : : {
2490 : 0 : m = gfc_match_pointer_assignment ();
2491 : 0 : if (m == MATCH_ERROR)
2492 : 0 : goto cleanup;
2493 : 0 : if (m == MATCH_NO)
2494 : 0 : goto syntax;
2495 : : }
2496 : :
2497 : 6 : c = XCNEW (gfc_code);
2498 : 6 : *c = new_st;
2499 : 6 : c->loc = gfc_current_locus;
2500 : :
2501 : 6 : if (gfc_match_eos () != MATCH_YES)
2502 : 0 : goto syntax;
2503 : :
2504 : 6 : gfc_clear_new_st ();
2505 : 6 : new_st.op = EXEC_FORALL;
2506 : 6 : new_st.expr1 = mask;
2507 : 6 : new_st.ext.forall_iterator = head;
2508 : 6 : new_st.block = gfc_get_code (EXEC_FORALL);
2509 : 6 : new_st.block->next = c;
2510 : :
2511 : 6 : return MATCH_YES;
2512 : :
2513 : 0 : syntax:
2514 : 0 : gfc_syntax_error (ST_FORALL);
2515 : :
2516 : 0 : cleanup:
2517 : 0 : gfc_free_forall_iterator (head);
2518 : 0 : gfc_free_expr (mask);
2519 : :
2520 : 0 : return MATCH_ERROR;
2521 : : }
2522 : :
2523 : :
2524 : : /* Match a FORALL statement. */
2525 : :
2526 : : match
2527 : 454729 : gfc_match_forall (gfc_statement *st)
2528 : : {
2529 : 454729 : gfc_forall_iterator *head;
2530 : 454729 : gfc_expr *mask;
2531 : 454729 : gfc_code *c;
2532 : 454729 : match m0, m;
2533 : :
2534 : 454729 : head = NULL;
2535 : 454729 : mask = NULL;
2536 : 454729 : c = NULL;
2537 : :
2538 : 454729 : m0 = gfc_match_label ();
2539 : 454729 : if (m0 == MATCH_ERROR)
2540 : : return MATCH_ERROR;
2541 : :
2542 : 454721 : m = gfc_match (" forall");
2543 : 454721 : if (m != MATCH_YES)
2544 : : return m;
2545 : :
2546 : 1996 : m = match_forall_header (&head, &mask);
2547 : 1996 : if (m == MATCH_ERROR)
2548 : 0 : goto cleanup;
2549 : 1996 : if (m == MATCH_NO)
2550 : 0 : goto syntax;
2551 : :
2552 : 1996 : if (gfc_match_eos () == MATCH_YES)
2553 : : {
2554 : 511 : *st = ST_FORALL_BLOCK;
2555 : 511 : new_st.op = EXEC_FORALL;
2556 : 511 : new_st.expr1 = mask;
2557 : 511 : new_st.ext.forall_iterator = head;
2558 : 511 : return MATCH_YES;
2559 : : }
2560 : :
2561 : 1485 : m = gfc_match_assignment ();
2562 : 1485 : if (m == MATCH_ERROR)
2563 : 0 : goto cleanup;
2564 : 1485 : if (m == MATCH_NO)
2565 : : {
2566 : 0 : m = gfc_match_pointer_assignment ();
2567 : 0 : if (m == MATCH_ERROR)
2568 : 0 : goto cleanup;
2569 : 0 : if (m == MATCH_NO)
2570 : 0 : goto syntax;
2571 : : }
2572 : :
2573 : 1485 : c = XCNEW (gfc_code);
2574 : 1485 : *c = new_st;
2575 : 1485 : c->loc = gfc_current_locus;
2576 : :
2577 : 1485 : gfc_clear_new_st ();
2578 : 1485 : new_st.op = EXEC_FORALL;
2579 : 1485 : new_st.expr1 = mask;
2580 : 1485 : new_st.ext.forall_iterator = head;
2581 : 1485 : new_st.block = gfc_get_code (EXEC_FORALL);
2582 : 1485 : new_st.block->next = c;
2583 : :
2584 : 1485 : *st = ST_FORALL;
2585 : 1485 : return MATCH_YES;
2586 : :
2587 : 0 : syntax:
2588 : 0 : gfc_syntax_error (ST_FORALL);
2589 : :
2590 : 0 : cleanup:
2591 : 0 : gfc_free_forall_iterator (head);
2592 : 0 : gfc_free_expr (mask);
2593 : 0 : gfc_free_statements (c);
2594 : 0 : return MATCH_NO;
2595 : : }
2596 : :
2597 : :
2598 : : /* Match a DO statement. */
2599 : :
2600 : : match
2601 : 452714 : gfc_match_do (void)
2602 : : {
2603 : 452714 : gfc_iterator iter, *ip;
2604 : 452714 : locus old_loc;
2605 : 452714 : gfc_st_label *label;
2606 : 452714 : match m;
2607 : :
2608 : 452714 : old_loc = gfc_current_locus;
2609 : :
2610 : 452714 : memset (&iter, '\0', sizeof (gfc_iterator));
2611 : 452714 : label = NULL;
2612 : :
2613 : 452714 : m = gfc_match_label ();
2614 : 452714 : if (m == MATCH_ERROR)
2615 : : return m;
2616 : :
2617 : 452706 : if (gfc_match (" do") != MATCH_YES)
2618 : : return MATCH_NO;
2619 : :
2620 : 29449 : m = gfc_match_st_label (&label);
2621 : 29449 : if (m == MATCH_ERROR)
2622 : 0 : goto cleanup;
2623 : :
2624 : : /* Match an infinite DO, make it like a DO WHILE(.TRUE.). */
2625 : :
2626 : 29449 : if (gfc_match_eos () == MATCH_YES)
2627 : : {
2628 : 241 : iter.end = gfc_get_logical_expr (gfc_default_logical_kind, NULL, true);
2629 : 241 : new_st.op = EXEC_DO_WHILE;
2630 : 241 : goto done;
2631 : : }
2632 : :
2633 : : /* Match an optional comma, if no comma is found, a space is obligatory. */
2634 : 29208 : if (gfc_match_char (',') != MATCH_YES && gfc_match ("% ") != MATCH_YES)
2635 : : return MATCH_NO;
2636 : :
2637 : : /* Check for balanced parens. */
2638 : :
2639 : 29208 : if (gfc_match_parens () == MATCH_ERROR)
2640 : : return MATCH_ERROR;
2641 : :
2642 : 29206 : if (gfc_match (" concurrent") == MATCH_YES)
2643 : : {
2644 : 63 : gfc_forall_iterator *head;
2645 : 63 : gfc_expr *mask;
2646 : :
2647 : 63 : if (!gfc_notify_std (GFC_STD_F2008, "DO CONCURRENT construct at %C"))
2648 : : return MATCH_ERROR;
2649 : :
2650 : :
2651 : 63 : mask = NULL;
2652 : 63 : head = NULL;
2653 : 63 : m = match_forall_header (&head, &mask);
2654 : :
2655 : 63 : if (m == MATCH_NO)
2656 : : return m;
2657 : 63 : if (m == MATCH_ERROR)
2658 : 0 : goto concurr_cleanup;
2659 : :
2660 : 63 : if (gfc_match_eos () != MATCH_YES)
2661 : 0 : goto concurr_cleanup;
2662 : :
2663 : 63 : if (label != NULL
2664 : 63 : && !gfc_reference_st_label (label, ST_LABEL_DO_TARGET))
2665 : 0 : goto concurr_cleanup;
2666 : :
2667 : 63 : new_st.label1 = label;
2668 : 63 : new_st.op = EXEC_DO_CONCURRENT;
2669 : 63 : new_st.expr1 = mask;
2670 : 63 : new_st.ext.forall_iterator = head;
2671 : :
2672 : 63 : return MATCH_YES;
2673 : :
2674 : 0 : concurr_cleanup:
2675 : 0 : gfc_syntax_error (ST_DO);
2676 : 0 : gfc_free_expr (mask);
2677 : 0 : gfc_free_forall_iterator (head);
2678 : 0 : return MATCH_ERROR;
2679 : : }
2680 : :
2681 : : /* See if we have a DO WHILE. */
2682 : 29143 : if (gfc_match (" while ( %e )%t", &iter.end) == MATCH_YES)
2683 : : {
2684 : 263 : new_st.op = EXEC_DO_WHILE;
2685 : 263 : goto done;
2686 : : }
2687 : :
2688 : : /* The abortive DO WHILE may have done something to the symbol
2689 : : table, so we start over. */
2690 : 28880 : gfc_undo_symbols ();
2691 : 28880 : gfc_current_locus = old_loc;
2692 : :
2693 : 28880 : gfc_match_label (); /* This won't error. */
2694 : 28880 : gfc_match (" do "); /* This will work. */
2695 : :
2696 : 28880 : gfc_match_st_label (&label); /* Can't error out. */
2697 : 28880 : gfc_match_char (','); /* Optional comma. */
2698 : :
2699 : 28880 : m = gfc_match_iterator (&iter, 0);
2700 : 28880 : if (m == MATCH_NO)
2701 : : return MATCH_NO;
2702 : 28879 : if (m == MATCH_ERROR)
2703 : 5 : goto cleanup;
2704 : :
2705 : 28874 : iter.var->symtree->n.sym->attr.implied_index = 0;
2706 : 28874 : gfc_check_do_variable (iter.var->symtree);
2707 : :
2708 : 28874 : if (gfc_match_eos () != MATCH_YES)
2709 : : {
2710 : 0 : gfc_syntax_error (ST_DO);
2711 : 0 : goto cleanup;
2712 : : }
2713 : :
2714 : 28874 : new_st.op = EXEC_DO;
2715 : :
2716 : 29378 : done:
2717 : 29378 : if (label != NULL
2718 : 29378 : && !gfc_reference_st_label (label, ST_LABEL_DO_TARGET))
2719 : 0 : goto cleanup;
2720 : :
2721 : 29378 : new_st.label1 = label;
2722 : :
2723 : 29378 : if (new_st.op == EXEC_DO_WHILE)
2724 : 504 : new_st.expr1 = iter.end;
2725 : : else
2726 : : {
2727 : 28874 : new_st.ext.iterator = ip = gfc_get_iterator ();
2728 : 28874 : *ip = iter;
2729 : : }
2730 : :
2731 : : return MATCH_YES;
2732 : :
2733 : 5 : cleanup:
2734 : 5 : gfc_free_iterator (&iter, 0);
2735 : :
2736 : 5 : return MATCH_ERROR;
2737 : : }
2738 : :
2739 : :
2740 : : /* Match an EXIT or CYCLE statement. */
2741 : :
2742 : : static match
2743 : 729 : match_exit_cycle (gfc_statement st, gfc_exec_op op)
2744 : : {
2745 : 729 : gfc_state_data *p, *o;
2746 : 729 : gfc_symbol *sym;
2747 : 729 : match m;
2748 : 729 : int cnt;
2749 : :
2750 : 729 : if (gfc_match_eos () == MATCH_YES)
2751 : : sym = NULL;
2752 : : else
2753 : : {
2754 : 234 : char name[GFC_MAX_SYMBOL_LEN + 1];
2755 : 234 : gfc_symtree* stree;
2756 : :
2757 : 234 : m = gfc_match ("% %n%t", name);
2758 : 234 : if (m == MATCH_ERROR)
2759 : 3 : return MATCH_ERROR;
2760 : 234 : if (m == MATCH_NO)
2761 : : {
2762 : 0 : gfc_syntax_error (st);
2763 : 0 : return MATCH_ERROR;
2764 : : }
2765 : :
2766 : : /* Find the corresponding symbol. If there's a BLOCK statement
2767 : : between here and the label, it is not in gfc_current_ns but a parent
2768 : : namespace! */
2769 : 234 : stree = gfc_find_symtree_in_proc (name, gfc_current_ns);
2770 : 234 : if (!stree)
2771 : : {
2772 : 2 : gfc_error ("Name %qs in %s statement at %C is unknown",
2773 : : name, gfc_ascii_statement (st));
2774 : 2 : return MATCH_ERROR;
2775 : : }
2776 : :
2777 : 232 : sym = stree->n.sym;
2778 : 232 : if (sym->attr.flavor != FL_LABEL)
2779 : : {
2780 : 1 : gfc_error ("Name %qs in %s statement at %C is not a construct name",
2781 : : name, gfc_ascii_statement (st));
2782 : 1 : return MATCH_ERROR;
2783 : : }
2784 : : }
2785 : :
2786 : : /* Find the loop specified by the label (or lack of a label). */
2787 : 1059 : for (o = NULL, p = gfc_state_stack; p; p = p->previous)
2788 : 1057 : if (o == NULL && p->state == COMP_OMP_STRUCTURED_BLOCK)
2789 : : o = p;
2790 : 1054 : else if (p->state == COMP_CRITICAL)
2791 : : {
2792 : 3 : gfc_error("%s statement at %C leaves CRITICAL construct",
2793 : : gfc_ascii_statement (st));
2794 : 3 : return MATCH_ERROR;
2795 : : }
2796 : 1051 : else if (p->state == COMP_DO_CONCURRENT
2797 : 11 : && (op == EXEC_EXIT || (sym && sym != p->sym)))
2798 : : {
2799 : : /* F2008, C821 & C845. */
2800 : 3 : gfc_error("%s statement at %C leaves DO CONCURRENT construct",
2801 : : gfc_ascii_statement (st));
2802 : 3 : return MATCH_ERROR;
2803 : : }
2804 : 1041 : else if ((sym && sym == p->sym)
2805 : 822 : || (!sym && (p->state == COMP_DO
2806 : 211 : || p->state == COMP_DO_CONCURRENT)))
2807 : : break;
2808 : :
2809 : 720 : if (p == NULL)
2810 : : {
2811 : 2 : if (sym == NULL)
2812 : 1 : gfc_error ("%s statement at %C is not within a construct",
2813 : : gfc_ascii_statement (st));
2814 : : else
2815 : 1 : gfc_error ("%s statement at %C is not within construct %qs",
2816 : : gfc_ascii_statement (st), sym->name);
2817 : :
2818 : 2 : return MATCH_ERROR;
2819 : : }
2820 : :
2821 : : /* Special checks for EXIT from non-loop constructs. */
2822 : 718 : switch (p->state)
2823 : : {
2824 : : case COMP_DO:
2825 : : case COMP_DO_CONCURRENT:
2826 : : break;
2827 : :
2828 : 0 : case COMP_CRITICAL:
2829 : : /* This is already handled above. */
2830 : 0 : gcc_unreachable ();
2831 : :
2832 : 87 : case COMP_ASSOCIATE:
2833 : 87 : case COMP_BLOCK:
2834 : 87 : case COMP_IF:
2835 : 87 : case COMP_SELECT:
2836 : 87 : case COMP_SELECT_TYPE:
2837 : 87 : case COMP_SELECT_RANK:
2838 : 87 : gcc_assert (sym);
2839 : 87 : if (op == EXEC_CYCLE)
2840 : : {
2841 : 1 : gfc_error ("CYCLE statement at %C is not applicable to non-loop"
2842 : : " construct %qs", sym->name);
2843 : 1 : return MATCH_ERROR;
2844 : : }
2845 : 86 : gcc_assert (op == EXEC_EXIT);
2846 : 86 : if (!gfc_notify_std (GFC_STD_F2008, "EXIT statement with no"
2847 : : " do-construct-name at %C"))
2848 : : return MATCH_ERROR;
2849 : : break;
2850 : :
2851 : 1 : default:
2852 : 1 : gfc_error ("%s statement at %C is not applicable to construct %qs",
2853 : : gfc_ascii_statement (st), sym->name);
2854 : 1 : return MATCH_ERROR;
2855 : : }
2856 : :
2857 : 715 : if (o != NULL)
2858 : : {
2859 : 3 : gfc_error (is_oacc (p)
2860 : : ? G_("%s statement at %C leaving OpenACC structured block")
2861 : : : G_("%s statement at %C leaving OpenMP structured block"),
2862 : : gfc_ascii_statement (st));
2863 : 3 : return MATCH_ERROR;
2864 : : }
2865 : :
2866 : 1504 : for (o = p, cnt = 0; o->state == COMP_DO && o->previous != NULL; cnt++)
2867 : 792 : o = o->previous;
2868 : :
2869 : 712 : int count = 1;
2870 : 712 : if (cnt > 0
2871 : 712 : && o != NULL
2872 : 619 : && o->state == COMP_OMP_STRUCTURED_BLOCK)
2873 : 149 : switch (o->head->op)
2874 : : {
2875 : 20 : case EXEC_OACC_LOOP:
2876 : 20 : case EXEC_OACC_KERNELS_LOOP:
2877 : 20 : case EXEC_OACC_PARALLEL_LOOP:
2878 : 20 : case EXEC_OACC_SERIAL_LOOP:
2879 : 20 : gcc_assert (o->head->next != NULL
2880 : : && (o->head->next->op == EXEC_DO
2881 : : || o->head->next->op == EXEC_DO_WHILE)
2882 : : && o->previous != NULL
2883 : : && o->previous->tail->op == o->head->op);
2884 : 20 : if (o->previous->tail->ext.omp_clauses != NULL)
2885 : : {
2886 : : /* Both collapsed and tiled loops are lowered the same way, but are
2887 : : not compatible. In gfc_trans_omp_do, the tile is prioritized. */
2888 : 20 : if (o->previous->tail->ext.omp_clauses->tile_list)
2889 : : {
2890 : : count = 0;
2891 : : gfc_expr_list *el
2892 : : = o->previous->tail->ext.omp_clauses->tile_list;
2893 : 6 : for ( ; el; el = el->next)
2894 : 4 : ++count;
2895 : : }
2896 : 18 : else if (o->previous->tail->ext.omp_clauses->collapse > 1)
2897 : 20 : count = o->previous->tail->ext.omp_clauses->collapse;
2898 : : }
2899 : 20 : if (st == ST_EXIT && cnt <= count)
2900 : : {
2901 : 14 : gfc_error ("EXIT statement at %C terminating !$ACC LOOP loop");
2902 : 14 : return MATCH_ERROR;
2903 : : }
2904 : 6 : if (st == ST_CYCLE && cnt < count)
2905 : : {
2906 : 4 : gfc_error (o->previous->tail->ext.omp_clauses->tile_list
2907 : : ? G_("CYCLE statement at %C to non-innermost tiled "
2908 : : "!$ACC LOOP loop")
2909 : : : G_("CYCLE statement at %C to non-innermost collapsed "
2910 : : "!$ACC LOOP loop"));
2911 : 4 : return MATCH_ERROR;
2912 : : }
2913 : : break;
2914 : 127 : case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
2915 : 127 : case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
2916 : 127 : case EXEC_OMP_TARGET_SIMD:
2917 : 127 : case EXEC_OMP_TASKLOOP_SIMD:
2918 : 127 : case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
2919 : 127 : case EXEC_OMP_MASTER_TASKLOOP_SIMD:
2920 : 127 : case EXEC_OMP_PARALLEL_MASKED_TASKLOOP_SIMD:
2921 : 127 : case EXEC_OMP_MASKED_TASKLOOP_SIMD:
2922 : 127 : case EXEC_OMP_PARALLEL_DO_SIMD:
2923 : 127 : case EXEC_OMP_DISTRIBUTE_SIMD:
2924 : 127 : case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
2925 : 127 : case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
2926 : 127 : case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
2927 : 127 : case EXEC_OMP_LOOP:
2928 : 127 : case EXEC_OMP_PARALLEL_LOOP:
2929 : 127 : case EXEC_OMP_TEAMS_LOOP:
2930 : 127 : case EXEC_OMP_TARGET_PARALLEL_LOOP:
2931 : 127 : case EXEC_OMP_TARGET_TEAMS_LOOP:
2932 : 127 : case EXEC_OMP_DO:
2933 : 127 : case EXEC_OMP_PARALLEL_DO:
2934 : 127 : case EXEC_OMP_SIMD:
2935 : 127 : case EXEC_OMP_DO_SIMD:
2936 : 127 : case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
2937 : 127 : case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
2938 : 127 : case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
2939 : 127 : case EXEC_OMP_TARGET_PARALLEL_DO:
2940 : 127 : case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
2941 : :
2942 : 127 : gcc_assert (o->head->next != NULL
2943 : : && (o->head->next->op == EXEC_DO
2944 : : || o->head->next->op == EXEC_DO_WHILE)
2945 : : && o->previous != NULL
2946 : : && o->previous->tail->op == o->head->op);
2947 : 127 : if (o->previous->tail->ext.omp_clauses != NULL)
2948 : : {
2949 : 127 : if (o->previous->tail->ext.omp_clauses->collapse > 1)
2950 : : count = o->previous->tail->ext.omp_clauses->collapse;
2951 : 127 : if (o->previous->tail->ext.omp_clauses->orderedc)
2952 : 0 : count = o->previous->tail->ext.omp_clauses->orderedc;
2953 : : }
2954 : 127 : if (st == ST_EXIT && cnt <= count)
2955 : : {
2956 : 63 : gfc_error ("EXIT statement at %C terminating !$OMP DO loop");
2957 : 63 : return MATCH_ERROR;
2958 : : }
2959 : 64 : if (st == ST_CYCLE && cnt < count)
2960 : : {
2961 : 3 : gfc_error ("CYCLE statement at %C to non-innermost collapsed "
2962 : : "!$OMP DO loop");
2963 : 3 : return MATCH_ERROR;
2964 : : }
2965 : : break;
2966 : : default:
2967 : : break;
2968 : : }
2969 : :
2970 : : /* Save the first statement in the construct - needed by the backend. */
2971 : 628 : new_st.ext.which_construct = p->construct;
2972 : :
2973 : 628 : new_st.op = op;
2974 : :
2975 : 628 : return MATCH_YES;
2976 : : }
2977 : :
2978 : :
2979 : : /* Match the EXIT statement. */
2980 : :
2981 : : match
2982 : 603 : gfc_match_exit (void)
2983 : : {
2984 : 603 : return match_exit_cycle (ST_EXIT, EXEC_EXIT);
2985 : : }
2986 : :
2987 : :
2988 : : /* Match the CYCLE statement. */
2989 : :
2990 : : match
2991 : 126 : gfc_match_cycle (void)
2992 : : {
2993 : 126 : return match_exit_cycle (ST_CYCLE, EXEC_CYCLE);
2994 : : }
2995 : :
2996 : :
2997 : : /* Match a stop-code after an (ERROR) STOP or PAUSE statement. The
2998 : : requirements for a stop-code differ in the standards.
2999 : :
3000 : : Fortran 95 has
3001 : :
3002 : : R840 stop-stmt is STOP [ stop-code ]
3003 : : R841 stop-code is scalar-char-constant
3004 : : or digit [ digit [ digit [ digit [ digit ] ] ] ]
3005 : :
3006 : : Fortran 2003 matches Fortran 95 except R840 and R841 are now R849 and R850.
3007 : : Fortran 2008 has
3008 : :
3009 : : R855 stop-stmt is STOP [ stop-code ]
3010 : : R856 allstop-stmt is ALL STOP [ stop-code ]
3011 : : R857 stop-code is scalar-default-char-constant-expr
3012 : : or scalar-int-constant-expr
3013 : : Fortran 2018 has
3014 : :
3015 : : R1160 stop-stmt is STOP [ stop-code ] [ , QUIET = scalar-logical-expr]
3016 : : R1161 error-stop-stmt is
3017 : : ERROR STOP [ stop-code ] [ , QUIET = scalar-logical-expr]
3018 : : R1162 stop-code is scalar-default-char-expr
3019 : : or scalar-int-expr
3020 : :
3021 : : For free-form source code, all standards contain a statement of the form:
3022 : :
3023 : : A blank shall be used to separate names, constants, or labels from
3024 : : adjacent keywords, names, constants, or labels.
3025 : :
3026 : : A stop-code is not a name, constant, or label. So, under Fortran 95 and 2003,
3027 : :
3028 : : STOP123
3029 : :
3030 : : is valid, but it is invalid Fortran 2008. */
3031 : :
3032 : : static match
3033 : 174792 : gfc_match_stopcode (gfc_statement st)
3034 : : {
3035 : 174792 : gfc_expr *e = NULL;
3036 : 174792 : gfc_expr *quiet = NULL;
3037 : 174792 : match m;
3038 : 174792 : bool f95, f03, f08;
3039 : 174792 : char c;
3040 : :
3041 : : /* Set f95 for -std=f95. */
3042 : 174792 : f95 = (gfc_option.allow_std == GFC_STD_OPT_F95);
3043 : :
3044 : : /* Set f03 for -std=f2003. */
3045 : 174792 : f03 = (gfc_option.allow_std == GFC_STD_OPT_F03);
3046 : :
3047 : : /* Set f08 for -std=f2008. */
3048 : 174792 : f08 = (gfc_option.allow_std == GFC_STD_OPT_F08);
3049 : :
3050 : : /* Plain STOP statement? */
3051 : 174792 : if (gfc_match_eos () == MATCH_YES)
3052 : 4974 : goto checks;
3053 : :
3054 : : /* Look for a blank between STOP and the stop-code for F2008 or later.
3055 : : But allow for F2018's ,QUIET= specifier. */
3056 : 169818 : c = gfc_peek_ascii_char ();
3057 : :
3058 : 169818 : if (gfc_current_form != FORM_FIXED && !(f95 || f03) && c != ',')
3059 : : {
3060 : : /* Look for end-of-statement. There is no stop-code. */
3061 : : if (c == '\n' || c == '!' || c == ';')
3062 : 0 : goto done;
3063 : :
3064 : : if (c != ' ')
3065 : : {
3066 : 3 : gfc_error ("Blank required in %s statement near %C",
3067 : : gfc_ascii_statement (st));
3068 : 3 : return MATCH_ERROR;
3069 : : }
3070 : : }
3071 : :
3072 : 4719 : if (c == ' ')
3073 : : {
3074 : 165702 : gfc_gobble_whitespace ();
3075 : 165702 : c = gfc_peek_ascii_char ();
3076 : : }
3077 : 169815 : if (c != ',')
3078 : : {
3079 : 169811 : int stopcode;
3080 : 169811 : locus old_locus;
3081 : :
3082 : : /* First look for the F95 or F2003 digit [...] construct. */
3083 : 169811 : old_locus = gfc_current_locus;
3084 : 169811 : m = gfc_match_small_int (&stopcode);
3085 : 169811 : if (m == MATCH_YES && (f95 || f03))
3086 : : {
3087 : 611 : if (stopcode < 0)
3088 : : {
3089 : 2 : gfc_error ("STOP code at %C cannot be negative");
3090 : 4 : return MATCH_ERROR;
3091 : : }
3092 : :
3093 : 609 : if (stopcode > 99999)
3094 : : {
3095 : 2 : gfc_error ("STOP code at %C contains too many digits");
3096 : 2 : return MATCH_ERROR;
3097 : : }
3098 : : }
3099 : :
3100 : : /* Reset the locus and now load gfc_expr. */
3101 : 169807 : gfc_current_locus = old_locus;
3102 : 169807 : m = gfc_match_expr (&e);
3103 : 169807 : if (m == MATCH_ERROR)
3104 : 0 : goto cleanup;
3105 : 169807 : if (m == MATCH_NO)
3106 : 0 : goto syntax;
3107 : : }
3108 : :
3109 : 169811 : if (gfc_match (" , quiet = %e", &quiet) == MATCH_YES)
3110 : : {
3111 : 38 : if (!gfc_notify_std (GFC_STD_F2018, "QUIET= specifier for %s at %L",
3112 : 38 : gfc_ascii_statement (st), &quiet->where))
3113 : 0 : goto cleanup;
3114 : : }
3115 : :
3116 : 169811 : if (gfc_match_eos () != MATCH_YES)
3117 : 1 : goto syntax;
3118 : :
3119 : 169810 : checks:
3120 : :
3121 : 174784 : if (gfc_pure (NULL))
3122 : : {
3123 : 63 : if (st == ST_ERROR_STOP)
3124 : : {
3125 : 63 : if (!gfc_notify_std (GFC_STD_F2018, "%s statement at %C in PURE "
3126 : : "procedure", gfc_ascii_statement (st)))
3127 : 1 : goto cleanup;
3128 : : }
3129 : : else
3130 : : {
3131 : 0 : gfc_error ("%s statement not allowed in PURE procedure at %C",
3132 : : gfc_ascii_statement (st));
3133 : 0 : goto cleanup;
3134 : : }
3135 : : }
3136 : :
3137 : 174783 : gfc_unset_implicit_pure (NULL);
3138 : :
3139 : 174783 : if (st == ST_STOP && gfc_find_state (COMP_CRITICAL))
3140 : : {
3141 : 1 : gfc_error ("Image control statement STOP at %C in CRITICAL block");
3142 : 1 : goto cleanup;
3143 : : }
3144 : 174782 : if (st == ST_STOP && gfc_find_state (COMP_DO_CONCURRENT))
3145 : : {
3146 : 1 : gfc_error ("Image control statement STOP at %C in DO CONCURRENT block");
3147 : 1 : goto cleanup;
3148 : : }
3149 : :
3150 : 174781 : if (e != NULL)
3151 : : {
3152 : 169804 : if (!gfc_simplify_expr (e, 0))
3153 : 1 : goto cleanup;
3154 : :
3155 : : /* Test for F95 and F2003 style STOP stop-code. */
3156 : 169803 : if (e->expr_type != EXPR_CONSTANT && (f95 || f03))
3157 : : {
3158 : 0 : gfc_error ("STOP code at %L must be a scalar CHARACTER constant "
3159 : : "or digit[digit[digit[digit[digit]]]]", &e->where);
3160 : 0 : goto cleanup;
3161 : : }
3162 : :
3163 : : /* Use the machinery for an initialization expression to reduce the
3164 : : stop-code to a constant. */
3165 : 169803 : gfc_reduce_init_expr (e);
3166 : :
3167 : : /* Test for F2008 style STOP stop-code. */
3168 : 169803 : if (e->expr_type != EXPR_CONSTANT && f08)
3169 : : {
3170 : 1 : gfc_error ("STOP code at %L must be a scalar default CHARACTER or "
3171 : : "INTEGER constant expression", &e->where);
3172 : 1 : goto cleanup;
3173 : : }
3174 : :
3175 : 169802 : if (!(e->ts.type == BT_CHARACTER || e->ts.type == BT_INTEGER))
3176 : : {
3177 : 2 : gfc_error ("STOP code at %L must be either INTEGER or CHARACTER type",
3178 : : &e->where);
3179 : 2 : goto cleanup;
3180 : : }
3181 : :
3182 : 169800 : if (e->rank != 0)
3183 : : {
3184 : 1 : gfc_error ("STOP code at %L must be scalar", &e->where);
3185 : 1 : goto cleanup;
3186 : : }
3187 : :
3188 : 169799 : if (e->ts.type == BT_CHARACTER
3189 : 366 : && e->ts.kind != gfc_default_character_kind)
3190 : : {
3191 : 0 : gfc_error ("STOP code at %L must be default character KIND=%d",
3192 : : &e->where, (int) gfc_default_character_kind);
3193 : 0 : goto cleanup;
3194 : : }
3195 : :
3196 : 169433 : if (e->ts.type == BT_INTEGER && e->ts.kind != gfc_default_integer_kind
3197 : 169807 : && !gfc_notify_std (GFC_STD_F2018,
3198 : : "STOP code at %L must be default integer KIND=%d",
3199 : : &e->where, (int) gfc_default_integer_kind))
3200 : 0 : goto cleanup;
3201 : : }
3202 : :
3203 : 174776 : if (quiet != NULL)
3204 : : {
3205 : 38 : if (!gfc_simplify_expr (quiet, 0))
3206 : 0 : goto cleanup;
3207 : :
3208 : 38 : if (quiet->rank != 0)
3209 : : {
3210 : 1 : gfc_error ("QUIET specifier at %L must be a scalar LOGICAL",
3211 : : &quiet->where);
3212 : 1 : goto cleanup;
3213 : : }
3214 : : }
3215 : :
3216 : 174738 : done:
3217 : :
3218 : 174775 : switch (st)
3219 : : {
3220 : 156810 : case ST_STOP:
3221 : 156810 : new_st.op = EXEC_STOP;
3222 : 156810 : break;
3223 : 17937 : case ST_ERROR_STOP:
3224 : 17937 : new_st.op = EXEC_ERROR_STOP;
3225 : 17937 : break;
3226 : 28 : case ST_PAUSE:
3227 : 28 : new_st.op = EXEC_PAUSE;
3228 : 28 : break;
3229 : 0 : default:
3230 : 0 : gcc_unreachable ();
3231 : : }
3232 : :
3233 : 174775 : new_st.expr1 = e;
3234 : 174775 : new_st.expr2 = quiet;
3235 : 174775 : new_st.ext.stop_code = -1;
3236 : :
3237 : 174775 : return MATCH_YES;
3238 : :
3239 : 1 : syntax:
3240 : 1 : gfc_syntax_error (st);
3241 : :
3242 : 10 : cleanup:
3243 : :
3244 : 10 : gfc_free_expr (e);
3245 : 10 : gfc_free_expr (quiet);
3246 : 10 : return MATCH_ERROR;
3247 : : }
3248 : :
3249 : :
3250 : : /* Match the (deprecated) PAUSE statement. */
3251 : :
3252 : : match
3253 : 28 : gfc_match_pause (void)
3254 : : {
3255 : 28 : match m;
3256 : :
3257 : 28 : m = gfc_match_stopcode (ST_PAUSE);
3258 : 28 : if (m == MATCH_YES)
3259 : : {
3260 : 28 : if (!gfc_notify_std (GFC_STD_F95_DEL, "PAUSE statement at %C"))
3261 : 0 : m = MATCH_ERROR;
3262 : : }
3263 : 28 : return m;
3264 : : }
3265 : :
3266 : :
3267 : : /* Match the STOP statement. */
3268 : :
3269 : : match
3270 : 156826 : gfc_match_stop (void)
3271 : : {
3272 : 156826 : return gfc_match_stopcode (ST_STOP);
3273 : : }
3274 : :
3275 : :
3276 : : /* Match the ERROR STOP statement. */
3277 : :
3278 : : match
3279 : 17939 : gfc_match_error_stop (void)
3280 : : {
3281 : 17939 : if (!gfc_notify_std (GFC_STD_F2008, "ERROR STOP statement at %C"))
3282 : : return MATCH_ERROR;
3283 : :
3284 : 17938 : return gfc_match_stopcode (ST_ERROR_STOP);
3285 : : }
3286 : :
3287 : : /* Match EVENT POST/WAIT statement. Syntax:
3288 : : EVENT POST ( event-variable [, sync-stat-list] )
3289 : : EVENT WAIT ( event-variable [, wait-spec-list] )
3290 : : with
3291 : : wait-spec-list is sync-stat-list or until-spec
3292 : : until-spec is UNTIL_COUNT = scalar-int-expr
3293 : : sync-stat is STAT= or ERRMSG=. */
3294 : :
3295 : : static match
3296 : 40 : event_statement (gfc_statement st)
3297 : : {
3298 : 40 : match m;
3299 : 40 : gfc_expr *tmp, *eventvar, *until_count, *stat, *errmsg;
3300 : 40 : bool saw_until_count, saw_stat, saw_errmsg;
3301 : :
3302 : 40 : tmp = eventvar = until_count = stat = errmsg = NULL;
3303 : 40 : saw_until_count = saw_stat = saw_errmsg = false;
3304 : :
3305 : 40 : if (gfc_pure (NULL))
3306 : : {
3307 : 0 : gfc_error ("Image control statement EVENT %s at %C in PURE procedure",
3308 : : st == ST_EVENT_POST ? "POST" : "WAIT");
3309 : 0 : return MATCH_ERROR;
3310 : : }
3311 : :
3312 : 40 : gfc_unset_implicit_pure (NULL);
3313 : :
3314 : 40 : if (flag_coarray == GFC_FCOARRAY_NONE)
3315 : : {
3316 : 0 : gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
3317 : : return MATCH_ERROR;
3318 : : }
3319 : :
3320 : 40 : if (gfc_find_state (COMP_CRITICAL))
3321 : : {
3322 : 0 : gfc_error ("Image control statement EVENT %s at %C in CRITICAL block",
3323 : : st == ST_EVENT_POST ? "POST" : "WAIT");
3324 : 0 : return MATCH_ERROR;
3325 : : }
3326 : :
3327 : 40 : if (gfc_find_state (COMP_DO_CONCURRENT))
3328 : : {
3329 : 0 : gfc_error ("Image control statement EVENT %s at %C in DO CONCURRENT "
3330 : : "block", st == ST_EVENT_POST ? "POST" : "WAIT");
3331 : 0 : return MATCH_ERROR;
3332 : : }
3333 : :
3334 : 40 : if (gfc_match_char ('(') != MATCH_YES)
3335 : 0 : goto syntax;
3336 : :
3337 : 40 : if (gfc_match ("%e", &eventvar) != MATCH_YES)
3338 : 1 : goto syntax;
3339 : 39 : m = gfc_match_char (',');
3340 : 39 : if (m == MATCH_ERROR)
3341 : 0 : goto syntax;
3342 : 39 : if (m == MATCH_NO)
3343 : : {
3344 : 23 : m = gfc_match_char (')');
3345 : 23 : if (m == MATCH_YES)
3346 : 23 : goto done;
3347 : 0 : goto syntax;
3348 : : }
3349 : :
3350 : 20 : for (;;)
3351 : : {
3352 : 20 : m = gfc_match (" stat = %v", &tmp);
3353 : 20 : if (m == MATCH_ERROR)
3354 : 0 : goto syntax;
3355 : 20 : if (m == MATCH_YES)
3356 : : {
3357 : 8 : if (saw_stat)
3358 : : {
3359 : 0 : gfc_error ("Redundant STAT tag found at %L", &tmp->where);
3360 : 0 : goto cleanup;
3361 : : }
3362 : 8 : stat = tmp;
3363 : 8 : saw_stat = true;
3364 : :
3365 : 8 : m = gfc_match_char (',');
3366 : 8 : if (m == MATCH_YES)
3367 : 4 : continue;
3368 : :
3369 : 4 : tmp = NULL;
3370 : 4 : break;
3371 : : }
3372 : :
3373 : 12 : m = gfc_match (" errmsg = %v", &tmp);
3374 : 12 : if (m == MATCH_ERROR)
3375 : 0 : goto syntax;
3376 : 12 : if (m == MATCH_YES)
3377 : : {
3378 : 0 : if (saw_errmsg)
3379 : : {
3380 : 0 : gfc_error ("Redundant ERRMSG tag found at %L", &tmp->where);
3381 : 0 : goto cleanup;
3382 : : }
3383 : 0 : errmsg = tmp;
3384 : 0 : saw_errmsg = true;
3385 : :
3386 : 0 : m = gfc_match_char (',');
3387 : 0 : if (m == MATCH_YES)
3388 : 0 : continue;
3389 : :
3390 : 0 : tmp = NULL;
3391 : 0 : break;
3392 : : }
3393 : :
3394 : 12 : m = gfc_match (" until_count = %e", &tmp);
3395 : 12 : if (m == MATCH_ERROR || st == ST_EVENT_POST)
3396 : 0 : goto syntax;
3397 : 12 : if (m == MATCH_YES)
3398 : : {
3399 : 12 : if (saw_until_count)
3400 : : {
3401 : 0 : gfc_error ("Redundant UNTIL_COUNT tag found at %L",
3402 : 0 : &tmp->where);
3403 : 0 : goto cleanup;
3404 : : }
3405 : 12 : until_count = tmp;
3406 : 12 : saw_until_count = true;
3407 : :
3408 : 12 : m = gfc_match_char (',');
3409 : 12 : if (m == MATCH_YES)
3410 : 0 : continue;
3411 : :
3412 : 12 : tmp = NULL;
3413 : 12 : break;
3414 : : }
3415 : :
3416 : : break;
3417 : : }
3418 : :
3419 : 16 : if (m == MATCH_ERROR)
3420 : 0 : goto syntax;
3421 : :
3422 : 16 : if (gfc_match (" )%t") != MATCH_YES)
3423 : 0 : goto syntax;
3424 : :
3425 : 16 : done:
3426 : 39 : switch (st)
3427 : : {
3428 : 23 : case ST_EVENT_POST:
3429 : 23 : new_st.op = EXEC_EVENT_POST;
3430 : 23 : break;
3431 : 16 : case ST_EVENT_WAIT:
3432 : 16 : new_st.op = EXEC_EVENT_WAIT;
3433 : 16 : break;
3434 : 0 : default:
3435 : 0 : gcc_unreachable ();
3436 : : }
3437 : :
3438 : 39 : new_st.expr1 = eventvar;
3439 : 39 : new_st.expr2 = stat;
3440 : 39 : new_st.expr3 = errmsg;
3441 : 39 : new_st.expr4 = until_count;
3442 : :
3443 : 39 : return MATCH_YES;
3444 : :
3445 : 1 : syntax:
3446 : 1 : gfc_syntax_error (st);
3447 : :
3448 : 1 : cleanup:
3449 : 1 : if (until_count != tmp)
3450 : 0 : gfc_free_expr (until_count);
3451 : 1 : if (errmsg != tmp)
3452 : 0 : gfc_free_expr (errmsg);
3453 : 1 : if (stat != tmp)
3454 : 0 : gfc_free_expr (stat);
3455 : :
3456 : 1 : gfc_free_expr (tmp);
3457 : 1 : gfc_free_expr (eventvar);
3458 : :
3459 : 1 : return MATCH_ERROR;
3460 : :
3461 : : }
3462 : :
3463 : :
3464 : : match
3465 : 24 : gfc_match_event_post (void)
3466 : : {
3467 : 24 : if (!gfc_notify_std (GFC_STD_F2018, "EVENT POST statement at %C"))
3468 : : return MATCH_ERROR;
3469 : :
3470 : 24 : return event_statement (ST_EVENT_POST);
3471 : : }
3472 : :
3473 : :
3474 : : match
3475 : 16 : gfc_match_event_wait (void)
3476 : : {
3477 : 16 : if (!gfc_notify_std (GFC_STD_F2018, "EVENT WAIT statement at %C"))
3478 : : return MATCH_ERROR;
3479 : :
3480 : 16 : return event_statement (ST_EVENT_WAIT);
3481 : : }
3482 : :
3483 : :
3484 : : /* Match a FAIL IMAGE statement. */
3485 : :
3486 : : match
3487 : 7 : gfc_match_fail_image (void)
3488 : : {
3489 : 7 : if (!gfc_notify_std (GFC_STD_F2018, "FAIL IMAGE statement at %C"))
3490 : : return MATCH_ERROR;
3491 : :
3492 : 7 : if (gfc_match_char ('(') == MATCH_YES)
3493 : 2 : goto syntax;
3494 : :
3495 : 5 : new_st.op = EXEC_FAIL_IMAGE;
3496 : :
3497 : 5 : return MATCH_YES;
3498 : :
3499 : 2 : syntax:
3500 : 2 : gfc_syntax_error (ST_FAIL_IMAGE);
3501 : :
3502 : 2 : return MATCH_ERROR;
3503 : : }
3504 : :
3505 : : /* Match a FORM TEAM statement. */
3506 : :
3507 : : match
3508 : 30 : gfc_match_form_team (void)
3509 : : {
3510 : 30 : match m;
3511 : 30 : gfc_expr *teamid,*team;
3512 : :
3513 : 30 : if (!gfc_notify_std (GFC_STD_F2018, "FORM TEAM statement at %C"))
3514 : : return MATCH_ERROR;
3515 : :
3516 : 30 : if (gfc_match_char ('(') == MATCH_NO)
3517 : 0 : goto syntax;
3518 : :
3519 : 30 : new_st.op = EXEC_FORM_TEAM;
3520 : :
3521 : 30 : if (gfc_match ("%e", &teamid) != MATCH_YES)
3522 : 0 : goto syntax;
3523 : 30 : m = gfc_match_char (',');
3524 : 30 : if (m == MATCH_ERROR)
3525 : 0 : goto syntax;
3526 : 30 : if (gfc_match ("%e", &team) != MATCH_YES)
3527 : 0 : goto syntax;
3528 : :
3529 : 30 : m = gfc_match_char (')');
3530 : 30 : if (m == MATCH_NO)
3531 : 0 : goto syntax;
3532 : :
3533 : 30 : new_st.expr1 = teamid;
3534 : 30 : new_st.expr2 = team;
3535 : :
3536 : 30 : return MATCH_YES;
3537 : :
3538 : 0 : syntax:
3539 : 0 : gfc_syntax_error (ST_FORM_TEAM);
3540 : :
3541 : 0 : return MATCH_ERROR;
3542 : : }
3543 : :
3544 : : /* Match a CHANGE TEAM statement. */
3545 : :
3546 : : match
3547 : 20 : gfc_match_change_team (void)
3548 : : {
3549 : 20 : match m;
3550 : 20 : gfc_expr *team;
3551 : :
3552 : 20 : if (!gfc_notify_std (GFC_STD_F2018, "CHANGE TEAM statement at %C"))
3553 : : return MATCH_ERROR;
3554 : :
3555 : 20 : if (gfc_match_char ('(') == MATCH_NO)
3556 : 0 : goto syntax;
3557 : :
3558 : 20 : new_st.op = EXEC_CHANGE_TEAM;
3559 : :
3560 : 20 : if (gfc_match ("%e", &team) != MATCH_YES)
3561 : 0 : goto syntax;
3562 : :
3563 : 20 : m = gfc_match_char (')');
3564 : 20 : if (m == MATCH_NO)
3565 : 0 : goto syntax;
3566 : :
3567 : 20 : new_st.expr1 = team;
3568 : :
3569 : 20 : return MATCH_YES;
3570 : :
3571 : 0 : syntax:
3572 : 0 : gfc_syntax_error (ST_CHANGE_TEAM);
3573 : :
3574 : 0 : return MATCH_ERROR;
3575 : : }
3576 : :
3577 : : /* Match a END TEAM statement. */
3578 : :
3579 : : match
3580 : 20 : gfc_match_end_team (void)
3581 : : {
3582 : 20 : if (!gfc_notify_std (GFC_STD_F2018, "END TEAM statement at %C"))
3583 : : return MATCH_ERROR;
3584 : :
3585 : 20 : if (gfc_match_char ('(') == MATCH_YES)
3586 : 0 : goto syntax;
3587 : :
3588 : 20 : new_st.op = EXEC_END_TEAM;
3589 : :
3590 : 20 : return MATCH_YES;
3591 : :
3592 : 0 : syntax:
3593 : 0 : gfc_syntax_error (ST_END_TEAM);
3594 : :
3595 : 0 : return MATCH_ERROR;
3596 : : }
3597 : :
3598 : : /* Match a SYNC TEAM statement. */
3599 : :
3600 : : match
3601 : 1 : gfc_match_sync_team (void)
3602 : : {
3603 : 1 : match m;
3604 : 1 : gfc_expr *team;
3605 : :
3606 : 1 : if (!gfc_notify_std (GFC_STD_F2018, "SYNC TEAM statement at %C"))
3607 : : return MATCH_ERROR;
3608 : :
3609 : 1 : if (gfc_match_char ('(') == MATCH_NO)
3610 : 0 : goto syntax;
3611 : :
3612 : 1 : new_st.op = EXEC_SYNC_TEAM;
3613 : :
3614 : 1 : if (gfc_match ("%e", &team) != MATCH_YES)
3615 : 0 : goto syntax;
3616 : :
3617 : 1 : m = gfc_match_char (')');
3618 : 1 : if (m == MATCH_NO)
3619 : 0 : goto syntax;
3620 : :
3621 : 1 : new_st.expr1 = team;
3622 : :
3623 : 1 : return MATCH_YES;
3624 : :
3625 : 0 : syntax:
3626 : 0 : gfc_syntax_error (ST_SYNC_TEAM);
3627 : :
3628 : 0 : return MATCH_ERROR;
3629 : : }
3630 : :
3631 : : /* Match LOCK/UNLOCK statement. Syntax:
3632 : : LOCK ( lock-variable [ , lock-stat-list ] )
3633 : : UNLOCK ( lock-variable [ , sync-stat-list ] )
3634 : : where lock-stat is ACQUIRED_LOCK or sync-stat
3635 : : and sync-stat is STAT= or ERRMSG=. */
3636 : :
3637 : : static match
3638 : 102 : lock_unlock_statement (gfc_statement st)
3639 : : {
3640 : 102 : match m;
3641 : 102 : gfc_expr *tmp, *lockvar, *acq_lock, *stat, *errmsg;
3642 : 102 : bool saw_acq_lock, saw_stat, saw_errmsg;
3643 : :
3644 : 102 : tmp = lockvar = acq_lock = stat = errmsg = NULL;
3645 : 102 : saw_acq_lock = saw_stat = saw_errmsg = false;
3646 : :
3647 : 102 : if (gfc_pure (NULL))
3648 : : {
3649 : 0 : gfc_error ("Image control statement %s at %C in PURE procedure",
3650 : : st == ST_LOCK ? "LOCK" : "UNLOCK");
3651 : 0 : return MATCH_ERROR;
3652 : : }
3653 : :
3654 : 102 : gfc_unset_implicit_pure (NULL);
3655 : :
3656 : 102 : if (flag_coarray == GFC_FCOARRAY_NONE)
3657 : : {
3658 : 0 : gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
3659 : : return MATCH_ERROR;
3660 : : }
3661 : :
3662 : 102 : if (gfc_find_state (COMP_CRITICAL))
3663 : : {
3664 : 2 : gfc_error ("Image control statement %s at %C in CRITICAL block",
3665 : : st == ST_LOCK ? "LOCK" : "UNLOCK");
3666 : 2 : return MATCH_ERROR;
3667 : : }
3668 : :
3669 : 100 : if (gfc_find_state (COMP_DO_CONCURRENT))
3670 : : {
3671 : 2 : gfc_error ("Image control statement %s at %C in DO CONCURRENT block",
3672 : : st == ST_LOCK ? "LOCK" : "UNLOCK");
3673 : 2 : return MATCH_ERROR;
3674 : : }
3675 : :
3676 : 98 : if (gfc_match_char ('(') != MATCH_YES)
3677 : 0 : goto syntax;
3678 : :
3679 : 98 : if (gfc_match ("%e", &lockvar) != MATCH_YES)
3680 : 1 : goto syntax;
3681 : 97 : m = gfc_match_char (',');
3682 : 97 : if (m == MATCH_ERROR)
3683 : 0 : goto syntax;
3684 : 97 : if (m == MATCH_NO)
3685 : : {
3686 : 53 : m = gfc_match_char (')');
3687 : 53 : if (m == MATCH_YES)
3688 : 53 : goto done;
3689 : 0 : goto syntax;
3690 : : }
3691 : :
3692 : 48 : for (;;)
3693 : : {
3694 : 48 : m = gfc_match (" stat = %v", &tmp);
3695 : 48 : if (m == MATCH_ERROR)
3696 : 0 : goto syntax;
3697 : 48 : if (m == MATCH_YES)
3698 : : {
3699 : 30 : if (saw_stat)
3700 : : {
3701 : 0 : gfc_error ("Redundant STAT tag found at %L", &tmp->where);
3702 : 0 : goto cleanup;
3703 : : }
3704 : 30 : stat = tmp;
3705 : 30 : saw_stat = true;
3706 : :
3707 : 30 : m = gfc_match_char (',');
3708 : 30 : if (m == MATCH_YES)
3709 : 2 : continue;
3710 : :
3711 : 28 : tmp = NULL;
3712 : 28 : break;
3713 : : }
3714 : :
3715 : 18 : m = gfc_match (" errmsg = %v", &tmp);
3716 : 18 : if (m == MATCH_ERROR)
3717 : 0 : goto syntax;
3718 : 18 : if (m == MATCH_YES)
3719 : : {
3720 : 2 : if (saw_errmsg)
3721 : : {
3722 : 0 : gfc_error ("Redundant ERRMSG tag found at %L", &tmp->where);
3723 : 0 : goto cleanup;
3724 : : }
3725 : 2 : errmsg = tmp;
3726 : 2 : saw_errmsg = true;
3727 : :
3728 : 2 : m = gfc_match_char (',');
3729 : 2 : if (m == MATCH_YES)
3730 : 0 : continue;
3731 : :
3732 : 2 : tmp = NULL;
3733 : 2 : break;
3734 : : }
3735 : :
3736 : 16 : m = gfc_match (" acquired_lock = %v", &tmp);
3737 : 16 : if (m == MATCH_ERROR || st == ST_UNLOCK)
3738 : 0 : goto syntax;
3739 : 16 : if (m == MATCH_YES)
3740 : : {
3741 : 16 : if (saw_acq_lock)
3742 : : {
3743 : 0 : gfc_error ("Redundant ACQUIRED_LOCK tag found at %L",
3744 : 0 : &tmp->where);
3745 : 0 : goto cleanup;
3746 : : }
3747 : 16 : acq_lock = tmp;
3748 : 16 : saw_acq_lock = true;
3749 : :
3750 : 16 : m = gfc_match_char (',');
3751 : 16 : if (m == MATCH_YES)
3752 : 2 : continue;
3753 : :
3754 : 14 : tmp = NULL;
3755 : 14 : break;
3756 : : }
3757 : :
3758 : : break;
3759 : : }
3760 : :
3761 : 44 : if (m == MATCH_ERROR)
3762 : 0 : goto syntax;
3763 : :
3764 : 44 : if (gfc_match (" )%t") != MATCH_YES)
3765 : 0 : goto syntax;
3766 : :
3767 : 44 : done:
3768 : 97 : switch (st)
3769 : : {
3770 : 53 : case ST_LOCK:
3771 : 53 : new_st.op = EXEC_LOCK;
3772 : 53 : break;
3773 : 44 : case ST_UNLOCK:
3774 : 44 : new_st.op = EXEC_UNLOCK;
3775 : 44 : break;
3776 : 0 : default:
3777 : 0 : gcc_unreachable ();
3778 : : }
3779 : :
3780 : 97 : new_st.expr1 = lockvar;
3781 : 97 : new_st.expr2 = stat;
3782 : 97 : new_st.expr3 = errmsg;
3783 : 97 : new_st.expr4 = acq_lock;
3784 : :
3785 : 97 : return MATCH_YES;
3786 : :
3787 : 1 : syntax:
3788 : 1 : gfc_syntax_error (st);
3789 : :
3790 : 1 : cleanup:
3791 : 1 : if (acq_lock != tmp)
3792 : 0 : gfc_free_expr (acq_lock);
3793 : 1 : if (errmsg != tmp)
3794 : 0 : gfc_free_expr (errmsg);
3795 : 1 : if (stat != tmp)
3796 : 0 : gfc_free_expr (stat);
3797 : :
3798 : 1 : gfc_free_expr (tmp);
3799 : 1 : gfc_free_expr (lockvar);
3800 : :
3801 : 1 : return MATCH_ERROR;
3802 : : }
3803 : :
3804 : :
3805 : : match
3806 : 57 : gfc_match_lock (void)
3807 : : {
3808 : 57 : if (!gfc_notify_std (GFC_STD_F2008, "LOCK statement at %C"))
3809 : : return MATCH_ERROR;
3810 : :
3811 : 56 : return lock_unlock_statement (ST_LOCK);
3812 : : }
3813 : :
3814 : :
3815 : : match
3816 : 47 : gfc_match_unlock (void)
3817 : : {
3818 : 47 : if (!gfc_notify_std (GFC_STD_F2008, "UNLOCK statement at %C"))
3819 : : return MATCH_ERROR;
3820 : :
3821 : 46 : return lock_unlock_statement (ST_UNLOCK);
3822 : : }
3823 : :
3824 : :
3825 : : /* Match SYNC ALL/IMAGES/MEMORY statement. Syntax:
3826 : : SYNC ALL [(sync-stat-list)]
3827 : : SYNC MEMORY [(sync-stat-list)]
3828 : : SYNC IMAGES (image-set [, sync-stat-list] )
3829 : : with sync-stat is int-expr or *. */
3830 : :
3831 : : static match
3832 : 752 : sync_statement (gfc_statement st)
3833 : : {
3834 : 752 : match m;
3835 : 752 : gfc_expr *tmp, *imageset, *stat, *errmsg;
3836 : 752 : bool saw_stat, saw_errmsg;
3837 : :
3838 : 752 : tmp = imageset = stat = errmsg = NULL;
3839 : 752 : saw_stat = saw_errmsg = false;
3840 : :
3841 : 752 : if (gfc_pure (NULL))
3842 : : {
3843 : 1 : gfc_error ("Image control statement SYNC at %C in PURE procedure");
3844 : 1 : return MATCH_ERROR;
3845 : : }
3846 : :
3847 : 751 : gfc_unset_implicit_pure (NULL);
3848 : :
3849 : 751 : if (!gfc_notify_std (GFC_STD_F2008, "SYNC statement at %C"))
3850 : : return MATCH_ERROR;
3851 : :
3852 : 748 : if (flag_coarray == GFC_FCOARRAY_NONE)
3853 : : {
3854 : 0 : gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to "
3855 : : "enable");
3856 : : return MATCH_ERROR;
3857 : : }
3858 : :
3859 : 748 : if (gfc_find_state (COMP_CRITICAL))
3860 : : {
3861 : 1 : gfc_error ("Image control statement SYNC at %C in CRITICAL block");
3862 : 1 : return MATCH_ERROR;
3863 : : }
3864 : :
3865 : 747 : if (gfc_find_state (COMP_DO_CONCURRENT))
3866 : : {
3867 : 1 : gfc_error ("Image control statement SYNC at %C in DO CONCURRENT block");
3868 : 1 : return MATCH_ERROR;
3869 : : }
3870 : :
3871 : 746 : if (gfc_match_eos () == MATCH_YES)
3872 : : {
3873 : 557 : if (st == ST_SYNC_IMAGES)
3874 : 0 : goto syntax;
3875 : 557 : goto done;
3876 : : }
3877 : :
3878 : 189 : if (gfc_match_char ('(') != MATCH_YES)
3879 : 0 : goto syntax;
3880 : :
3881 : 189 : if (st == ST_SYNC_IMAGES)
3882 : : {
3883 : : /* Denote '*' as imageset == NULL. */
3884 : 78 : m = gfc_match_char ('*');
3885 : 78 : if (m == MATCH_ERROR)
3886 : 0 : goto syntax;
3887 : 78 : if (m == MATCH_NO)
3888 : : {
3889 : 48 : if (gfc_match ("%e", &imageset) != MATCH_YES)
3890 : 0 : goto syntax;
3891 : : }
3892 : 78 : m = gfc_match_char (',');
3893 : 78 : if (m == MATCH_ERROR)
3894 : 0 : goto syntax;
3895 : 78 : if (m == MATCH_NO)
3896 : : {
3897 : 42 : m = gfc_match_char (')');
3898 : 42 : if (m == MATCH_YES)
3899 : 42 : goto done;
3900 : 0 : goto syntax;
3901 : : }
3902 : : }
3903 : :
3904 : 181 : for (;;)
3905 : : {
3906 : 181 : m = gfc_match (" stat = %e", &tmp);
3907 : 181 : if (m == MATCH_ERROR)
3908 : 0 : goto syntax;
3909 : 181 : if (m == MATCH_YES)
3910 : : {
3911 : 86 : if (saw_stat)
3912 : : {
3913 : 1 : gfc_error ("Redundant STAT tag found at %L", &tmp->where);
3914 : 1 : goto cleanup;
3915 : : }
3916 : 85 : stat = tmp;
3917 : 85 : saw_stat = true;
3918 : :
3919 : 85 : if (gfc_match_char (',') == MATCH_YES)
3920 : 13 : continue;
3921 : :
3922 : 72 : tmp = NULL;
3923 : 72 : break;
3924 : : }
3925 : :
3926 : 95 : m = gfc_match (" errmsg = %e", &tmp);
3927 : 95 : if (m == MATCH_ERROR)
3928 : 0 : goto syntax;
3929 : 95 : if (m == MATCH_YES)
3930 : : {
3931 : 75 : if (saw_errmsg)
3932 : : {
3933 : 0 : gfc_error ("Redundant ERRMSG tag found at %L", &tmp->where);
3934 : 0 : goto cleanup;
3935 : : }
3936 : 75 : errmsg = tmp;
3937 : 75 : saw_errmsg = true;
3938 : :
3939 : 75 : if (gfc_match_char (',') == MATCH_YES)
3940 : 21 : continue;
3941 : :
3942 : 54 : tmp = NULL;
3943 : 54 : break;
3944 : : }
3945 : :
3946 : : break;
3947 : : }
3948 : :
3949 : 146 : if (gfc_match (" )%t") != MATCH_YES)
3950 : 0 : goto syntax;
3951 : :
3952 : 146 : done:
3953 : 745 : switch (st)
3954 : : {
3955 : 603 : case ST_SYNC_ALL:
3956 : 603 : new_st.op = EXEC_SYNC_ALL;
3957 : 603 : break;
3958 : 78 : case ST_SYNC_IMAGES:
3959 : 78 : new_st.op = EXEC_SYNC_IMAGES;
3960 : 78 : break;
3961 : 64 : case ST_SYNC_MEMORY:
3962 : 64 : new_st.op = EXEC_SYNC_MEMORY;
3963 : 64 : break;
3964 : 0 : default:
3965 : 0 : gcc_unreachable ();
3966 : : }
3967 : :
3968 : 745 : new_st.expr1 = imageset;
3969 : 745 : new_st.expr2 = stat;
3970 : 745 : new_st.expr3 = errmsg;
3971 : :
3972 : 745 : return MATCH_YES;
3973 : :
3974 : 0 : syntax:
3975 : 0 : gfc_syntax_error (st);
3976 : :
3977 : 1 : cleanup:
3978 : 1 : if (stat != tmp)
3979 : 1 : gfc_free_expr (stat);
3980 : 1 : if (errmsg != tmp)
3981 : 1 : gfc_free_expr (errmsg);
3982 : :
3983 : 1 : gfc_free_expr (tmp);
3984 : 1 : gfc_free_expr (imageset);
3985 : :
3986 : 1 : return MATCH_ERROR;
3987 : : }
3988 : :
3989 : :
3990 : : /* Match SYNC ALL statement. */
3991 : :
3992 : : match
3993 : 608 : gfc_match_sync_all (void)
3994 : : {
3995 : 608 : return sync_statement (ST_SYNC_ALL);
3996 : : }
3997 : :
3998 : :
3999 : : /* Match SYNC IMAGES statement. */
4000 : :
4001 : : match
4002 : 79 : gfc_match_sync_images (void)
4003 : : {
4004 : 79 : return sync_statement (ST_SYNC_IMAGES);
4005 : : }
4006 : :
4007 : :
4008 : : /* Match SYNC MEMORY statement. */
4009 : :
4010 : : match
4011 : 65 : gfc_match_sync_memory (void)
4012 : : {
4013 : 65 : return sync_statement (ST_SYNC_MEMORY);
4014 : : }
4015 : :
4016 : :
4017 : : /* Match a CONTINUE statement. */
4018 : :
4019 : : match
4020 : 2754 : gfc_match_continue (void)
4021 : : {
4022 : 2754 : if (gfc_match_eos () != MATCH_YES)
4023 : : {
4024 : 0 : gfc_syntax_error (ST_CONTINUE);
4025 : 0 : return MATCH_ERROR;
4026 : : }
4027 : :
4028 : 2754 : new_st.op = EXEC_CONTINUE;
4029 : 2754 : return MATCH_YES;
4030 : : }
4031 : :
4032 : :
4033 : : /* Match the (deprecated) ASSIGN statement. */
4034 : :
4035 : : match
4036 : 126 : gfc_match_assign (void)
4037 : : {
4038 : 126 : gfc_expr *expr;
4039 : 126 : gfc_st_label *label;
4040 : :
4041 : 126 : if (gfc_match (" %l", &label) == MATCH_YES)
4042 : : {
4043 : 126 : if (!gfc_reference_st_label (label, ST_LABEL_UNKNOWN))
4044 : : return MATCH_ERROR;
4045 : 126 : if (gfc_match (" to %v%t", &expr) == MATCH_YES)
4046 : : {
4047 : 126 : if (!gfc_notify_std (GFC_STD_F95_DEL, "ASSIGN statement at %C"))
4048 : : return MATCH_ERROR;
4049 : :
4050 : 126 : expr->symtree->n.sym->attr.assign = 1;
4051 : :
4052 : 126 : new_st.op = EXEC_LABEL_ASSIGN;
4053 : 126 : new_st.label1 = label;
4054 : 126 : new_st.expr1 = expr;
4055 : 126 : return MATCH_YES;
4056 : : }
4057 : : }
4058 : : return MATCH_NO;
4059 : : }
4060 : :
4061 : :
4062 : : /* Match the GO TO statement. As a computed GOTO statement is
4063 : : matched, it is transformed into an equivalent SELECT block. No
4064 : : tree is necessary, and the resulting jumps-to-jumps are
4065 : : specifically optimized away by the back end. */
4066 : :
4067 : : match
4068 : 993 : gfc_match_goto (void)
4069 : : {
4070 : 993 : gfc_code *head, *tail;
4071 : 993 : gfc_expr *expr;
4072 : 993 : gfc_case *cp;
4073 : 993 : gfc_st_label *label;
4074 : 993 : int i;
4075 : 993 : match m;
4076 : :
4077 : 993 : if (gfc_match (" %l%t", &label) == MATCH_YES)
4078 : : {
4079 : 910 : if (!gfc_reference_st_label (label, ST_LABEL_TARGET))
4080 : : return MATCH_ERROR;
4081 : :
4082 : 910 : new_st.op = EXEC_GOTO;
4083 : 910 : new_st.label1 = label;
4084 : 910 : return MATCH_YES;
4085 : : }
4086 : :
4087 : : /* The assigned GO TO statement. */
4088 : :
4089 : 83 : if (gfc_match_variable (&expr, 0) == MATCH_YES)
4090 : : {
4091 : 78 : if (!gfc_notify_std (GFC_STD_F95_DEL, "Assigned GOTO statement at %C"))
4092 : : return MATCH_ERROR;
4093 : :
4094 : 78 : new_st.op = EXEC_GOTO;
4095 : 78 : new_st.expr1 = expr;
4096 : :
4097 : 78 : if (gfc_match_eos () == MATCH_YES)
4098 : : return MATCH_YES;
4099 : :
4100 : : /* Match label list. */
4101 : 27 : gfc_match_char (',');
4102 : 27 : if (gfc_match_char ('(') != MATCH_YES)
4103 : : {
4104 : 0 : gfc_syntax_error (ST_GOTO);
4105 : 0 : return MATCH_ERROR;
4106 : : }
4107 : : head = tail = NULL;
4108 : :
4109 : 76 : do
4110 : : {
4111 : 76 : m = gfc_match_st_label (&label);
4112 : 76 : if (m != MATCH_YES)
4113 : 0 : goto syntax;
4114 : :
4115 : 76 : if (!gfc_reference_st_label (label, ST_LABEL_TARGET))
4116 : 0 : goto cleanup;
4117 : :
4118 : 76 : if (head == NULL)
4119 : 27 : head = tail = gfc_get_code (EXEC_GOTO);
4120 : : else
4121 : : {
4122 : 49 : tail->block = gfc_get_code (EXEC_GOTO);
4123 : 49 : tail = tail->block;
4124 : : }
4125 : :
4126 : 76 : tail->label1 = label;
4127 : : }
4128 : 76 : while (gfc_match_char (',') == MATCH_YES);
4129 : :
4130 : 27 : if (gfc_match (" )%t") != MATCH_YES)
4131 : 0 : goto syntax;
4132 : :
4133 : 27 : if (head == NULL)
4134 : : {
4135 : 0 : gfc_error ("Statement label list in GOTO at %C cannot be empty");
4136 : 0 : goto syntax;
4137 : : }
4138 : 27 : new_st.block = head;
4139 : :
4140 : 27 : return MATCH_YES;
4141 : : }
4142 : :
4143 : : /* Last chance is a computed GO TO statement. */
4144 : 5 : if (gfc_match_char ('(') != MATCH_YES)
4145 : : {
4146 : 0 : gfc_syntax_error (ST_GOTO);
4147 : 0 : return MATCH_ERROR;
4148 : : }
4149 : :
4150 : : head = tail = NULL;
4151 : : i = 1;
4152 : :
4153 : 13 : do
4154 : : {
4155 : 13 : m = gfc_match_st_label (&label);
4156 : 13 : if (m != MATCH_YES)
4157 : 0 : goto syntax;
4158 : :
4159 : 13 : if (!gfc_reference_st_label (label, ST_LABEL_TARGET))
4160 : 0 : goto cleanup;
4161 : :
4162 : 13 : if (head == NULL)
4163 : 5 : head = tail = gfc_get_code (EXEC_SELECT);
4164 : : else
4165 : : {
4166 : 8 : tail->block = gfc_get_code (EXEC_SELECT);
4167 : 8 : tail = tail->block;
4168 : : }
4169 : :
4170 : 13 : cp = gfc_get_case ();
4171 : 26 : cp->low = cp->high = gfc_get_int_expr (gfc_default_integer_kind,
4172 : 13 : NULL, i++);
4173 : :
4174 : 13 : tail->ext.block.case_list = cp;
4175 : :
4176 : 13 : tail->next = gfc_get_code (EXEC_GOTO);
4177 : 13 : tail->next->label1 = label;
4178 : : }
4179 : 13 : while (gfc_match_char (',') == MATCH_YES);
4180 : :
4181 : 5 : if (gfc_match_char (')') != MATCH_YES)
4182 : 0 : goto syntax;
4183 : :
4184 : 5 : if (head == NULL)
4185 : : {
4186 : 0 : gfc_error ("Statement label list in GOTO at %C cannot be empty");
4187 : 0 : goto syntax;
4188 : : }
4189 : :
4190 : : /* Get the rest of the statement. */
4191 : 5 : gfc_match_char (',');
4192 : :
4193 : 5 : if (gfc_match (" %e%t", &expr) != MATCH_YES)
4194 : 0 : goto syntax;
4195 : :
4196 : 5 : if (!gfc_notify_std (GFC_STD_F95_OBS, "Computed GOTO at %C"))
4197 : : return MATCH_ERROR;
4198 : :
4199 : : /* At this point, a computed GOTO has been fully matched and an
4200 : : equivalent SELECT statement constructed. */
4201 : :
4202 : 5 : new_st.op = EXEC_SELECT;
4203 : 5 : new_st.expr1 = NULL;
4204 : :
4205 : : /* Hack: For a "real" SELECT, the expression is in expr. We put
4206 : : it in expr2 so we can distinguish then and produce the correct
4207 : : diagnostics. */
4208 : 5 : new_st.expr2 = expr;
4209 : 5 : new_st.block = head;
4210 : 5 : return MATCH_YES;
4211 : :
4212 : 0 : syntax:
4213 : 0 : gfc_syntax_error (ST_GOTO);
4214 : 0 : cleanup:
4215 : 0 : gfc_free_statements (head);
4216 : 0 : return MATCH_ERROR;
4217 : : }
4218 : :
4219 : :
4220 : : /* Frees a list of gfc_alloc structures. */
4221 : :
4222 : : void
4223 : 19194 : gfc_free_alloc_list (gfc_alloc *p)
4224 : : {
4225 : 19194 : gfc_alloc *q;
4226 : :
4227 : 42637 : for (; p; p = q)
4228 : : {
4229 : 23443 : q = p->next;
4230 : 23443 : gfc_free_expr (p->expr);
4231 : 23443 : free (p);
4232 : : }
4233 : 19194 : }
4234 : :
4235 : :
4236 : : /* Match an ALLOCATE statement. */
4237 : :
4238 : : match
4239 : 11708 : gfc_match_allocate (void)
4240 : : {
4241 : 11708 : gfc_alloc *head, *tail;
4242 : 11708 : gfc_expr *stat, *errmsg, *tmp, *source, *mold;
4243 : 11708 : gfc_typespec ts;
4244 : 11708 : gfc_symbol *sym;
4245 : 11708 : match m;
4246 : 11708 : locus old_locus, deferred_locus, assumed_locus;
4247 : 11708 : bool saw_stat, saw_errmsg, saw_source, saw_mold, saw_deferred, b1, b2, b3;
4248 : 11708 : bool saw_unlimited = false, saw_assumed = false;
4249 : :
4250 : 11708 : head = tail = NULL;
4251 : 11708 : stat = errmsg = source = mold = tmp = NULL;
4252 : 11708 : saw_stat = saw_errmsg = saw_source = saw_mold = saw_deferred = false;
4253 : :
4254 : 11708 : if (gfc_match_char ('(') != MATCH_YES)
4255 : : {
4256 : 1 : gfc_syntax_error (ST_ALLOCATE);
4257 : 1 : return MATCH_ERROR;
4258 : : }
4259 : :
4260 : : /* Match an optional type-spec. */
4261 : 11707 : old_locus = gfc_current_locus;
4262 : 11707 : m = gfc_match_type_spec (&ts);
4263 : 11707 : if (m == MATCH_ERROR)
4264 : 7 : goto cleanup;
4265 : 11700 : else if (m == MATCH_NO)
4266 : : {
4267 : 10382 : char name[GFC_MAX_SYMBOL_LEN + 3];
4268 : :
4269 : 10382 : if (gfc_match ("%n :: ", name) == MATCH_YES)
4270 : : {
4271 : 7 : gfc_error ("Error in type-spec at %L", &old_locus);
4272 : 7 : goto cleanup;
4273 : : }
4274 : :
4275 : 10375 : ts.type = BT_UNKNOWN;
4276 : : }
4277 : : else
4278 : : {
4279 : : /* Needed for the F2008:C631 check below. */
4280 : 1318 : assumed_locus = gfc_current_locus;
4281 : :
4282 : 1318 : if (gfc_match (" :: ") == MATCH_YES)
4283 : : {
4284 : 1306 : if (!gfc_notify_std (GFC_STD_F2003, "typespec in ALLOCATE at %L",
4285 : : &old_locus))
4286 : 0 : goto cleanup;
4287 : :
4288 : 1306 : if (ts.deferred)
4289 : : {
4290 : 5 : gfc_error ("Type-spec at %L cannot contain a deferred "
4291 : : "type parameter", &old_locus);
4292 : 5 : goto cleanup;
4293 : : }
4294 : :
4295 : 1301 : if (ts.type == BT_CHARACTER)
4296 : : {
4297 : 378 : if (!ts.u.cl->length)
4298 : : saw_assumed = true;
4299 : : else
4300 : 368 : ts.u.cl->length_from_typespec = true;
4301 : : }
4302 : :
4303 : 1301 : if (type_param_spec_list
4304 : 1301 : && gfc_spec_list_type (type_param_spec_list, NULL)
4305 : : == SPEC_DEFERRED)
4306 : : {
4307 : 0 : gfc_error ("The type parameter spec list in the type-spec at "
4308 : : "%L cannot contain DEFERRED parameters", &old_locus);
4309 : 0 : goto cleanup;
4310 : : }
4311 : : }
4312 : : else
4313 : : {
4314 : 12 : ts.type = BT_UNKNOWN;
4315 : 12 : gfc_current_locus = old_locus;
4316 : : }
4317 : : }
4318 : :
4319 : 14252 : for (;;)
4320 : : {
4321 : 14252 : if (head == NULL)
4322 : 11688 : head = tail = gfc_get_alloc ();
4323 : : else
4324 : : {
4325 : 2564 : tail->next = gfc_get_alloc ();
4326 : 2564 : tail = tail->next;
4327 : : }
4328 : :
4329 : 14252 : m = gfc_match_variable (&tail->expr, 0);
4330 : 14252 : if (m == MATCH_NO)
4331 : 0 : goto syntax;
4332 : 14252 : if (m == MATCH_ERROR)
4333 : 11 : goto cleanup;
4334 : :
4335 : 14241 : if (tail->expr->expr_type == EXPR_CONSTANT)
4336 : : {
4337 : 1 : gfc_error ("Unexpected constant at %C");
4338 : 1 : goto cleanup;
4339 : : }
4340 : :
4341 : 14240 : if (gfc_check_do_variable (tail->expr->symtree))
4342 : 0 : goto cleanup;
4343 : :
4344 : 14240 : bool impure = gfc_impure_variable (tail->expr->symtree->n.sym);
4345 : 14240 : if (impure && gfc_pure (NULL))
4346 : : {
4347 : 0 : gfc_error ("Bad allocate-object at %C for a PURE procedure");
4348 : 0 : goto cleanup;
4349 : : }
4350 : :
4351 : 14240 : if (impure)
4352 : 349 : gfc_unset_implicit_pure (NULL);
4353 : :
4354 : : /* F2008:C631 (R626) A type-param-value in a type-spec shall be an
4355 : : asterisk if and only if each allocate-object is a dummy argument
4356 : : for which the corresponding type parameter is assumed. */
4357 : 14240 : if (saw_assumed
4358 : 17 : && (tail->expr->ts.deferred
4359 : 16 : || (tail->expr->ts.u.cl && tail->expr->ts.u.cl->length)
4360 : 14 : || tail->expr->symtree->n.sym->attr.dummy == 0))
4361 : : {
4362 : 4 : gfc_error ("Incompatible allocate-object at %C for CHARACTER "
4363 : : "type-spec at %L", &assumed_locus);
4364 : 4 : goto cleanup;
4365 : : }
4366 : :
4367 : 14236 : if (tail->expr->ts.deferred)
4368 : : {
4369 : 760 : saw_deferred = true;
4370 : 760 : deferred_locus = tail->expr->where;
4371 : : }
4372 : :
4373 : 14236 : if (gfc_find_state (COMP_DO_CONCURRENT)
4374 : 14236 : || gfc_find_state (COMP_CRITICAL))
4375 : : {
4376 : 2 : gfc_ref *ref;
4377 : 2 : bool coarray = tail->expr->symtree->n.sym->attr.codimension;
4378 : 4 : for (ref = tail->expr->ref; ref; ref = ref->next)
4379 : 2 : if (ref->type == REF_COMPONENT)
4380 : 0 : coarray = ref->u.c.component->attr.codimension;
4381 : :
4382 : 2 : if (coarray && gfc_find_state (COMP_DO_CONCURRENT))
4383 : : {
4384 : 1 : gfc_error ("ALLOCATE of coarray at %C in DO CONCURRENT block");
4385 : 1 : goto cleanup;
4386 : : }
4387 : 1 : if (coarray && gfc_find_state (COMP_CRITICAL))
4388 : : {
4389 : 1 : gfc_error ("ALLOCATE of coarray at %C in CRITICAL block");
4390 : 1 : goto cleanup;
4391 : : }
4392 : : }
4393 : :
4394 : : /* Check for F08:C628. */
4395 : 14234 : sym = tail->expr->symtree->n.sym;
4396 : 14234 : b1 = !(tail->expr->ref
4397 : 10498 : && (tail->expr->ref->type == REF_COMPONENT
4398 : : || tail->expr->ref->type == REF_ARRAY));
4399 : 14234 : if (sym && sym->ts.type == BT_CLASS && sym->attr.class_ok)
4400 : 3034 : b2 = !(CLASS_DATA (sym)->attr.allocatable
4401 : : || CLASS_DATA (sym)->attr.class_pointer);
4402 : : else
4403 : 11200 : b2 = sym && !(sym->attr.allocatable || sym->attr.pointer
4404 : : || sym->attr.proc_pointer);
4405 : 14234 : b3 = sym && sym->ns && sym->ns->proc_name
4406 : 14234 : && (sym->ns->proc_name->attr.allocatable
4407 : : || sym->ns->proc_name->attr.pointer
4408 : 14234 : || sym->ns->proc_name->attr.proc_pointer);
4409 : 14234 : if (b1 && b2 && !b3)
4410 : : {
4411 : 6 : gfc_error ("Allocate-object at %L is neither a data pointer "
4412 : : "nor an allocatable variable", &tail->expr->where);
4413 : 6 : goto cleanup;
4414 : : }
4415 : :
4416 : : /* The ALLOCATE statement had an optional typespec. Check the
4417 : : constraints. */
4418 : 14228 : if (ts.type != BT_UNKNOWN)
4419 : : {
4420 : : /* Enforce F03:C624. */
4421 : 1506 : if (!gfc_type_compatible (&tail->expr->ts, &ts))
4422 : : {
4423 : 13 : gfc_error ("Type of entity at %L is type incompatible with "
4424 : 13 : "typespec", &tail->expr->where);
4425 : 13 : goto cleanup;
4426 : : }
4427 : :
4428 : : /* Enforce F03:C627. */
4429 : 1493 : if (ts.kind != tail->expr->ts.kind && !UNLIMITED_POLY (tail->expr))
4430 : : {
4431 : 8 : gfc_error ("Kind type parameter for entity at %L differs from "
4432 : : "the kind type parameter of the typespec",
4433 : : &tail->expr->where);
4434 : 8 : goto cleanup;
4435 : : }
4436 : : }
4437 : :
4438 : 14207 : if (tail->expr->ts.type == BT_DERIVED)
4439 : 2260 : tail->expr->ts.u.derived = gfc_use_derived (tail->expr->ts.u.derived);
4440 : :
4441 : 14207 : if (type_param_spec_list)
4442 : 41 : tail->expr->param_list = gfc_copy_actual_arglist (type_param_spec_list);
4443 : :
4444 : 14207 : saw_unlimited = saw_unlimited | UNLIMITED_POLY (tail->expr);
4445 : :
4446 : 14207 : if (gfc_peek_ascii_char () == '(' && !sym->attr.dimension)
4447 : : {
4448 : 2 : gfc_error ("Shape specification for allocatable scalar at %C");
4449 : 2 : goto cleanup;
4450 : : }
4451 : :
4452 : 14205 : if (gfc_match_char (',') != MATCH_YES)
4453 : : break;
4454 : :
4455 : 5778 : alloc_opt_list:
4456 : :
4457 : 5901 : m = gfc_match (" stat = %e", &tmp);
4458 : 5901 : if (m == MATCH_ERROR)
4459 : 7 : goto cleanup;
4460 : 5894 : if (m == MATCH_YES)
4461 : : {
4462 : : /* Enforce C630. */
4463 : 313 : if (saw_stat)
4464 : : {
4465 : 1 : gfc_error ("Redundant STAT tag found at %L", &tmp->where);
4466 : 1 : goto cleanup;
4467 : : }
4468 : :
4469 : 312 : stat = tmp;
4470 : 312 : tmp = NULL;
4471 : 312 : saw_stat = true;
4472 : :
4473 : 312 : if (stat->expr_type == EXPR_CONSTANT)
4474 : : {
4475 : 5 : gfc_error ("STAT tag at %L cannot be a constant", &stat->where);
4476 : 5 : goto cleanup;
4477 : : }
4478 : :
4479 : 307 : if (gfc_check_do_variable (stat->symtree))
4480 : 0 : goto cleanup;
4481 : :
4482 : 307 : if (gfc_match_char (',') == MATCH_YES)
4483 : 80 : goto alloc_opt_list;
4484 : : }
4485 : :
4486 : 5808 : m = gfc_match (" errmsg = %e", &tmp);
4487 : 5808 : if (m == MATCH_ERROR)
4488 : 0 : goto cleanup;
4489 : 5808 : if (m == MATCH_YES)
4490 : : {
4491 : 85 : if (!gfc_notify_std (GFC_STD_F2003, "ERRMSG tag at %L", &tmp->where))
4492 : 1 : goto cleanup;
4493 : :
4494 : : /* Enforce C630. */
4495 : 84 : if (saw_errmsg)
4496 : : {
4497 : 1 : gfc_error ("Redundant ERRMSG tag found at %L", &tmp->where);
4498 : 1 : goto cleanup;
4499 : : }
4500 : :
4501 : 83 : errmsg = tmp;
4502 : 83 : tmp = NULL;
4503 : 83 : saw_errmsg = true;
4504 : :
4505 : 83 : if (gfc_match_char (',') == MATCH_YES)
4506 : 4 : goto alloc_opt_list;
4507 : : }
4508 : :
4509 : 5802 : m = gfc_match (" source = %e", &tmp);
4510 : 5802 : if (m == MATCH_ERROR)
4511 : 2 : goto cleanup;
4512 : 5800 : if (m == MATCH_YES)
4513 : : {
4514 : 2693 : if (!gfc_notify_std (GFC_STD_F2003, "SOURCE tag at %L", &tmp->where))
4515 : 1 : goto cleanup;
4516 : :
4517 : : /* Enforce C630. */
4518 : 2692 : if (saw_source)
4519 : : {
4520 : 1 : gfc_error ("Redundant SOURCE tag found at %L", &tmp->where);
4521 : 1 : goto cleanup;
4522 : : }
4523 : :
4524 : : /* The next 2 conditionals check C631. */
4525 : 2691 : if (ts.type != BT_UNKNOWN)
4526 : : {
4527 : 1 : gfc_error ("SOURCE tag at %L conflicts with the typespec at %L",
4528 : 1 : &tmp->where, &old_locus);
4529 : 1 : goto cleanup;
4530 : : }
4531 : :
4532 : 2690 : if (head->next
4533 : 2713 : && !gfc_notify_std (GFC_STD_F2008, "SOURCE tag at %L"
4534 : : " with more than a single allocate object",
4535 : 23 : &tmp->where))
4536 : 1 : goto cleanup;
4537 : :
4538 : 2689 : source = tmp;
4539 : 2689 : tmp = NULL;
4540 : 2689 : saw_source = true;
4541 : :
4542 : 2689 : if (gfc_match_char (',') == MATCH_YES)
4543 : 38 : goto alloc_opt_list;
4544 : : }
4545 : :
4546 : 5758 : m = gfc_match (" mold = %e", &tmp);
4547 : 5758 : if (m == MATCH_ERROR)
4548 : 0 : goto cleanup;
4549 : 5758 : if (m == MATCH_YES)
4550 : : {
4551 : 237 : if (!gfc_notify_std (GFC_STD_F2008, "MOLD tag at %L", &tmp->where))
4552 : 1 : goto cleanup;
4553 : :
4554 : : /* Check F08:C636. */
4555 : 236 : if (saw_mold)
4556 : : {
4557 : 1 : gfc_error ("Redundant MOLD tag found at %L", &tmp->where);
4558 : 1 : goto cleanup;
4559 : : }
4560 : :
4561 : : /* Check F08:C637. */
4562 : 235 : if (ts.type != BT_UNKNOWN)
4563 : : {
4564 : 1 : gfc_error ("MOLD tag at %L conflicts with the typespec at %L",
4565 : 1 : &tmp->where, &old_locus);
4566 : 1 : goto cleanup;
4567 : : }
4568 : :
4569 : 234 : mold = tmp;
4570 : 234 : tmp = NULL;
4571 : 234 : saw_mold = true;
4572 : 234 : mold->mold = 1;
4573 : :
4574 : 234 : if (gfc_match_char (',') == MATCH_YES)
4575 : 1 : goto alloc_opt_list;
4576 : : }
4577 : :
4578 : 5754 : gfc_gobble_whitespace ();
4579 : :
4580 : 5754 : if (gfc_peek_char () == ')')
4581 : : break;
4582 : : }
4583 : :
4584 : 11617 : if (gfc_match (" )%t") != MATCH_YES)
4585 : 1 : goto syntax;
4586 : :
4587 : : /* Check F08:C637. */
4588 : 11616 : if (source && mold)
4589 : : {
4590 : 1 : gfc_error ("MOLD tag at %L conflicts with SOURCE tag at %L",
4591 : : &mold->where, &source->where);
4592 : 1 : goto cleanup;
4593 : : }
4594 : :
4595 : : /* Check F03:C623, */
4596 : 11615 : if (saw_deferred && ts.type == BT_UNKNOWN && !source && !mold)
4597 : : {
4598 : 1 : gfc_error ("Allocate-object at %L with a deferred type parameter "
4599 : : "requires either a type-spec or SOURCE tag or a MOLD tag",
4600 : : &deferred_locus);
4601 : 1 : goto cleanup;
4602 : : }
4603 : :
4604 : : /* Check F03:C625, */
4605 : 11614 : if (saw_unlimited && ts.type == BT_UNKNOWN && !source && !mold)
4606 : : {
4607 : 2 : for (tail = head; tail; tail = tail->next)
4608 : : {
4609 : 1 : if (UNLIMITED_POLY (tail->expr))
4610 : 1 : gfc_error ("Unlimited polymorphic allocate-object at %L "
4611 : : "requires either a type-spec or SOURCE tag "
4612 : : "or a MOLD tag", &tail->expr->where);
4613 : : }
4614 : 1 : goto cleanup;
4615 : : }
4616 : :
4617 : 11613 : new_st.op = EXEC_ALLOCATE;
4618 : 11613 : new_st.expr1 = stat;
4619 : 11613 : new_st.expr2 = errmsg;
4620 : 11613 : if (source)
4621 : 2687 : new_st.expr3 = source;
4622 : : else
4623 : 8926 : new_st.expr3 = mold;
4624 : 11613 : new_st.ext.alloc.list = head;
4625 : 11613 : new_st.ext.alloc.ts = ts;
4626 : :
4627 : 11613 : if (type_param_spec_list)
4628 : 41 : gfc_free_actual_arglist (type_param_spec_list);
4629 : :
4630 : : return MATCH_YES;
4631 : :
4632 : 1 : syntax:
4633 : 1 : gfc_syntax_error (ST_ALLOCATE);
4634 : :
4635 : 94 : cleanup:
4636 : 94 : gfc_free_expr (errmsg);
4637 : 94 : gfc_free_expr (source);
4638 : 94 : gfc_free_expr (stat);
4639 : 94 : gfc_free_expr (mold);
4640 : 94 : if (tmp && tmp->expr_type) gfc_free_expr (tmp);
4641 : 94 : gfc_free_alloc_list (head);
4642 : 94 : if (type_param_spec_list)
4643 : 0 : gfc_free_actual_arglist (type_param_spec_list);
4644 : : return MATCH_ERROR;
4645 : : }
4646 : :
4647 : :
4648 : : /* Match a NULLIFY statement. A NULLIFY statement is transformed into
4649 : : a set of pointer assignments to intrinsic NULL(). */
4650 : :
4651 : : match
4652 : 564 : gfc_match_nullify (void)
4653 : : {
4654 : 564 : gfc_code *tail;
4655 : 564 : gfc_expr *e, *p;
4656 : 564 : match m;
4657 : :
4658 : 564 : tail = NULL;
4659 : :
4660 : 564 : if (gfc_match_char ('(') != MATCH_YES)
4661 : 0 : goto syntax;
4662 : :
4663 : 956 : for (;;)
4664 : : {
4665 : 956 : m = gfc_match_variable (&p, 0);
4666 : 956 : if (m == MATCH_ERROR)
4667 : 2 : goto cleanup;
4668 : 954 : if (m == MATCH_NO)
4669 : 0 : goto syntax;
4670 : :
4671 : 954 : if (gfc_check_do_variable (p->symtree))
4672 : 0 : goto cleanup;
4673 : :
4674 : : /* F2008, C1242. */
4675 : 954 : if (gfc_is_coindexed (p))
4676 : : {
4677 : 1 : gfc_error ("Pointer object at %C shall not be coindexed");
4678 : 1 : goto cleanup;
4679 : : }
4680 : :
4681 : : /* Check for valid array pointer object. Bounds remapping is not
4682 : : allowed with NULLIFY. */
4683 : 953 : if (p->ref)
4684 : : {
4685 : : gfc_ref *remap = p->ref;
4686 : 938 : for (; remap; remap = remap->next)
4687 : 492 : if (!remap->next && remap->type == REF_ARRAY
4688 : 328 : && remap->u.ar.type != AR_FULL)
4689 : : break;
4690 : : if (remap)
4691 : : {
4692 : 2 : gfc_error ("NULLIFY does not allow bounds remapping for "
4693 : : "pointer object at %C");
4694 : 2 : goto cleanup;
4695 : : }
4696 : : }
4697 : :
4698 : : /* build ' => NULL() '. */
4699 : 951 : e = gfc_get_null_expr (&gfc_current_locus);
4700 : :
4701 : : /* Chain to list. */
4702 : 951 : if (tail == NULL)
4703 : : {
4704 : 560 : tail = &new_st;
4705 : 560 : tail->op = EXEC_POINTER_ASSIGN;
4706 : : }
4707 : : else
4708 : : {
4709 : 391 : tail->next = gfc_get_code (EXEC_POINTER_ASSIGN);
4710 : 391 : tail = tail->next;
4711 : : }
4712 : :
4713 : 951 : tail->expr1 = p;
4714 : 951 : tail->expr2 = e;
4715 : :
4716 : 951 : if (gfc_match (" )%t") == MATCH_YES)
4717 : : break;
4718 : 392 : if (gfc_match_char (',') != MATCH_YES)
4719 : 0 : goto syntax;
4720 : : }
4721 : :
4722 : : return MATCH_YES;
4723 : :
4724 : 0 : syntax:
4725 : 0 : gfc_syntax_error (ST_NULLIFY);
4726 : :
4727 : 5 : cleanup:
4728 : 5 : gfc_free_statements (new_st.next);
4729 : 5 : new_st.next = NULL;
4730 : 5 : gfc_free_expr (new_st.expr1);
4731 : 5 : new_st.expr1 = NULL;
4732 : 5 : gfc_free_expr (new_st.expr2);
4733 : 5 : new_st.expr2 = NULL;
4734 : 5 : return MATCH_ERROR;
4735 : : }
4736 : :
4737 : :
4738 : : /* Match a DEALLOCATE statement. */
4739 : :
4740 : : match
4741 : 5112 : gfc_match_deallocate (void)
4742 : : {
4743 : 5112 : gfc_alloc *head, *tail;
4744 : 5112 : gfc_expr *stat, *errmsg, *tmp;
4745 : 5112 : gfc_symbol *sym;
4746 : 5112 : match m;
4747 : 5112 : bool saw_stat, saw_errmsg, b1, b2;
4748 : :
4749 : 5112 : head = tail = NULL;
4750 : 5112 : stat = errmsg = tmp = NULL;
4751 : 5112 : saw_stat = saw_errmsg = false;
4752 : :
4753 : 5112 : if (gfc_match_char ('(') != MATCH_YES)
4754 : 0 : goto syntax;
4755 : :
4756 : 6816 : for (;;)
4757 : : {
4758 : 6816 : if (head == NULL)
4759 : 5112 : head = tail = gfc_get_alloc ();
4760 : : else
4761 : : {
4762 : 1704 : tail->next = gfc_get_alloc ();
4763 : 1704 : tail = tail->next;
4764 : : }
4765 : :
4766 : 6816 : m = gfc_match_variable (&tail->expr, 0);
4767 : 6816 : if (m == MATCH_ERROR)
4768 : 0 : goto cleanup;
4769 : 6816 : if (m == MATCH_NO)
4770 : 0 : goto syntax;
4771 : :
4772 : 6816 : if (tail->expr->expr_type == EXPR_CONSTANT)
4773 : : {
4774 : 1 : gfc_error ("Unexpected constant at %C");
4775 : 1 : goto cleanup;
4776 : : }
4777 : :
4778 : 6815 : if (gfc_check_do_variable (tail->expr->symtree))
4779 : 0 : goto cleanup;
4780 : :
4781 : 6815 : sym = tail->expr->symtree->n.sym;
4782 : :
4783 : 6815 : bool impure = gfc_impure_variable (sym);
4784 : 6815 : if (impure && gfc_pure (NULL))
4785 : : {
4786 : 0 : gfc_error ("Illegal allocate-object at %C for a PURE procedure");
4787 : 0 : goto cleanup;
4788 : : }
4789 : :
4790 : 6815 : if (impure)
4791 : 266 : gfc_unset_implicit_pure (NULL);
4792 : :
4793 : 6815 : if (gfc_is_coarray (tail->expr)
4794 : 6815 : && gfc_find_state (COMP_DO_CONCURRENT))
4795 : : {
4796 : 1 : gfc_error ("DEALLOCATE of coarray at %C in DO CONCURRENT block");
4797 : 1 : goto cleanup;
4798 : : }
4799 : :
4800 : 6814 : if (gfc_is_coarray (tail->expr)
4801 : 6814 : && gfc_find_state (COMP_CRITICAL))
4802 : : {
4803 : 1 : gfc_error ("DEALLOCATE of coarray at %C in CRITICAL block");
4804 : 1 : goto cleanup;
4805 : : }
4806 : :
4807 : : /* FIXME: disable the checking on derived types. */
4808 : 6813 : b1 = !(tail->expr->ref
4809 : 5056 : && (tail->expr->ref->type == REF_COMPONENT
4810 : : || tail->expr->ref->type == REF_ARRAY));
4811 : 6813 : if (sym && sym->ts.type == BT_CLASS)
4812 : 1210 : b2 = !(CLASS_DATA (sym) && (CLASS_DATA (sym)->attr.allocatable
4813 : 1207 : || CLASS_DATA (sym)->attr.class_pointer));
4814 : : else
4815 : 5603 : b2 = sym && !(sym->attr.allocatable || sym->attr.pointer
4816 : : || sym->attr.proc_pointer);
4817 : 6813 : if (b1 && b2)
4818 : : {
4819 : 3 : gfc_error ("Allocate-object at %C is not a nonprocedure pointer "
4820 : : "nor an allocatable variable");
4821 : 3 : goto cleanup;
4822 : : }
4823 : :
4824 : 6810 : if (gfc_match_char (',') != MATCH_YES)
4825 : : break;
4826 : :
4827 : 2018 : dealloc_opt_list:
4828 : :
4829 : 2083 : m = gfc_match (" stat = %e", &tmp);
4830 : 2083 : if (m == MATCH_ERROR)
4831 : 2 : goto cleanup;
4832 : 2081 : if (m == MATCH_YES)
4833 : : {
4834 : 311 : if (saw_stat)
4835 : : {
4836 : 1 : gfc_error ("Redundant STAT tag found at %L", &tmp->where);
4837 : 1 : gfc_free_expr (tmp);
4838 : 1 : goto cleanup;
4839 : : }
4840 : :
4841 : 310 : stat = tmp;
4842 : 310 : saw_stat = true;
4843 : :
4844 : 310 : if (gfc_check_do_variable (stat->symtree))
4845 : 0 : goto cleanup;
4846 : :
4847 : 310 : if (gfc_match_char (',') == MATCH_YES)
4848 : 61 : goto dealloc_opt_list;
4849 : : }
4850 : :
4851 : 2019 : m = gfc_match (" errmsg = %e", &tmp);
4852 : 2019 : if (m == MATCH_ERROR)
4853 : 0 : goto cleanup;
4854 : 2019 : if (m == MATCH_YES)
4855 : : {
4856 : 66 : if (!gfc_notify_std (GFC_STD_F2003, "ERRMSG at %L", &tmp->where))
4857 : 0 : goto cleanup;
4858 : :
4859 : 66 : if (saw_errmsg)
4860 : : {
4861 : 1 : gfc_error ("Redundant ERRMSG tag found at %L", &tmp->where);
4862 : 1 : gfc_free_expr (tmp);
4863 : 1 : goto cleanup;
4864 : : }
4865 : :
4866 : 65 : errmsg = tmp;
4867 : 65 : saw_errmsg = true;
4868 : :
4869 : 65 : if (gfc_match_char (',') == MATCH_YES)
4870 : 4 : goto dealloc_opt_list;
4871 : : }
4872 : :
4873 : 2014 : gfc_gobble_whitespace ();
4874 : :
4875 : 2014 : if (gfc_peek_char () == ')')
4876 : : break;
4877 : : }
4878 : :
4879 : 5102 : if (gfc_match (" )%t") != MATCH_YES)
4880 : 1 : goto syntax;
4881 : :
4882 : 5101 : new_st.op = EXEC_DEALLOCATE;
4883 : 5101 : new_st.expr1 = stat;
4884 : 5101 : new_st.expr2 = errmsg;
4885 : 5101 : new_st.ext.alloc.list = head;
4886 : :
4887 : 5101 : return MATCH_YES;
4888 : :
4889 : 1 : syntax:
4890 : 1 : gfc_syntax_error (ST_DEALLOCATE);
4891 : :
4892 : 11 : cleanup:
4893 : 11 : gfc_free_expr (errmsg);
4894 : 11 : gfc_free_expr (stat);
4895 : 11 : gfc_free_alloc_list (head);
4896 : 11 : return MATCH_ERROR;
4897 : : }
4898 : :
4899 : :
4900 : : /* Match a RETURN statement. */
4901 : :
4902 : : match
4903 : 2966 : gfc_match_return (void)
4904 : : {
4905 : 2966 : gfc_expr *e;
4906 : 2966 : match m;
4907 : 2966 : gfc_compile_state s;
4908 : :
4909 : 2966 : e = NULL;
4910 : :
4911 : 2966 : if (gfc_find_state (COMP_CRITICAL))
4912 : : {
4913 : 1 : gfc_error ("Image control statement RETURN at %C in CRITICAL block");
4914 : 1 : return MATCH_ERROR;
4915 : : }
4916 : :
4917 : 2965 : if (gfc_find_state (COMP_DO_CONCURRENT))
4918 : : {
4919 : 1 : gfc_error ("Image control statement RETURN at %C in DO CONCURRENT block");
4920 : 1 : return MATCH_ERROR;
4921 : : }
4922 : :
4923 : 2964 : if (gfc_match_eos () == MATCH_YES)
4924 : 2910 : goto done;
4925 : :
4926 : 54 : if (!gfc_find_state (COMP_SUBROUTINE))
4927 : : {
4928 : 0 : gfc_error ("Alternate RETURN statement at %C is only allowed within "
4929 : : "a SUBROUTINE");
4930 : 0 : goto cleanup;
4931 : : }
4932 : :
4933 : 54 : if (gfc_current_form == FORM_FREE)
4934 : : {
4935 : : /* The following are valid, so we can't require a blank after the
4936 : : RETURN keyword:
4937 : : return+1
4938 : : return(1) */
4939 : 54 : char c = gfc_peek_ascii_char ();
4940 : 54 : if (ISALPHA (c) || ISDIGIT (c))
4941 : : return MATCH_NO;
4942 : : }
4943 : :
4944 : 53 : m = gfc_match (" %e%t", &e);
4945 : 53 : if (m == MATCH_YES)
4946 : 53 : goto done;
4947 : 0 : if (m == MATCH_ERROR)
4948 : 0 : goto cleanup;
4949 : :
4950 : 0 : gfc_syntax_error (ST_RETURN);
4951 : :
4952 : 0 : cleanup:
4953 : 0 : gfc_free_expr (e);
4954 : 0 : return MATCH_ERROR;
4955 : :
4956 : 2963 : done:
4957 : 2963 : gfc_enclosing_unit (&s);
4958 : 2963 : if (s == COMP_PROGRAM
4959 : 2963 : && !gfc_notify_std (GFC_STD_GNU, "RETURN statement in "
4960 : : "main program at %C"))
4961 : : return MATCH_ERROR;
4962 : :
4963 : 2963 : new_st.op = EXEC_RETURN;
4964 : 2963 : new_st.expr1 = e;
4965 : :
4966 : 2963 : return MATCH_YES;
4967 : : }
4968 : :
4969 : :
4970 : : /* Match the call of a type-bound procedure, if CALL%var has already been
4971 : : matched and var found to be a derived-type variable. */
4972 : :
4973 : : static match
4974 : 1273 : match_typebound_call (gfc_symtree* varst)
4975 : : {
4976 : 1273 : gfc_expr* base;
4977 : 1273 : match m;
4978 : :
4979 : 1273 : base = gfc_get_expr ();
4980 : 1273 : base->expr_type = EXPR_VARIABLE;
4981 : 1273 : base->symtree = varst;
4982 : 1273 : base->where = gfc_current_locus;
4983 : 1273 : gfc_set_sym_referenced (varst->n.sym);
4984 : :
4985 : 1273 : m = gfc_match_varspec (base, 0, true, true);
4986 : 1273 : if (m == MATCH_NO)
4987 : 0 : gfc_error ("Expected component reference at %C");
4988 : 1273 : if (m != MATCH_YES)
4989 : : {
4990 : 5 : gfc_free_expr (base);
4991 : 5 : return MATCH_ERROR;
4992 : : }
4993 : :
4994 : 1268 : if (gfc_match_eos () != MATCH_YES)
4995 : : {
4996 : 1 : gfc_error ("Junk after CALL at %C");
4997 : 1 : gfc_free_expr (base);
4998 : 1 : return MATCH_ERROR;
4999 : : }
5000 : :
5001 : 1267 : if (base->expr_type == EXPR_COMPCALL)
5002 : 1145 : new_st.op = EXEC_COMPCALL;
5003 : 122 : else if (base->expr_type == EXPR_PPC)
5004 : 121 : new_st.op = EXEC_CALL_PPC;
5005 : : else
5006 : : {
5007 : 1 : gfc_error ("Expected type-bound procedure or procedure pointer component "
5008 : : "at %C");
5009 : 1 : gfc_free_expr (base);
5010 : 1 : return MATCH_ERROR;
5011 : : }
5012 : 1266 : new_st.expr1 = base;
5013 : :
5014 : 1266 : return MATCH_YES;
5015 : : }
5016 : :
5017 : :
5018 : : /* Match a CALL statement. The tricky part here are possible
5019 : : alternate return specifiers. We handle these by having all
5020 : : "subroutines" actually return an integer via a register that gives
5021 : : the return number. If the call specifies alternate returns, we
5022 : : generate code for a SELECT statement whose case clauses contain
5023 : : GOTOs to the various labels. */
5024 : :
5025 : : match
5026 : 67894 : gfc_match_call (void)
5027 : : {
5028 : 67894 : char name[GFC_MAX_SYMBOL_LEN + 1];
5029 : 67894 : gfc_actual_arglist *a, *arglist;
5030 : 67894 : gfc_case *new_case;
5031 : 67894 : gfc_symbol *sym;
5032 : 67894 : gfc_symtree *st;
5033 : 67894 : gfc_code *c;
5034 : 67894 : match m;
5035 : 67894 : int i;
5036 : :
5037 : 67894 : arglist = NULL;
5038 : :
5039 : 67894 : m = gfc_match ("% %n", name);
5040 : 67894 : if (m == MATCH_NO)
5041 : 0 : goto syntax;
5042 : 67894 : if (m != MATCH_YES)
5043 : : return m;
5044 : :
5045 : 67894 : if (gfc_get_ha_sym_tree (name, &st))
5046 : : return MATCH_ERROR;
5047 : :
5048 : 67892 : sym = st->n.sym;
5049 : :
5050 : : /* If this is a variable of derived-type, it probably starts a type-bound
5051 : : procedure call. Associate variable targets have to be resolved for the
5052 : : target type. */
5053 : 67892 : if (((sym->attr.flavor != FL_PROCEDURE
5054 : 50234 : || gfc_is_function_return_value (sym, gfc_current_ns))
5055 : 17660 : && (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS))
5056 : 67892 : ||
5057 : 66619 : (sym->assoc && sym->assoc->target
5058 : 0 : && gfc_resolve_expr (sym->assoc->target)
5059 : 0 : && (sym->assoc->target->ts.type == BT_DERIVED
5060 : 0 : || sym->assoc->target->ts.type == BT_CLASS)))
5061 : 1273 : return match_typebound_call (st);
5062 : :
5063 : : /* If it does not seem to be callable (include functions so that the
5064 : : right association is made. They are thrown out in resolution.)
5065 : : ... */
5066 : 66619 : if (!sym->attr.generic
5067 : : && !sym->attr.subroutine
5068 : 66619 : && !sym->attr.function)
5069 : : {
5070 : 17284 : if (!(sym->attr.external && !sym->attr.referenced))
5071 : : {
5072 : : /* ...create a symbol in this scope... */
5073 : 16634 : if (sym->ns != gfc_current_ns
5074 : 16634 : && gfc_get_sym_tree (name, NULL, &st, false) == 1)
5075 : : return MATCH_ERROR;
5076 : :
5077 : 16634 : if (sym != st->n.sym)
5078 : 17284 : sym = st->n.sym;
5079 : : }
5080 : :
5081 : : /* ...and then to try to make the symbol into a subroutine. */
5082 : 17284 : if (!gfc_add_subroutine (&sym->attr, sym->name, NULL))
5083 : : return MATCH_ERROR;
5084 : : }
5085 : :
5086 : 66617 : gfc_set_sym_referenced (sym);
5087 : :
5088 : 66617 : if (gfc_match_eos () != MATCH_YES)
5089 : : {
5090 : 62598 : m = gfc_match_actual_arglist (1, &arglist);
5091 : 62598 : if (m == MATCH_NO)
5092 : 0 : goto syntax;
5093 : 62598 : if (m == MATCH_ERROR)
5094 : 8 : goto cleanup;
5095 : :
5096 : 62590 : if (gfc_match_eos () != MATCH_YES)
5097 : 1 : goto syntax;
5098 : : }
5099 : :
5100 : : /* Walk the argument list looking for invalid BOZ. */
5101 : 216913 : for (a = arglist; a; a = a->next)
5102 : 150306 : if (a->expr && a->expr->ts.type == BT_BOZ)
5103 : : {
5104 : 1 : gfc_error ("A BOZ literal constant at %L cannot appear as an actual "
5105 : : "argument in a subroutine reference", &a->expr->where);
5106 : 1 : goto cleanup;
5107 : : }
5108 : :
5109 : :
5110 : : /* If any alternate return labels were found, construct a SELECT
5111 : : statement that will jump to the right place. */
5112 : :
5113 : 216620 : i = 0;
5114 : 216620 : for (a = arglist; a; a = a->next)
5115 : 150163 : if (a->expr == NULL)
5116 : : {
5117 : : i = 1;
5118 : : break;
5119 : : }
5120 : :
5121 : 66607 : if (i)
5122 : : {
5123 : 150 : gfc_symtree *select_st;
5124 : 150 : gfc_symbol *select_sym;
5125 : 150 : char name[GFC_MAX_SYMBOL_LEN + 1];
5126 : :
5127 : 150 : new_st.next = c = gfc_get_code (EXEC_SELECT);
5128 : 150 : sprintf (name, "_result_%s", sym->name);
5129 : 150 : gfc_get_ha_sym_tree (name, &select_st); /* Can't fail. */
5130 : :
5131 : 150 : select_sym = select_st->n.sym;
5132 : 150 : select_sym->ts.type = BT_INTEGER;
5133 : 150 : select_sym->ts.kind = gfc_default_integer_kind;
5134 : 150 : gfc_set_sym_referenced (select_sym);
5135 : 150 : c->expr1 = gfc_get_expr ();
5136 : 150 : c->expr1->expr_type = EXPR_VARIABLE;
5137 : 150 : c->expr1->symtree = select_st;
5138 : 150 : c->expr1->ts = select_sym->ts;
5139 : 150 : c->expr1->where = gfc_current_locus;
5140 : :
5141 : 150 : i = 0;
5142 : 618 : for (a = arglist; a; a = a->next)
5143 : : {
5144 : 468 : if (a->expr != NULL)
5145 : 232 : continue;
5146 : :
5147 : 236 : if (!gfc_reference_st_label (a->label, ST_LABEL_TARGET))
5148 : 0 : continue;
5149 : :
5150 : 236 : i++;
5151 : :
5152 : 236 : c->block = gfc_get_code (EXEC_SELECT);
5153 : 236 : c = c->block;
5154 : :
5155 : 236 : new_case = gfc_get_case ();
5156 : 236 : new_case->high = gfc_get_int_expr (gfc_default_integer_kind, NULL, i);
5157 : 236 : new_case->low = new_case->high;
5158 : 236 : c->ext.block.case_list = new_case;
5159 : :
5160 : 236 : c->next = gfc_get_code (EXEC_GOTO);
5161 : 236 : c->next->label1 = a->label;
5162 : : }
5163 : : }
5164 : :
5165 : 66607 : new_st.op = EXEC_CALL;
5166 : 66607 : new_st.symtree = st;
5167 : 66607 : new_st.ext.actual = arglist;
5168 : :
5169 : 66607 : return MATCH_YES;
5170 : :
5171 : 1 : syntax:
5172 : 1 : gfc_syntax_error (ST_CALL);
5173 : :
5174 : 10 : cleanup:
5175 : 10 : gfc_free_actual_arglist (arglist);
5176 : 10 : return MATCH_ERROR;
5177 : : }
5178 : :
5179 : :
5180 : : /* Given a name, return a pointer to the common head structure,
5181 : : creating it if it does not exist. If FROM_MODULE is nonzero, we
5182 : : mangle the name so that it doesn't interfere with commons defined
5183 : : in the using namespace.
5184 : : TODO: Add to global symbol tree. */
5185 : :
5186 : : gfc_common_head *
5187 : 2023 : gfc_get_common (const char *name, int from_module)
5188 : : {
5189 : 2023 : gfc_symtree *st;
5190 : 2023 : static int serial = 0;
5191 : 2023 : char mangled_name[GFC_MAX_SYMBOL_LEN + 1];
5192 : :
5193 : 2023 : if (from_module)
5194 : : {
5195 : : /* A use associated common block is only needed to correctly layout
5196 : : the variables it contains. */
5197 : 168 : snprintf (mangled_name, GFC_MAX_SYMBOL_LEN, "_%d_%s", serial++, name);
5198 : 168 : st = gfc_new_symtree (&gfc_current_ns->common_root, mangled_name);
5199 : : }
5200 : : else
5201 : : {
5202 : 1855 : st = gfc_find_symtree (gfc_current_ns->common_root, name);
5203 : :
5204 : 1855 : if (st == NULL)
5205 : 1767 : st = gfc_new_symtree (&gfc_current_ns->common_root, name);
5206 : : }
5207 : :
5208 : 2023 : if (st->n.common == NULL)
5209 : : {
5210 : 1935 : st->n.common = gfc_get_common_head ();
5211 : 1935 : st->n.common->where = gfc_current_locus;
5212 : 1935 : strcpy (st->n.common->name, name);
5213 : : }
5214 : :
5215 : 2023 : return st->n.common;
5216 : : }
5217 : :
5218 : :
5219 : : /* Match a common block name. */
5220 : :
5221 : : match
5222 : 2079 : gfc_match_common_name (char *name)
5223 : : {
5224 : 2079 : match m;
5225 : :
5226 : 2079 : if (gfc_match_char ('/') == MATCH_NO)
5227 : : {
5228 : 139 : name[0] = '\0';
5229 : 139 : return MATCH_YES;
5230 : : }
5231 : :
5232 : 1940 : if (gfc_match_char ('/') == MATCH_YES)
5233 : : {
5234 : 85 : name[0] = '\0';
5235 : 85 : return MATCH_YES;
5236 : : }
5237 : :
5238 : 1855 : m = gfc_match_name (name);
5239 : :
5240 : 1855 : if (m == MATCH_ERROR)
5241 : : return MATCH_ERROR;
5242 : 1855 : if (m == MATCH_YES && gfc_match_char ('/') == MATCH_YES)
5243 : : return MATCH_YES;
5244 : :
5245 : 0 : gfc_error ("Syntax error in common block name at %C");
5246 : 0 : return MATCH_ERROR;
5247 : : }
5248 : :
5249 : :
5250 : : /* Match a COMMON statement. */
5251 : :
5252 : : match
5253 : 1999 : gfc_match_common (void)
5254 : : {
5255 : 1999 : gfc_symbol *sym, **head, *tail, *other;
5256 : 1999 : char name[GFC_MAX_SYMBOL_LEN + 1];
5257 : 1999 : gfc_common_head *t;
5258 : 1999 : gfc_array_spec *as;
5259 : 1999 : gfc_equiv *e1, *e2;
5260 : 1999 : match m;
5261 : 1999 : char c;
5262 : :
5263 : : /* COMMON has been matched. In free form source code, the next character
5264 : : needs to be whitespace or '/'. Check that here. Fixed form source
5265 : : code needs to be checked below. */
5266 : 1999 : c = gfc_peek_ascii_char ();
5267 : 1999 : if (gfc_current_form == FORM_FREE && !gfc_is_whitespace (c) && c != '/')
5268 : : return MATCH_NO;
5269 : :
5270 : 1998 : as = NULL;
5271 : :
5272 : 2003 : for (;;)
5273 : : {
5274 : 2003 : m = gfc_match_common_name (name);
5275 : 2003 : if (m == MATCH_ERROR)
5276 : 0 : goto cleanup;
5277 : :
5278 : 2003 : if (name[0] == '\0')
5279 : : {
5280 : 224 : t = &gfc_current_ns->blank_common;
5281 : 224 : if (t->head == NULL)
5282 : 222 : t->where = gfc_current_locus;
5283 : : }
5284 : : else
5285 : : {
5286 : 1779 : t = gfc_get_common (name, 0);
5287 : : }
5288 : 2003 : head = &t->head;
5289 : :
5290 : 2003 : if (*head == NULL)
5291 : : tail = NULL;
5292 : : else
5293 : : {
5294 : : tail = *head;
5295 : 114 : while (tail->common_next)
5296 : : tail = tail->common_next;
5297 : : }
5298 : :
5299 : : /* Grab the list of symbols. */
5300 : 5873 : for (;;)
5301 : : {
5302 : 5873 : m = gfc_match_symbol (&sym, 0);
5303 : 5873 : if (m == MATCH_ERROR)
5304 : 0 : goto cleanup;
5305 : 5873 : if (m == MATCH_NO)
5306 : 7 : goto syntax;
5307 : :
5308 : : /* See if we know the current common block is bind(c), and if
5309 : : so, then see if we can check if the symbol is (which it'll
5310 : : need to be). This can happen if the bind(c) attr stmt was
5311 : : applied to the common block, and the variable(s) already
5312 : : defined, before declaring the common block. */
5313 : 5866 : if (t->is_bind_c == 1)
5314 : : {
5315 : 13 : if (sym->ts.type != BT_UNKNOWN && sym->ts.is_c_interop != 1)
5316 : : {
5317 : : /* If we find an error, just print it and continue,
5318 : : cause it's just semantic, and we can see if there
5319 : : are more errors. */
5320 : 0 : gfc_error_now ("Variable %qs at %L in common block %qs "
5321 : : "at %C must be declared with a C "
5322 : : "interoperable kind since common block "
5323 : : "%qs is bind(c)",
5324 : : sym->name, &(sym->declared_at), t->name,
5325 : 0 : t->name);
5326 : : }
5327 : :
5328 : 13 : if (sym->attr.is_bind_c == 1)
5329 : 0 : gfc_error_now ("Variable %qs in common block %qs at %C cannot "
5330 : : "be bind(c) since it is not global", sym->name,
5331 : 0 : t->name);
5332 : : }
5333 : :
5334 : 5866 : if (sym->attr.in_common)
5335 : : {
5336 : 2 : gfc_error ("Symbol %qs at %C is already in a COMMON block",
5337 : : sym->name);
5338 : 2 : goto cleanup;
5339 : : }
5340 : :
5341 : 5864 : if (((sym->value != NULL && sym->value->expr_type != EXPR_NULL)
5342 : 5864 : || sym->attr.data) && gfc_current_state () != COMP_BLOCK_DATA)
5343 : : {
5344 : 6 : if (!gfc_notify_std (GFC_STD_GNU, "Initialized symbol %qs at "
5345 : : "%C can only be COMMON in BLOCK DATA",
5346 : : sym->name))
5347 : 2 : goto cleanup;
5348 : : }
5349 : :
5350 : : /* F2018:R874: common-block-object is variable-name [ (array-spec) ]
5351 : : F2018:C8121: A variable-name shall not be a name made accessible
5352 : : by use association. */
5353 : 5862 : if (sym->attr.use_assoc)
5354 : : {
5355 : 2 : gfc_error ("Symbol %qs at %C is USE associated from module %qs "
5356 : : "and cannot occur in COMMON", sym->name, sym->module);
5357 : 2 : goto cleanup;
5358 : : }
5359 : :
5360 : : /* Deal with an optional array specification after the
5361 : : symbol name. */
5362 : 5860 : m = gfc_match_array_spec (&as, true, true);
5363 : 5860 : if (m == MATCH_ERROR)
5364 : 2 : goto cleanup;
5365 : :
5366 : 5858 : if (m == MATCH_YES)
5367 : : {
5368 : 2127 : if (as->type != AS_EXPLICIT)
5369 : : {
5370 : 0 : gfc_error ("Array specification for symbol %qs in COMMON "
5371 : : "at %C must be explicit", sym->name);
5372 : 0 : goto cleanup;
5373 : : }
5374 : :
5375 : 2127 : if (as->corank)
5376 : : {
5377 : 1 : gfc_error ("Symbol %qs in COMMON at %C cannot be a "
5378 : : "coarray", sym->name);
5379 : 1 : goto cleanup;
5380 : : }
5381 : :
5382 : 2126 : if (!gfc_add_dimension (&sym->attr, sym->name, NULL))
5383 : 0 : goto cleanup;
5384 : :
5385 : 2126 : if (sym->attr.pointer)
5386 : : {
5387 : 0 : gfc_error ("Symbol %qs in COMMON at %C cannot be a "
5388 : : "POINTER array", sym->name);
5389 : 0 : goto cleanup;
5390 : : }
5391 : :
5392 : 2126 : sym->as = as;
5393 : 2126 : as = NULL;
5394 : :
5395 : : }
5396 : :
5397 : : /* Add the in_common attribute, but ignore the reported errors
5398 : : if any, and continue matching. */
5399 : 5857 : gfc_add_in_common (&sym->attr, sym->name, NULL);
5400 : :
5401 : 5857 : sym->common_block = t;
5402 : 5857 : sym->common_block->refs++;
5403 : :
5404 : 5857 : if (tail != NULL)
5405 : 3882 : tail->common_next = sym;
5406 : : else
5407 : 1975 : *head = sym;
5408 : :
5409 : 5857 : tail = sym;
5410 : :
5411 : 5857 : sym->common_head = t;
5412 : :
5413 : : /* Check to see if the symbol is already in an equivalence group.
5414 : : If it is, set the other members as being in common. */
5415 : 5857 : if (sym->attr.in_equivalence)
5416 : : {
5417 : 20 : for (e1 = gfc_current_ns->equiv; e1; e1 = e1->next)
5418 : : {
5419 : 29 : for (e2 = e1; e2; e2 = e2->eq)
5420 : 23 : if (e2->expr->symtree->n.sym == sym)
5421 : 8 : goto equiv_found;
5422 : :
5423 : 6 : continue;
5424 : :
5425 : 8 : equiv_found:
5426 : :
5427 : 23 : for (e2 = e1; e2; e2 = e2->eq)
5428 : : {
5429 : 16 : other = e2->expr->symtree->n.sym;
5430 : 16 : if (other->common_head
5431 : 9 : && other->common_head != sym->common_head)
5432 : : {
5433 : 1 : gfc_error ("Symbol %qs, in COMMON block %qs at "
5434 : : "%C is being indirectly equivalenced to "
5435 : : "another COMMON block %qs",
5436 : 1 : sym->name, sym->common_head->name,
5437 : 1 : other->common_head->name);
5438 : 1 : goto cleanup;
5439 : : }
5440 : 15 : other->attr.in_common = 1;
5441 : 15 : other->common_head = t;
5442 : : }
5443 : : }
5444 : : }
5445 : :
5446 : :
5447 : 5856 : gfc_gobble_whitespace ();
5448 : 5856 : if (gfc_match_eos () == MATCH_YES)
5449 : 1980 : goto done;
5450 : 3876 : c = gfc_peek_ascii_char ();
5451 : 3876 : if (c == '/')
5452 : : break;
5453 : 3873 : if (c != ',')
5454 : : {
5455 : : /* In Fixed form source code, gfortran can end up here for an
5456 : : expression of the form COMMONI = RHS. This may not be an
5457 : : error, so return MATCH_NO. */
5458 : 1 : if (gfc_current_form == FORM_FIXED && c == '=')
5459 : : {
5460 : 1 : gfc_free_array_spec (as);
5461 : 1 : return MATCH_NO;
5462 : : }
5463 : 0 : goto syntax;
5464 : : }
5465 : : else
5466 : 3872 : gfc_match_char (',');
5467 : :
5468 : 3872 : gfc_gobble_whitespace ();
5469 : 3872 : if (gfc_peek_ascii_char () == '/')
5470 : : break;
5471 : : }
5472 : : }
5473 : :
5474 : 1980 : done:
5475 : 1980 : return MATCH_YES;
5476 : :
5477 : 7 : syntax:
5478 : 7 : gfc_syntax_error (ST_COMMON);
5479 : :
5480 : 17 : cleanup:
5481 : 17 : gfc_free_array_spec (as);
5482 : 17 : return MATCH_ERROR;
5483 : : }
5484 : :
5485 : :
5486 : : /* Match a BLOCK DATA program unit. */
5487 : :
5488 : : match
5489 : 84 : gfc_match_block_data (void)
5490 : : {
5491 : 84 : char name[GFC_MAX_SYMBOL_LEN + 1];
5492 : 84 : gfc_symbol *sym;
5493 : 84 : match m;
5494 : :
5495 : 84 : if (!gfc_notify_std (GFC_STD_F2018_OBS, "BLOCK DATA construct at %L",
5496 : : &gfc_current_locus))
5497 : : return MATCH_ERROR;
5498 : :
5499 : 84 : if (gfc_match_eos () == MATCH_YES)
5500 : : {
5501 : 49 : gfc_new_block = NULL;
5502 : 49 : return MATCH_YES;
5503 : : }
5504 : :
5505 : 35 : m = gfc_match ("% %n%t", name);
5506 : 35 : if (m != MATCH_YES)
5507 : : return MATCH_ERROR;
5508 : :
5509 : 35 : if (gfc_get_symbol (name, NULL, &sym))
5510 : : return MATCH_ERROR;
5511 : :
5512 : 35 : if (!gfc_add_flavor (&sym->attr, FL_BLOCK_DATA, sym->name, NULL))
5513 : : return MATCH_ERROR;
5514 : :
5515 : 35 : gfc_new_block = sym;
5516 : :
5517 : 35 : return MATCH_YES;
5518 : : }
5519 : :
5520 : :
5521 : : /* Free a namelist structure. */
5522 : :
5523 : : void
5524 : 4898173 : gfc_free_namelist (gfc_namelist *name)
5525 : : {
5526 : 4898173 : gfc_namelist *n;
5527 : :
5528 : 4900212 : for (; name; name = n)
5529 : : {
5530 : 2039 : n = name->next;
5531 : 2039 : free (name);
5532 : : }
5533 : 4898173 : }
5534 : :
5535 : :
5536 : : /* Free an OpenMP namelist structure. */
5537 : :
5538 : : void
5539 : 1000018 : gfc_free_omp_namelist (gfc_omp_namelist *name, bool free_ns,
5540 : : bool free_align_allocator,
5541 : : bool free_mem_traits_space)
5542 : : {
5543 : 1000018 : gfc_omp_namelist *n;
5544 : :
5545 : 1040616 : for (; name; name = n)
5546 : : {
5547 : 40598 : gfc_free_expr (name->expr);
5548 : 40598 : if (free_align_allocator)
5549 : 413 : gfc_free_expr (name->u.align);
5550 : : else if (free_mem_traits_space)
5551 : : { } /* name->u.memspace_sym: shall not call gfc_free_symbol here. */
5552 : 40598 : if (free_ns)
5553 : 1964 : gfc_free_namespace (name->u2.ns);
5554 : 38634 : else if (free_align_allocator)
5555 : 413 : gfc_free_expr (name->u2.allocator);
5556 : 38221 : else if (free_mem_traits_space)
5557 : : { } /* name->u2.traits_sym: shall not call gfc_free_symbol here. */
5558 : 38135 : else if (name->u2.udr)
5559 : : {
5560 : 467 : if (name->u2.udr->combiner)
5561 : 467 : gfc_free_statement (name->u2.udr->combiner);
5562 : 467 : if (name->u2.udr->initializer)
5563 : 330 : gfc_free_statement (name->u2.udr->initializer);
5564 : 467 : free (name->u2.udr);
5565 : : }
5566 : 40598 : n = name->next;
5567 : 40598 : free (name);
5568 : : }
5569 : 1000018 : }
5570 : :
5571 : :
5572 : : /* Match a NAMELIST statement. */
5573 : :
5574 : : match
5575 : 945 : gfc_match_namelist (void)
5576 : : {
5577 : 945 : gfc_symbol *group_name, *sym;
5578 : 945 : gfc_namelist *nl;
5579 : 945 : match m, m2;
5580 : :
5581 : 945 : m = gfc_match (" / %s /", &group_name);
5582 : 945 : if (m == MATCH_NO)
5583 : 0 : goto syntax;
5584 : 945 : if (m == MATCH_ERROR)
5585 : 0 : goto error;
5586 : :
5587 : 945 : for (;;)
5588 : : {
5589 : 945 : if (group_name->ts.type != BT_UNKNOWN)
5590 : : {
5591 : 0 : gfc_error ("Namelist group name %qs at %C already has a basic "
5592 : : "type of %s", group_name->name,
5593 : : gfc_typename (&group_name->ts));
5594 : 0 : return MATCH_ERROR;
5595 : : }
5596 : :
5597 : 945 : if (group_name->attr.flavor == FL_NAMELIST
5598 : 220 : && group_name->attr.use_assoc
5599 : 954 : && !gfc_notify_std (GFC_STD_GNU, "Namelist group name %qs "
5600 : : "at %C already is USE associated and can"
5601 : : "not be respecified.", group_name->name))
5602 : : return MATCH_ERROR;
5603 : :
5604 : 942 : if (group_name->attr.flavor != FL_NAMELIST
5605 : 942 : && !gfc_add_flavor (&group_name->attr, FL_NAMELIST,
5606 : : group_name->name, NULL))
5607 : : return MATCH_ERROR;
5608 : :
5609 : 1963 : for (;;)
5610 : : {
5611 : 1963 : m = gfc_match_symbol (&sym, 1);
5612 : 1963 : if (m == MATCH_NO)
5613 : 1 : goto syntax;
5614 : 1962 : if (m == MATCH_ERROR)
5615 : 0 : goto error;
5616 : :
5617 : 1962 : if (sym->ts.type == BT_UNKNOWN)
5618 : : {
5619 : 50 : if (gfc_current_ns->seen_implicit_none)
5620 : : {
5621 : : /* It is required that members of a namelist be declared
5622 : : before the namelist. We check this by checking if the
5623 : : symbol has a defined type for IMPLICIT NONE. */
5624 : 1 : gfc_error ("Symbol %qs in namelist %qs at %C must be "
5625 : : "declared before the namelist is declared.",
5626 : : sym->name, group_name->name);
5627 : 1 : gfc_error_check ();
5628 : : }
5629 : : else
5630 : : {
5631 : : /* Before the symbol is given an implicit type, check to
5632 : : see if the symbol is already available in the namespace,
5633 : : possibly through host association. Importantly, the
5634 : : symbol may be a user defined type. */
5635 : :
5636 : 49 : gfc_symbol *tmp;
5637 : :
5638 : 49 : gfc_find_symbol (sym->name, NULL, 1, &tmp);
5639 : 49 : if (tmp && tmp->attr.generic
5640 : 51 : && (tmp = gfc_find_dt_in_generic (tmp)))
5641 : : {
5642 : 2 : if (tmp->attr.flavor == FL_DERIVED)
5643 : : {
5644 : 2 : gfc_error ("Derived type %qs at %L conflicts with "
5645 : : "namelist object %qs at %C",
5646 : : tmp->name, &tmp->declared_at, sym->name);
5647 : 2 : goto error;
5648 : : }
5649 : : }
5650 : :
5651 : : /* Set type of the symbol to its implicit default type. It is
5652 : : not allowed to set it later to any other type. */
5653 : 47 : gfc_set_default_type (sym, 0, gfc_current_ns);
5654 : : }
5655 : : }
5656 : 1960 : if (sym->attr.in_namelist == 0
5657 : 1960 : && !gfc_add_in_namelist (&sym->attr, sym->name, NULL))
5658 : 2 : goto error;
5659 : :
5660 : : /* Use gfc_error_check here, rather than goto error, so that
5661 : : these are the only errors for the next two lines. */
5662 : 1958 : if (sym->as && sym->as->type == AS_ASSUMED_SIZE)
5663 : : {
5664 : 1 : gfc_error ("Assumed size array %qs in namelist %qs at "
5665 : : "%C is not allowed", sym->name, group_name->name);
5666 : 1 : gfc_error_check ();
5667 : : }
5668 : :
5669 : 1958 : nl = gfc_get_namelist ();
5670 : 1958 : nl->sym = sym;
5671 : 1958 : sym->refs++;
5672 : :
5673 : 1958 : if (group_name->namelist == NULL)
5674 : 719 : group_name->namelist = group_name->namelist_tail = nl;
5675 : : else
5676 : : {
5677 : 1239 : group_name->namelist_tail->next = nl;
5678 : 1239 : group_name->namelist_tail = nl;
5679 : : }
5680 : :
5681 : 1958 : if (gfc_match_eos () == MATCH_YES)
5682 : 935 : goto done;
5683 : :
5684 : 1023 : m = gfc_match_char (',');
5685 : :
5686 : 1023 : if (gfc_match_char ('/') == MATCH_YES)
5687 : : {
5688 : 0 : m2 = gfc_match (" %s /", &group_name);
5689 : 0 : if (m2 == MATCH_YES)
5690 : : break;
5691 : 0 : if (m2 == MATCH_ERROR)
5692 : 0 : goto error;
5693 : 0 : goto syntax;
5694 : : }
5695 : :
5696 : 1023 : if (m != MATCH_YES)
5697 : 0 : goto syntax;
5698 : : }
5699 : : }
5700 : :
5701 : 935 : done:
5702 : 935 : return MATCH_YES;
5703 : :
5704 : 1 : syntax:
5705 : 1 : gfc_syntax_error (ST_NAMELIST);
5706 : :
5707 : : error:
5708 : : return MATCH_ERROR;
5709 : : }
5710 : :
5711 : :
5712 : : /* Match a MODULE statement. */
5713 : :
5714 : : match
5715 : 8602 : gfc_match_module (void)
5716 : : {
5717 : 8602 : match m;
5718 : :
5719 : 8602 : m = gfc_match (" %s%t", &gfc_new_block);
5720 : 8602 : if (m != MATCH_YES)
5721 : : return m;
5722 : :
5723 : 8579 : if (!gfc_add_flavor (&gfc_new_block->attr, FL_MODULE,
5724 : : gfc_new_block->name, NULL))
5725 : 0 : return MATCH_ERROR;
5726 : :
5727 : : return MATCH_YES;
5728 : : }
5729 : :
5730 : :
5731 : : /* Free equivalence sets and lists. Recursively is the easiest way to
5732 : : do this. */
5733 : :
5734 : : void
5735 : 7666250 : gfc_free_equiv_until (gfc_equiv *eq, gfc_equiv *stop)
5736 : : {
5737 : 7666250 : if (eq == stop)
5738 : : return;
5739 : :
5740 : 3225 : gfc_free_equiv (eq->eq);
5741 : 3225 : gfc_free_equiv_until (eq->next, stop);
5742 : 3225 : gfc_free_expr (eq->expr);
5743 : 3225 : free (eq);
5744 : : }
5745 : :
5746 : :
5747 : : void
5748 : 417552 : gfc_free_equiv (gfc_equiv *eq)
5749 : : {
5750 : 417552 : gfc_free_equiv_until (eq, NULL);
5751 : 417552 : }
5752 : :
5753 : :
5754 : : /* Match an EQUIVALENCE statement. */
5755 : :
5756 : : match
5757 : 1032 : gfc_match_equivalence (void)
5758 : : {
5759 : 1032 : gfc_equiv *eq, *set, *tail;
5760 : 1032 : gfc_ref *ref;
5761 : 1032 : gfc_symbol *sym;
5762 : 1032 : match m;
5763 : 1032 : gfc_common_head *common_head = NULL;
5764 : 1032 : bool common_flag;
5765 : 1032 : int cnt;
5766 : 1032 : char c;
5767 : :
5768 : : /* EQUIVALENCE has been matched. After gobbling any possible whitespace,
5769 : : the next character needs to be '('. Check that here, and return
5770 : : MATCH_NO for a variable of the form equivalence. */
5771 : 1032 : gfc_gobble_whitespace ();
5772 : 1032 : c = gfc_peek_ascii_char ();
5773 : 1032 : if (c != '(')
5774 : : return MATCH_NO;
5775 : :
5776 : : tail = NULL;
5777 : :
5778 : 1464 : for (;;)
5779 : : {
5780 : 1464 : eq = gfc_get_equiv ();
5781 : 1464 : if (tail == NULL)
5782 : 1031 : tail = eq;
5783 : :
5784 : 1464 : eq->next = gfc_current_ns->equiv;
5785 : 1464 : gfc_current_ns->equiv = eq;
5786 : :
5787 : 1464 : if (gfc_match_char ('(') != MATCH_YES)
5788 : 0 : goto syntax;
5789 : :
5790 : : set = eq;
5791 : : common_flag = false;
5792 : : cnt = 0;
5793 : :
5794 : 4478 : for (;;)
5795 : : {
5796 : 2971 : m = gfc_match_equiv_variable (&set->expr);
5797 : 2971 : if (m == MATCH_ERROR)
5798 : 1 : goto cleanup;
5799 : 2970 : if (m == MATCH_NO)
5800 : 0 : goto syntax;
5801 : :
5802 : : /* count the number of objects. */
5803 : 2970 : cnt++;
5804 : :
5805 : 2970 : if (gfc_match_char ('%') == MATCH_YES)
5806 : : {
5807 : 0 : gfc_error ("Derived type component %C is not a "
5808 : : "permitted EQUIVALENCE member");
5809 : 0 : goto cleanup;
5810 : : }
5811 : :
5812 : 5057 : for (ref = set->expr->ref; ref; ref = ref->next)
5813 : 2087 : if (ref->type == REF_ARRAY && ref->u.ar.type == AR_SECTION)
5814 : : {
5815 : 0 : gfc_error ("Array reference in EQUIVALENCE at %C cannot "
5816 : : "be an array section");
5817 : 0 : goto cleanup;
5818 : : }
5819 : :
5820 : 2970 : sym = set->expr->symtree->n.sym;
5821 : :
5822 : 2970 : if (!gfc_add_in_equivalence (&sym->attr, sym->name, NULL))
5823 : 4 : goto cleanup;
5824 : 2966 : if (sym->ts.type == BT_CLASS
5825 : 3 : && CLASS_DATA (sym)
5826 : 2969 : && !gfc_add_in_equivalence (&CLASS_DATA (sym)->attr,
5827 : : sym->name, NULL))
5828 : 3 : goto cleanup;
5829 : :
5830 : 2963 : if (sym->attr.in_common)
5831 : : {
5832 : 301 : common_flag = true;
5833 : 301 : common_head = sym->common_head;
5834 : : }
5835 : :
5836 : 2963 : if (gfc_match_char (')') == MATCH_YES)
5837 : : break;
5838 : :
5839 : 1507 : if (gfc_match_char (',') != MATCH_YES)
5840 : 0 : goto syntax;
5841 : :
5842 : 1507 : set->eq = gfc_get_equiv ();
5843 : 1507 : set = set->eq;
5844 : : }
5845 : :
5846 : 1456 : if (cnt < 2)
5847 : : {
5848 : 1 : gfc_error ("EQUIVALENCE at %C requires two or more objects");
5849 : 1 : goto cleanup;
5850 : : }
5851 : :
5852 : : /* If one of the members of an equivalence is in common, then
5853 : : mark them all as being in common. Before doing this, check
5854 : : that members of the equivalence group are not in different
5855 : : common blocks. */
5856 : 1455 : if (common_flag)
5857 : 901 : for (set = eq; set; set = set->eq)
5858 : : {
5859 : 609 : sym = set->expr->symtree->n.sym;
5860 : 609 : if (sym->common_head && sym->common_head != common_head)
5861 : : {
5862 : 1 : gfc_error ("Attempt to indirectly overlap COMMON "
5863 : : "blocks %s and %s by EQUIVALENCE at %C",
5864 : 1 : sym->common_head->name, common_head->name);
5865 : 1 : goto cleanup;
5866 : : }
5867 : 608 : sym->attr.in_common = 1;
5868 : 608 : sym->common_head = common_head;
5869 : : }
5870 : :
5871 : 1454 : if (gfc_match_eos () == MATCH_YES)
5872 : : break;
5873 : 434 : if (gfc_match_char (',') != MATCH_YES)
5874 : : {
5875 : 1 : gfc_error ("Expecting a comma in EQUIVALENCE at %C");
5876 : 1 : goto cleanup;
5877 : : }
5878 : : }
5879 : :
5880 : 1020 : if (!gfc_notify_std (GFC_STD_F2018_OBS, "EQUIVALENCE statement at %C"))
5881 : : return MATCH_ERROR;
5882 : :
5883 : : return MATCH_YES;
5884 : :
5885 : 0 : syntax:
5886 : 0 : gfc_syntax_error (ST_EQUIVALENCE);
5887 : :
5888 : 11 : cleanup:
5889 : 11 : eq = tail->next;
5890 : 11 : tail->next = NULL;
5891 : :
5892 : 11 : gfc_free_equiv (gfc_current_ns->equiv);
5893 : 11 : gfc_current_ns->equiv = eq;
5894 : :
5895 : 11 : return MATCH_ERROR;
5896 : : }
5897 : :
5898 : :
5899 : : /* Check that a statement function is not recursive. This is done by looking
5900 : : for the statement function symbol(sym) by looking recursively through its
5901 : : expression(e). If a reference to sym is found, true is returned.
5902 : : 12.5.4 requires that any variable of function that is implicitly typed
5903 : : shall have that type confirmed by any subsequent type declaration. The
5904 : : implicit typing is conveniently done here. */
5905 : : static bool
5906 : : recursive_stmt_fcn (gfc_expr *, gfc_symbol *);
5907 : :
5908 : : static bool
5909 : 867 : check_stmt_fcn (gfc_expr *e, gfc_symbol *sym, int *f ATTRIBUTE_UNUSED)
5910 : : {
5911 : :
5912 : 867 : if (e == NULL)
5913 : : return false;
5914 : :
5915 : 867 : switch (e->expr_type)
5916 : : {
5917 : 106 : case EXPR_FUNCTION:
5918 : 106 : if (e->symtree == NULL)
5919 : : return false;
5920 : :
5921 : : /* Check the name before testing for nested recursion! */
5922 : 106 : if (sym->name == e->symtree->n.sym->name)
5923 : : return true;
5924 : :
5925 : : /* Catch recursion via other statement functions. */
5926 : 105 : if (e->symtree->n.sym->attr.proc == PROC_ST_FUNCTION
5927 : 4 : && e->symtree->n.sym->value
5928 : 109 : && recursive_stmt_fcn (e->symtree->n.sym->value, sym))
5929 : : return true;
5930 : :
5931 : 103 : if (e->symtree->n.sym->ts.type == BT_UNKNOWN)
5932 : 53 : gfc_set_default_type (e->symtree->n.sym, 0, NULL);
5933 : :
5934 : : break;
5935 : :
5936 : 396 : case EXPR_VARIABLE:
5937 : 396 : if (e->symtree && sym->name == e->symtree->n.sym->name)
5938 : : return true;
5939 : :
5940 : 396 : if (e->symtree->n.sym->ts.type == BT_UNKNOWN)
5941 : 150 : gfc_set_default_type (e->symtree->n.sym, 0, NULL);
5942 : : break;
5943 : :
5944 : : default:
5945 : : break;
5946 : : }
5947 : :
5948 : : return false;
5949 : : }
5950 : :
5951 : :
5952 : : static bool
5953 : 226 : recursive_stmt_fcn (gfc_expr *e, gfc_symbol *sym)
5954 : : {
5955 : 4 : return gfc_traverse_expr (e, sym, check_stmt_fcn, 0);
5956 : : }
5957 : :
5958 : :
5959 : : /* Check for invalid uses of statement function dummy arguments in body. */
5960 : :
5961 : : static bool
5962 : 840 : chk_stmt_fcn_body (gfc_expr *e, gfc_symbol *sym, int *f ATTRIBUTE_UNUSED)
5963 : : {
5964 : 840 : gfc_formal_arglist *formal;
5965 : :
5966 : 840 : if (e == NULL || e->symtree == NULL || e->expr_type != EXPR_FUNCTION)
5967 : : return false;
5968 : :
5969 : 239 : for (formal = sym->formal; formal; formal = formal->next)
5970 : : {
5971 : 141 : if (formal->sym == e->symtree->n.sym)
5972 : : {
5973 : 2 : gfc_error ("Invalid use of statement function argument at %L",
5974 : : &e->where);
5975 : 2 : return true;
5976 : : }
5977 : : }
5978 : :
5979 : : return false;
5980 : : }
5981 : :
5982 : :
5983 : : /* Match a statement function declaration. It is so easy to match
5984 : : non-statement function statements with a MATCH_ERROR as opposed to
5985 : : MATCH_NO that we suppress error message in most cases. */
5986 : :
5987 : : match
5988 : 349628 : gfc_match_st_function (void)
5989 : : {
5990 : 349628 : gfc_error_buffer old_error;
5991 : 349628 : gfc_symbol *sym;
5992 : 349628 : gfc_expr *expr;
5993 : 349628 : match m;
5994 : 349628 : char name[GFC_MAX_SYMBOL_LEN + 1];
5995 : 349628 : locus old_locus;
5996 : 349628 : bool fcn;
5997 : 349628 : gfc_formal_arglist *ptr;
5998 : :
5999 : : /* Read the possible statement function name, and then check to see if
6000 : : a symbol is already present in the namespace. Record if it is a
6001 : : function and whether it has been referenced. */
6002 : 349628 : fcn = false;
6003 : 349628 : ptr = NULL;
6004 : 349628 : old_locus = gfc_current_locus;
6005 : 349628 : m = gfc_match_name (name);
6006 : 349628 : if (m == MATCH_YES)
6007 : : {
6008 : 349628 : gfc_find_symbol (name, NULL, 1, &sym);
6009 : 349628 : if (sym && sym->attr.function && !sym->attr.referenced)
6010 : : {
6011 : 105 : fcn = true;
6012 : 105 : ptr = sym->formal;
6013 : : }
6014 : : }
6015 : :
6016 : 349628 : gfc_current_locus = old_locus;
6017 : 349628 : m = gfc_match_symbol (&sym, 0);
6018 : 349628 : if (m != MATCH_YES)
6019 : : return m;
6020 : :
6021 : 349615 : gfc_push_error (&old_error);
6022 : :
6023 : 349615 : if (!gfc_add_procedure (&sym->attr, PROC_ST_FUNCTION, sym->name, NULL))
6024 : 301 : goto undo_error;
6025 : :
6026 : 349314 : if (gfc_match_formal_arglist (sym, 1, 0) != MATCH_YES)
6027 : 290281 : goto undo_error;
6028 : :
6029 : 59033 : m = gfc_match (" = %e%t", &expr);
6030 : 59033 : if (m == MATCH_NO)
6031 : 58811 : goto undo_error;
6032 : :
6033 : 222 : gfc_free_error (&old_error);
6034 : :
6035 : 222 : if (m == MATCH_ERROR)
6036 : : return m;
6037 : :
6038 : 222 : if (recursive_stmt_fcn (expr, sym))
6039 : : {
6040 : 1 : gfc_error ("Statement function at %L is recursive", &expr->where);
6041 : 1 : return MATCH_ERROR;
6042 : : }
6043 : :
6044 : 221 : if (fcn && ptr != sym->formal)
6045 : : {
6046 : 2 : gfc_error ("Statement function %qs at %L conflicts with function name",
6047 : 2 : sym->name, &expr->where);
6048 : 2 : return MATCH_ERROR;
6049 : : }
6050 : :
6051 : 219 : if (gfc_traverse_expr (expr, sym, chk_stmt_fcn_body, 0))
6052 : : return MATCH_ERROR;
6053 : :
6054 : 217 : sym->value = expr;
6055 : :
6056 : 217 : if ((gfc_current_state () == COMP_FUNCTION
6057 : 217 : || gfc_current_state () == COMP_SUBROUTINE)
6058 : 130 : && gfc_state_stack->previous->state == COMP_INTERFACE)
6059 : : {
6060 : 1 : gfc_error ("Statement function at %L cannot appear within an INTERFACE",
6061 : : &expr->where);
6062 : 1 : return MATCH_ERROR;
6063 : : }
6064 : :
6065 : 216 : if (!gfc_notify_std (GFC_STD_F95_OBS, "Statement function at %C"))
6066 : : return MATCH_ERROR;
6067 : :
6068 : : return MATCH_YES;
6069 : :
6070 : 349393 : undo_error:
6071 : 349393 : gfc_pop_error (&old_error);
6072 : 349393 : return MATCH_NO;
6073 : 349628 : }
6074 : :
6075 : :
6076 : : /* Match an assignment to a pointer function (F2008). This could, in
6077 : : general be ambiguous with a statement function. In this implementation
6078 : : it remains so if it is the first statement after the specification
6079 : : block. */
6080 : :
6081 : : match
6082 : 850341 : gfc_match_ptr_fcn_assign (void)
6083 : : {
6084 : 850341 : gfc_error_buffer old_error;
6085 : 850341 : locus old_loc;
6086 : 850341 : gfc_symbol *sym;
6087 : 850341 : gfc_expr *expr;
6088 : 850341 : match m;
6089 : 850341 : char name[GFC_MAX_SYMBOL_LEN + 1];
6090 : :
6091 : 850341 : old_loc = gfc_current_locus;
6092 : 850341 : m = gfc_match_name (name);
6093 : 850341 : if (m != MATCH_YES)
6094 : : return m;
6095 : :
6096 : 850338 : gfc_find_symbol (name, NULL, 1, &sym);
6097 : 850338 : if (sym && sym->attr.flavor != FL_PROCEDURE)
6098 : : return MATCH_NO;
6099 : :
6100 : 850078 : gfc_push_error (&old_error);
6101 : :
6102 : 850078 : if (sym && sym->attr.function)
6103 : 772 : goto match_actual_arglist;
6104 : :
6105 : 849306 : gfc_current_locus = old_loc;
6106 : 849306 : m = gfc_match_symbol (&sym, 0);
6107 : 849306 : if (m != MATCH_YES)
6108 : : return m;
6109 : :
6110 : 849293 : if (!gfc_add_procedure (&sym->attr, PROC_UNKNOWN, sym->name, NULL))
6111 : 0 : goto undo_error;
6112 : :
6113 : 849293 : match_actual_arglist:
6114 : 850065 : gfc_current_locus = old_loc;
6115 : 850065 : m = gfc_match (" %e", &expr);
6116 : 850065 : if (m != MATCH_YES)
6117 : 533521 : goto undo_error;
6118 : :
6119 : 316544 : new_st.op = EXEC_ASSIGN;
6120 : 316544 : new_st.expr1 = expr;
6121 : 316544 : expr = NULL;
6122 : :
6123 : 316544 : m = gfc_match (" = %e%t", &expr);
6124 : 316544 : if (m != MATCH_YES)
6125 : 316448 : goto undo_error;
6126 : :
6127 : 96 : new_st.expr2 = expr;
6128 : 96 : return MATCH_YES;
6129 : :
6130 : 849969 : undo_error:
6131 : 849969 : gfc_pop_error (&old_error);
6132 : 849969 : return MATCH_NO;
6133 : 850341 : }
6134 : :
6135 : :
6136 : : /***************** SELECT CASE subroutines ******************/
6137 : :
6138 : : /* Free a single case structure. */
6139 : :
6140 : : static void
6141 : 8996 : free_case (gfc_case *p)
6142 : : {
6143 : 8996 : if (p->low == p->high)
6144 : 4220 : p->high = NULL;
6145 : 8996 : gfc_free_expr (p->low);
6146 : 8996 : gfc_free_expr (p->high);
6147 : 8996 : free (p);
6148 : 8996 : }
6149 : :
6150 : :
6151 : : /* Free a list of case structures. */
6152 : :
6153 : : void
6154 : 8795 : gfc_free_case_list (gfc_case *p)
6155 : : {
6156 : 8795 : gfc_case *q;
6157 : :
6158 : 17781 : for (; p; p = q)
6159 : : {
6160 : 8986 : q = p->next;
6161 : 8986 : free_case (p);
6162 : : }
6163 : 8795 : }
6164 : :
6165 : :
6166 : : /* Match a single case selector. Combining the requirements of F08:C830
6167 : : and F08:C832 (R838) means that the case-value must have either CHARACTER,
6168 : : INTEGER, or LOGICAL type. */
6169 : :
6170 : : static match
6171 : 1313 : match_case_selector (gfc_case **cp)
6172 : : {
6173 : 1313 : gfc_case *c;
6174 : 1313 : match m;
6175 : :
6176 : 1313 : c = gfc_get_case ();
6177 : 1313 : c->where = gfc_current_locus;
6178 : :
6179 : 1313 : if (gfc_match_char (':') == MATCH_YES)
6180 : : {
6181 : 48 : m = gfc_match_init_expr (&c->high);
6182 : 48 : if (m == MATCH_NO)
6183 : 0 : goto need_expr;
6184 : 48 : if (m == MATCH_ERROR)
6185 : 0 : goto cleanup;
6186 : :
6187 : 48 : if (c->high->ts.type != BT_LOGICAL && c->high->ts.type != BT_INTEGER
6188 : 2 : && c->high->ts.type != BT_CHARACTER)
6189 : : {
6190 : 2 : gfc_error ("Expression in CASE selector at %L cannot be %s",
6191 : 2 : &c->high->where, gfc_typename (&c->high->ts));
6192 : 2 : goto cleanup;
6193 : : }
6194 : : }
6195 : : else
6196 : : {
6197 : 1265 : m = gfc_match_init_expr (&c->low);
6198 : 1265 : if (m == MATCH_ERROR)
6199 : 0 : goto cleanup;
6200 : 1265 : if (m == MATCH_NO)
6201 : 0 : goto need_expr;
6202 : :
6203 : 1265 : if (c->low->ts.type != BT_LOGICAL && c->low->ts.type != BT_INTEGER
6204 : 350 : && c->low->ts.type != BT_CHARACTER)
6205 : : {
6206 : 1 : gfc_error ("Expression in CASE selector at %L cannot be %s",
6207 : 1 : &c->low->where, gfc_typename (&c->low->ts));
6208 : 1 : goto cleanup;
6209 : : }
6210 : :
6211 : : /* If we're not looking at a ':' now, make a range out of a single
6212 : : target. Else get the upper bound for the case range. */
6213 : 1264 : if (gfc_match_char (':') != MATCH_YES)
6214 : 1087 : c->high = c->low;
6215 : : else
6216 : : {
6217 : 177 : m = gfc_match_init_expr (&c->high);
6218 : 177 : if (m == MATCH_ERROR)
6219 : 0 : goto cleanup;
6220 : 177 : if (m == MATCH_YES
6221 : 129 : && c->high->ts.type != BT_LOGICAL
6222 : : && c->high->ts.type != BT_INTEGER
6223 : : && c->high->ts.type != BT_CHARACTER)
6224 : : {
6225 : 1 : gfc_error ("Expression in CASE selector at %L cannot be %s",
6226 : 1 : &c->high->where, gfc_typename (c->high));
6227 : 1 : goto cleanup;
6228 : : }
6229 : : /* MATCH_NO is fine. It's OK if nothing is there! */
6230 : : }
6231 : : }
6232 : :
6233 : 1309 : if (c->low && c->low->rank != 0)
6234 : : {
6235 : 4 : gfc_error ("Expression in CASE selector at %L must be scalar",
6236 : : &c->low->where);
6237 : 4 : goto cleanup;
6238 : : }
6239 : 1305 : if (c->high && c->high->rank != 0)
6240 : : {
6241 : 2 : gfc_error ("Expression in CASE selector at %L must be scalar",
6242 : : &c->high->where);
6243 : 2 : goto cleanup;
6244 : : }
6245 : :
6246 : 1303 : *cp = c;
6247 : 1303 : return MATCH_YES;
6248 : :
6249 : 0 : need_expr:
6250 : 0 : gfc_error ("Expected initialization expression in CASE at %C");
6251 : :
6252 : 10 : cleanup:
6253 : 10 : free_case (c);
6254 : 10 : return MATCH_ERROR;
6255 : : }
6256 : :
6257 : :
6258 : : /* Match the end of a case statement. */
6259 : :
6260 : : static match
6261 : 8270 : match_case_eos (void)
6262 : : {
6263 : 8270 : char name[GFC_MAX_SYMBOL_LEN + 1];
6264 : 8270 : match m;
6265 : :
6266 : 8270 : if (gfc_match_eos () == MATCH_YES)
6267 : : return MATCH_YES;
6268 : :
6269 : : /* If the case construct doesn't have a case-construct-name, we
6270 : : should have matched the EOS. */
6271 : 21 : if (!gfc_current_block ())
6272 : : return MATCH_NO;
6273 : :
6274 : 17 : gfc_gobble_whitespace ();
6275 : :
6276 : 17 : m = gfc_match_name (name);
6277 : 17 : if (m != MATCH_YES)
6278 : : return m;
6279 : :
6280 : 17 : if (strcmp (name, gfc_current_block ()->name) != 0)
6281 : : {
6282 : 1 : gfc_error ("Expected block name %qs of SELECT construct at %C",
6283 : : gfc_current_block ()->name);
6284 : 1 : return MATCH_ERROR;
6285 : : }
6286 : :
6287 : 16 : return gfc_match_eos ();
6288 : : }
6289 : :
6290 : :
6291 : : /* Match a SELECT statement. */
6292 : :
6293 : : match
6294 : 421195 : gfc_match_select (void)
6295 : : {
6296 : 421195 : gfc_expr *expr;
6297 : 421195 : match m;
6298 : :
6299 : 421195 : m = gfc_match_label ();
6300 : 421195 : if (m == MATCH_ERROR)
6301 : : return m;
6302 : :
6303 : 421187 : m = gfc_match (" select case ( %e )%t", &expr);
6304 : 421187 : if (m != MATCH_YES)
6305 : : return m;
6306 : :
6307 : 529 : new_st.op = EXEC_SELECT;
6308 : 529 : new_st.expr1 = expr;
6309 : :
6310 : 529 : return MATCH_YES;
6311 : : }
6312 : :
6313 : :
6314 : : /* Transfer the selector typespec to the associate name. */
6315 : :
6316 : : static void
6317 : 526 : copy_ts_from_selector_to_associate (gfc_expr *associate, gfc_expr *selector)
6318 : : {
6319 : 526 : gfc_ref *ref;
6320 : 526 : gfc_symbol *assoc_sym;
6321 : 526 : int rank = 0;
6322 : :
6323 : 526 : assoc_sym = associate->symtree->n.sym;
6324 : :
6325 : : /* At this stage the expression rank and arrayspec dimensions have
6326 : : not been completely sorted out. We must get the expr2->rank
6327 : : right here, so that the correct class container is obtained. */
6328 : 526 : ref = selector->ref;
6329 : 777 : while (ref && ref->next)
6330 : : ref = ref->next;
6331 : :
6332 : 526 : if (selector->ts.type == BT_CLASS
6333 : 524 : && CLASS_DATA (selector)
6334 : 522 : && CLASS_DATA (selector)->as
6335 : 322 : && CLASS_DATA (selector)->as->type == AS_ASSUMED_RANK)
6336 : : {
6337 : 12 : assoc_sym->attr.dimension = 1;
6338 : 12 : assoc_sym->as = gfc_copy_array_spec (CLASS_DATA (selector)->as);
6339 : 12 : goto build_class_sym;
6340 : : }
6341 : 514 : else if (selector->ts.type == BT_CLASS
6342 : 512 : && CLASS_DATA (selector)
6343 : 510 : && CLASS_DATA (selector)->as
6344 : 310 : && ref && ref->type == REF_ARRAY)
6345 : : {
6346 : : /* Ensure that the array reference type is set. We cannot use
6347 : : gfc_resolve_expr at this point, so the usable parts of
6348 : : resolve.cc(resolve_array_ref) are employed to do it. */
6349 : 310 : if (ref->u.ar.type == AR_UNKNOWN)
6350 : : {
6351 : 99 : ref->u.ar.type = AR_ELEMENT;
6352 : 167 : for (int i = 0; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
6353 : 105 : if (ref->u.ar.dimen_type[i] == DIMEN_RANGE
6354 : 105 : || ref->u.ar.dimen_type[i] == DIMEN_VECTOR
6355 : 69 : || (ref->u.ar.dimen_type[i] == DIMEN_UNKNOWN
6356 : 69 : && ref->u.ar.start[i] && ref->u.ar.start[i]->rank))
6357 : : {
6358 : 37 : ref->u.ar.type = AR_SECTION;
6359 : 37 : break;
6360 : : }
6361 : : }
6362 : :
6363 : 310 : if (ref->u.ar.type == AR_FULL)
6364 : 211 : selector->rank = CLASS_DATA (selector)->as->rank;
6365 : 99 : else if (ref->u.ar.type == AR_SECTION)
6366 : 37 : selector->rank = ref->u.ar.dimen;
6367 : : else
6368 : 62 : selector->rank = 0;
6369 : :
6370 : 310 : rank = selector->rank;
6371 : : }
6372 : :
6373 : 310 : if (rank)
6374 : : {
6375 : 285 : for (int i = 0; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
6376 : 43 : if (ref->u.ar.dimen_type[i] == DIMEN_ELEMENT
6377 : 43 : || (ref->u.ar.dimen_type[i] == DIMEN_UNKNOWN
6378 : 7 : && ref->u.ar.end[i] == NULL
6379 : 7 : && ref->u.ar.stride[i] == NULL))
6380 : 7 : rank--;
6381 : :
6382 : 242 : if (rank)
6383 : : {
6384 : 241 : assoc_sym->attr.dimension = 1;
6385 : 241 : assoc_sym->as = gfc_get_array_spec ();
6386 : 241 : assoc_sym->as->rank = rank;
6387 : 241 : assoc_sym->as->type = AS_DEFERRED;
6388 : : }
6389 : : else
6390 : 1 : assoc_sym->as = NULL;
6391 : : }
6392 : : else
6393 : 272 : assoc_sym->as = NULL;
6394 : :
6395 : 526 : build_class_sym:
6396 : 526 : if (selector->ts.type == BT_CLASS)
6397 : : {
6398 : : /* The correct class container has to be available. */
6399 : 524 : assoc_sym->ts.type = BT_CLASS;
6400 : 1048 : assoc_sym->ts.u.derived = CLASS_DATA (selector)
6401 : 524 : ? CLASS_DATA (selector)->ts.u.derived : selector->ts.u.derived;
6402 : 524 : assoc_sym->attr.pointer = 1;
6403 : 524 : gfc_build_class_symbol (&assoc_sym->ts, &assoc_sym->attr, &assoc_sym->as);
6404 : : }
6405 : 526 : }
6406 : :
6407 : :
6408 : : /* Build the associate name */
6409 : : static int
6410 : 520 : build_associate_name (const char *name, gfc_expr **e1, gfc_expr **e2)
6411 : : {
6412 : 520 : gfc_expr *expr1 = *e1;
6413 : 520 : gfc_expr *expr2 = *e2;
6414 : 520 : gfc_symbol *sym;
6415 : :
6416 : : /* For the case where the associate name is already an associate name. */
6417 : 520 : if (!expr2)
6418 : 43 : expr2 = expr1;
6419 : 520 : expr1 = gfc_get_expr ();
6420 : 520 : expr1->expr_type = EXPR_VARIABLE;
6421 : 520 : expr1->where = expr2->where;
6422 : 520 : if (gfc_get_sym_tree (name, NULL, &expr1->symtree, false))
6423 : : return 1;
6424 : :
6425 : 520 : sym = expr1->symtree->n.sym;
6426 : 520 : if (expr2->ts.type == BT_UNKNOWN)
6427 : 6 : sym->attr.untyped = 1;
6428 : : else
6429 : 514 : copy_ts_from_selector_to_associate (expr1, expr2);
6430 : :
6431 : 520 : sym->attr.flavor = FL_VARIABLE;
6432 : 520 : sym->attr.referenced = 1;
6433 : 520 : sym->attr.class_ok = 1;
6434 : :
6435 : 520 : *e1 = expr1;
6436 : 520 : *e2 = expr2;
6437 : 520 : return 0;
6438 : : }
6439 : :
6440 : :
6441 : : /* Push the current selector onto the SELECT TYPE stack. */
6442 : :
6443 : : static void
6444 : 3551 : select_type_push (gfc_symbol *sel)
6445 : : {
6446 : 3551 : gfc_select_type_stack *top = gfc_get_select_type_stack ();
6447 : 3551 : top->selector = sel;
6448 : 3551 : top->tmp = NULL;
6449 : 3551 : top->prev = select_type_stack;
6450 : :
6451 : 3551 : select_type_stack = top;
6452 : 3551 : }
6453 : :
6454 : :
6455 : : /* Set the temporary for the current intrinsic SELECT TYPE selector. */
6456 : :
6457 : : static gfc_symtree *
6458 : 3228 : select_intrinsic_set_tmp (gfc_typespec *ts)
6459 : : {
6460 : 3228 : char name[GFC_MAX_SYMBOL_LEN];
6461 : 3228 : gfc_symtree *tmp;
6462 : 3228 : HOST_WIDE_INT charlen = 0;
6463 : 3228 : gfc_symbol *selector = select_type_stack->selector;
6464 : 3228 : gfc_symbol *sym;
6465 : :
6466 : 3228 : if (ts->type == BT_CLASS || ts->type == BT_DERIVED)
6467 : : return NULL;
6468 : :
6469 : 1189 : if (selector->ts.type == BT_CLASS && !selector->attr.class_ok)
6470 : : return NULL;
6471 : :
6472 : : /* Case value == NULL corresponds to SELECT TYPE cases otherwise
6473 : : the values correspond to SELECT rank cases. */
6474 : 1188 : if (ts->type == BT_CHARACTER && ts->u.cl && ts->u.cl->length
6475 : 0 : && ts->u.cl->length->expr_type == EXPR_CONSTANT)
6476 : 0 : charlen = gfc_mpz_get_hwi (ts->u.cl->length->value.integer);
6477 : :
6478 : 1188 : if (ts->type != BT_CHARACTER)
6479 : 551 : sprintf (name, "__tmp_%s_%d", gfc_basic_typename (ts->type),
6480 : : ts->kind);
6481 : : else
6482 : 637 : snprintf (name, sizeof (name),
6483 : : "__tmp_%s_" HOST_WIDE_INT_PRINT_DEC "_%d",
6484 : : gfc_basic_typename (ts->type), charlen, ts->kind);
6485 : :
6486 : 1188 : gfc_get_sym_tree (name, gfc_current_ns, &tmp, false);
6487 : 1188 : sym = tmp->n.sym;
6488 : 1188 : gfc_add_type (sym, ts, NULL);
6489 : :
6490 : : /* Copy across the array spec to the selector. */
6491 : 1188 : if (selector->ts.type == BT_CLASS
6492 : 1186 : && (CLASS_DATA (selector)->attr.dimension
6493 : 1186 : || CLASS_DATA (selector)->attr.codimension))
6494 : : {
6495 : 568 : sym->attr.pointer = 1;
6496 : 568 : sym->attr.dimension = CLASS_DATA (selector)->attr.dimension;
6497 : 568 : sym->attr.codimension = CLASS_DATA (selector)->attr.codimension;
6498 : 568 : sym->as = gfc_copy_array_spec (CLASS_DATA (selector)->as);
6499 : : }
6500 : :
6501 : 1188 : gfc_set_sym_referenced (sym);
6502 : 1188 : gfc_add_flavor (&sym->attr, FL_VARIABLE, name, NULL);
6503 : 1188 : sym->attr.select_type_temporary = 1;
6504 : :
6505 : 1188 : return tmp;
6506 : : }
6507 : :
6508 : :
6509 : : /* Set up a temporary for the current TYPE IS / CLASS IS branch . */
6510 : :
6511 : : static void
6512 : 4566 : select_type_set_tmp (gfc_typespec *ts)
6513 : : {
6514 : 4566 : char name[GFC_MAX_SYMBOL_LEN + 12 + 1];
6515 : 4566 : gfc_symtree *tmp = NULL;
6516 : 4566 : gfc_symbol *selector = select_type_stack->selector;
6517 : 4566 : gfc_symbol *sym;
6518 : :
6519 : 4566 : if (!ts)
6520 : : {
6521 : 1338 : select_type_stack->tmp = NULL;
6522 : 1339 : return;
6523 : : }
6524 : :
6525 : 3228 : tmp = select_intrinsic_set_tmp (ts);
6526 : :
6527 : 3228 : if (tmp == NULL)
6528 : : {
6529 : 2040 : if (!ts->u.derived)
6530 : : return;
6531 : :
6532 : 2039 : if (ts->type == BT_CLASS)
6533 : 288 : sprintf (name, "__tmp_class_%s", ts->u.derived->name);
6534 : : else
6535 : 1751 : sprintf (name, "__tmp_type_%s", ts->u.derived->name);
6536 : :
6537 : 2039 : gfc_get_sym_tree (name, gfc_current_ns, &tmp, false);
6538 : 2039 : sym = tmp->n.sym;
6539 : 2039 : gfc_add_type (sym, ts, NULL);
6540 : :
6541 : 2039 : if (selector->ts.type == BT_CLASS && selector->attr.class_ok
6542 : 2015 : && selector->ts.u.derived && CLASS_DATA (selector))
6543 : : {
6544 : 2013 : sym->attr.pointer
6545 : 2013 : = CLASS_DATA (selector)->attr.class_pointer;
6546 : :
6547 : : /* Copy across the array spec to the selector. */
6548 : 2013 : if (CLASS_DATA (selector)->attr.dimension
6549 : 2013 : || CLASS_DATA (selector)->attr.codimension)
6550 : : {
6551 : 600 : sym->attr.dimension
6552 : 600 : = CLASS_DATA (selector)->attr.dimension;
6553 : 600 : sym->attr.codimension
6554 : 600 : = CLASS_DATA (selector)->attr.codimension;
6555 : 600 : if (CLASS_DATA (selector)->as->type != AS_EXPLICIT)
6556 : 575 : sym->as = gfc_copy_array_spec (CLASS_DATA (selector)->as);
6557 : : else
6558 : : {
6559 : 25 : sym->as = gfc_get_array_spec();
6560 : 25 : sym->as->rank = CLASS_DATA (selector)->as->rank;
6561 : 25 : sym->as->type = AS_DEFERRED;
6562 : : }
6563 : : }
6564 : : }
6565 : :
6566 : 2039 : gfc_set_sym_referenced (sym);
6567 : 2039 : gfc_add_flavor (&sym->attr, FL_VARIABLE, name, NULL);
6568 : 2039 : sym->attr.select_type_temporary = 1;
6569 : :
6570 : 2039 : if (ts->type == BT_CLASS)
6571 : 288 : gfc_build_class_symbol (&sym->ts, &sym->attr, &sym->as);
6572 : : }
6573 : : else
6574 : 1188 : sym = tmp->n.sym;
6575 : :
6576 : :
6577 : : /* Add an association for it, so the rest of the parser knows it is
6578 : : an associate-name. The target will be set during resolution. */
6579 : 3227 : sym->assoc = gfc_get_association_list ();
6580 : 3227 : sym->assoc->dangling = 1;
6581 : 3227 : sym->assoc->st = tmp;
6582 : :
6583 : 3227 : select_type_stack->tmp = tmp;
6584 : : }
6585 : :
6586 : :
6587 : : /* Match a SELECT TYPE statement. */
6588 : :
6589 : : match
6590 : 420666 : gfc_match_select_type (void)
6591 : : {
6592 : 420666 : gfc_expr *expr1, *expr2 = NULL;
6593 : 420666 : match m;
6594 : 420666 : char name[GFC_MAX_SYMBOL_LEN + 1];
6595 : 420666 : bool class_array;
6596 : 420666 : gfc_namespace *ns = gfc_current_ns;
6597 : :
6598 : 420666 : m = gfc_match_label ();
6599 : 420666 : if (m == MATCH_ERROR)
6600 : : return m;
6601 : :
6602 : 420658 : m = gfc_match (" select type ( ");
6603 : 420658 : if (m != MATCH_YES)
6604 : : return m;
6605 : :
6606 : 2573 : if (gfc_current_state() == COMP_MODULE
6607 : 2573 : || gfc_current_state() == COMP_SUBMODULE)
6608 : : {
6609 : 2 : gfc_error ("SELECT TYPE at %C cannot appear in this scope");
6610 : 2 : return MATCH_ERROR;
6611 : : }
6612 : :
6613 : 2571 : gfc_current_ns = gfc_build_block_ns (ns);
6614 : 2571 : m = gfc_match (" %n => %e", name, &expr2);
6615 : 2571 : if (m == MATCH_YES)
6616 : : {
6617 : 477 : if (build_associate_name (name, &expr1, &expr2))
6618 : : {
6619 : 0 : m = MATCH_ERROR;
6620 : 0 : goto cleanup;
6621 : : }
6622 : : }
6623 : : else
6624 : : {
6625 : 2094 : m = gfc_match (" %e ", &expr1);
6626 : 2094 : if (m != MATCH_YES)
6627 : : {
6628 : 0 : std::swap (ns, gfc_current_ns);
6629 : 0 : gfc_free_namespace (ns);
6630 : 0 : return m;
6631 : : }
6632 : : }
6633 : :
6634 : 2571 : m = gfc_match (" )%t");
6635 : 2571 : if (m != MATCH_YES)
6636 : : {
6637 : 1 : gfc_error ("parse error in SELECT TYPE statement at %C");
6638 : 1 : goto cleanup;
6639 : : }
6640 : :
6641 : : /* This ghastly expression seems to be needed to distinguish a CLASS
6642 : : array, which can have a reference, from other expressions that
6643 : : have references, such as derived type components, and are not
6644 : : allowed by the standard.
6645 : : TODO: see if it is sufficient to exclude component and substring
6646 : : references. */
6647 : 5140 : class_array = (expr1->expr_type == EXPR_VARIABLE
6648 : 2569 : && expr1->ts.type == BT_CLASS
6649 : 2069 : && CLASS_DATA (expr1)
6650 : 2067 : && (strcmp (CLASS_DATA (expr1)->name, "_data") == 0)
6651 : 2067 : && (CLASS_DATA (expr1)->attr.dimension
6652 : 2067 : || CLASS_DATA (expr1)->attr.codimension)
6653 : 716 : && expr1->ref
6654 : 716 : && expr1->ref->type == REF_ARRAY
6655 : 716 : && expr1->ref->u.ar.type == AR_FULL
6656 : 3285 : && expr1->ref->next == NULL);
6657 : :
6658 : : /* Check for F03:C811 (F08:C835). */
6659 : 2570 : if (!expr2 && (expr1->expr_type != EXPR_VARIABLE
6660 : 2093 : || (!class_array && expr1->ref != NULL)))
6661 : : {
6662 : 4 : gfc_error ("Selector in SELECT TYPE at %C is not a named variable; "
6663 : : "use associate-name=>");
6664 : 4 : m = MATCH_ERROR;
6665 : 4 : goto cleanup;
6666 : : }
6667 : :
6668 : : /* Prevent an existing associate name from reuse here by pushing expr1 to
6669 : : expr2 and building a new associate name. */
6670 : 2090 : if (!expr2 && expr1->symtree->n.sym->assoc
6671 : : && !expr1->symtree->n.sym->attr.select_type_temporary
6672 : 79 : && !expr1->symtree->n.sym->attr.select_rank_temporary
6673 : 2609 : && build_associate_name (expr1->symtree->n.sym->name, &expr1, &expr2))
6674 : : {
6675 : 0 : m = MATCH_ERROR;
6676 : 0 : goto cleanup;
6677 : : }
6678 : :
6679 : 2566 : new_st.op = EXEC_SELECT_TYPE;
6680 : 2566 : new_st.expr1 = expr1;
6681 : 2566 : new_st.expr2 = expr2;
6682 : 2566 : new_st.ext.block.ns = gfc_current_ns;
6683 : :
6684 : 2566 : select_type_push (expr1->symtree->n.sym);
6685 : 2566 : gfc_current_ns = ns;
6686 : :
6687 : 2566 : return MATCH_YES;
6688 : :
6689 : 5 : cleanup:
6690 : 5 : gfc_free_expr (expr1);
6691 : 5 : gfc_free_expr (expr2);
6692 : 5 : gfc_undo_symbols ();
6693 : 5 : std::swap (ns, gfc_current_ns);
6694 : 5 : gfc_free_namespace (ns);
6695 : 5 : return m;
6696 : : }
6697 : :
6698 : :
6699 : : /* Set the temporary for the current intrinsic SELECT RANK selector. */
6700 : :
6701 : : static void
6702 : 1324 : select_rank_set_tmp (gfc_typespec *ts, int *case_value)
6703 : : {
6704 : 1324 : char name[2 * GFC_MAX_SYMBOL_LEN];
6705 : 1324 : char tname[GFC_MAX_SYMBOL_LEN + 7];
6706 : 1324 : gfc_symtree *tmp;
6707 : 1324 : gfc_symbol *selector = select_type_stack->selector;
6708 : 1324 : gfc_symbol *sym;
6709 : 1324 : gfc_symtree *st;
6710 : 1324 : HOST_WIDE_INT charlen = 0;
6711 : :
6712 : 1324 : if (case_value == NULL)
6713 : 2 : return;
6714 : :
6715 : 1324 : if (ts->type == BT_CHARACTER && ts->u.cl && ts->u.cl->length
6716 : 265 : && ts->u.cl->length->expr_type == EXPR_CONSTANT)
6717 : 186 : charlen = gfc_mpz_get_hwi (ts->u.cl->length->value.integer);
6718 : :
6719 : 1324 : if (ts->type == BT_CLASS)
6720 : 110 : sprintf (tname, "class_%s", ts->u.derived->name);
6721 : 1214 : else if (ts->type == BT_DERIVED)
6722 : 110 : sprintf (tname, "type_%s", ts->u.derived->name);
6723 : 1104 : else if (ts->type != BT_CHARACTER)
6724 : 557 : sprintf (tname, "%s_%d", gfc_basic_typename (ts->type), ts->kind);
6725 : : else
6726 : 547 : sprintf (tname, "%s_" HOST_WIDE_INT_PRINT_DEC "_%d",
6727 : : gfc_basic_typename (ts->type), charlen, ts->kind);
6728 : :
6729 : : /* Case value == NULL corresponds to SELECT TYPE cases otherwise
6730 : : the values correspond to SELECT rank cases. */
6731 : 1324 : if (*case_value >=0)
6732 : 1291 : sprintf (name, "__tmp_%s_rank_%d", tname, *case_value);
6733 : : else
6734 : 33 : sprintf (name, "__tmp_%s_rank_m%d", tname, -*case_value);
6735 : :
6736 : 1324 : gfc_find_sym_tree (name, gfc_current_ns, 0, &st);
6737 : 1324 : if (st)
6738 : : return;
6739 : :
6740 : 1322 : gfc_get_sym_tree (name, gfc_current_ns, &tmp, false);
6741 : 1322 : sym = tmp->n.sym;
6742 : 1322 : gfc_add_type (sym, ts, NULL);
6743 : :
6744 : : /* Copy across the array spec to the selector. */
6745 : 1322 : if (selector->ts.type == BT_CLASS)
6746 : : {
6747 : 110 : sym->ts.u.derived = CLASS_DATA (selector)->ts.u.derived;
6748 : 110 : sym->attr.pointer = CLASS_DATA (selector)->attr.pointer;
6749 : 110 : sym->attr.allocatable = CLASS_DATA (selector)->attr.allocatable;
6750 : 110 : sym->attr.target = CLASS_DATA (selector)->attr.target;
6751 : 110 : sym->attr.class_ok = 0;
6752 : 110 : if (case_value && *case_value != 0)
6753 : : {
6754 : 86 : sym->attr.dimension = 1;
6755 : 86 : sym->as = gfc_copy_array_spec (CLASS_DATA (selector)->as);
6756 : 86 : if (*case_value > 0)
6757 : : {
6758 : 86 : sym->as->type = AS_DEFERRED;
6759 : 86 : sym->as->rank = *case_value;
6760 : : }
6761 : 0 : else if (*case_value == -1)
6762 : : {
6763 : 0 : sym->as->type = AS_ASSUMED_SIZE;
6764 : 0 : sym->as->rank = 1;
6765 : : }
6766 : : }
6767 : : }
6768 : : else
6769 : : {
6770 : 1212 : sym->attr.pointer = selector->attr.pointer;
6771 : 1212 : sym->attr.allocatable = selector->attr.allocatable;
6772 : 1212 : sym->attr.target = selector->attr.target;
6773 : 1212 : if (case_value && *case_value != 0)
6774 : : {
6775 : 1169 : sym->attr.dimension = 1;
6776 : 1169 : sym->as = gfc_copy_array_spec (selector->as);
6777 : 1169 : if (*case_value > 0)
6778 : : {
6779 : 1137 : sym->as->type = AS_DEFERRED;
6780 : 1137 : sym->as->rank = *case_value;
6781 : : }
6782 : 32 : else if (*case_value == -1)
6783 : : {
6784 : 32 : sym->as->type = AS_ASSUMED_SIZE;
6785 : 32 : sym->as->rank = 1;
6786 : : }
6787 : : }
6788 : : }
6789 : :
6790 : 1322 : gfc_set_sym_referenced (sym);
6791 : 1322 : gfc_add_flavor (&sym->attr, FL_VARIABLE, name, NULL);
6792 : 1322 : sym->attr.select_type_temporary = 1;
6793 : 1322 : if (case_value)
6794 : 1322 : sym->attr.select_rank_temporary = 1;
6795 : :
6796 : 1322 : if (ts->type == BT_CLASS)
6797 : 110 : gfc_build_class_symbol (&sym->ts, &sym->attr, &sym->as);
6798 : :
6799 : : /* Add an association for it, so the rest of the parser knows it is
6800 : : an associate-name. The target will be set during resolution. */
6801 : 1322 : sym->assoc = gfc_get_association_list ();
6802 : 1322 : sym->assoc->dangling = 1;
6803 : 1322 : sym->assoc->st = tmp;
6804 : :
6805 : 1322 : select_type_stack->tmp = tmp;
6806 : : }
6807 : :
6808 : :
6809 : : /* Match a SELECT RANK statement. */
6810 : :
6811 : : match
6812 : 418100 : gfc_match_select_rank (void)
6813 : : {
6814 : 418100 : gfc_expr *expr1, *expr2 = NULL;
6815 : 418100 : match m;
6816 : 418100 : char name[GFC_MAX_SYMBOL_LEN + 1];
6817 : 418100 : gfc_symbol *sym, *sym2;
6818 : 418100 : gfc_namespace *ns = gfc_current_ns;
6819 : 418100 : gfc_array_spec *as = NULL;
6820 : :
6821 : 418100 : m = gfc_match_label ();
6822 : 418100 : if (m == MATCH_ERROR)
6823 : : return m;
6824 : :
6825 : 418092 : m = gfc_match (" select% rank ( ");
6826 : 418092 : if (m != MATCH_YES)
6827 : : return m;
6828 : :
6829 : 990 : if (!gfc_notify_std (GFC_STD_F2018, "SELECT RANK statement at %C"))
6830 : : return MATCH_NO;
6831 : :
6832 : 990 : gfc_current_ns = gfc_build_block_ns (ns);
6833 : 990 : m = gfc_match (" %n => %e", name, &expr2);
6834 : :
6835 : 990 : if (m == MATCH_YES)
6836 : : {
6837 : : /* If expr2 corresponds to an implicitly typed variable, then the
6838 : : actual type of the variable may not have been set. Set it here. */
6839 : 43 : if (!gfc_current_ns->seen_implicit_none
6840 : 43 : && expr2->expr_type == EXPR_VARIABLE
6841 : 42 : && expr2->ts.type == BT_UNKNOWN
6842 : 1 : && expr2->symtree && expr2->symtree->n.sym)
6843 : : {
6844 : 1 : gfc_set_default_type (expr2->symtree->n.sym, 0, gfc_current_ns);
6845 : 1 : expr2->ts.type = expr2->symtree->n.sym->ts.type;
6846 : : }
6847 : :
6848 : 43 : expr1 = gfc_get_expr ();
6849 : 43 : expr1->expr_type = EXPR_VARIABLE;
6850 : 43 : expr1->where = expr2->where;
6851 : 43 : expr1->ref = gfc_copy_ref (expr2->ref);
6852 : 43 : if (gfc_get_sym_tree (name, NULL, &expr1->symtree, false))
6853 : : {
6854 : 0 : m = MATCH_ERROR;
6855 : 0 : goto cleanup;
6856 : : }
6857 : :
6858 : 43 : sym = expr1->symtree->n.sym;
6859 : :
6860 : 43 : if (expr2->symtree)
6861 : : {
6862 : 42 : sym2 = expr2->symtree->n.sym;
6863 : 42 : as = (sym2->ts.type == BT_CLASS
6864 : 42 : && CLASS_DATA (sym2)) ? CLASS_DATA (sym2)->as : sym2->as;
6865 : : }
6866 : :
6867 : 43 : if (expr2->expr_type != EXPR_VARIABLE
6868 : 42 : || !(as && as->type == AS_ASSUMED_RANK))
6869 : : {
6870 : 1 : gfc_error ("The SELECT RANK selector at %C must be an assumed "
6871 : : "rank variable");
6872 : 1 : m = MATCH_ERROR;
6873 : 1 : goto cleanup;
6874 : : }
6875 : :
6876 : 42 : if (expr2->ts.type == BT_CLASS && CLASS_DATA (sym2))
6877 : : {
6878 : 12 : copy_ts_from_selector_to_associate (expr1, expr2);
6879 : :
6880 : 12 : sym->attr.flavor = FL_VARIABLE;
6881 : 12 : sym->attr.referenced = 1;
6882 : 12 : sym->attr.class_ok = 1;
6883 : 12 : CLASS_DATA (sym)->attr.allocatable = CLASS_DATA (sym2)->attr.allocatable;
6884 : 12 : CLASS_DATA (sym)->attr.pointer = CLASS_DATA (sym2)->attr.pointer;
6885 : 12 : CLASS_DATA (sym)->attr.target = CLASS_DATA (sym2)->attr.target;
6886 : 12 : sym->attr.pointer = 1;
6887 : : }
6888 : : else
6889 : : {
6890 : 30 : sym->ts = sym2->ts;
6891 : 30 : sym->as = gfc_copy_array_spec (sym2->as);
6892 : 30 : sym->attr.dimension = 1;
6893 : :
6894 : 30 : sym->attr.flavor = FL_VARIABLE;
6895 : 30 : sym->attr.referenced = 1;
6896 : 30 : sym->attr.class_ok = sym2->attr.class_ok;
6897 : 30 : sym->attr.allocatable = sym2->attr.allocatable;
6898 : 30 : sym->attr.pointer = sym2->attr.pointer;
6899 : 30 : sym->attr.target = sym2->attr.target;
6900 : : }
6901 : : }
6902 : : else
6903 : : {
6904 : 947 : m = gfc_match (" %e ", &expr1);
6905 : :
6906 : 947 : if (m != MATCH_YES)
6907 : : {
6908 : 1 : gfc_undo_symbols ();
6909 : 1 : std::swap (ns, gfc_current_ns);
6910 : 1 : gfc_free_namespace (ns);
6911 : 1 : return m;
6912 : : }
6913 : :
6914 : 946 : if (expr1->symtree)
6915 : : {
6916 : 945 : sym = expr1->symtree->n.sym;
6917 : 945 : as = (sym->ts.type == BT_CLASS
6918 : 945 : && CLASS_DATA (sym)) ? CLASS_DATA (sym)->as : sym->as;
6919 : : }
6920 : :
6921 : 946 : if (expr1->expr_type != EXPR_VARIABLE
6922 : 945 : || !(as && as->type == AS_ASSUMED_RANK))
6923 : : {
6924 : 3 : gfc_error("The SELECT RANK selector at %C must be an assumed "
6925 : : "rank variable");
6926 : 3 : m = MATCH_ERROR;
6927 : 3 : goto cleanup;
6928 : : }
6929 : : }
6930 : :
6931 : 985 : m = gfc_match (" )%t");
6932 : 985 : if (m != MATCH_YES)
6933 : : {
6934 : 0 : gfc_error ("parse error in SELECT RANK statement at %C");
6935 : 0 : goto cleanup;
6936 : : }
6937 : :
6938 : 985 : new_st.op = EXEC_SELECT_RANK;
6939 : 985 : new_st.expr1 = expr1;
6940 : 985 : new_st.expr2 = expr2;
6941 : 985 : new_st.ext.block.ns = gfc_current_ns;
6942 : :
6943 : 985 : select_type_push (expr1->symtree->n.sym);
6944 : 985 : gfc_current_ns = ns;
6945 : :
6946 : 985 : return MATCH_YES;
6947 : :
6948 : 4 : cleanup:
6949 : 4 : gfc_free_expr (expr1);
6950 : 4 : gfc_free_expr (expr2);
6951 : 4 : gfc_undo_symbols ();
6952 : 4 : std::swap (ns, gfc_current_ns);
6953 : 4 : gfc_free_namespace (ns);
6954 : 4 : return m;
6955 : : }
6956 : :
6957 : :
6958 : : /* Match a CASE statement. */
6959 : :
6960 : : match
6961 : 1482 : gfc_match_case (void)
6962 : : {
6963 : 1482 : gfc_case *c, *head, *tail;
6964 : 1482 : match m;
6965 : :
6966 : 1482 : head = tail = NULL;
6967 : :
6968 : 1482 : if (gfc_current_state () != COMP_SELECT)
6969 : : {
6970 : 3 : gfc_error ("Unexpected CASE statement at %C");
6971 : 3 : return MATCH_ERROR;
6972 : : }
6973 : :
6974 : 1479 : if (gfc_match ("% default") == MATCH_YES)
6975 : : {
6976 : 369 : m = match_case_eos ();
6977 : 369 : if (m == MATCH_NO)
6978 : 1 : goto syntax;
6979 : 368 : if (m == MATCH_ERROR)
6980 : 0 : goto cleanup;
6981 : :
6982 : 368 : new_st.op = EXEC_SELECT;
6983 : 368 : c = gfc_get_case ();
6984 : 368 : c->where = gfc_current_locus;
6985 : 368 : new_st.ext.block.case_list = c;
6986 : 368 : return MATCH_YES;
6987 : : }
6988 : :
6989 : 1110 : if (gfc_match_char ('(') != MATCH_YES)
6990 : 0 : goto syntax;
6991 : :
6992 : 1313 : for (;;)
6993 : : {
6994 : 1313 : if (match_case_selector (&c) == MATCH_ERROR)
6995 : 10 : goto cleanup;
6996 : :
6997 : 1303 : if (head == NULL)
6998 : 1100 : head = c;
6999 : : else
7000 : 203 : tail->next = c;
7001 : :
7002 : 1303 : tail = c;
7003 : :
7004 : 1303 : if (gfc_match_char (')') == MATCH_YES)
7005 : : break;
7006 : 203 : if (gfc_match_char (',') != MATCH_YES)
7007 : 0 : goto syntax;
7008 : : }
7009 : :
7010 : 1100 : m = match_case_eos ();
7011 : 1100 : if (m == MATCH_NO)
7012 : 2 : goto syntax;
7013 : 1098 : if (m == MATCH_ERROR)
7014 : 0 : goto cleanup;
7015 : :
7016 : 1098 : new_st.op = EXEC_SELECT;
7017 : 1098 : new_st.ext.block.case_list = head;
7018 : :
7019 : 1098 : return MATCH_YES;
7020 : :
7021 : 3 : syntax:
7022 : 3 : gfc_error ("Syntax error in CASE specification at %C");
7023 : :
7024 : 13 : cleanup:
7025 : 13 : gfc_free_case_list (head); /* new_st is cleaned up in parse.cc. */
7026 : 13 : return MATCH_ERROR;
7027 : : }
7028 : :
7029 : :
7030 : : /* Match a TYPE IS statement. */
7031 : :
7032 : : match
7033 : 2946 : gfc_match_type_is (void)
7034 : : {
7035 : 2946 : gfc_case *c = NULL;
7036 : 2946 : match m;
7037 : :
7038 : 2946 : if (gfc_current_state () != COMP_SELECT_TYPE)
7039 : : {
7040 : 1 : gfc_error ("Unexpected TYPE IS statement at %C");
7041 : 1 : return MATCH_ERROR;
7042 : : }
7043 : :
7044 : 2945 : if (gfc_match_char ('(') != MATCH_YES)
7045 : 1 : goto syntax;
7046 : :
7047 : 2944 : c = gfc_get_case ();
7048 : 2944 : c->where = gfc_current_locus;
7049 : :
7050 : 2944 : m = gfc_match_type_spec (&c->ts);
7051 : 2944 : if (m == MATCH_NO)
7052 : 2 : goto syntax;
7053 : 2942 : if (m == MATCH_ERROR)
7054 : 0 : goto cleanup;
7055 : :
7056 : 2942 : if (gfc_match_char (')') != MATCH_YES)
7057 : 0 : goto syntax;
7058 : :
7059 : 2942 : m = match_case_eos ();
7060 : 2942 : if (m == MATCH_NO)
7061 : 0 : goto syntax;
7062 : 2942 : if (m == MATCH_ERROR)
7063 : 0 : goto cleanup;
7064 : :
7065 : 2942 : new_st.op = EXEC_SELECT_TYPE;
7066 : 2942 : new_st.ext.block.case_list = c;
7067 : :
7068 : 2942 : if (c->ts.type == BT_DERIVED && c->ts.u.derived
7069 : 1753 : && (c->ts.u.derived->attr.sequence
7070 : 1753 : || c->ts.u.derived->attr.is_bind_c))
7071 : : {
7072 : 1 : gfc_error ("The type-spec shall not specify a sequence derived "
7073 : : "type or a type with the BIND attribute in SELECT "
7074 : : "TYPE at %C [F2003:C815]");
7075 : 1 : return MATCH_ERROR;
7076 : : }
7077 : :
7078 : 2941 : if (c->ts.type == BT_DERIVED
7079 : 1752 : && c->ts.u.derived && c->ts.u.derived->attr.pdt_type
7080 : 2969 : && gfc_spec_list_type (type_param_spec_list, c->ts.u.derived)
7081 : : != SPEC_ASSUMED)
7082 : : {
7083 : 1 : gfc_error ("All the LEN type parameters in the TYPE IS statement "
7084 : : "at %C must be ASSUMED");
7085 : 1 : return MATCH_ERROR;
7086 : : }
7087 : :
7088 : : /* Create temporary variable. */
7089 : 2940 : select_type_set_tmp (&c->ts);
7090 : :
7091 : 2940 : return MATCH_YES;
7092 : :
7093 : 3 : syntax:
7094 : 3 : gfc_error ("Syntax error in TYPE IS specification at %C");
7095 : :
7096 : 3 : cleanup:
7097 : 3 : if (c != NULL)
7098 : 2 : gfc_free_case_list (c); /* new_st is cleaned up in parse.cc. */
7099 : : return MATCH_ERROR;
7100 : : }
7101 : :
7102 : :
7103 : : /* Match a CLASS IS or CLASS DEFAULT statement. */
7104 : :
7105 : : match
7106 : 1658 : gfc_match_class_is (void)
7107 : : {
7108 : 1658 : gfc_case *c = NULL;
7109 : 1658 : match m;
7110 : :
7111 : 1658 : if (gfc_current_state () != COMP_SELECT_TYPE)
7112 : : return MATCH_NO;
7113 : :
7114 : 1632 : if (gfc_match ("% default") == MATCH_YES)
7115 : : {
7116 : 1338 : m = match_case_eos ();
7117 : 1338 : if (m == MATCH_NO)
7118 : 0 : goto syntax;
7119 : 1338 : if (m == MATCH_ERROR)
7120 : 0 : goto cleanup;
7121 : :
7122 : 1338 : new_st.op = EXEC_SELECT_TYPE;
7123 : 1338 : c = gfc_get_case ();
7124 : 1338 : c->where = gfc_current_locus;
7125 : 1338 : c->ts.type = BT_UNKNOWN;
7126 : 1338 : new_st.ext.block.case_list = c;
7127 : 1338 : select_type_set_tmp (NULL);
7128 : 1338 : return MATCH_YES;
7129 : : }
7130 : :
7131 : 294 : m = gfc_match ("% is");
7132 : 294 : if (m == MATCH_NO)
7133 : 0 : goto syntax;
7134 : 294 : if (m == MATCH_ERROR)
7135 : 0 : goto cleanup;
7136 : :
7137 : 294 : if (gfc_match_char ('(') != MATCH_YES)
7138 : 0 : goto syntax;
7139 : :
7140 : 294 : c = gfc_get_case ();
7141 : 294 : c->where = gfc_current_locus;
7142 : :
7143 : 294 : m = match_derived_type_spec (&c->ts);
7144 : 294 : if (m == MATCH_NO)
7145 : 4 : goto syntax;
7146 : 290 : if (m == MATCH_ERROR)
7147 : 0 : goto cleanup;
7148 : :
7149 : 290 : if (c->ts.type == BT_DERIVED)
7150 : 290 : c->ts.type = BT_CLASS;
7151 : :
7152 : 290 : if (gfc_match_char (')') != MATCH_YES)
7153 : 0 : goto syntax;
7154 : :
7155 : 290 : m = match_case_eos ();
7156 : 290 : if (m == MATCH_NO)
7157 : 1 : goto syntax;
7158 : 289 : if (m == MATCH_ERROR)
7159 : 1 : goto cleanup;
7160 : :
7161 : 288 : new_st.op = EXEC_SELECT_TYPE;
7162 : 288 : new_st.ext.block.case_list = c;
7163 : :
7164 : : /* Create temporary variable. */
7165 : 288 : select_type_set_tmp (&c->ts);
7166 : :
7167 : 288 : return MATCH_YES;
7168 : :
7169 : 5 : syntax:
7170 : 5 : gfc_error ("Syntax error in CLASS IS specification at %C");
7171 : :
7172 : 6 : cleanup:
7173 : 6 : if (c != NULL)
7174 : 6 : gfc_free_case_list (c); /* new_st is cleaned up in parse.cc. */
7175 : : return MATCH_ERROR;
7176 : : }
7177 : :
7178 : :
7179 : : /* Match a RANK statement. */
7180 : :
7181 : : match
7182 : 2239 : gfc_match_rank_is (void)
7183 : : {
7184 : 2239 : gfc_case *c = NULL;
7185 : 2239 : match m;
7186 : 2239 : int case_value;
7187 : :
7188 : 2239 : if (gfc_current_state () != COMP_SELECT_RANK)
7189 : : {
7190 : 5 : gfc_error ("Unexpected RANK statement at %C");
7191 : 5 : return MATCH_ERROR;
7192 : : }
7193 : :
7194 : 2234 : if (gfc_match ("% default") == MATCH_YES)
7195 : : {
7196 : 907 : m = match_case_eos ();
7197 : 907 : if (m == MATCH_NO)
7198 : 0 : goto syntax;
7199 : 907 : if (m == MATCH_ERROR)
7200 : 0 : goto cleanup;
7201 : :
7202 : 907 : new_st.op = EXEC_SELECT_RANK;
7203 : 907 : c = gfc_get_case ();
7204 : 907 : c->ts.type = BT_UNKNOWN;
7205 : 907 : c->where = gfc_current_locus;
7206 : 907 : new_st.ext.block.case_list = c;
7207 : 907 : select_type_stack->tmp = NULL;
7208 : 907 : return MATCH_YES;
7209 : : }
7210 : :
7211 : 1327 : if (gfc_match_char ('(') != MATCH_YES)
7212 : 0 : goto syntax;
7213 : :
7214 : 1327 : c = gfc_get_case ();
7215 : 1327 : c->where = gfc_current_locus;
7216 : 1327 : c->ts = select_type_stack->selector->ts;
7217 : :
7218 : 1327 : m = gfc_match_expr (&c->low);
7219 : 1327 : if (m == MATCH_NO)
7220 : : {
7221 : 33 : if (gfc_match_char ('*') == MATCH_YES)
7222 : 33 : c->low = gfc_get_int_expr (gfc_default_integer_kind,
7223 : : NULL, -1);
7224 : : else
7225 : 0 : goto syntax;
7226 : :
7227 : 33 : case_value = -1;
7228 : : }
7229 : 1294 : else if (m == MATCH_YES)
7230 : : {
7231 : : /* F2018: R1150 */
7232 : 1294 : if (c->low->expr_type != EXPR_CONSTANT
7233 : 1293 : || c->low->ts.type != BT_INTEGER
7234 : 1293 : || c->low->rank)
7235 : : {
7236 : 1 : gfc_error ("The SELECT RANK CASE expression at %C must be a "
7237 : : "scalar, integer constant");
7238 : 1 : goto cleanup;
7239 : : }
7240 : :
7241 : 1293 : case_value = (int) mpz_get_si (c->low->value.integer);
7242 : : /* F2018: C1151 */
7243 : 1293 : if ((case_value < 0) || (case_value > GFC_MAX_DIMENSIONS))
7244 : : {
7245 : 2 : gfc_error ("The value of the SELECT RANK CASE expression at "
7246 : : "%C must not be less than zero or greater than %d",
7247 : : GFC_MAX_DIMENSIONS);
7248 : 2 : goto cleanup;
7249 : : }
7250 : : }
7251 : : else
7252 : 0 : goto cleanup;
7253 : :
7254 : 1324 : if (gfc_match_char (')') != MATCH_YES)
7255 : 0 : goto syntax;
7256 : :
7257 : 1324 : m = match_case_eos ();
7258 : 1324 : if (m == MATCH_NO)
7259 : 0 : goto syntax;
7260 : 1324 : if (m == MATCH_ERROR)
7261 : 0 : goto cleanup;
7262 : :
7263 : 1324 : new_st.op = EXEC_SELECT_RANK;
7264 : 1324 : new_st.ext.block.case_list = c;
7265 : :
7266 : : /* Create temporary variable. Recycle the select type code. */
7267 : 1324 : select_rank_set_tmp (&c->ts, &case_value);
7268 : :
7269 : 1324 : return MATCH_YES;
7270 : :
7271 : 0 : syntax:
7272 : 0 : gfc_error ("Syntax error in RANK specification at %C");
7273 : :
7274 : 3 : cleanup:
7275 : 3 : if (c != NULL)
7276 : 3 : gfc_free_case_list (c); /* new_st is cleaned up in parse.cc. */
7277 : : return MATCH_ERROR;
7278 : : }
7279 : :
7280 : : /********************* WHERE subroutines ********************/
7281 : :
7282 : : /* Match the rest of a simple WHERE statement that follows an IF statement.
7283 : : */
7284 : :
7285 : : static match
7286 : 7 : match_simple_where (void)
7287 : : {
7288 : 7 : gfc_expr *expr;
7289 : 7 : gfc_code *c;
7290 : 7 : match m;
7291 : :
7292 : 7 : m = gfc_match (" ( %e )", &expr);
7293 : 7 : if (m != MATCH_YES)
7294 : : return m;
7295 : :
7296 : 7 : m = gfc_match_assignment ();
7297 : 7 : if (m == MATCH_NO)
7298 : 0 : goto syntax;
7299 : 7 : if (m == MATCH_ERROR)
7300 : 0 : goto cleanup;
7301 : :
7302 : 7 : if (gfc_match_eos () != MATCH_YES)
7303 : 0 : goto syntax;
7304 : :
7305 : 7 : c = gfc_get_code (EXEC_WHERE);
7306 : 7 : c->expr1 = expr;
7307 : :
7308 : 7 : c->next = XCNEW (gfc_code);
7309 : 7 : *c->next = new_st;
7310 : 7 : c->next->loc = gfc_current_locus;
7311 : 7 : gfc_clear_new_st ();
7312 : :
7313 : 7 : new_st.op = EXEC_WHERE;
7314 : 7 : new_st.block = c;
7315 : :
7316 : 7 : return MATCH_YES;
7317 : :
7318 : 0 : syntax:
7319 : 0 : gfc_syntax_error (ST_WHERE);
7320 : :
7321 : 0 : cleanup:
7322 : 0 : gfc_free_expr (expr);
7323 : 0 : return MATCH_ERROR;
7324 : : }
7325 : :
7326 : :
7327 : : /* Match a WHERE statement. */
7328 : :
7329 : : match
7330 : 455182 : gfc_match_where (gfc_statement *st)
7331 : : {
7332 : 455182 : gfc_expr *expr;
7333 : 455182 : match m0, m;
7334 : 455182 : gfc_code *c;
7335 : :
7336 : 455182 : m0 = gfc_match_label ();
7337 : 455182 : if (m0 == MATCH_ERROR)
7338 : : return m0;
7339 : :
7340 : 455174 : m = gfc_match (" where ( %e )", &expr);
7341 : 455174 : if (m != MATCH_YES)
7342 : : return m;
7343 : :
7344 : 453 : if (gfc_match_eos () == MATCH_YES)
7345 : : {
7346 : 376 : *st = ST_WHERE_BLOCK;
7347 : 376 : new_st.op = EXEC_WHERE;
7348 : 376 : new_st.expr1 = expr;
7349 : 376 : return MATCH_YES;
7350 : : }
7351 : :
7352 : 77 : m = gfc_match_assignment ();
7353 : 77 : if (m == MATCH_NO)
7354 : 0 : gfc_syntax_error (ST_WHERE);
7355 : :
7356 : 77 : if (m != MATCH_YES)
7357 : : {
7358 : 0 : gfc_free_expr (expr);
7359 : 0 : return MATCH_ERROR;
7360 : : }
7361 : :
7362 : : /* We've got a simple WHERE statement. */
7363 : 77 : *st = ST_WHERE;
7364 : 77 : c = gfc_get_code (EXEC_WHERE);
7365 : 77 : c->expr1 = expr;
7366 : :
7367 : : /* Put in the assignment. It will not be processed by add_statement, so we
7368 : : need to copy the location here. */
7369 : :
7370 : 77 : c->next = XCNEW (gfc_code);
7371 : 77 : *c->next = new_st;
7372 : 77 : c->next->loc = gfc_current_locus;
7373 : 77 : gfc_clear_new_st ();
7374 : :
7375 : 77 : new_st.op = EXEC_WHERE;
7376 : 77 : new_st.block = c;
7377 : :
7378 : 77 : return MATCH_YES;
7379 : : }
7380 : :
7381 : :
7382 : : /* Match an ELSEWHERE statement. We leave behind a WHERE node in
7383 : : new_st if successful. */
7384 : :
7385 : : match
7386 : 323 : gfc_match_elsewhere (void)
7387 : : {
7388 : 323 : char name[GFC_MAX_SYMBOL_LEN + 1];
7389 : 323 : gfc_expr *expr;
7390 : 323 : match m;
7391 : :
7392 : 323 : if (gfc_current_state () != COMP_WHERE)
7393 : : {
7394 : 0 : gfc_error ("ELSEWHERE statement at %C not enclosed in WHERE block");
7395 : 0 : return MATCH_ERROR;
7396 : : }
7397 : :
7398 : 323 : expr = NULL;
7399 : :
7400 : 323 : if (gfc_match_char ('(') == MATCH_YES)
7401 : : {
7402 : 184 : m = gfc_match_expr (&expr);
7403 : 184 : if (m == MATCH_NO)
7404 : 0 : goto syntax;
7405 : 184 : if (m == MATCH_ERROR)
7406 : : return MATCH_ERROR;
7407 : :
7408 : 184 : if (gfc_match_char (')') != MATCH_YES)
7409 : 0 : goto syntax;
7410 : : }
7411 : :
7412 : 323 : if (gfc_match_eos () != MATCH_YES)
7413 : : {
7414 : : /* Only makes sense if we have a where-construct-name. */
7415 : 2 : if (!gfc_current_block ())
7416 : : {
7417 : 1 : m = MATCH_ERROR;
7418 : 1 : goto cleanup;
7419 : : }
7420 : : /* Better be a name at this point. */
7421 : 1 : m = gfc_match_name (name);
7422 : 1 : if (m == MATCH_NO)
7423 : 0 : goto syntax;
7424 : 1 : if (m == MATCH_ERROR)
7425 : 0 : goto cleanup;
7426 : :
7427 : 1 : if (gfc_match_eos () != MATCH_YES)
7428 : 0 : goto syntax;
7429 : :
7430 : 1 : if (strcmp (name, gfc_current_block ()->name) != 0)
7431 : : {
7432 : 0 : gfc_error ("Label %qs at %C doesn't match WHERE label %qs",
7433 : : name, gfc_current_block ()->name);
7434 : 0 : goto cleanup;
7435 : : }
7436 : : }
7437 : :
7438 : 322 : new_st.op = EXEC_WHERE;
7439 : 322 : new_st.expr1 = expr;
7440 : 322 : return MATCH_YES;
7441 : :
7442 : 0 : syntax:
7443 : 0 : gfc_syntax_error (ST_ELSEWHERE);
7444 : :
7445 : 1 : cleanup:
7446 : 1 : gfc_free_expr (expr);
7447 : 1 : return MATCH_ERROR;
7448 : : }
|