1 /* OpenMP directive matching and resolving.
2    Copyright (C) 2005-2020 Free Software Foundation, Inc.
3    Contributed by Jakub Jelinek
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 "gfortran.h"
25 #include "arith.h"
26 #include "match.h"
27 #include "parse.h"
28 #include "diagnostic.h"
29 #include "gomp-constants.h"
30 
31 /* Match an end of OpenMP directive.  End of OpenMP directive is optional
32    whitespace, followed by '\n' or comment '!'.  */
33 
34 static match
gfc_match_omp_eos(void)35 gfc_match_omp_eos (void)
36 {
37   locus old_loc;
38   char c;
39 
40   old_loc = gfc_current_locus;
41   gfc_gobble_whitespace ();
42 
43   c = gfc_next_ascii_char ();
44   switch (c)
45     {
46     case '!':
47       do
48 	c = gfc_next_ascii_char ();
49       while (c != '\n');
50       /* Fall through */
51 
52     case '\n':
53       return MATCH_YES;
54     }
55 
56   gfc_current_locus = old_loc;
57   return MATCH_NO;
58 }
59 
60 match
gfc_match_omp_eos_error(void)61 gfc_match_omp_eos_error (void)
62 {
63   if (gfc_match_omp_eos() == MATCH_YES)
64     return MATCH_YES;
65 
66   gfc_error ("Unexpected junk at %C");
67   return MATCH_ERROR;
68 }
69 
70 
71 /* Free an omp_clauses structure.  */
72 
73 void
gfc_free_omp_clauses(gfc_omp_clauses * c)74 gfc_free_omp_clauses (gfc_omp_clauses *c)
75 {
76   int i;
77   if (c == NULL)
78     return;
79 
80   gfc_free_expr (c->if_expr);
81   gfc_free_expr (c->final_expr);
82   gfc_free_expr (c->num_threads);
83   gfc_free_expr (c->chunk_size);
84   gfc_free_expr (c->safelen_expr);
85   gfc_free_expr (c->simdlen_expr);
86   gfc_free_expr (c->num_teams);
87   gfc_free_expr (c->device);
88   gfc_free_expr (c->thread_limit);
89   gfc_free_expr (c->dist_chunk_size);
90   gfc_free_expr (c->grainsize);
91   gfc_free_expr (c->hint);
92   gfc_free_expr (c->num_tasks);
93   gfc_free_expr (c->priority);
94   for (i = 0; i < OMP_IF_LAST; i++)
95     gfc_free_expr (c->if_exprs[i]);
96   gfc_free_expr (c->async_expr);
97   gfc_free_expr (c->gang_num_expr);
98   gfc_free_expr (c->gang_static_expr);
99   gfc_free_expr (c->worker_expr);
100   gfc_free_expr (c->vector_expr);
101   gfc_free_expr (c->num_gangs_expr);
102   gfc_free_expr (c->num_workers_expr);
103   gfc_free_expr (c->vector_length_expr);
104   for (i = 0; i < OMP_LIST_NUM; i++)
105     gfc_free_omp_namelist (c->lists[i]);
106   gfc_free_expr_list (c->wait_list);
107   gfc_free_expr_list (c->tile_list);
108   free (CONST_CAST (char *, c->critical_name));
109   free (c);
110 }
111 
112 /* Free oacc_declare structures.  */
113 
114 void
gfc_free_oacc_declare_clauses(struct gfc_oacc_declare * oc)115 gfc_free_oacc_declare_clauses (struct gfc_oacc_declare *oc)
116 {
117   struct gfc_oacc_declare *decl = oc;
118 
119   do
120     {
121       struct gfc_oacc_declare *next;
122 
123       next = decl->next;
124       gfc_free_omp_clauses (decl->clauses);
125       free (decl);
126       decl = next;
127     }
128   while (decl);
129 }
130 
131 /* Free expression list. */
132 void
gfc_free_expr_list(gfc_expr_list * list)133 gfc_free_expr_list (gfc_expr_list *list)
134 {
135   gfc_expr_list *n;
136 
137   for (; list; list = n)
138     {
139       n = list->next;
140       free (list);
141     }
142 }
143 
144 /* Free an !$omp declare simd construct list.  */
145 
146 void
gfc_free_omp_declare_simd(gfc_omp_declare_simd * ods)147 gfc_free_omp_declare_simd (gfc_omp_declare_simd *ods)
148 {
149   if (ods)
150     {
151       gfc_free_omp_clauses (ods->clauses);
152       free (ods);
153     }
154 }
155 
156 void
gfc_free_omp_declare_simd_list(gfc_omp_declare_simd * list)157 gfc_free_omp_declare_simd_list (gfc_omp_declare_simd *list)
158 {
159   while (list)
160     {
161       gfc_omp_declare_simd *current = list;
162       list = list->next;
163       gfc_free_omp_declare_simd (current);
164     }
165 }
166 
167 /* Free an !$omp declare reduction.  */
168 
169 void
gfc_free_omp_udr(gfc_omp_udr * omp_udr)170 gfc_free_omp_udr (gfc_omp_udr *omp_udr)
171 {
172   if (omp_udr)
173     {
174       gfc_free_omp_udr (omp_udr->next);
175       gfc_free_namespace (omp_udr->combiner_ns);
176       if (omp_udr->initializer_ns)
177 	gfc_free_namespace (omp_udr->initializer_ns);
178       free (omp_udr);
179     }
180 }
181 
182 
183 static gfc_omp_udr *
gfc_find_omp_udr(gfc_namespace * ns,const char * name,gfc_typespec * ts)184 gfc_find_omp_udr (gfc_namespace *ns, const char *name, gfc_typespec *ts)
185 {
186   gfc_symtree *st;
187 
188   if (ns == NULL)
189     ns = gfc_current_ns;
190   do
191     {
192       gfc_omp_udr *omp_udr;
193 
194       st = gfc_find_symtree (ns->omp_udr_root, name);
195       if (st != NULL)
196 	{
197 	  for (omp_udr = st->n.omp_udr; omp_udr; omp_udr = omp_udr->next)
198 	    if (ts == NULL)
199 	      return omp_udr;
200 	    else if (gfc_compare_types (&omp_udr->ts, ts))
201 	      {
202 		if (ts->type == BT_CHARACTER)
203 		  {
204 		    if (omp_udr->ts.u.cl->length == NULL)
205 		      return omp_udr;
206 		    if (ts->u.cl->length == NULL)
207 		      continue;
208 		    if (gfc_compare_expr (omp_udr->ts.u.cl->length,
209 					  ts->u.cl->length,
210 					  INTRINSIC_EQ) != 0)
211 		      continue;
212 		  }
213 		return omp_udr;
214 	      }
215 	}
216 
217       /* Don't escape an interface block.  */
218       if (ns && !ns->has_import_set
219 	  && ns->proc_name && ns->proc_name->attr.if_source == IFSRC_IFBODY)
220 	break;
221 
222       ns = ns->parent;
223     }
224   while (ns != NULL);
225 
226   return NULL;
227 }
228 
229 
230 /* Match a variable/common block list and construct a namelist from it.  */
231 
232 static match
233 gfc_match_omp_variable_list (const char *str, gfc_omp_namelist **list,
234 			     bool allow_common, bool *end_colon = NULL,
235 			     gfc_omp_namelist ***headp = NULL,
236 			     bool allow_sections = false,
237 			     bool allow_derived = false)
238 {
239   gfc_omp_namelist *head, *tail, *p;
240   locus old_loc, cur_loc;
241   char n[GFC_MAX_SYMBOL_LEN+1];
242   gfc_symbol *sym;
243   match m;
244   gfc_symtree *st;
245 
246   head = tail = NULL;
247 
248   old_loc = gfc_current_locus;
249 
250   m = gfc_match (str);
251   if (m != MATCH_YES)
252     return m;
253 
254   for (;;)
255     {
256       cur_loc = gfc_current_locus;
257       m = gfc_match_symbol (&sym, 1);
258       switch (m)
259 	{
260 	case MATCH_YES:
261 	  gfc_expr *expr;
262 	  expr = NULL;
263 	  if ((allow_sections && gfc_peek_ascii_char () == '(')
264 	      || (allow_derived && gfc_peek_ascii_char () == '%'))
265 	    {
266 	      gfc_current_locus = cur_loc;
267 	      m = gfc_match_variable (&expr, 0);
268 	      switch (m)
269 		{
270 		case MATCH_ERROR:
271 		  goto cleanup;
272 		case MATCH_NO:
273 		  goto syntax;
274 		default:
275 		  break;
276 		}
277 	      if (gfc_is_coindexed (expr))
278 		{
279 		  gfc_error ("List item shall not be coindexed at %C");
280 		  goto cleanup;
281 		}
282 	    }
283 	  gfc_set_sym_referenced (sym);
284 	  p = gfc_get_omp_namelist ();
285 	  if (head == NULL)
286 	    head = tail = p;
287 	  else
288 	    {
289 	      tail->next = p;
290 	      tail = tail->next;
291 	    }
292 	  tail->sym = sym;
293 	  tail->expr = expr;
294 	  tail->where = cur_loc;
295 	  goto next_item;
296 	case MATCH_NO:
297 	  break;
298 	case MATCH_ERROR:
299 	  goto cleanup;
300 	}
301 
302       if (!allow_common)
303 	goto syntax;
304 
305       m = gfc_match (" / %n /", n);
306       if (m == MATCH_ERROR)
307 	goto cleanup;
308       if (m == MATCH_NO)
309 	goto syntax;
310 
311       st = gfc_find_symtree (gfc_current_ns->common_root, n);
312       if (st == NULL)
313 	{
314 	  gfc_error ("COMMON block /%s/ not found at %C", n);
315 	  goto cleanup;
316 	}
317       for (sym = st->n.common->head; sym; sym = sym->common_next)
318 	{
319 	  gfc_set_sym_referenced (sym);
320 	  p = gfc_get_omp_namelist ();
321 	  if (head == NULL)
322 	    head = tail = p;
323 	  else
324 	    {
325 	      tail->next = p;
326 	      tail = tail->next;
327 	    }
328 	  tail->sym = sym;
329 	  tail->where = cur_loc;
330 	}
331 
332     next_item:
333       if (end_colon && gfc_match_char (':') == MATCH_YES)
334 	{
335 	  *end_colon = true;
336 	  break;
337 	}
338       if (gfc_match_char (')') == MATCH_YES)
339 	break;
340       if (gfc_match_char (',') != MATCH_YES)
341 	goto syntax;
342     }
343 
344   while (*list)
345     list = &(*list)->next;
346 
347   *list = head;
348   if (headp)
349     *headp = list;
350   return MATCH_YES;
351 
352 syntax:
353   gfc_error ("Syntax error in OpenMP variable list at %C");
354 
355 cleanup:
356   gfc_free_omp_namelist (head);
357   gfc_current_locus = old_loc;
358   return MATCH_ERROR;
359 }
360 
361 /* Match a variable/procedure/common block list and construct a namelist
362    from it.  */
363 
364 static match
gfc_match_omp_to_link(const char * str,gfc_omp_namelist ** list)365 gfc_match_omp_to_link (const char *str, gfc_omp_namelist **list)
366 {
367   gfc_omp_namelist *head, *tail, *p;
368   locus old_loc, cur_loc;
369   char n[GFC_MAX_SYMBOL_LEN+1];
370   gfc_symbol *sym;
371   match m;
372   gfc_symtree *st;
373 
374   head = tail = NULL;
375 
376   old_loc = gfc_current_locus;
377 
378   m = gfc_match (str);
379   if (m != MATCH_YES)
380     return m;
381 
382   for (;;)
383     {
384       cur_loc = gfc_current_locus;
385       m = gfc_match_symbol (&sym, 1);
386       switch (m)
387 	{
388 	case MATCH_YES:
389 	  p = gfc_get_omp_namelist ();
390 	  if (head == NULL)
391 	    head = tail = p;
392 	  else
393 	    {
394 	      tail->next = p;
395 	      tail = tail->next;
396 	    }
397 	  tail->sym = sym;
398 	  tail->where = cur_loc;
399 	  goto next_item;
400 	case MATCH_NO:
401 	  break;
402 	case MATCH_ERROR:
403 	  goto cleanup;
404 	}
405 
406       m = gfc_match (" / %n /", n);
407       if (m == MATCH_ERROR)
408 	goto cleanup;
409       if (m == MATCH_NO)
410 	goto syntax;
411 
412       st = gfc_find_symtree (gfc_current_ns->common_root, n);
413       if (st == NULL)
414 	{
415 	  gfc_error ("COMMON block /%s/ not found at %C", n);
416 	  goto cleanup;
417 	}
418       p = gfc_get_omp_namelist ();
419       if (head == NULL)
420 	head = tail = p;
421       else
422 	{
423 	  tail->next = p;
424 	  tail = tail->next;
425 	}
426       tail->u.common = st->n.common;
427       tail->where = cur_loc;
428 
429     next_item:
430       if (gfc_match_char (')') == MATCH_YES)
431 	break;
432       if (gfc_match_char (',') != MATCH_YES)
433 	goto syntax;
434     }
435 
436   while (*list)
437     list = &(*list)->next;
438 
439   *list = head;
440   return MATCH_YES;
441 
442 syntax:
443   gfc_error ("Syntax error in OpenMP variable list at %C");
444 
445 cleanup:
446   gfc_free_omp_namelist (head);
447   gfc_current_locus = old_loc;
448   return MATCH_ERROR;
449 }
450 
451 /* Match depend(sink : ...) construct a namelist from it.  */
452 
453 static match
gfc_match_omp_depend_sink(gfc_omp_namelist ** list)454 gfc_match_omp_depend_sink (gfc_omp_namelist **list)
455 {
456   gfc_omp_namelist *head, *tail, *p;
457   locus old_loc, cur_loc;
458   gfc_symbol *sym;
459 
460   head = tail = NULL;
461 
462   old_loc = gfc_current_locus;
463 
464   for (;;)
465     {
466       cur_loc = gfc_current_locus;
467       switch (gfc_match_symbol (&sym, 1))
468 	{
469 	case MATCH_YES:
470 	  gfc_set_sym_referenced (sym);
471 	  p = gfc_get_omp_namelist ();
472 	  if (head == NULL)
473 	    {
474 	      head = tail = p;
475 	      head->u.depend_op = OMP_DEPEND_SINK_FIRST;
476 	    }
477 	  else
478 	    {
479 	      tail->next = p;
480 	      tail = tail->next;
481 	      tail->u.depend_op = OMP_DEPEND_SINK;
482 	    }
483 	  tail->sym = sym;
484 	  tail->expr = NULL;
485 	  tail->where = cur_loc;
486 	  if (gfc_match_char ('+') == MATCH_YES)
487 	    {
488 	      if (gfc_match_literal_constant (&tail->expr, 0) != MATCH_YES)
489 		goto syntax;
490 	    }
491 	  else if (gfc_match_char ('-') == MATCH_YES)
492 	    {
493 	      if (gfc_match_literal_constant (&tail->expr, 0) != MATCH_YES)
494 		goto syntax;
495 	      tail->expr = gfc_uminus (tail->expr);
496 	    }
497 	  break;
498 	case MATCH_NO:
499 	  goto syntax;
500 	case MATCH_ERROR:
501 	  goto cleanup;
502 	}
503 
504       if (gfc_match_char (')') == MATCH_YES)
505 	break;
506       if (gfc_match_char (',') != MATCH_YES)
507 	goto syntax;
508     }
509 
510   while (*list)
511     list = &(*list)->next;
512 
513   *list = head;
514   return MATCH_YES;
515 
516 syntax:
517   gfc_error ("Syntax error in OpenMP DEPEND SINK list at %C");
518 
519 cleanup:
520   gfc_free_omp_namelist (head);
521   gfc_current_locus = old_loc;
522   return MATCH_ERROR;
523 }
524 
525 static match
match_oacc_expr_list(const char * str,gfc_expr_list ** list,bool allow_asterisk)526 match_oacc_expr_list (const char *str, gfc_expr_list **list,
527 		      bool allow_asterisk)
528 {
529   gfc_expr_list *head, *tail, *p;
530   locus old_loc;
531   gfc_expr *expr;
532   match m;
533 
534   head = tail = NULL;
535 
536   old_loc = gfc_current_locus;
537 
538   m = gfc_match (str);
539   if (m != MATCH_YES)
540     return m;
541 
542   for (;;)
543     {
544       m = gfc_match_expr (&expr);
545       if (m == MATCH_YES || allow_asterisk)
546 	{
547 	  p = gfc_get_expr_list ();
548 	  if (head == NULL)
549 	    head = tail = p;
550 	  else
551 	    {
552 	      tail->next = p;
553 	      tail = tail->next;
554 	    }
555 	  if (m == MATCH_YES)
556 	    tail->expr = expr;
557 	  else if (gfc_match (" *") != MATCH_YES)
558 	    goto syntax;
559 	  goto next_item;
560 	}
561       if (m == MATCH_ERROR)
562 	goto cleanup;
563       goto syntax;
564 
565     next_item:
566       if (gfc_match_char (')') == MATCH_YES)
567 	break;
568       if (gfc_match_char (',') != MATCH_YES)
569 	goto syntax;
570     }
571 
572   while (*list)
573     list = &(*list)->next;
574 
575   *list = head;
576   return MATCH_YES;
577 
578 syntax:
579   gfc_error ("Syntax error in OpenACC expression list at %C");
580 
581 cleanup:
582   gfc_free_expr_list (head);
583   gfc_current_locus = old_loc;
584   return MATCH_ERROR;
585 }
586 
587 static match
match_oacc_clause_gwv(gfc_omp_clauses * cp,unsigned gwv)588 match_oacc_clause_gwv (gfc_omp_clauses *cp, unsigned gwv)
589 {
590   match ret = MATCH_YES;
591 
592   if (gfc_match (" ( ") != MATCH_YES)
593     return MATCH_NO;
594 
595   if (gwv == GOMP_DIM_GANG)
596     {
597         /* The gang clause accepts two optional arguments, num and static.
598 	 The num argument may either be explicit (num: <val>) or
599 	 implicit without (<val> without num:).  */
600 
601       while (ret == MATCH_YES)
602 	{
603 	  if (gfc_match (" static :") == MATCH_YES)
604 	    {
605 	      if (cp->gang_static)
606 		return MATCH_ERROR;
607 	      else
608 		cp->gang_static = true;
609 	      if (gfc_match_char ('*') == MATCH_YES)
610 		cp->gang_static_expr = NULL;
611 	      else if (gfc_match (" %e ", &cp->gang_static_expr) != MATCH_YES)
612 		return MATCH_ERROR;
613 	    }
614 	  else
615 	    {
616 	      if (cp->gang_num_expr)
617 		return MATCH_ERROR;
618 
619 	      /* The 'num' argument is optional.  */
620 	      gfc_match (" num :");
621 
622 	      if (gfc_match (" %e ", &cp->gang_num_expr) != MATCH_YES)
623 		return MATCH_ERROR;
624 	    }
625 
626 	  ret = gfc_match (" , ");
627 	}
628     }
629   else if (gwv == GOMP_DIM_WORKER)
630     {
631       /* The 'num' argument is optional.  */
632       gfc_match (" num :");
633 
634       if (gfc_match (" %e ", &cp->worker_expr) != MATCH_YES)
635 	return MATCH_ERROR;
636     }
637   else if (gwv == GOMP_DIM_VECTOR)
638     {
639       /* The 'length' argument is optional.  */
640       gfc_match (" length :");
641 
642       if (gfc_match (" %e ", &cp->vector_expr) != MATCH_YES)
643 	return MATCH_ERROR;
644     }
645   else
646     gfc_fatal_error ("Unexpected OpenACC parallelism.");
647 
648   return gfc_match (" )");
649 }
650 
651 static match
gfc_match_oacc_clause_link(const char * str,gfc_omp_namelist ** list)652 gfc_match_oacc_clause_link (const char *str, gfc_omp_namelist **list)
653 {
654   gfc_omp_namelist *head = NULL;
655   gfc_omp_namelist *tail, *p;
656   locus old_loc;
657   char n[GFC_MAX_SYMBOL_LEN+1];
658   gfc_symbol *sym;
659   match m;
660   gfc_symtree *st;
661 
662   old_loc = gfc_current_locus;
663 
664   m = gfc_match (str);
665   if (m != MATCH_YES)
666     return m;
667 
668   m = gfc_match (" (");
669 
670   for (;;)
671     {
672       m = gfc_match_symbol (&sym, 0);
673       switch (m)
674 	{
675 	case MATCH_YES:
676 	  if (sym->attr.in_common)
677 	    {
678 	      gfc_error_now ("Variable at %C is an element of a COMMON block");
679 	      goto cleanup;
680 	    }
681 	  gfc_set_sym_referenced (sym);
682 	  p = gfc_get_omp_namelist ();
683 	  if (head == NULL)
684 	    head = tail = p;
685 	  else
686 	    {
687 	      tail->next = p;
688 	      tail = tail->next;
689 	    }
690 	  tail->sym = sym;
691 	  tail->expr = NULL;
692 	  tail->where = gfc_current_locus;
693 	  goto next_item;
694 	case MATCH_NO:
695 	  break;
696 
697 	case MATCH_ERROR:
698 	  goto cleanup;
699 	}
700 
701       m = gfc_match (" / %n /", n);
702       if (m == MATCH_ERROR)
703 	goto cleanup;
704       if (m == MATCH_NO || n[0] == '\0')
705 	goto syntax;
706 
707       st = gfc_find_symtree (gfc_current_ns->common_root, n);
708       if (st == NULL)
709 	{
710 	  gfc_error ("COMMON block /%s/ not found at %C", n);
711 	  goto cleanup;
712 	}
713 
714       for (sym = st->n.common->head; sym; sym = sym->common_next)
715 	{
716 	  gfc_set_sym_referenced (sym);
717 	  p = gfc_get_omp_namelist ();
718 	  if (head == NULL)
719 	    head = tail = p;
720 	  else
721 	    {
722 	      tail->next = p;
723 	      tail = tail->next;
724 	    }
725 	  tail->sym = sym;
726 	  tail->where = gfc_current_locus;
727 	}
728 
729     next_item:
730       if (gfc_match_char (')') == MATCH_YES)
731 	break;
732       if (gfc_match_char (',') != MATCH_YES)
733 	goto syntax;
734     }
735 
736   if (gfc_match_omp_eos () != MATCH_YES)
737     {
738       gfc_error ("Unexpected junk after !$ACC DECLARE at %C");
739       goto cleanup;
740     }
741 
742   while (*list)
743     list = &(*list)->next;
744   *list = head;
745   return MATCH_YES;
746 
747 syntax:
748   gfc_error ("Syntax error in !$ACC DECLARE list at %C");
749 
750 cleanup:
751   gfc_current_locus = old_loc;
752   return MATCH_ERROR;
753 }
754 
755 /* OpenMP 4.5 clauses.  */
756 enum omp_mask1
757 {
758   OMP_CLAUSE_PRIVATE,
759   OMP_CLAUSE_FIRSTPRIVATE,
760   OMP_CLAUSE_LASTPRIVATE,
761   OMP_CLAUSE_COPYPRIVATE,
762   OMP_CLAUSE_SHARED,
763   OMP_CLAUSE_COPYIN,
764   OMP_CLAUSE_REDUCTION,
765   OMP_CLAUSE_IF,
766   OMP_CLAUSE_NUM_THREADS,
767   OMP_CLAUSE_SCHEDULE,
768   OMP_CLAUSE_DEFAULT,
769   OMP_CLAUSE_ORDERED,
770   OMP_CLAUSE_COLLAPSE,
771   OMP_CLAUSE_UNTIED,
772   OMP_CLAUSE_FINAL,
773   OMP_CLAUSE_MERGEABLE,
774   OMP_CLAUSE_ALIGNED,
775   OMP_CLAUSE_DEPEND,
776   OMP_CLAUSE_INBRANCH,
777   OMP_CLAUSE_LINEAR,
778   OMP_CLAUSE_NOTINBRANCH,
779   OMP_CLAUSE_PROC_BIND,
780   OMP_CLAUSE_SAFELEN,
781   OMP_CLAUSE_SIMDLEN,
782   OMP_CLAUSE_UNIFORM,
783   OMP_CLAUSE_DEVICE,
784   OMP_CLAUSE_MAP,
785   OMP_CLAUSE_TO,
786   OMP_CLAUSE_FROM,
787   OMP_CLAUSE_NUM_TEAMS,
788   OMP_CLAUSE_THREAD_LIMIT,
789   OMP_CLAUSE_DIST_SCHEDULE,
790   OMP_CLAUSE_DEFAULTMAP,
791   OMP_CLAUSE_GRAINSIZE,
792   OMP_CLAUSE_HINT,
793   OMP_CLAUSE_IS_DEVICE_PTR,
794   OMP_CLAUSE_LINK,
795   OMP_CLAUSE_NOGROUP,
796   OMP_CLAUSE_NUM_TASKS,
797   OMP_CLAUSE_PRIORITY,
798   OMP_CLAUSE_SIMD,
799   OMP_CLAUSE_THREADS,
800   OMP_CLAUSE_USE_DEVICE_PTR,
801   OMP_CLAUSE_USE_DEVICE_ADDR,  /* Actually, OpenMP 5.0.  */
802   OMP_CLAUSE_NOWAIT,
803   /* This must come last.  */
804   OMP_MASK1_LAST
805 };
806 
807 /* OpenACC 2.0+ specific clauses. */
808 enum omp_mask2
809 {
810   OMP_CLAUSE_ASYNC,
811   OMP_CLAUSE_NUM_GANGS,
812   OMP_CLAUSE_NUM_WORKERS,
813   OMP_CLAUSE_VECTOR_LENGTH,
814   OMP_CLAUSE_COPY,
815   OMP_CLAUSE_COPYOUT,
816   OMP_CLAUSE_CREATE,
817   OMP_CLAUSE_NO_CREATE,
818   OMP_CLAUSE_PRESENT,
819   OMP_CLAUSE_DEVICEPTR,
820   OMP_CLAUSE_GANG,
821   OMP_CLAUSE_WORKER,
822   OMP_CLAUSE_VECTOR,
823   OMP_CLAUSE_SEQ,
824   OMP_CLAUSE_INDEPENDENT,
825   OMP_CLAUSE_USE_DEVICE,
826   OMP_CLAUSE_DEVICE_RESIDENT,
827   OMP_CLAUSE_HOST_SELF,
828   OMP_CLAUSE_WAIT,
829   OMP_CLAUSE_DELETE,
830   OMP_CLAUSE_AUTO,
831   OMP_CLAUSE_TILE,
832   OMP_CLAUSE_IF_PRESENT,
833   OMP_CLAUSE_FINALIZE,
834   OMP_CLAUSE_ATTACH,
835   OMP_CLAUSE_DETACH,
836   /* This must come last.  */
837   OMP_MASK2_LAST
838 };
839 
840 struct omp_inv_mask;
841 
842 /* Customized bitset for up to 128-bits.
843    The two enums above provide bit numbers to use, and which of the
844    two enums it is determines which of the two mask fields is used.
845    Supported operations are defining a mask, like:
846    #define XXX_CLAUSES \
847      (omp_mask (OMP_CLAUSE_XXX) | OMP_CLAUSE_YYY | OMP_CLAUSE_ZZZ)
848    oring such bitsets together or removing selected bits:
849    (XXX_CLAUSES | YYY_CLAUSES) & ~(omp_mask (OMP_CLAUSE_VVV))
850    and testing individual bits:
851    if (mask & OMP_CLAUSE_UUU)  */
852 
853 struct omp_mask {
854   const uint64_t mask1;
855   const uint64_t mask2;
856   inline omp_mask ();
857   inline omp_mask (omp_mask1);
858   inline omp_mask (omp_mask2);
859   inline omp_mask (uint64_t, uint64_t);
860   inline omp_mask operator| (omp_mask1) const;
861   inline omp_mask operator| (omp_mask2) const;
862   inline omp_mask operator| (omp_mask) const;
863   inline omp_mask operator& (const omp_inv_mask &) const;
864   inline bool operator& (omp_mask1) const;
865   inline bool operator& (omp_mask2) const;
866   inline omp_inv_mask operator~ () const;
867 };
868 
869 struct omp_inv_mask : public omp_mask {
870   inline omp_inv_mask (const omp_mask &);
871 };
872 
omp_mask()873 omp_mask::omp_mask () : mask1 (0), mask2 (0)
874 {
875 }
876 
omp_mask(omp_mask1 m)877 omp_mask::omp_mask (omp_mask1 m) : mask1 (((uint64_t) 1) << m), mask2 (0)
878 {
879 }
880 
omp_mask(omp_mask2 m)881 omp_mask::omp_mask (omp_mask2 m) : mask1 (0), mask2 (((uint64_t) 1) << m)
882 {
883 }
884 
omp_mask(uint64_t m1,uint64_t m2)885 omp_mask::omp_mask (uint64_t m1, uint64_t m2) : mask1 (m1), mask2 (m2)
886 {
887 }
888 
889 omp_mask
890 omp_mask::operator| (omp_mask1 m) const
891 {
892   return omp_mask (mask1 | (((uint64_t) 1) << m), mask2);
893 }
894 
895 omp_mask
896 omp_mask::operator| (omp_mask2 m) const
897 {
898   return omp_mask (mask1, mask2 | (((uint64_t) 1) << m));
899 }
900 
901 omp_mask
902 omp_mask::operator| (omp_mask m) const
903 {
904   return omp_mask (mask1 | m.mask1, mask2 | m.mask2);
905 }
906 
907 omp_mask
908 omp_mask::operator& (const omp_inv_mask &m) const
909 {
910   return omp_mask (mask1 & ~m.mask1, mask2 & ~m.mask2);
911 }
912 
913 bool
914 omp_mask::operator& (omp_mask1 m) const
915 {
916   return (mask1 & (((uint64_t) 1) << m)) != 0;
917 }
918 
919 bool
920 omp_mask::operator& (omp_mask2 m) const
921 {
922   return (mask2 & (((uint64_t) 1) << m)) != 0;
923 }
924 
925 omp_inv_mask
926 omp_mask::operator~ () const
927 {
928   return omp_inv_mask (*this);
929 }
930 
omp_inv_mask(const omp_mask & m)931 omp_inv_mask::omp_inv_mask (const omp_mask &m) : omp_mask (m)
932 {
933 }
934 
935 /* Helper function for OpenACC and OpenMP clauses involving memory
936    mapping.  */
937 
938 static bool
gfc_match_omp_map_clause(gfc_omp_namelist ** list,gfc_omp_map_op map_op,bool allow_common,bool allow_derived)939 gfc_match_omp_map_clause (gfc_omp_namelist **list, gfc_omp_map_op map_op,
940 			  bool allow_common, bool allow_derived)
941 {
942   gfc_omp_namelist **head = NULL;
943   if (gfc_match_omp_variable_list ("", list, allow_common, NULL, &head, true,
944 				   allow_derived)
945       == MATCH_YES)
946     {
947       gfc_omp_namelist *n;
948       for (n = *head; n; n = n->next)
949 	n->u.map_op = map_op;
950       return true;
951     }
952 
953   return false;
954 }
955 
956 /* Match OpenMP and OpenACC directive clauses. MASK is a bitmask of
957    clauses that are allowed for a particular directive.  */
958 
959 static match
960 gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
961 		       bool first = true, bool needs_space = true,
962 		       bool openacc = false)
963 {
964   gfc_omp_clauses *c = gfc_get_omp_clauses ();
965   locus old_loc;
966   /* Determine whether we're dealing with an OpenACC directive that permits
967      derived type member accesses.  This in particular disallows
968      "!$acc declare" from using such accesses, because it's not clear if/how
969      that should work.  */
970   bool allow_derived = (openacc
971 			&& ((mask & OMP_CLAUSE_ATTACH)
972 			    || (mask & OMP_CLAUSE_DETACH)
973 			    || (mask & OMP_CLAUSE_HOST_SELF)));
974 
975   gcc_checking_assert (OMP_MASK1_LAST <= 64 && OMP_MASK2_LAST <= 64);
976   *cp = NULL;
977   while (1)
978     {
979       if ((first || gfc_match_char (',') != MATCH_YES)
980 	  && (needs_space && gfc_match_space () != MATCH_YES))
981 	break;
982       needs_space = false;
983       first = false;
984       gfc_gobble_whitespace ();
985       bool end_colon;
986       gfc_omp_namelist **head;
987       old_loc = gfc_current_locus;
988       char pc = gfc_peek_ascii_char ();
989       switch (pc)
990 	{
991 	case 'a':
992 	  end_colon = false;
993 	  head = NULL;
994 	  if ((mask & OMP_CLAUSE_ALIGNED)
995 	      && gfc_match_omp_variable_list ("aligned (",
996 					      &c->lists[OMP_LIST_ALIGNED],
997 					      false, &end_colon,
998 					      &head) == MATCH_YES)
999 	    {
1000 	      gfc_expr *alignment = NULL;
1001 	      gfc_omp_namelist *n;
1002 
1003 	      if (end_colon && gfc_match (" %e )", &alignment) != MATCH_YES)
1004 		{
1005 		  gfc_free_omp_namelist (*head);
1006 		  gfc_current_locus = old_loc;
1007 		  *head = NULL;
1008 		  break;
1009 		}
1010 	      for (n = *head; n; n = n->next)
1011 		if (n->next && alignment)
1012 		  n->expr = gfc_copy_expr (alignment);
1013 		else
1014 		  n->expr = alignment;
1015 	      continue;
1016 	    }
1017 	  if ((mask & OMP_CLAUSE_ASYNC)
1018 	      && !c->async
1019 	      && gfc_match ("async") == MATCH_YES)
1020 	    {
1021 	      c->async = true;
1022 	      match m = gfc_match (" ( %e )", &c->async_expr);
1023 	      if (m == MATCH_ERROR)
1024 		{
1025 		  gfc_current_locus = old_loc;
1026 		  break;
1027 		}
1028 	      else if (m == MATCH_NO)
1029 		{
1030 		  c->async_expr
1031 		    = gfc_get_constant_expr (BT_INTEGER,
1032 					     gfc_default_integer_kind,
1033 					     &gfc_current_locus);
1034 		  mpz_set_si (c->async_expr->value.integer, GOMP_ASYNC_NOVAL);
1035 		  needs_space = true;
1036 		}
1037 	      continue;
1038 	    }
1039 	  if ((mask & OMP_CLAUSE_AUTO)
1040 	      && !c->par_auto
1041 	      && gfc_match ("auto") == MATCH_YES)
1042 	    {
1043 	      c->par_auto = true;
1044 	      needs_space = true;
1045 	      continue;
1046 	    }
1047 	  if ((mask & OMP_CLAUSE_ATTACH)
1048 	      && gfc_match ("attach ( ") == MATCH_YES
1049 	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1050 					   OMP_MAP_ATTACH, false,
1051 					   allow_derived))
1052 	    continue;
1053 	  break;
1054 	case 'c':
1055 	  if ((mask & OMP_CLAUSE_COLLAPSE)
1056 	      && !c->collapse)
1057 	    {
1058 	      gfc_expr *cexpr = NULL;
1059 	      match m = gfc_match ("collapse ( %e )", &cexpr);
1060 
1061 	      if (m == MATCH_YES)
1062 		{
1063 		  int collapse;
1064 		  if (gfc_extract_int (cexpr, &collapse, -1))
1065 		    collapse = 1;
1066 		  else if (collapse <= 0)
1067 		    {
1068 		      gfc_error_now ("COLLAPSE clause argument not"
1069 				     " constant positive integer at %C");
1070 		      collapse = 1;
1071 		    }
1072 		  c->collapse = collapse;
1073 		  gfc_free_expr (cexpr);
1074 		  continue;
1075 		}
1076 	    }
1077 	  if ((mask & OMP_CLAUSE_COPY)
1078 	      && gfc_match ("copy ( ") == MATCH_YES
1079 	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1080 					   OMP_MAP_TOFROM, true,
1081 					   allow_derived))
1082 	    continue;
1083 	  if (mask & OMP_CLAUSE_COPYIN)
1084 	    {
1085 	      if (openacc)
1086 		{
1087 		  if (gfc_match ("copyin ( ") == MATCH_YES
1088 		      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1089 						   OMP_MAP_TO, true,
1090 						   allow_derived))
1091 		    continue;
1092 		}
1093 	      else if (gfc_match_omp_variable_list ("copyin (",
1094 						    &c->lists[OMP_LIST_COPYIN],
1095 						    true) == MATCH_YES)
1096 		continue;
1097 	    }
1098 	  if ((mask & OMP_CLAUSE_COPYOUT)
1099 	      && gfc_match ("copyout ( ") == MATCH_YES
1100 	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1101 					   OMP_MAP_FROM, true, allow_derived))
1102 	    continue;
1103 	  if ((mask & OMP_CLAUSE_COPYPRIVATE)
1104 	      && gfc_match_omp_variable_list ("copyprivate (",
1105 					      &c->lists[OMP_LIST_COPYPRIVATE],
1106 					      true) == MATCH_YES)
1107 	    continue;
1108 	  if ((mask & OMP_CLAUSE_CREATE)
1109 	      && gfc_match ("create ( ") == MATCH_YES
1110 	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1111 					   OMP_MAP_ALLOC, true, allow_derived))
1112 	    continue;
1113 	  break;
1114 	case 'd':
1115 	  if ((mask & OMP_CLAUSE_DEFAULT)
1116 	      && c->default_sharing == OMP_DEFAULT_UNKNOWN)
1117 	    {
1118 	      if (gfc_match ("default ( none )") == MATCH_YES)
1119 		c->default_sharing = OMP_DEFAULT_NONE;
1120 	      else if (openacc)
1121 		{
1122 		  if (gfc_match ("default ( present )") == MATCH_YES)
1123 		    c->default_sharing = OMP_DEFAULT_PRESENT;
1124 		}
1125 	      else
1126 		{
1127 		  if (gfc_match ("default ( firstprivate )") == MATCH_YES)
1128 		    c->default_sharing = OMP_DEFAULT_FIRSTPRIVATE;
1129 		  else if (gfc_match ("default ( private )") == MATCH_YES)
1130 		    c->default_sharing = OMP_DEFAULT_PRIVATE;
1131 		  else if (gfc_match ("default ( shared )") == MATCH_YES)
1132 		    c->default_sharing = OMP_DEFAULT_SHARED;
1133 		}
1134 	      if (c->default_sharing != OMP_DEFAULT_UNKNOWN)
1135 		continue;
1136 	    }
1137 	  if ((mask & OMP_CLAUSE_DEFAULTMAP)
1138 	      && !c->defaultmap
1139 	      && gfc_match ("defaultmap ( tofrom : scalar )") == MATCH_YES)
1140 	    {
1141 	      c->defaultmap = true;
1142 	      continue;
1143 	    }
1144 	  if ((mask & OMP_CLAUSE_DELETE)
1145 	      && gfc_match ("delete ( ") == MATCH_YES
1146 	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1147 					   OMP_MAP_RELEASE, true,
1148 					   allow_derived))
1149 	    continue;
1150 	  if ((mask & OMP_CLAUSE_DEPEND)
1151 	      && gfc_match ("depend ( ") == MATCH_YES)
1152 	    {
1153 	      match m = MATCH_YES;
1154 	      gfc_omp_depend_op depend_op = OMP_DEPEND_OUT;
1155 	      if (gfc_match ("inout") == MATCH_YES)
1156 		depend_op = OMP_DEPEND_INOUT;
1157 	      else if (gfc_match ("in") == MATCH_YES)
1158 		depend_op = OMP_DEPEND_IN;
1159 	      else if (gfc_match ("out") == MATCH_YES)
1160 		depend_op = OMP_DEPEND_OUT;
1161 	      else if (!c->depend_source
1162 		       && gfc_match ("source )") == MATCH_YES)
1163 		{
1164 		  c->depend_source = true;
1165 		  continue;
1166 		}
1167 	      else if (gfc_match ("sink : ") == MATCH_YES)
1168 		{
1169 		  if (gfc_match_omp_depend_sink (&c->lists[OMP_LIST_DEPEND])
1170 		      == MATCH_YES)
1171 		    continue;
1172 		  m = MATCH_NO;
1173 		}
1174 	      else
1175 		m = MATCH_NO;
1176 	      head = NULL;
1177 	      if (m == MATCH_YES
1178 		  && gfc_match_omp_variable_list (" : ",
1179 						  &c->lists[OMP_LIST_DEPEND],
1180 						  false, NULL, &head,
1181 						  true) == MATCH_YES)
1182 		{
1183 		  gfc_omp_namelist *n;
1184 		  for (n = *head; n; n = n->next)
1185 		    n->u.depend_op = depend_op;
1186 		  continue;
1187 		}
1188 	      else
1189 		gfc_current_locus = old_loc;
1190 	    }
1191 	  if ((mask & OMP_CLAUSE_DETACH)
1192 	      && gfc_match ("detach ( ") == MATCH_YES
1193 	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1194 					   OMP_MAP_DETACH, false,
1195 					   allow_derived))
1196 	    continue;
1197 	  if ((mask & OMP_CLAUSE_DEVICE)
1198 	      && !openacc
1199 	      && c->device == NULL
1200 	      && gfc_match ("device ( %e )", &c->device) == MATCH_YES)
1201 	    continue;
1202 	  if ((mask & OMP_CLAUSE_DEVICE)
1203 	      && openacc
1204 	      && gfc_match ("device ( ") == MATCH_YES
1205 	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1206 					   OMP_MAP_FORCE_TO, true,
1207 					   allow_derived))
1208 	    continue;
1209 	  if ((mask & OMP_CLAUSE_DEVICEPTR)
1210 	      && gfc_match ("deviceptr ( ") == MATCH_YES
1211 	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1212 					   OMP_MAP_FORCE_DEVICEPTR, false,
1213 					   allow_derived))
1214 	    continue;
1215 	  if ((mask & OMP_CLAUSE_DEVICE_RESIDENT)
1216 	      && gfc_match_omp_variable_list
1217 		   ("device_resident (",
1218 		    &c->lists[OMP_LIST_DEVICE_RESIDENT], true) == MATCH_YES)
1219 	    continue;
1220 	  if ((mask & OMP_CLAUSE_DIST_SCHEDULE)
1221 	      && c->dist_sched_kind == OMP_SCHED_NONE
1222 	      && gfc_match ("dist_schedule ( static") == MATCH_YES)
1223 	    {
1224 	      match m = MATCH_NO;
1225 	      c->dist_sched_kind = OMP_SCHED_STATIC;
1226 	      m = gfc_match (" , %e )", &c->dist_chunk_size);
1227 	      if (m != MATCH_YES)
1228 		m = gfc_match_char (')');
1229 	      if (m != MATCH_YES)
1230 		{
1231 		  c->dist_sched_kind = OMP_SCHED_NONE;
1232 		  gfc_current_locus = old_loc;
1233 		}
1234 	      else
1235 		continue;
1236 	    }
1237 	  break;
1238 	case 'f':
1239 	  if ((mask & OMP_CLAUSE_FINAL)
1240 	      && c->final_expr == NULL
1241 	      && gfc_match ("final ( %e )", &c->final_expr) == MATCH_YES)
1242 	    continue;
1243 	  if ((mask & OMP_CLAUSE_FINALIZE)
1244 	      && !c->finalize
1245 	      && gfc_match ("finalize") == MATCH_YES)
1246 	    {
1247 	      c->finalize = true;
1248 	      needs_space = true;
1249 	      continue;
1250 	    }
1251 	  if ((mask & OMP_CLAUSE_FIRSTPRIVATE)
1252 	      && gfc_match_omp_variable_list ("firstprivate (",
1253 					      &c->lists[OMP_LIST_FIRSTPRIVATE],
1254 					      true) == MATCH_YES)
1255 	    continue;
1256 	  if ((mask & OMP_CLAUSE_FROM)
1257 	      && gfc_match_omp_variable_list ("from (",
1258 					      &c->lists[OMP_LIST_FROM], false,
1259 					      NULL, &head, true) == MATCH_YES)
1260 	    continue;
1261 	  break;
1262 	case 'g':
1263 	  if ((mask & OMP_CLAUSE_GANG)
1264 	      && !c->gang
1265 	      && gfc_match ("gang") == MATCH_YES)
1266 	    {
1267 	      c->gang = true;
1268 	      match m = match_oacc_clause_gwv (c, GOMP_DIM_GANG);
1269 	      if (m == MATCH_ERROR)
1270 		{
1271 		  gfc_current_locus = old_loc;
1272 		  break;
1273 		}
1274 	      else if (m == MATCH_NO)
1275 		needs_space = true;
1276 	      continue;
1277 	    }
1278 	  if ((mask & OMP_CLAUSE_GRAINSIZE)
1279 	      && c->grainsize == NULL
1280 	      && gfc_match ("grainsize ( %e )", &c->grainsize) == MATCH_YES)
1281 	    continue;
1282 	  break;
1283 	case 'h':
1284 	  if ((mask & OMP_CLAUSE_HINT)
1285 	      && c->hint == NULL
1286 	      && gfc_match ("hint ( %e )", &c->hint) == MATCH_YES)
1287 	    continue;
1288 	  if ((mask & OMP_CLAUSE_HOST_SELF)
1289 	      && gfc_match ("host ( ") == MATCH_YES
1290 	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1291 					   OMP_MAP_FORCE_FROM, true,
1292 					   allow_derived))
1293 	    continue;
1294 	  break;
1295 	case 'i':
1296 	  if ((mask & OMP_CLAUSE_IF)
1297 	      && c->if_expr == NULL
1298 	      && gfc_match ("if ( ") == MATCH_YES)
1299 	    {
1300 	      if (gfc_match ("%e )", &c->if_expr) == MATCH_YES)
1301 		continue;
1302 	      if (!openacc)
1303 		{
1304 		  /* This should match the enum gfc_omp_if_kind order.  */
1305 		  static const char *ifs[OMP_IF_LAST] = {
1306 		    " parallel : %e )",
1307 		    " task : %e )",
1308 		    " taskloop : %e )",
1309 		    " target : %e )",
1310 		    " target data : %e )",
1311 		    " target update : %e )",
1312 		    " target enter data : %e )",
1313 		    " target exit data : %e )" };
1314 		  int i;
1315 		  for (i = 0; i < OMP_IF_LAST; i++)
1316 		    if (c->if_exprs[i] == NULL
1317 			&& gfc_match (ifs[i], &c->if_exprs[i]) == MATCH_YES)
1318 		      break;
1319 		  if (i < OMP_IF_LAST)
1320 		    continue;
1321 		}
1322 	      gfc_current_locus = old_loc;
1323 	    }
1324 	  if ((mask & OMP_CLAUSE_IF_PRESENT)
1325 	      && !c->if_present
1326 	      && gfc_match ("if_present") == MATCH_YES)
1327 	    {
1328 	      c->if_present = true;
1329 	      needs_space = true;
1330 	      continue;
1331 	    }
1332 	  if ((mask & OMP_CLAUSE_INBRANCH)
1333 	      && !c->inbranch
1334 	      && !c->notinbranch
1335 	      && gfc_match ("inbranch") == MATCH_YES)
1336 	    {
1337 	      c->inbranch = needs_space = true;
1338 	      continue;
1339 	    }
1340 	  if ((mask & OMP_CLAUSE_INDEPENDENT)
1341 	      && !c->independent
1342 	      && gfc_match ("independent") == MATCH_YES)
1343 	    {
1344 	      c->independent = true;
1345 	      needs_space = true;
1346 	      continue;
1347 	    }
1348 	  if ((mask & OMP_CLAUSE_IS_DEVICE_PTR)
1349 	      && gfc_match_omp_variable_list
1350 		   ("is_device_ptr (",
1351 		    &c->lists[OMP_LIST_IS_DEVICE_PTR], false) == MATCH_YES)
1352 	    continue;
1353 	  break;
1354 	case 'l':
1355 	  if ((mask & OMP_CLAUSE_LASTPRIVATE)
1356 	      && gfc_match_omp_variable_list ("lastprivate (",
1357 					      &c->lists[OMP_LIST_LASTPRIVATE],
1358 					      true) == MATCH_YES)
1359 	    continue;
1360 	  end_colon = false;
1361 	  head = NULL;
1362 	  if ((mask & OMP_CLAUSE_LINEAR)
1363 	      && gfc_match ("linear (") == MATCH_YES)
1364 	    {
1365 	      gfc_omp_linear_op linear_op = OMP_LINEAR_DEFAULT;
1366 	      gfc_expr *step = NULL;
1367 
1368 	      if (gfc_match_omp_variable_list (" ref (",
1369 					       &c->lists[OMP_LIST_LINEAR],
1370 					       false, NULL, &head)
1371 		  == MATCH_YES)
1372 		linear_op = OMP_LINEAR_REF;
1373 	      else if (gfc_match_omp_variable_list (" val (",
1374 						    &c->lists[OMP_LIST_LINEAR],
1375 						    false, NULL, &head)
1376 		       == MATCH_YES)
1377 		linear_op = OMP_LINEAR_VAL;
1378 	      else if (gfc_match_omp_variable_list (" uval (",
1379 						    &c->lists[OMP_LIST_LINEAR],
1380 						    false, NULL, &head)
1381 		       == MATCH_YES)
1382 		linear_op = OMP_LINEAR_UVAL;
1383 	      else if (gfc_match_omp_variable_list ("",
1384 						    &c->lists[OMP_LIST_LINEAR],
1385 						    false, &end_colon, &head)
1386 		       == MATCH_YES)
1387 		linear_op = OMP_LINEAR_DEFAULT;
1388 	      else
1389 		{
1390 		  gfc_current_locus = old_loc;
1391 		  break;
1392 		}
1393 	      if (linear_op != OMP_LINEAR_DEFAULT)
1394 		{
1395 		  if (gfc_match (" :") == MATCH_YES)
1396 		    end_colon = true;
1397 		  else if (gfc_match (" )") != MATCH_YES)
1398 		    {
1399 		      gfc_free_omp_namelist (*head);
1400 		      gfc_current_locus = old_loc;
1401 		      *head = NULL;
1402 		      break;
1403 		    }
1404 		}
1405 	      if (end_colon && gfc_match (" %e )", &step) != MATCH_YES)
1406 		{
1407 		  gfc_free_omp_namelist (*head);
1408 		  gfc_current_locus = old_loc;
1409 		  *head = NULL;
1410 		  break;
1411 		}
1412 	      else if (!end_colon)
1413 		{
1414 		  step = gfc_get_constant_expr (BT_INTEGER,
1415 						gfc_default_integer_kind,
1416 						&old_loc);
1417 		  mpz_set_si (step->value.integer, 1);
1418 		}
1419 	      (*head)->expr = step;
1420 	      if (linear_op != OMP_LINEAR_DEFAULT)
1421 		for (gfc_omp_namelist *n = *head; n; n = n->next)
1422 		  n->u.linear_op = linear_op;
1423 	      continue;
1424 	    }
1425 	  if ((mask & OMP_CLAUSE_LINK)
1426 	      && openacc
1427 	      && (gfc_match_oacc_clause_link ("link (",
1428 					      &c->lists[OMP_LIST_LINK])
1429 		  == MATCH_YES))
1430 	    continue;
1431 	  else if ((mask & OMP_CLAUSE_LINK)
1432 		   && !openacc
1433 		   && (gfc_match_omp_to_link ("link (",
1434 					      &c->lists[OMP_LIST_LINK])
1435 		       == MATCH_YES))
1436 	    continue;
1437 	  break;
1438 	case 'm':
1439 	  if ((mask & OMP_CLAUSE_MAP)
1440 	      && gfc_match ("map ( ") == MATCH_YES)
1441 	    {
1442 	      locus old_loc2 = gfc_current_locus;
1443 	      bool always = false;
1444 	      gfc_omp_map_op map_op = OMP_MAP_TOFROM;
1445 	      if (gfc_match ("always , ") == MATCH_YES)
1446 		always = true;
1447 	      if (gfc_match ("alloc : ") == MATCH_YES)
1448 		map_op = OMP_MAP_ALLOC;
1449 	      else if (gfc_match ("tofrom : ") == MATCH_YES)
1450 		map_op = always ? OMP_MAP_ALWAYS_TOFROM : OMP_MAP_TOFROM;
1451 	      else if (gfc_match ("to : ") == MATCH_YES)
1452 		map_op = always ? OMP_MAP_ALWAYS_TO : OMP_MAP_TO;
1453 	      else if (gfc_match ("from : ") == MATCH_YES)
1454 		map_op = always ? OMP_MAP_ALWAYS_FROM : OMP_MAP_FROM;
1455 	      else if (gfc_match ("release : ") == MATCH_YES)
1456 		map_op = OMP_MAP_RELEASE;
1457 	      else if (gfc_match ("delete : ") == MATCH_YES)
1458 		map_op = OMP_MAP_DELETE;
1459 	      else if (always)
1460 		{
1461 		  gfc_current_locus = old_loc2;
1462 		  always = false;
1463 		}
1464 	      head = NULL;
1465 	      if (gfc_match_omp_variable_list ("", &c->lists[OMP_LIST_MAP],
1466 					       false, NULL, &head,
1467 					       true) == MATCH_YES)
1468 		{
1469 		  gfc_omp_namelist *n;
1470 		  for (n = *head; n; n = n->next)
1471 		    n->u.map_op = map_op;
1472 		  continue;
1473 		}
1474 	      else
1475 		gfc_current_locus = old_loc;
1476 	    }
1477 	  if ((mask & OMP_CLAUSE_MERGEABLE) && !c->mergeable
1478 	      && gfc_match ("mergeable") == MATCH_YES)
1479 	    {
1480 	      c->mergeable = needs_space = true;
1481 	      continue;
1482 	    }
1483 	  break;
1484 	case 'n':
1485 	  if ((mask & OMP_CLAUSE_NO_CREATE)
1486 	      && gfc_match ("no_create ( ") == MATCH_YES
1487 	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1488 					   OMP_MAP_IF_PRESENT, true,
1489 					   allow_derived))
1490 	    continue;
1491 	  if ((mask & OMP_CLAUSE_NOGROUP)
1492 	      && !c->nogroup
1493 	      && gfc_match ("nogroup") == MATCH_YES)
1494 	    {
1495 	      c->nogroup = needs_space = true;
1496 	      continue;
1497 	    }
1498 	  if ((mask & OMP_CLAUSE_NOTINBRANCH)
1499 	      && !c->notinbranch
1500 	      && !c->inbranch
1501 	      && gfc_match ("notinbranch") == MATCH_YES)
1502 	    {
1503 	      c->notinbranch = needs_space = true;
1504 	      continue;
1505 	    }
1506 	  if ((mask & OMP_CLAUSE_NOWAIT)
1507 	      && !c->nowait
1508 	      && gfc_match ("nowait") == MATCH_YES)
1509 	    {
1510 	      c->nowait = needs_space = true;
1511 	      continue;
1512 	    }
1513 	  if ((mask & OMP_CLAUSE_NUM_GANGS)
1514 	      && c->num_gangs_expr == NULL
1515 	      && gfc_match ("num_gangs ( %e )",
1516 			    &c->num_gangs_expr) == MATCH_YES)
1517 	    continue;
1518 	  if ((mask & OMP_CLAUSE_NUM_TASKS)
1519 	      && c->num_tasks == NULL
1520 	      && gfc_match ("num_tasks ( %e )", &c->num_tasks) == MATCH_YES)
1521 	    continue;
1522 	  if ((mask & OMP_CLAUSE_NUM_TEAMS)
1523 	      && c->num_teams == NULL
1524 	      && gfc_match ("num_teams ( %e )", &c->num_teams) == MATCH_YES)
1525 	    continue;
1526 	  if ((mask & OMP_CLAUSE_NUM_THREADS)
1527 	      && c->num_threads == NULL
1528 	      && (gfc_match ("num_threads ( %e )", &c->num_threads)
1529 		  == MATCH_YES))
1530 	    continue;
1531 	  if ((mask & OMP_CLAUSE_NUM_WORKERS)
1532 	      && c->num_workers_expr == NULL
1533 	      && gfc_match ("num_workers ( %e )",
1534 			    &c->num_workers_expr) == MATCH_YES)
1535 	    continue;
1536 	  break;
1537 	case 'o':
1538 	  if ((mask & OMP_CLAUSE_ORDERED)
1539 	      && !c->ordered
1540 	      && gfc_match ("ordered") == MATCH_YES)
1541 	    {
1542 	      gfc_expr *cexpr = NULL;
1543 	      match m = gfc_match (" ( %e )", &cexpr);
1544 
1545 	      c->ordered = true;
1546 	      if (m == MATCH_YES)
1547 		{
1548 		  int ordered = 0;
1549 		  if (gfc_extract_int (cexpr, &ordered, -1))
1550 		    ordered = 0;
1551 		  else if (ordered <= 0)
1552 		    {
1553 		      gfc_error_now ("ORDERED clause argument not"
1554 				     " constant positive integer at %C");
1555 		      ordered = 0;
1556 		    }
1557 		  c->orderedc = ordered;
1558 		  gfc_free_expr (cexpr);
1559 		  continue;
1560 		}
1561 
1562 	      needs_space = true;
1563 	      continue;
1564 	    }
1565 	  break;
1566 	case 'p':
1567 	  if ((mask & OMP_CLAUSE_COPY)
1568 	      && gfc_match ("pcopy ( ") == MATCH_YES
1569 	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1570 					   OMP_MAP_TOFROM, true, allow_derived))
1571 	    continue;
1572 	  if ((mask & OMP_CLAUSE_COPYIN)
1573 	      && gfc_match ("pcopyin ( ") == MATCH_YES
1574 	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1575 					   OMP_MAP_TO, true, allow_derived))
1576 	    continue;
1577 	  if ((mask & OMP_CLAUSE_COPYOUT)
1578 	      && gfc_match ("pcopyout ( ") == MATCH_YES
1579 	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1580 					   OMP_MAP_FROM, true, allow_derived))
1581 	    continue;
1582 	  if ((mask & OMP_CLAUSE_CREATE)
1583 	      && gfc_match ("pcreate ( ") == MATCH_YES
1584 	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1585 					   OMP_MAP_ALLOC, true, allow_derived))
1586 	    continue;
1587 	  if ((mask & OMP_CLAUSE_PRESENT)
1588 	      && gfc_match ("present ( ") == MATCH_YES
1589 	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1590 					   OMP_MAP_FORCE_PRESENT, false,
1591 					   allow_derived))
1592 	    continue;
1593 	  if ((mask & OMP_CLAUSE_COPY)
1594 	      && gfc_match ("present_or_copy ( ") == MATCH_YES
1595 	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1596 					   OMP_MAP_TOFROM, true,
1597 					   allow_derived))
1598 	    continue;
1599 	  if ((mask & OMP_CLAUSE_COPYIN)
1600 	      && gfc_match ("present_or_copyin ( ") == MATCH_YES
1601 	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1602 					   OMP_MAP_TO, true, allow_derived))
1603 	    continue;
1604 	  if ((mask & OMP_CLAUSE_COPYOUT)
1605 	      && gfc_match ("present_or_copyout ( ") == MATCH_YES
1606 	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1607 					   OMP_MAP_FROM, true, allow_derived))
1608 	    continue;
1609 	  if ((mask & OMP_CLAUSE_CREATE)
1610 	      && gfc_match ("present_or_create ( ") == MATCH_YES
1611 	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1612 					   OMP_MAP_ALLOC, true, allow_derived))
1613 	    continue;
1614 	  if ((mask & OMP_CLAUSE_PRIORITY)
1615 	      && c->priority == NULL
1616 	      && gfc_match ("priority ( %e )", &c->priority) == MATCH_YES)
1617 	    continue;
1618 	  if ((mask & OMP_CLAUSE_PRIVATE)
1619 	      && gfc_match_omp_variable_list ("private (",
1620 					      &c->lists[OMP_LIST_PRIVATE],
1621 					      true) == MATCH_YES)
1622 	    continue;
1623 	  if ((mask & OMP_CLAUSE_PROC_BIND)
1624 	      && c->proc_bind == OMP_PROC_BIND_UNKNOWN)
1625 	    {
1626 	      if (gfc_match ("proc_bind ( master )") == MATCH_YES)
1627 		c->proc_bind = OMP_PROC_BIND_MASTER;
1628 	      else if (gfc_match ("proc_bind ( spread )") == MATCH_YES)
1629 		c->proc_bind = OMP_PROC_BIND_SPREAD;
1630 	      else if (gfc_match ("proc_bind ( close )") == MATCH_YES)
1631 		c->proc_bind = OMP_PROC_BIND_CLOSE;
1632 	      if (c->proc_bind != OMP_PROC_BIND_UNKNOWN)
1633 		continue;
1634 	    }
1635 	  break;
1636 	case 'r':
1637 	  if ((mask & OMP_CLAUSE_REDUCTION)
1638 	      && gfc_match ("reduction ( ") == MATCH_YES)
1639 	    {
1640 	      gfc_omp_reduction_op rop = OMP_REDUCTION_NONE;
1641 	      char buffer[GFC_MAX_SYMBOL_LEN + 3];
1642 	      if (gfc_match_char ('+') == MATCH_YES)
1643 		rop = OMP_REDUCTION_PLUS;
1644 	      else if (gfc_match_char ('*') == MATCH_YES)
1645 		rop = OMP_REDUCTION_TIMES;
1646 	      else if (gfc_match_char ('-') == MATCH_YES)
1647 		rop = OMP_REDUCTION_MINUS;
1648 	      else if (gfc_match (".and.") == MATCH_YES)
1649 		rop = OMP_REDUCTION_AND;
1650 	      else if (gfc_match (".or.") == MATCH_YES)
1651 		rop = OMP_REDUCTION_OR;
1652 	      else if (gfc_match (".eqv.") == MATCH_YES)
1653 		rop = OMP_REDUCTION_EQV;
1654 	      else if (gfc_match (".neqv.") == MATCH_YES)
1655 		rop = OMP_REDUCTION_NEQV;
1656 	      if (rop != OMP_REDUCTION_NONE)
1657 		snprintf (buffer, sizeof buffer, "operator %s",
1658 			  gfc_op2string ((gfc_intrinsic_op) rop));
1659 	      else if (gfc_match_defined_op_name (buffer + 1, 1) == MATCH_YES)
1660 		{
1661 		  buffer[0] = '.';
1662 		  strcat (buffer, ".");
1663 		}
1664 	      else if (gfc_match_name (buffer) == MATCH_YES)
1665 		{
1666 		  gfc_symbol *sym;
1667 		  const char *n = buffer;
1668 
1669 		  gfc_find_symbol (buffer, NULL, 1, &sym);
1670 		  if (sym != NULL)
1671 		    {
1672 		      if (sym->attr.intrinsic)
1673 			n = sym->name;
1674 		      else if ((sym->attr.flavor != FL_UNKNOWN
1675 				&& sym->attr.flavor != FL_PROCEDURE)
1676 			       || sym->attr.external
1677 			       || sym->attr.generic
1678 			       || sym->attr.entry
1679 			       || sym->attr.result
1680 			       || sym->attr.dummy
1681 			       || sym->attr.subroutine
1682 			       || sym->attr.pointer
1683 			       || sym->attr.target
1684 			       || sym->attr.cray_pointer
1685 			       || sym->attr.cray_pointee
1686 			       || (sym->attr.proc != PROC_UNKNOWN
1687 				   && sym->attr.proc != PROC_INTRINSIC)
1688 			       || sym->attr.if_source != IFSRC_UNKNOWN
1689 			       || sym == sym->ns->proc_name)
1690 			{
1691 			  sym = NULL;
1692 			  n = NULL;
1693 			}
1694 		      else
1695 			n = sym->name;
1696 		    }
1697 		  if (n == NULL)
1698 		    rop = OMP_REDUCTION_NONE;
1699 		  else if (strcmp (n, "max") == 0)
1700 		    rop = OMP_REDUCTION_MAX;
1701 		  else if (strcmp (n, "min") == 0)
1702 		    rop = OMP_REDUCTION_MIN;
1703 		  else if (strcmp (n, "iand") == 0)
1704 		    rop = OMP_REDUCTION_IAND;
1705 		  else if (strcmp (n, "ior") == 0)
1706 		    rop = OMP_REDUCTION_IOR;
1707 		  else if (strcmp (n, "ieor") == 0)
1708 		    rop = OMP_REDUCTION_IEOR;
1709 		  if (rop != OMP_REDUCTION_NONE
1710 		      && sym != NULL
1711 		      && ! sym->attr.intrinsic
1712 		      && ! sym->attr.use_assoc
1713 		      && ((sym->attr.flavor == FL_UNKNOWN
1714 			  && !gfc_add_flavor (&sym->attr, FL_PROCEDURE,
1715 					      sym->name, NULL))
1716 			  || !gfc_add_intrinsic (&sym->attr, NULL)))
1717 		    rop = OMP_REDUCTION_NONE;
1718 		}
1719 	      else
1720 		buffer[0] = '\0';
1721 	      gfc_omp_udr *udr
1722 		= (buffer[0]
1723 		   ? gfc_find_omp_udr (gfc_current_ns, buffer, NULL) : NULL);
1724 	      gfc_omp_namelist **head = NULL;
1725 	      if (rop == OMP_REDUCTION_NONE && udr)
1726 		rop = OMP_REDUCTION_USER;
1727 
1728 	      if (gfc_match_omp_variable_list (" :",
1729 					       &c->lists[OMP_LIST_REDUCTION],
1730 					       false, NULL, &head, openacc,
1731 					       allow_derived) == MATCH_YES)
1732 		{
1733 		  gfc_omp_namelist *n;
1734 		  if (rop == OMP_REDUCTION_NONE)
1735 		    {
1736 		      n = *head;
1737 		      *head = NULL;
1738 		      gfc_error_now ("!$OMP DECLARE REDUCTION %s not found "
1739 				     "at %L", buffer, &old_loc);
1740 		      gfc_free_omp_namelist (n);
1741 		    }
1742 		  else
1743 		    for (n = *head; n; n = n->next)
1744 		      {
1745 			n->u.reduction_op = rop;
1746 			if (udr)
1747 			  {
1748 			    n->udr = gfc_get_omp_namelist_udr ();
1749 			    n->udr->udr = udr;
1750 			  }
1751 		      }
1752 		  continue;
1753 		}
1754 	      else
1755 		gfc_current_locus = old_loc;
1756 	    }
1757 	  break;
1758 	case 's':
1759 	  if ((mask & OMP_CLAUSE_SAFELEN)
1760 	      && c->safelen_expr == NULL
1761 	      && gfc_match ("safelen ( %e )", &c->safelen_expr) == MATCH_YES)
1762 	    continue;
1763 	  if ((mask & OMP_CLAUSE_SCHEDULE)
1764 	      && c->sched_kind == OMP_SCHED_NONE
1765 	      && gfc_match ("schedule ( ") == MATCH_YES)
1766 	    {
1767 	      int nmodifiers = 0;
1768 	      locus old_loc2 = gfc_current_locus;
1769 	      do
1770 		{
1771 		  if (gfc_match ("simd") == MATCH_YES)
1772 		    {
1773 		      c->sched_simd = true;
1774 		      nmodifiers++;
1775 		    }
1776 		  else if (gfc_match ("monotonic") == MATCH_YES)
1777 		    {
1778 		      c->sched_monotonic = true;
1779 		      nmodifiers++;
1780 		    }
1781 		  else if (gfc_match ("nonmonotonic") == MATCH_YES)
1782 		    {
1783 		      c->sched_nonmonotonic = true;
1784 		      nmodifiers++;
1785 		    }
1786 		  else
1787 		    {
1788 		      if (nmodifiers)
1789 			gfc_current_locus = old_loc2;
1790 		      break;
1791 		    }
1792 		  if (nmodifiers == 1
1793 		      && gfc_match (" , ") == MATCH_YES)
1794 		    continue;
1795 		  else if (gfc_match (" : ") == MATCH_YES)
1796 		    break;
1797 		  gfc_current_locus = old_loc2;
1798 		  break;
1799 		}
1800 	      while (1);
1801 	      if (gfc_match ("static") == MATCH_YES)
1802 		c->sched_kind = OMP_SCHED_STATIC;
1803 	      else if (gfc_match ("dynamic") == MATCH_YES)
1804 		c->sched_kind = OMP_SCHED_DYNAMIC;
1805 	      else if (gfc_match ("guided") == MATCH_YES)
1806 		c->sched_kind = OMP_SCHED_GUIDED;
1807 	      else if (gfc_match ("runtime") == MATCH_YES)
1808 		c->sched_kind = OMP_SCHED_RUNTIME;
1809 	      else if (gfc_match ("auto") == MATCH_YES)
1810 		c->sched_kind = OMP_SCHED_AUTO;
1811 	      if (c->sched_kind != OMP_SCHED_NONE)
1812 		{
1813 		  match m = MATCH_NO;
1814 		  if (c->sched_kind != OMP_SCHED_RUNTIME
1815 		      && c->sched_kind != OMP_SCHED_AUTO)
1816 		    m = gfc_match (" , %e )", &c->chunk_size);
1817 		  if (m != MATCH_YES)
1818 		    m = gfc_match_char (')');
1819 		  if (m != MATCH_YES)
1820 		    c->sched_kind = OMP_SCHED_NONE;
1821 		}
1822 	      if (c->sched_kind != OMP_SCHED_NONE)
1823 		continue;
1824 	      else
1825 		gfc_current_locus = old_loc;
1826 	    }
1827 	  if ((mask & OMP_CLAUSE_HOST_SELF)
1828 	      && gfc_match ("self ( ") == MATCH_YES
1829 	      && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
1830 					   OMP_MAP_FORCE_FROM, true,
1831 					   allow_derived))
1832 	    continue;
1833 	  if ((mask & OMP_CLAUSE_SEQ)
1834 	      && !c->seq
1835 	      && gfc_match ("seq") == MATCH_YES)
1836 	    {
1837 	      c->seq = true;
1838 	      needs_space = true;
1839 	      continue;
1840 	    }
1841 	  if ((mask & OMP_CLAUSE_SHARED)
1842 	      && gfc_match_omp_variable_list ("shared (",
1843 					      &c->lists[OMP_LIST_SHARED],
1844 					      true) == MATCH_YES)
1845 	    continue;
1846 	  if ((mask & OMP_CLAUSE_SIMDLEN)
1847 	      && c->simdlen_expr == NULL
1848 	      && gfc_match ("simdlen ( %e )", &c->simdlen_expr) == MATCH_YES)
1849 	    continue;
1850 	  if ((mask & OMP_CLAUSE_SIMD)
1851 	      && !c->simd
1852 	      && gfc_match ("simd") == MATCH_YES)
1853 	    {
1854 	      c->simd = needs_space = true;
1855 	      continue;
1856 	    }
1857 	  break;
1858 	case 't':
1859 	  if ((mask & OMP_CLAUSE_THREAD_LIMIT)
1860 	      && c->thread_limit == NULL
1861 	      && gfc_match ("thread_limit ( %e )",
1862 			    &c->thread_limit) == MATCH_YES)
1863 	    continue;
1864 	  if ((mask & OMP_CLAUSE_THREADS)
1865 	      && !c->threads
1866 	      && gfc_match ("threads") == MATCH_YES)
1867 	    {
1868 	      c->threads = needs_space = true;
1869 	      continue;
1870 	    }
1871 	  if ((mask & OMP_CLAUSE_TILE)
1872 	      && !c->tile_list
1873 	      && match_oacc_expr_list ("tile (", &c->tile_list,
1874 				       true) == MATCH_YES)
1875 	    continue;
1876 	  if ((mask & OMP_CLAUSE_TO) && (mask & OMP_CLAUSE_LINK))
1877 	    {
1878 	      if (gfc_match_omp_to_link ("to (", &c->lists[OMP_LIST_TO])
1879 		  == MATCH_YES)
1880 		continue;
1881 	    }
1882 	  else if ((mask & OMP_CLAUSE_TO)
1883 	      && gfc_match_omp_variable_list ("to (",
1884 					      &c->lists[OMP_LIST_TO], false,
1885 					      NULL, &head, true) == MATCH_YES)
1886 	    continue;
1887 	  break;
1888 	case 'u':
1889 	  if ((mask & OMP_CLAUSE_UNIFORM)
1890 	      && gfc_match_omp_variable_list ("uniform (",
1891 					      &c->lists[OMP_LIST_UNIFORM],
1892 					      false) == MATCH_YES)
1893 	    continue;
1894 	  if ((mask & OMP_CLAUSE_UNTIED)
1895 	      && !c->untied
1896 	      && gfc_match ("untied") == MATCH_YES)
1897 	    {
1898 	      c->untied = needs_space = true;
1899 	      continue;
1900 	    }
1901 	  if ((mask & OMP_CLAUSE_USE_DEVICE)
1902 	      && gfc_match_omp_variable_list ("use_device (",
1903 					      &c->lists[OMP_LIST_USE_DEVICE],
1904 					      true) == MATCH_YES)
1905 	    continue;
1906 	  if ((mask & OMP_CLAUSE_USE_DEVICE_PTR)
1907 	      && gfc_match_omp_variable_list
1908 		   ("use_device_ptr (",
1909 		    &c->lists[OMP_LIST_USE_DEVICE_PTR], false) == MATCH_YES)
1910 	    continue;
1911 	  if ((mask & OMP_CLAUSE_USE_DEVICE_ADDR)
1912 	      && gfc_match_omp_variable_list
1913 		   ("use_device_addr (",
1914 		    &c->lists[OMP_LIST_USE_DEVICE_ADDR], false) == MATCH_YES)
1915 	    continue;
1916 	  break;
1917 	case 'v':
1918 	  /* VECTOR_LENGTH must be matched before VECTOR, because the latter
1919 	     doesn't unconditionally match '('.  */
1920 	  if ((mask & OMP_CLAUSE_VECTOR_LENGTH)
1921 	      && c->vector_length_expr == NULL
1922 	      && (gfc_match ("vector_length ( %e )", &c->vector_length_expr)
1923 		  == MATCH_YES))
1924 	    continue;
1925 	  if ((mask & OMP_CLAUSE_VECTOR)
1926 	      && !c->vector
1927 	      && gfc_match ("vector") == MATCH_YES)
1928 	    {
1929 	      c->vector = true;
1930 	      match m = match_oacc_clause_gwv (c, GOMP_DIM_VECTOR);
1931 	      if (m == MATCH_ERROR)
1932 		{
1933 		  gfc_current_locus = old_loc;
1934 		  break;
1935 		}
1936 	      if (m == MATCH_NO)
1937 		needs_space = true;
1938 	      continue;
1939 	    }
1940 	  break;
1941 	case 'w':
1942 	  if ((mask & OMP_CLAUSE_WAIT)
1943 	      && gfc_match ("wait") == MATCH_YES)
1944 	    {
1945 	      match m = match_oacc_expr_list (" (", &c->wait_list, false);
1946 	      if (m == MATCH_ERROR)
1947 		{
1948 		  gfc_current_locus = old_loc;
1949 		  break;
1950 		}
1951 	      else if (m == MATCH_NO)
1952 		{
1953 		  gfc_expr *expr
1954 		    = gfc_get_constant_expr (BT_INTEGER,
1955 					     gfc_default_integer_kind,
1956 					     &gfc_current_locus);
1957 		  mpz_set_si (expr->value.integer, GOMP_ASYNC_NOVAL);
1958 		  gfc_expr_list **expr_list = &c->wait_list;
1959 		  while (*expr_list)
1960 		    expr_list = &(*expr_list)->next;
1961 		  *expr_list = gfc_get_expr_list ();
1962 		  (*expr_list)->expr = expr;
1963 		  needs_space = true;
1964 		}
1965 	      continue;
1966 	    }
1967 	  if ((mask & OMP_CLAUSE_WORKER)
1968 	      && !c->worker
1969 	      && gfc_match ("worker") == MATCH_YES)
1970 	    {
1971 	      c->worker = true;
1972 	      match m = match_oacc_clause_gwv (c, GOMP_DIM_WORKER);
1973 	      if (m == MATCH_ERROR)
1974 		{
1975 		  gfc_current_locus = old_loc;
1976 		  break;
1977 		}
1978 	      else if (m == MATCH_NO)
1979 		needs_space = true;
1980 	      continue;
1981 	    }
1982 	  break;
1983 	}
1984       break;
1985     }
1986 
1987   if (gfc_match_omp_eos () != MATCH_YES)
1988     {
1989       if (!gfc_error_flag_test ())
1990 	gfc_error ("Failed to match clause at %C");
1991       gfc_free_omp_clauses (c);
1992       return MATCH_ERROR;
1993     }
1994 
1995   *cp = c;
1996   return MATCH_YES;
1997 }
1998 
1999 
2000 #define OACC_PARALLEL_CLAUSES \
2001   (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS	      \
2002    | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_REDUCTION \
2003    | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT		      \
2004    | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT	      \
2005    | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE      \
2006    | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
2007 #define OACC_KERNELS_CLAUSES \
2008   (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS	      \
2009    | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_DEVICEPTR \
2010    | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT		      \
2011    | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT	      \
2012    | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
2013 #define OACC_SERIAL_CLAUSES \
2014   (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_REDUCTION	      \
2015    | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT		      \
2016    | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT	      \
2017    | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE      \
2018    | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
2019 #define OACC_DATA_CLAUSES \
2020   (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_DEVICEPTR  | OMP_CLAUSE_COPY	      \
2021    | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_CREATE		      \
2022    | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT | OMP_CLAUSE_ATTACH)
2023 #define OACC_LOOP_CLAUSES \
2024   (omp_mask (OMP_CLAUSE_COLLAPSE) | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER	      \
2025    | OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ | OMP_CLAUSE_INDEPENDENT	      \
2026    | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_AUTO	      \
2027    | OMP_CLAUSE_TILE)
2028 #define OACC_PARALLEL_LOOP_CLAUSES \
2029   (OACC_LOOP_CLAUSES | OACC_PARALLEL_CLAUSES)
2030 #define OACC_KERNELS_LOOP_CLAUSES \
2031   (OACC_LOOP_CLAUSES | OACC_KERNELS_CLAUSES)
2032 #define OACC_SERIAL_LOOP_CLAUSES \
2033   (OACC_LOOP_CLAUSES | OACC_SERIAL_CLAUSES)
2034 #define OACC_HOST_DATA_CLAUSES \
2035   (omp_mask (OMP_CLAUSE_USE_DEVICE)					      \
2036    | OMP_CLAUSE_IF							      \
2037    | OMP_CLAUSE_IF_PRESENT)
2038 #define OACC_DECLARE_CLAUSES \
2039   (omp_mask (OMP_CLAUSE_COPY) | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT	      \
2040    | OMP_CLAUSE_CREATE | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_DEVICE_RESIDENT    \
2041    | OMP_CLAUSE_PRESENT			      \
2042    | OMP_CLAUSE_LINK)
2043 #define OACC_UPDATE_CLAUSES \
2044   (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_HOST_SELF	      \
2045    | OMP_CLAUSE_DEVICE | OMP_CLAUSE_WAIT | OMP_CLAUSE_IF_PRESENT)
2046 #define OACC_ENTER_DATA_CLAUSES \
2047   (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT	      \
2048    | OMP_CLAUSE_COPYIN | OMP_CLAUSE_CREATE | OMP_CLAUSE_ATTACH)
2049 #define OACC_EXIT_DATA_CLAUSES \
2050   (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT	      \
2051    | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_DELETE | OMP_CLAUSE_FINALIZE	      \
2052    | OMP_CLAUSE_DETACH)
2053 #define OACC_WAIT_CLAUSES \
2054   omp_mask (OMP_CLAUSE_ASYNC)
2055 #define OACC_ROUTINE_CLAUSES \
2056   (omp_mask (OMP_CLAUSE_GANG) | OMP_CLAUSE_WORKER | OMP_CLAUSE_VECTOR	      \
2057    | OMP_CLAUSE_SEQ)
2058 
2059 
2060 static match
match_acc(gfc_exec_op op,const omp_mask mask)2061 match_acc (gfc_exec_op op, const omp_mask mask)
2062 {
2063   gfc_omp_clauses *c;
2064   if (gfc_match_omp_clauses (&c, mask, false, false, true) != MATCH_YES)
2065     return MATCH_ERROR;
2066   new_st.op = op;
2067   new_st.ext.omp_clauses = c;
2068   return MATCH_YES;
2069 }
2070 
2071 match
gfc_match_oacc_parallel_loop(void)2072 gfc_match_oacc_parallel_loop (void)
2073 {
2074   return match_acc (EXEC_OACC_PARALLEL_LOOP, OACC_PARALLEL_LOOP_CLAUSES);
2075 }
2076 
2077 
2078 match
gfc_match_oacc_parallel(void)2079 gfc_match_oacc_parallel (void)
2080 {
2081   return match_acc (EXEC_OACC_PARALLEL, OACC_PARALLEL_CLAUSES);
2082 }
2083 
2084 
2085 match
gfc_match_oacc_kernels_loop(void)2086 gfc_match_oacc_kernels_loop (void)
2087 {
2088   return match_acc (EXEC_OACC_KERNELS_LOOP, OACC_KERNELS_LOOP_CLAUSES);
2089 }
2090 
2091 
2092 match
gfc_match_oacc_kernels(void)2093 gfc_match_oacc_kernels (void)
2094 {
2095   return match_acc (EXEC_OACC_KERNELS, OACC_KERNELS_CLAUSES);
2096 }
2097 
2098 
2099 match
gfc_match_oacc_serial_loop(void)2100 gfc_match_oacc_serial_loop (void)
2101 {
2102   return match_acc (EXEC_OACC_SERIAL_LOOP, OACC_SERIAL_LOOP_CLAUSES);
2103 }
2104 
2105 
2106 match
gfc_match_oacc_serial(void)2107 gfc_match_oacc_serial (void)
2108 {
2109   return match_acc (EXEC_OACC_SERIAL, OACC_SERIAL_CLAUSES);
2110 }
2111 
2112 
2113 match
gfc_match_oacc_data(void)2114 gfc_match_oacc_data (void)
2115 {
2116   return match_acc (EXEC_OACC_DATA, OACC_DATA_CLAUSES);
2117 }
2118 
2119 
2120 match
gfc_match_oacc_host_data(void)2121 gfc_match_oacc_host_data (void)
2122 {
2123   return match_acc (EXEC_OACC_HOST_DATA, OACC_HOST_DATA_CLAUSES);
2124 }
2125 
2126 
2127 match
gfc_match_oacc_loop(void)2128 gfc_match_oacc_loop (void)
2129 {
2130   return match_acc (EXEC_OACC_LOOP, OACC_LOOP_CLAUSES);
2131 }
2132 
2133 
2134 match
gfc_match_oacc_declare(void)2135 gfc_match_oacc_declare (void)
2136 {
2137   gfc_omp_clauses *c;
2138   gfc_omp_namelist *n;
2139   gfc_namespace *ns = gfc_current_ns;
2140   gfc_oacc_declare *new_oc;
2141   bool module_var = false;
2142   locus where = gfc_current_locus;
2143 
2144   if (gfc_match_omp_clauses (&c, OACC_DECLARE_CLAUSES, false, false, true)
2145       != MATCH_YES)
2146     return MATCH_ERROR;
2147 
2148   for (n = c->lists[OMP_LIST_DEVICE_RESIDENT]; n != NULL; n = n->next)
2149     n->sym->attr.oacc_declare_device_resident = 1;
2150 
2151   for (n = c->lists[OMP_LIST_LINK]; n != NULL; n = n->next)
2152     n->sym->attr.oacc_declare_link = 1;
2153 
2154   for (n = c->lists[OMP_LIST_MAP]; n != NULL; n = n->next)
2155     {
2156       gfc_symbol *s = n->sym;
2157 
2158       if (gfc_current_ns->proc_name
2159 	  && gfc_current_ns->proc_name->attr.flavor == FL_MODULE)
2160 	{
2161 	  if (n->u.map_op != OMP_MAP_ALLOC && n->u.map_op != OMP_MAP_TO)
2162 	    {
2163 	      gfc_error ("Invalid clause in module with !$ACC DECLARE at %L",
2164 			 &where);
2165 	      return MATCH_ERROR;
2166 	    }
2167 
2168 	  module_var = true;
2169 	}
2170 
2171       if (s->attr.use_assoc)
2172 	{
2173 	  gfc_error ("Variable is USE-associated with !$ACC DECLARE at %L",
2174 		     &where);
2175 	  return MATCH_ERROR;
2176 	}
2177 
2178       if ((s->result == s && s->ns->contained != gfc_current_ns)
2179 	  || ((s->attr.flavor == FL_UNKNOWN || s->attr.flavor == FL_VARIABLE)
2180 	      && s->ns != gfc_current_ns))
2181 	{
2182 	  gfc_error ("Variable %qs shall be declared in the same scoping unit "
2183 		     "as !$ACC DECLARE at %L", s->name, &where);
2184 	  return MATCH_ERROR;
2185 	}
2186 
2187       if ((s->attr.dimension || s->attr.codimension)
2188 	  && s->attr.dummy && s->as->type != AS_EXPLICIT)
2189 	{
2190 	  gfc_error ("Assumed-size dummy array with !$ACC DECLARE at %L",
2191 		     &where);
2192 	  return MATCH_ERROR;
2193 	}
2194 
2195       switch (n->u.map_op)
2196 	{
2197 	  case OMP_MAP_FORCE_ALLOC:
2198 	  case OMP_MAP_ALLOC:
2199 	    s->attr.oacc_declare_create = 1;
2200 	    break;
2201 
2202 	  case OMP_MAP_FORCE_TO:
2203 	  case OMP_MAP_TO:
2204 	    s->attr.oacc_declare_copyin = 1;
2205 	    break;
2206 
2207 	  case OMP_MAP_FORCE_DEVICEPTR:
2208 	    s->attr.oacc_declare_deviceptr = 1;
2209 	    break;
2210 
2211 	  default:
2212 	    break;
2213 	}
2214     }
2215 
2216   new_oc = gfc_get_oacc_declare ();
2217   new_oc->next = ns->oacc_declare;
2218   new_oc->module_var = module_var;
2219   new_oc->clauses = c;
2220   new_oc->loc = gfc_current_locus;
2221   ns->oacc_declare = new_oc;
2222 
2223   return MATCH_YES;
2224 }
2225 
2226 
2227 match
gfc_match_oacc_update(void)2228 gfc_match_oacc_update (void)
2229 {
2230   gfc_omp_clauses *c;
2231   locus here = gfc_current_locus;
2232 
2233   if (gfc_match_omp_clauses (&c, OACC_UPDATE_CLAUSES, false, false, true)
2234       != MATCH_YES)
2235     return MATCH_ERROR;
2236 
2237   if (!c->lists[OMP_LIST_MAP])
2238     {
2239       gfc_error ("%<acc update%> must contain at least one "
2240 		 "%<device%> or %<host%> or %<self%> clause at %L", &here);
2241       return MATCH_ERROR;
2242     }
2243 
2244   new_st.op = EXEC_OACC_UPDATE;
2245   new_st.ext.omp_clauses = c;
2246   return MATCH_YES;
2247 }
2248 
2249 
2250 match
gfc_match_oacc_enter_data(void)2251 gfc_match_oacc_enter_data (void)
2252 {
2253   return match_acc (EXEC_OACC_ENTER_DATA, OACC_ENTER_DATA_CLAUSES);
2254 }
2255 
2256 
2257 match
gfc_match_oacc_exit_data(void)2258 gfc_match_oacc_exit_data (void)
2259 {
2260   return match_acc (EXEC_OACC_EXIT_DATA, OACC_EXIT_DATA_CLAUSES);
2261 }
2262 
2263 
2264 match
gfc_match_oacc_wait(void)2265 gfc_match_oacc_wait (void)
2266 {
2267   gfc_omp_clauses *c = gfc_get_omp_clauses ();
2268   gfc_expr_list *wait_list = NULL, *el;
2269   bool space = true;
2270   match m;
2271 
2272   m = match_oacc_expr_list (" (", &wait_list, true);
2273   if (m == MATCH_ERROR)
2274     return m;
2275   else if (m == MATCH_YES)
2276     space = false;
2277 
2278   if (gfc_match_omp_clauses (&c, OACC_WAIT_CLAUSES, space, space, true)
2279       == MATCH_ERROR)
2280     return MATCH_ERROR;
2281 
2282   if (wait_list)
2283     for (el = wait_list; el; el = el->next)
2284       {
2285 	if (el->expr == NULL)
2286 	  {
2287 	    gfc_error ("Invalid argument to !$ACC WAIT at %C");
2288 	    return MATCH_ERROR;
2289 	  }
2290 
2291 	if (!gfc_resolve_expr (el->expr)
2292 	    || el->expr->ts.type != BT_INTEGER || el->expr->rank != 0)
2293 	  {
2294 	    gfc_error ("WAIT clause at %L requires a scalar INTEGER expression",
2295 		       &el->expr->where);
2296 
2297 	    return MATCH_ERROR;
2298 	  }
2299       }
2300   c->wait_list = wait_list;
2301   new_st.op = EXEC_OACC_WAIT;
2302   new_st.ext.omp_clauses = c;
2303   return MATCH_YES;
2304 }
2305 
2306 
2307 match
gfc_match_oacc_cache(void)2308 gfc_match_oacc_cache (void)
2309 {
2310   gfc_omp_clauses *c = gfc_get_omp_clauses ();
2311   /* The OpenACC cache directive explicitly only allows "array elements or
2312      subarrays", which we're currently not checking here.  Either check this
2313      after the call of gfc_match_omp_variable_list, or add something like a
2314      only_sections variant next to its allow_sections parameter.  */
2315   match m = gfc_match_omp_variable_list (" (",
2316 					 &c->lists[OMP_LIST_CACHE], true,
2317 					 NULL, NULL, true);
2318   if (m != MATCH_YES)
2319     {
2320       gfc_free_omp_clauses(c);
2321       return m;
2322     }
2323 
2324   if (gfc_current_state() != COMP_DO
2325       && gfc_current_state() != COMP_DO_CONCURRENT)
2326     {
2327       gfc_error ("ACC CACHE directive must be inside of loop %C");
2328       gfc_free_omp_clauses(c);
2329       return MATCH_ERROR;
2330     }
2331 
2332   new_st.op = EXEC_OACC_CACHE;
2333   new_st.ext.omp_clauses = c;
2334   return MATCH_YES;
2335 }
2336 
2337 /* Determine the OpenACC 'routine' directive's level of parallelism.  */
2338 
2339 static oacc_routine_lop
gfc_oacc_routine_lop(gfc_omp_clauses * clauses)2340 gfc_oacc_routine_lop (gfc_omp_clauses *clauses)
2341 {
2342   oacc_routine_lop ret = OACC_ROUTINE_LOP_SEQ;
2343 
2344   if (clauses)
2345     {
2346       unsigned n_lop_clauses = 0;
2347 
2348       if (clauses->gang)
2349 	{
2350 	  ++n_lop_clauses;
2351 	  ret = OACC_ROUTINE_LOP_GANG;
2352 	}
2353       if (clauses->worker)
2354 	{
2355 	  ++n_lop_clauses;
2356 	  ret = OACC_ROUTINE_LOP_WORKER;
2357 	}
2358       if (clauses->vector)
2359 	{
2360 	  ++n_lop_clauses;
2361 	  ret = OACC_ROUTINE_LOP_VECTOR;
2362 	}
2363       if (clauses->seq)
2364 	{
2365 	  ++n_lop_clauses;
2366 	  ret = OACC_ROUTINE_LOP_SEQ;
2367 	}
2368 
2369       if (n_lop_clauses > 1)
2370 	ret = OACC_ROUTINE_LOP_ERROR;
2371     }
2372 
2373   return ret;
2374 }
2375 
2376 match
gfc_match_oacc_routine(void)2377 gfc_match_oacc_routine (void)
2378 {
2379   locus old_loc;
2380   match m;
2381   gfc_intrinsic_sym *isym = NULL;
2382   gfc_symbol *sym = NULL;
2383   gfc_omp_clauses *c = NULL;
2384   gfc_oacc_routine_name *n = NULL;
2385   oacc_routine_lop lop = OACC_ROUTINE_LOP_NONE;
2386 
2387   old_loc = gfc_current_locus;
2388 
2389   m = gfc_match (" (");
2390 
2391   if (gfc_current_ns->proc_name
2392       && gfc_current_ns->proc_name->attr.if_source == IFSRC_IFBODY
2393       && m == MATCH_YES)
2394     {
2395       gfc_error ("Only the !$ACC ROUTINE form without "
2396 		 "list is allowed in interface block at %C");
2397       goto cleanup;
2398     }
2399 
2400   if (m == MATCH_YES)
2401     {
2402       char buffer[GFC_MAX_SYMBOL_LEN + 1];
2403 
2404       m = gfc_match_name (buffer);
2405       if (m == MATCH_YES)
2406 	{
2407 	  gfc_symtree *st = NULL;
2408 
2409 	  /* First look for an intrinsic symbol.  */
2410 	  isym = gfc_find_function (buffer);
2411 	  if (!isym)
2412 	    isym = gfc_find_subroutine (buffer);
2413 	  /* If no intrinsic symbol found, search the current namespace.  */
2414 	  if (!isym)
2415 	    st = gfc_find_symtree (gfc_current_ns->sym_root, buffer);
2416 	  if (st)
2417 	    {
2418 	      sym = st->n.sym;
2419 	      /* If the name in a 'routine' directive refers to the containing
2420 		 subroutine or function, then make sure that we'll later handle
2421 		 this accordingly.  */
2422 	      if (gfc_current_ns->proc_name != NULL
2423 		  && strcmp (sym->name, gfc_current_ns->proc_name->name) == 0)
2424 	        sym = NULL;
2425 	    }
2426 
2427 	  if (isym == NULL && st == NULL)
2428 	    {
2429 	      gfc_error ("Invalid NAME %qs in !$ACC ROUTINE ( NAME ) at %C",
2430 			 buffer);
2431 	      gfc_current_locus = old_loc;
2432 	      return MATCH_ERROR;
2433 	    }
2434 	}
2435       else
2436         {
2437 	  gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C");
2438 	  gfc_current_locus = old_loc;
2439 	  return MATCH_ERROR;
2440 	}
2441 
2442       if (gfc_match_char (')') != MATCH_YES)
2443 	{
2444 	  gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C, expecting"
2445 		     " ')' after NAME");
2446 	  gfc_current_locus = old_loc;
2447 	  return MATCH_ERROR;
2448 	}
2449     }
2450 
2451   if (gfc_match_omp_eos () != MATCH_YES
2452       && (gfc_match_omp_clauses (&c, OACC_ROUTINE_CLAUSES, false, false, true)
2453 	  != MATCH_YES))
2454     return MATCH_ERROR;
2455 
2456   lop = gfc_oacc_routine_lop (c);
2457   if (lop == OACC_ROUTINE_LOP_ERROR)
2458     {
2459       gfc_error ("Multiple loop axes specified for routine at %C");
2460       goto cleanup;
2461     }
2462 
2463   if (isym != NULL)
2464     {
2465       /* Diagnose any OpenACC 'routine' directive that doesn't match the
2466 	 (implicit) one with a 'seq' clause.  */
2467       if (c && (c->gang || c->worker || c->vector))
2468 	{
2469 	  gfc_error ("Intrinsic symbol specified in !$ACC ROUTINE ( NAME )"
2470 		     " at %C marked with incompatible GANG, WORKER, or VECTOR"
2471 		     " clause");
2472 	  goto cleanup;
2473 	}
2474     }
2475   else if (sym != NULL)
2476     {
2477       bool add = true;
2478 
2479       /* For a repeated OpenACC 'routine' directive, diagnose if it doesn't
2480 	 match the first one.  */
2481       for (gfc_oacc_routine_name *n_p = gfc_current_ns->oacc_routine_names;
2482 	   n_p;
2483 	   n_p = n_p->next)
2484 	if (n_p->sym == sym)
2485 	  {
2486 	    add = false;
2487 	    if (lop != gfc_oacc_routine_lop (n_p->clauses))
2488 	      {
2489 		gfc_error ("!$ACC ROUTINE already applied at %C");
2490 		goto cleanup;
2491 	      }
2492 	  }
2493 
2494       if (add)
2495 	{
2496 	  sym->attr.oacc_routine_lop = lop;
2497 
2498 	  n = gfc_get_oacc_routine_name ();
2499 	  n->sym = sym;
2500 	  n->clauses = c;
2501 	  n->next = gfc_current_ns->oacc_routine_names;
2502 	  n->loc = old_loc;
2503 	  gfc_current_ns->oacc_routine_names = n;
2504 	}
2505     }
2506   else if (gfc_current_ns->proc_name)
2507     {
2508       /* For a repeated OpenACC 'routine' directive, diagnose if it doesn't
2509 	 match the first one.  */
2510       oacc_routine_lop lop_p = gfc_current_ns->proc_name->attr.oacc_routine_lop;
2511       if (lop_p != OACC_ROUTINE_LOP_NONE
2512 	  && lop != lop_p)
2513 	{
2514 	  gfc_error ("!$ACC ROUTINE already applied at %C");
2515 	  goto cleanup;
2516 	}
2517 
2518       if (!gfc_add_omp_declare_target (&gfc_current_ns->proc_name->attr,
2519 				       gfc_current_ns->proc_name->name,
2520 				       &old_loc))
2521 	goto cleanup;
2522       gfc_current_ns->proc_name->attr.oacc_routine_lop = lop;
2523     }
2524   else
2525     /* Something has gone wrong, possibly a syntax error.  */
2526     goto cleanup;
2527 
2528   if (n)
2529     n->clauses = c;
2530   else if (gfc_current_ns->oacc_routine)
2531     gfc_current_ns->oacc_routine_clauses = c;
2532 
2533   new_st.op = EXEC_OACC_ROUTINE;
2534   new_st.ext.omp_clauses = c;
2535   return MATCH_YES;
2536 
2537 cleanup:
2538   gfc_current_locus = old_loc;
2539   return MATCH_ERROR;
2540 }
2541 
2542 
2543 #define OMP_PARALLEL_CLAUSES \
2544   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
2545    | OMP_CLAUSE_SHARED | OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION	\
2546    | OMP_CLAUSE_IF | OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT	\
2547    | OMP_CLAUSE_PROC_BIND)
2548 #define OMP_DECLARE_SIMD_CLAUSES \
2549   (omp_mask (OMP_CLAUSE_SIMDLEN) | OMP_CLAUSE_LINEAR			\
2550    | OMP_CLAUSE_UNIFORM	| OMP_CLAUSE_ALIGNED | OMP_CLAUSE_INBRANCH	\
2551    | OMP_CLAUSE_NOTINBRANCH)
2552 #define OMP_DO_CLAUSES \
2553   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
2554    | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION			\
2555    | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED | OMP_CLAUSE_COLLAPSE	\
2556    | OMP_CLAUSE_LINEAR)
2557 #define OMP_SECTIONS_CLAUSES \
2558   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
2559    | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION)
2560 #define OMP_SIMD_CLAUSES \
2561   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE		\
2562    | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN	\
2563    | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ALIGNED | OMP_CLAUSE_SIMDLEN)
2564 #define OMP_TASK_CLAUSES \
2565   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
2566    | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT		\
2567    | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE	\
2568    | OMP_CLAUSE_DEPEND | OMP_CLAUSE_PRIORITY)
2569 #define OMP_TASKLOOP_CLAUSES \
2570   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
2571    | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF		\
2572    | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL		\
2573    | OMP_CLAUSE_MERGEABLE | OMP_CLAUSE_PRIORITY | OMP_CLAUSE_GRAINSIZE	\
2574    | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_NOGROUP)
2575 #define OMP_TARGET_CLAUSES \
2576   (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF	\
2577    | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE		\
2578    | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP			\
2579    | OMP_CLAUSE_IS_DEVICE_PTR)
2580 #define OMP_TARGET_DATA_CLAUSES \
2581   (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF	\
2582    | OMP_CLAUSE_USE_DEVICE_PTR | OMP_CLAUSE_USE_DEVICE_ADDR)
2583 #define OMP_TARGET_ENTER_DATA_CLAUSES \
2584   (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF	\
2585    | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
2586 #define OMP_TARGET_EXIT_DATA_CLAUSES \
2587   (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF	\
2588    | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
2589 #define OMP_TARGET_UPDATE_CLAUSES \
2590   (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_IF | OMP_CLAUSE_TO		\
2591    | OMP_CLAUSE_FROM | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
2592 #define OMP_TEAMS_CLAUSES \
2593   (omp_mask (OMP_CLAUSE_NUM_TEAMS) | OMP_CLAUSE_THREAD_LIMIT		\
2594    | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE	\
2595    | OMP_CLAUSE_SHARED | OMP_CLAUSE_REDUCTION)
2596 #define OMP_DISTRIBUTE_CLAUSES \
2597   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
2598    | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_DIST_SCHEDULE)
2599 #define OMP_SINGLE_CLAUSES \
2600   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE)
2601 #define OMP_ORDERED_CLAUSES \
2602   (omp_mask (OMP_CLAUSE_THREADS) | OMP_CLAUSE_SIMD)
2603 #define OMP_DECLARE_TARGET_CLAUSES \
2604   (omp_mask (OMP_CLAUSE_TO) | OMP_CLAUSE_LINK)
2605 
2606 
2607 static match
match_omp(gfc_exec_op op,const omp_mask mask)2608 match_omp (gfc_exec_op op, const omp_mask mask)
2609 {
2610   gfc_omp_clauses *c;
2611   if (gfc_match_omp_clauses (&c, mask) != MATCH_YES)
2612     return MATCH_ERROR;
2613   new_st.op = op;
2614   new_st.ext.omp_clauses = c;
2615   return MATCH_YES;
2616 }
2617 
2618 
2619 match
gfc_match_omp_critical(void)2620 gfc_match_omp_critical (void)
2621 {
2622   char n[GFC_MAX_SYMBOL_LEN+1];
2623   gfc_omp_clauses *c = NULL;
2624 
2625   if (gfc_match (" ( %n )", n) != MATCH_YES)
2626     {
2627       n[0] = '\0';
2628       if (gfc_match_omp_eos () != MATCH_YES)
2629 	{
2630 	  gfc_error ("Unexpected junk after $OMP CRITICAL statement at %C");
2631 	  return MATCH_ERROR;
2632 	}
2633     }
2634   else if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_HINT)) != MATCH_YES)
2635     return MATCH_ERROR;
2636 
2637   new_st.op = EXEC_OMP_CRITICAL;
2638   new_st.ext.omp_clauses = c;
2639   if (n[0])
2640     c->critical_name = xstrdup (n);
2641   return MATCH_YES;
2642 }
2643 
2644 
2645 match
gfc_match_omp_end_critical(void)2646 gfc_match_omp_end_critical (void)
2647 {
2648   char n[GFC_MAX_SYMBOL_LEN+1];
2649 
2650   if (gfc_match (" ( %n )", n) != MATCH_YES)
2651     n[0] = '\0';
2652   if (gfc_match_omp_eos () != MATCH_YES)
2653     {
2654       gfc_error ("Unexpected junk after $OMP CRITICAL statement at %C");
2655       return MATCH_ERROR;
2656     }
2657 
2658   new_st.op = EXEC_OMP_END_CRITICAL;
2659   new_st.ext.omp_name = n[0] ? xstrdup (n) : NULL;
2660   return MATCH_YES;
2661 }
2662 
2663 
2664 match
gfc_match_omp_distribute(void)2665 gfc_match_omp_distribute (void)
2666 {
2667   return match_omp (EXEC_OMP_DISTRIBUTE, OMP_DISTRIBUTE_CLAUSES);
2668 }
2669 
2670 
2671 match
gfc_match_omp_distribute_parallel_do(void)2672 gfc_match_omp_distribute_parallel_do (void)
2673 {
2674   return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO,
2675 		    (OMP_DISTRIBUTE_CLAUSES | OMP_PARALLEL_CLAUSES
2676 		     | OMP_DO_CLAUSES)
2677 		    & ~(omp_mask (OMP_CLAUSE_ORDERED))
2678 		    & ~(omp_mask (OMP_CLAUSE_LINEAR)));
2679 }
2680 
2681 
2682 match
gfc_match_omp_distribute_parallel_do_simd(void)2683 gfc_match_omp_distribute_parallel_do_simd (void)
2684 {
2685   return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD,
2686 		    (OMP_DISTRIBUTE_CLAUSES | OMP_PARALLEL_CLAUSES
2687 		     | OMP_DO_CLAUSES | OMP_SIMD_CLAUSES)
2688 		    & ~(omp_mask (OMP_CLAUSE_ORDERED)));
2689 }
2690 
2691 
2692 match
gfc_match_omp_distribute_simd(void)2693 gfc_match_omp_distribute_simd (void)
2694 {
2695   return match_omp (EXEC_OMP_DISTRIBUTE_SIMD,
2696 		    OMP_DISTRIBUTE_CLAUSES | OMP_SIMD_CLAUSES);
2697 }
2698 
2699 
2700 match
gfc_match_omp_do(void)2701 gfc_match_omp_do (void)
2702 {
2703   return match_omp (EXEC_OMP_DO, OMP_DO_CLAUSES);
2704 }
2705 
2706 
2707 match
gfc_match_omp_do_simd(void)2708 gfc_match_omp_do_simd (void)
2709 {
2710   return match_omp (EXEC_OMP_DO_SIMD, OMP_DO_CLAUSES | OMP_SIMD_CLAUSES);
2711 }
2712 
2713 
2714 match
gfc_match_omp_flush(void)2715 gfc_match_omp_flush (void)
2716 {
2717   gfc_omp_namelist *list = NULL;
2718   gfc_match_omp_variable_list (" (", &list, true);
2719   if (gfc_match_omp_eos () != MATCH_YES)
2720     {
2721       gfc_error ("Unexpected junk after $OMP FLUSH statement at %C");
2722       gfc_free_omp_namelist (list);
2723       return MATCH_ERROR;
2724     }
2725   new_st.op = EXEC_OMP_FLUSH;
2726   new_st.ext.omp_namelist = list;
2727   return MATCH_YES;
2728 }
2729 
2730 
2731 match
gfc_match_omp_declare_simd(void)2732 gfc_match_omp_declare_simd (void)
2733 {
2734   locus where = gfc_current_locus;
2735   gfc_symbol *proc_name;
2736   gfc_omp_clauses *c;
2737   gfc_omp_declare_simd *ods;
2738   bool needs_space = false;
2739 
2740   switch (gfc_match (" ( %s ) ", &proc_name))
2741     {
2742     case MATCH_YES: break;
2743     case MATCH_NO: proc_name = NULL; needs_space = true; break;
2744     case MATCH_ERROR: return MATCH_ERROR;
2745     }
2746 
2747   if (gfc_match_omp_clauses (&c, OMP_DECLARE_SIMD_CLAUSES, true,
2748 			     needs_space) != MATCH_YES)
2749     return MATCH_ERROR;
2750 
2751   if (gfc_current_ns->is_block_data)
2752     {
2753       gfc_free_omp_clauses (c);
2754       return MATCH_YES;
2755     }
2756 
2757   ods = gfc_get_omp_declare_simd ();
2758   ods->where = where;
2759   ods->proc_name = proc_name;
2760   ods->clauses = c;
2761   ods->next = gfc_current_ns->omp_declare_simd;
2762   gfc_current_ns->omp_declare_simd = ods;
2763   return MATCH_YES;
2764 }
2765 
2766 
2767 static bool
match_udr_expr(gfc_symtree * omp_sym1,gfc_symtree * omp_sym2)2768 match_udr_expr (gfc_symtree *omp_sym1, gfc_symtree *omp_sym2)
2769 {
2770   match m;
2771   locus old_loc = gfc_current_locus;
2772   char sname[GFC_MAX_SYMBOL_LEN + 1];
2773   gfc_symbol *sym;
2774   gfc_namespace *ns = gfc_current_ns;
2775   gfc_expr *lvalue = NULL, *rvalue = NULL;
2776   gfc_symtree *st;
2777   gfc_actual_arglist *arglist;
2778 
2779   m = gfc_match (" %v =", &lvalue);
2780   if (m != MATCH_YES)
2781     gfc_current_locus = old_loc;
2782   else
2783     {
2784       m = gfc_match (" %e )", &rvalue);
2785       if (m == MATCH_YES)
2786 	{
2787 	  ns->code = gfc_get_code (EXEC_ASSIGN);
2788 	  ns->code->expr1 = lvalue;
2789 	  ns->code->expr2 = rvalue;
2790 	  ns->code->loc = old_loc;
2791 	  return true;
2792 	}
2793 
2794       gfc_current_locus = old_loc;
2795       gfc_free_expr (lvalue);
2796     }
2797 
2798   m = gfc_match (" %n", sname);
2799   if (m != MATCH_YES)
2800     return false;
2801 
2802   if (strcmp (sname, omp_sym1->name) == 0
2803       || strcmp (sname, omp_sym2->name) == 0)
2804     return false;
2805 
2806   gfc_current_ns = ns->parent;
2807   if (gfc_get_ha_sym_tree (sname, &st))
2808     return false;
2809 
2810   sym = st->n.sym;
2811   if (sym->attr.flavor != FL_PROCEDURE
2812       && sym->attr.flavor != FL_UNKNOWN)
2813     return false;
2814 
2815   if (!sym->attr.generic
2816       && !sym->attr.subroutine
2817       && !sym->attr.function)
2818     {
2819       if (!(sym->attr.external && !sym->attr.referenced))
2820 	{
2821 	  /* ...create a symbol in this scope...  */
2822 	  if (sym->ns != gfc_current_ns
2823 	      && gfc_get_sym_tree (sname, NULL, &st, false) == 1)
2824 	    return false;
2825 
2826 	  if (sym != st->n.sym)
2827 	    sym = st->n.sym;
2828 	}
2829 
2830       /* ...and then to try to make the symbol into a subroutine.  */
2831       if (!gfc_add_subroutine (&sym->attr, sym->name, NULL))
2832 	return false;
2833     }
2834 
2835   gfc_set_sym_referenced (sym);
2836   gfc_gobble_whitespace ();
2837   if (gfc_peek_ascii_char () != '(')
2838     return false;
2839 
2840   gfc_current_ns = ns;
2841   m = gfc_match_actual_arglist (1, &arglist);
2842   if (m != MATCH_YES)
2843     return false;
2844 
2845   if (gfc_match_char (')') != MATCH_YES)
2846     return false;
2847 
2848   ns->code = gfc_get_code (EXEC_CALL);
2849   ns->code->symtree = st;
2850   ns->code->ext.actual = arglist;
2851   ns->code->loc = old_loc;
2852   return true;
2853 }
2854 
2855 static bool
gfc_omp_udr_predef(gfc_omp_reduction_op rop,const char * name,gfc_typespec * ts,const char ** n)2856 gfc_omp_udr_predef (gfc_omp_reduction_op rop, const char *name,
2857 		    gfc_typespec *ts, const char **n)
2858 {
2859   if (!gfc_numeric_ts (ts) && ts->type != BT_LOGICAL)
2860     return false;
2861 
2862   switch (rop)
2863     {
2864     case OMP_REDUCTION_PLUS:
2865     case OMP_REDUCTION_MINUS:
2866     case OMP_REDUCTION_TIMES:
2867       return ts->type != BT_LOGICAL;
2868     case OMP_REDUCTION_AND:
2869     case OMP_REDUCTION_OR:
2870     case OMP_REDUCTION_EQV:
2871     case OMP_REDUCTION_NEQV:
2872       return ts->type == BT_LOGICAL;
2873     case OMP_REDUCTION_USER:
2874       if (name[0] != '.' && (ts->type == BT_INTEGER || ts->type == BT_REAL))
2875 	{
2876 	  gfc_symbol *sym;
2877 
2878 	  gfc_find_symbol (name, NULL, 1, &sym);
2879 	  if (sym != NULL)
2880 	    {
2881 	      if (sym->attr.intrinsic)
2882 		*n = sym->name;
2883 	      else if ((sym->attr.flavor != FL_UNKNOWN
2884 			&& sym->attr.flavor != FL_PROCEDURE)
2885 		       || sym->attr.external
2886 		       || sym->attr.generic
2887 		       || sym->attr.entry
2888 		       || sym->attr.result
2889 		       || sym->attr.dummy
2890 		       || sym->attr.subroutine
2891 		       || sym->attr.pointer
2892 		       || sym->attr.target
2893 		       || sym->attr.cray_pointer
2894 		       || sym->attr.cray_pointee
2895 		       || (sym->attr.proc != PROC_UNKNOWN
2896 			   && sym->attr.proc != PROC_INTRINSIC)
2897 		       || sym->attr.if_source != IFSRC_UNKNOWN
2898 		       || sym == sym->ns->proc_name)
2899 		*n = NULL;
2900 	      else
2901 		*n = sym->name;
2902 	    }
2903 	  else
2904 	    *n = name;
2905 	  if (*n
2906 	      && (strcmp (*n, "max") == 0 || strcmp (*n, "min") == 0))
2907 	    return true;
2908 	  else if (*n
2909 		   && ts->type == BT_INTEGER
2910 		   && (strcmp (*n, "iand") == 0
2911 		       || strcmp (*n, "ior") == 0
2912 		       || strcmp (*n, "ieor") == 0))
2913 	    return true;
2914 	}
2915       break;
2916     default:
2917       break;
2918     }
2919   return false;
2920 }
2921 
2922 gfc_omp_udr *
gfc_omp_udr_find(gfc_symtree * st,gfc_typespec * ts)2923 gfc_omp_udr_find (gfc_symtree *st, gfc_typespec *ts)
2924 {
2925   gfc_omp_udr *omp_udr;
2926 
2927   if (st == NULL)
2928     return NULL;
2929 
2930   for (omp_udr = st->n.omp_udr; omp_udr; omp_udr = omp_udr->next)
2931     if (omp_udr->ts.type == ts->type
2932 	|| ((omp_udr->ts.type == BT_DERIVED || omp_udr->ts.type == BT_CLASS)
2933 	    && (ts->type == BT_DERIVED || ts->type == BT_CLASS)))
2934       {
2935 	if (omp_udr->ts.type == BT_DERIVED || omp_udr->ts.type == BT_CLASS)
2936 	  {
2937 	    if (strcmp (omp_udr->ts.u.derived->name, ts->u.derived->name) == 0)
2938 	      return omp_udr;
2939 	  }
2940 	else if (omp_udr->ts.kind == ts->kind)
2941 	  {
2942 	    if (omp_udr->ts.type == BT_CHARACTER)
2943 	      {
2944 		if (omp_udr->ts.u.cl->length == NULL
2945 		    || ts->u.cl->length == NULL)
2946 		  return omp_udr;
2947 		if (omp_udr->ts.u.cl->length->expr_type != EXPR_CONSTANT)
2948 		  return omp_udr;
2949 		if (ts->u.cl->length->expr_type != EXPR_CONSTANT)
2950 		  return omp_udr;
2951 		if (omp_udr->ts.u.cl->length->ts.type != BT_INTEGER)
2952 		  return omp_udr;
2953 		if (ts->u.cl->length->ts.type != BT_INTEGER)
2954 		  return omp_udr;
2955 		if (gfc_compare_expr (omp_udr->ts.u.cl->length,
2956 				      ts->u.cl->length, INTRINSIC_EQ) != 0)
2957 		  continue;
2958 	      }
2959 	    return omp_udr;
2960 	  }
2961       }
2962   return NULL;
2963 }
2964 
2965 match
gfc_match_omp_declare_reduction(void)2966 gfc_match_omp_declare_reduction (void)
2967 {
2968   match m;
2969   gfc_intrinsic_op op;
2970   char name[GFC_MAX_SYMBOL_LEN + 3];
2971   auto_vec<gfc_typespec, 5> tss;
2972   gfc_typespec ts;
2973   unsigned int i;
2974   gfc_symtree *st;
2975   locus where = gfc_current_locus;
2976   locus end_loc = gfc_current_locus;
2977   bool end_loc_set = false;
2978   gfc_omp_reduction_op rop = OMP_REDUCTION_NONE;
2979 
2980   if (gfc_match_char ('(') != MATCH_YES)
2981     return MATCH_ERROR;
2982 
2983   m = gfc_match (" %o : ", &op);
2984   if (m == MATCH_ERROR)
2985     return MATCH_ERROR;
2986   if (m == MATCH_YES)
2987     {
2988       snprintf (name, sizeof name, "operator %s", gfc_op2string (op));
2989       rop = (gfc_omp_reduction_op) op;
2990     }
2991   else
2992     {
2993       m = gfc_match_defined_op_name (name + 1, 1);
2994       if (m == MATCH_ERROR)
2995 	return MATCH_ERROR;
2996       if (m == MATCH_YES)
2997 	{
2998 	  name[0] = '.';
2999 	  strcat (name, ".");
3000 	  if (gfc_match (" : ") != MATCH_YES)
3001 	    return MATCH_ERROR;
3002 	}
3003       else
3004 	{
3005 	  if (gfc_match (" %n : ", name) != MATCH_YES)
3006 	    return MATCH_ERROR;
3007 	}
3008       rop = OMP_REDUCTION_USER;
3009     }
3010 
3011   m = gfc_match_type_spec (&ts);
3012   if (m != MATCH_YES)
3013     return MATCH_ERROR;
3014   /* Treat len=: the same as len=*.  */
3015   if (ts.type == BT_CHARACTER)
3016     ts.deferred = false;
3017   tss.safe_push (ts);
3018 
3019   while (gfc_match_char (',') == MATCH_YES)
3020     {
3021       m = gfc_match_type_spec (&ts);
3022       if (m != MATCH_YES)
3023 	return MATCH_ERROR;
3024       tss.safe_push (ts);
3025     }
3026   if (gfc_match_char (':') != MATCH_YES)
3027     return MATCH_ERROR;
3028 
3029   st = gfc_find_symtree (gfc_current_ns->omp_udr_root, name);
3030   for (i = 0; i < tss.length (); i++)
3031     {
3032       gfc_symtree *omp_out, *omp_in;
3033       gfc_symtree *omp_priv = NULL, *omp_orig = NULL;
3034       gfc_namespace *combiner_ns, *initializer_ns = NULL;
3035       gfc_omp_udr *prev_udr, *omp_udr;
3036       const char *predef_name = NULL;
3037 
3038       omp_udr = gfc_get_omp_udr ();
3039       omp_udr->name = gfc_get_string ("%s", name);
3040       omp_udr->rop = rop;
3041       omp_udr->ts = tss[i];
3042       omp_udr->where = where;
3043 
3044       gfc_current_ns = combiner_ns = gfc_get_namespace (gfc_current_ns, 1);
3045       combiner_ns->proc_name = combiner_ns->parent->proc_name;
3046 
3047       gfc_get_sym_tree ("omp_out", combiner_ns, &omp_out, false);
3048       gfc_get_sym_tree ("omp_in", combiner_ns, &omp_in, false);
3049       combiner_ns->omp_udr_ns = 1;
3050       omp_out->n.sym->ts = tss[i];
3051       omp_in->n.sym->ts = tss[i];
3052       omp_out->n.sym->attr.omp_udr_artificial_var = 1;
3053       omp_in->n.sym->attr.omp_udr_artificial_var = 1;
3054       omp_out->n.sym->attr.flavor = FL_VARIABLE;
3055       omp_in->n.sym->attr.flavor = FL_VARIABLE;
3056       gfc_commit_symbols ();
3057       omp_udr->combiner_ns = combiner_ns;
3058       omp_udr->omp_out = omp_out->n.sym;
3059       omp_udr->omp_in = omp_in->n.sym;
3060 
3061       locus old_loc = gfc_current_locus;
3062 
3063       if (!match_udr_expr (omp_out, omp_in))
3064 	{
3065 	 syntax:
3066 	  gfc_current_locus = old_loc;
3067 	  gfc_current_ns = combiner_ns->parent;
3068 	  gfc_undo_symbols ();
3069 	  gfc_free_omp_udr (omp_udr);
3070 	  return MATCH_ERROR;
3071 	}
3072 
3073       if (gfc_match (" initializer ( ") == MATCH_YES)
3074 	{
3075 	  gfc_current_ns = combiner_ns->parent;
3076 	  initializer_ns = gfc_get_namespace (gfc_current_ns, 1);
3077 	  gfc_current_ns = initializer_ns;
3078 	  initializer_ns->proc_name = initializer_ns->parent->proc_name;
3079 
3080 	  gfc_get_sym_tree ("omp_priv", initializer_ns, &omp_priv, false);
3081 	  gfc_get_sym_tree ("omp_orig", initializer_ns, &omp_orig, false);
3082 	  initializer_ns->omp_udr_ns = 1;
3083 	  omp_priv->n.sym->ts = tss[i];
3084 	  omp_orig->n.sym->ts = tss[i];
3085 	  omp_priv->n.sym->attr.omp_udr_artificial_var = 1;
3086 	  omp_orig->n.sym->attr.omp_udr_artificial_var = 1;
3087 	  omp_priv->n.sym->attr.flavor = FL_VARIABLE;
3088 	  omp_orig->n.sym->attr.flavor = FL_VARIABLE;
3089 	  gfc_commit_symbols ();
3090 	  omp_udr->initializer_ns = initializer_ns;
3091 	  omp_udr->omp_priv = omp_priv->n.sym;
3092 	  omp_udr->omp_orig = omp_orig->n.sym;
3093 
3094 	  if (!match_udr_expr (omp_priv, omp_orig))
3095 	    goto syntax;
3096 	}
3097 
3098       gfc_current_ns = combiner_ns->parent;
3099       if (!end_loc_set)
3100 	{
3101 	  end_loc_set = true;
3102 	  end_loc = gfc_current_locus;
3103 	}
3104       gfc_current_locus = old_loc;
3105 
3106       prev_udr = gfc_omp_udr_find (st, &tss[i]);
3107       if (gfc_omp_udr_predef (rop, name, &tss[i], &predef_name)
3108 	  /* Don't error on !$omp declare reduction (min : integer : ...)
3109 	     just yet, there could be integer :: min afterwards,
3110 	     making it valid.  When the UDR is resolved, we'll get
3111 	     to it again.  */
3112 	  && (rop != OMP_REDUCTION_USER || name[0] == '.'))
3113 	{
3114 	  if (predef_name)
3115 	    gfc_error_now ("Redefinition of predefined %s "
3116 			   "!$OMP DECLARE REDUCTION at %L",
3117 			   predef_name, &where);
3118 	  else
3119 	    gfc_error_now ("Redefinition of predefined "
3120 			   "!$OMP DECLARE REDUCTION at %L", &where);
3121 	}
3122       else if (prev_udr)
3123 	{
3124 	  gfc_error_now ("Redefinition of !$OMP DECLARE REDUCTION at %L",
3125 			 &where);
3126 	  gfc_error_now ("Previous !$OMP DECLARE REDUCTION at %L",
3127 			 &prev_udr->where);
3128 	}
3129       else if (st)
3130 	{
3131 	  omp_udr->next = st->n.omp_udr;
3132 	  st->n.omp_udr = omp_udr;
3133 	}
3134       else
3135 	{
3136 	  st = gfc_new_symtree (&gfc_current_ns->omp_udr_root, name);
3137 	  st->n.omp_udr = omp_udr;
3138 	}
3139     }
3140 
3141   if (end_loc_set)
3142     {
3143       gfc_current_locus = end_loc;
3144       if (gfc_match_omp_eos () != MATCH_YES)
3145 	{
3146 	  gfc_error ("Unexpected junk after !$OMP DECLARE REDUCTION at %C");
3147 	  gfc_current_locus = where;
3148 	  return MATCH_ERROR;
3149 	}
3150 
3151       return MATCH_YES;
3152     }
3153   gfc_clear_error ();
3154   return MATCH_ERROR;
3155 }
3156 
3157 
3158 match
gfc_match_omp_declare_target(void)3159 gfc_match_omp_declare_target (void)
3160 {
3161   locus old_loc;
3162   match m;
3163   gfc_omp_clauses *c = NULL;
3164   int list;
3165   gfc_omp_namelist *n;
3166   gfc_symbol *s;
3167 
3168   old_loc = gfc_current_locus;
3169 
3170   if (gfc_current_ns->proc_name
3171       && gfc_match_omp_eos () == MATCH_YES)
3172     {
3173       if (!gfc_add_omp_declare_target (&gfc_current_ns->proc_name->attr,
3174 				       gfc_current_ns->proc_name->name,
3175 				       &old_loc))
3176 	goto cleanup;
3177       return MATCH_YES;
3178     }
3179 
3180   if (gfc_current_ns->proc_name
3181       && gfc_current_ns->proc_name->attr.if_source == IFSRC_IFBODY)
3182     {
3183       gfc_error ("Only the !$OMP DECLARE TARGET form without "
3184 		 "clauses is allowed in interface block at %C");
3185       goto cleanup;
3186     }
3187 
3188   m = gfc_match (" (");
3189   if (m == MATCH_YES)
3190     {
3191       c = gfc_get_omp_clauses ();
3192       gfc_current_locus = old_loc;
3193       m = gfc_match_omp_to_link (" (", &c->lists[OMP_LIST_TO]);
3194       if (m != MATCH_YES)
3195 	goto syntax;
3196       if (gfc_match_omp_eos () != MATCH_YES)
3197 	{
3198 	  gfc_error ("Unexpected junk after !$OMP DECLARE TARGET at %C");
3199 	  goto cleanup;
3200 	}
3201     }
3202   else if (gfc_match_omp_clauses (&c, OMP_DECLARE_TARGET_CLAUSES) != MATCH_YES)
3203     return MATCH_ERROR;
3204 
3205   gfc_buffer_error (false);
3206 
3207   for (list = OMP_LIST_TO; list != OMP_LIST_NUM;
3208        list = (list == OMP_LIST_TO ? OMP_LIST_LINK : OMP_LIST_NUM))
3209     for (n = c->lists[list]; n; n = n->next)
3210       if (n->sym)
3211 	n->sym->mark = 0;
3212       else if (n->u.common->head)
3213 	n->u.common->head->mark = 0;
3214 
3215   for (list = OMP_LIST_TO; list != OMP_LIST_NUM;
3216        list = (list == OMP_LIST_TO ? OMP_LIST_LINK : OMP_LIST_NUM))
3217     for (n = c->lists[list]; n; n = n->next)
3218       if (n->sym)
3219 	{
3220 	  if (n->sym->attr.in_common)
3221 	    gfc_error_now ("OMP DECLARE TARGET variable at %L is an "
3222 			   "element of a COMMON block", &n->where);
3223 	  else if (n->sym->attr.omp_declare_target
3224 		   && n->sym->attr.omp_declare_target_link
3225 		   && list != OMP_LIST_LINK)
3226 	    gfc_error_now ("OMP DECLARE TARGET variable at %L previously "
3227 			   "mentioned in LINK clause and later in TO clause",
3228 			   &n->where);
3229 	  else if (n->sym->attr.omp_declare_target
3230 		   && !n->sym->attr.omp_declare_target_link
3231 		   && list == OMP_LIST_LINK)
3232 	    gfc_error_now ("OMP DECLARE TARGET variable at %L previously "
3233 			   "mentioned in TO clause and later in LINK clause",
3234 			   &n->where);
3235 	  else if (n->sym->mark)
3236 	    gfc_error_now ("Variable at %L mentioned multiple times in "
3237 			   "clauses of the same OMP DECLARE TARGET directive",
3238 			   &n->where);
3239 	  else if (gfc_add_omp_declare_target (&n->sym->attr, n->sym->name,
3240 					       &n->sym->declared_at))
3241 	    {
3242 	      if (list == OMP_LIST_LINK)
3243 		gfc_add_omp_declare_target_link (&n->sym->attr, n->sym->name,
3244 						 &n->sym->declared_at);
3245 	    }
3246 	  n->sym->mark = 1;
3247 	}
3248       else if (n->u.common->omp_declare_target
3249 	       && n->u.common->omp_declare_target_link
3250 	       && list != OMP_LIST_LINK)
3251 	gfc_error_now ("OMP DECLARE TARGET COMMON at %L previously "
3252 		       "mentioned in LINK clause and later in TO clause",
3253 		       &n->where);
3254       else if (n->u.common->omp_declare_target
3255 	       && !n->u.common->omp_declare_target_link
3256 	       && list == OMP_LIST_LINK)
3257 	gfc_error_now ("OMP DECLARE TARGET COMMON at %L previously "
3258 		       "mentioned in TO clause and later in LINK clause",
3259 		       &n->where);
3260       else if (n->u.common->head && n->u.common->head->mark)
3261 	gfc_error_now ("COMMON at %L mentioned multiple times in "
3262 		       "clauses of the same OMP DECLARE TARGET directive",
3263 		       &n->where);
3264       else
3265 	{
3266 	  n->u.common->omp_declare_target = 1;
3267 	  n->u.common->omp_declare_target_link = (list == OMP_LIST_LINK);
3268 	  for (s = n->u.common->head; s; s = s->common_next)
3269 	    {
3270 	      s->mark = 1;
3271 	      if (gfc_add_omp_declare_target (&s->attr, s->name,
3272 					      &s->declared_at))
3273 		{
3274 		  if (list == OMP_LIST_LINK)
3275 		    gfc_add_omp_declare_target_link (&s->attr, s->name,
3276 						     &s->declared_at);
3277 		}
3278 	    }
3279 	}
3280 
3281   gfc_buffer_error (true);
3282 
3283   if (c)
3284     gfc_free_omp_clauses (c);
3285   return MATCH_YES;
3286 
3287 syntax:
3288   gfc_error ("Syntax error in !$OMP DECLARE TARGET list at %C");
3289 
3290 cleanup:
3291   gfc_current_locus = old_loc;
3292   if (c)
3293     gfc_free_omp_clauses (c);
3294   return MATCH_ERROR;
3295 }
3296 
3297 
3298 match
gfc_match_omp_threadprivate(void)3299 gfc_match_omp_threadprivate (void)
3300 {
3301   locus old_loc;
3302   char n[GFC_MAX_SYMBOL_LEN+1];
3303   gfc_symbol *sym;
3304   match m;
3305   gfc_symtree *st;
3306 
3307   old_loc = gfc_current_locus;
3308 
3309   m = gfc_match (" (");
3310   if (m != MATCH_YES)
3311     return m;
3312 
3313   for (;;)
3314     {
3315       m = gfc_match_symbol (&sym, 0);
3316       switch (m)
3317 	{
3318 	case MATCH_YES:
3319 	  if (sym->attr.in_common)
3320 	    gfc_error_now ("Threadprivate variable at %C is an element of "
3321 			   "a COMMON block");
3322 	  else if (!gfc_add_threadprivate (&sym->attr, sym->name, &sym->declared_at))
3323 	    goto cleanup;
3324 	  goto next_item;
3325 	case MATCH_NO:
3326 	  break;
3327 	case MATCH_ERROR:
3328 	  goto cleanup;
3329 	}
3330 
3331       m = gfc_match (" / %n /", n);
3332       if (m == MATCH_ERROR)
3333 	goto cleanup;
3334       if (m == MATCH_NO || n[0] == '\0')
3335 	goto syntax;
3336 
3337       st = gfc_find_symtree (gfc_current_ns->common_root, n);
3338       if (st == NULL)
3339 	{
3340 	  gfc_error ("COMMON block /%s/ not found at %C", n);
3341 	  goto cleanup;
3342 	}
3343       st->n.common->threadprivate = 1;
3344       for (sym = st->n.common->head; sym; sym = sym->common_next)
3345 	if (!gfc_add_threadprivate (&sym->attr, sym->name, &sym->declared_at))
3346 	  goto cleanup;
3347 
3348     next_item:
3349       if (gfc_match_char (')') == MATCH_YES)
3350 	break;
3351       if (gfc_match_char (',') != MATCH_YES)
3352 	goto syntax;
3353     }
3354 
3355   if (gfc_match_omp_eos () != MATCH_YES)
3356     {
3357       gfc_error ("Unexpected junk after OMP THREADPRIVATE at %C");
3358       goto cleanup;
3359     }
3360 
3361   return MATCH_YES;
3362 
3363 syntax:
3364   gfc_error ("Syntax error in !$OMP THREADPRIVATE list at %C");
3365 
3366 cleanup:
3367   gfc_current_locus = old_loc;
3368   return MATCH_ERROR;
3369 }
3370 
3371 
3372 match
gfc_match_omp_parallel(void)3373 gfc_match_omp_parallel (void)
3374 {
3375   return match_omp (EXEC_OMP_PARALLEL, OMP_PARALLEL_CLAUSES);
3376 }
3377 
3378 
3379 match
gfc_match_omp_parallel_do(void)3380 gfc_match_omp_parallel_do (void)
3381 {
3382   return match_omp (EXEC_OMP_PARALLEL_DO,
3383 		    OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES);
3384 }
3385 
3386 
3387 match
gfc_match_omp_parallel_do_simd(void)3388 gfc_match_omp_parallel_do_simd (void)
3389 {
3390   return match_omp (EXEC_OMP_PARALLEL_DO_SIMD,
3391 		    OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES | OMP_SIMD_CLAUSES);
3392 }
3393 
3394 
3395 match
gfc_match_omp_parallel_sections(void)3396 gfc_match_omp_parallel_sections (void)
3397 {
3398   return match_omp (EXEC_OMP_PARALLEL_SECTIONS,
3399 		    OMP_PARALLEL_CLAUSES | OMP_SECTIONS_CLAUSES);
3400 }
3401 
3402 
3403 match
gfc_match_omp_parallel_workshare(void)3404 gfc_match_omp_parallel_workshare (void)
3405 {
3406   return match_omp (EXEC_OMP_PARALLEL_WORKSHARE, OMP_PARALLEL_CLAUSES);
3407 }
3408 
3409 
3410 match
gfc_match_omp_sections(void)3411 gfc_match_omp_sections (void)
3412 {
3413   return match_omp (EXEC_OMP_SECTIONS, OMP_SECTIONS_CLAUSES);
3414 }
3415 
3416 
3417 match
gfc_match_omp_simd(void)3418 gfc_match_omp_simd (void)
3419 {
3420   return match_omp (EXEC_OMP_SIMD, OMP_SIMD_CLAUSES);
3421 }
3422 
3423 
3424 match
gfc_match_omp_single(void)3425 gfc_match_omp_single (void)
3426 {
3427   return match_omp (EXEC_OMP_SINGLE, OMP_SINGLE_CLAUSES);
3428 }
3429 
3430 
3431 match
gfc_match_omp_target(void)3432 gfc_match_omp_target (void)
3433 {
3434   return match_omp (EXEC_OMP_TARGET, OMP_TARGET_CLAUSES);
3435 }
3436 
3437 
3438 match
gfc_match_omp_target_data(void)3439 gfc_match_omp_target_data (void)
3440 {
3441   return match_omp (EXEC_OMP_TARGET_DATA, OMP_TARGET_DATA_CLAUSES);
3442 }
3443 
3444 
3445 match
gfc_match_omp_target_enter_data(void)3446 gfc_match_omp_target_enter_data (void)
3447 {
3448   return match_omp (EXEC_OMP_TARGET_ENTER_DATA, OMP_TARGET_ENTER_DATA_CLAUSES);
3449 }
3450 
3451 
3452 match
gfc_match_omp_target_exit_data(void)3453 gfc_match_omp_target_exit_data (void)
3454 {
3455   return match_omp (EXEC_OMP_TARGET_EXIT_DATA, OMP_TARGET_EXIT_DATA_CLAUSES);
3456 }
3457 
3458 
3459 match
gfc_match_omp_target_parallel(void)3460 gfc_match_omp_target_parallel (void)
3461 {
3462   return match_omp (EXEC_OMP_TARGET_PARALLEL,
3463 		    (OMP_TARGET_CLAUSES | OMP_PARALLEL_CLAUSES)
3464 		    & ~(omp_mask (OMP_CLAUSE_COPYIN)));
3465 }
3466 
3467 
3468 match
gfc_match_omp_target_parallel_do(void)3469 gfc_match_omp_target_parallel_do (void)
3470 {
3471   return match_omp (EXEC_OMP_TARGET_PARALLEL_DO,
3472 		    (OMP_TARGET_CLAUSES | OMP_PARALLEL_CLAUSES
3473 		     | OMP_DO_CLAUSES) & ~(omp_mask (OMP_CLAUSE_COPYIN)));
3474 }
3475 
3476 
3477 match
gfc_match_omp_target_parallel_do_simd(void)3478 gfc_match_omp_target_parallel_do_simd (void)
3479 {
3480   return match_omp (EXEC_OMP_TARGET_PARALLEL_DO_SIMD,
3481 		    (OMP_TARGET_CLAUSES | OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES
3482 		     | OMP_SIMD_CLAUSES) & ~(omp_mask (OMP_CLAUSE_COPYIN)));
3483 }
3484 
3485 
3486 match
gfc_match_omp_target_simd(void)3487 gfc_match_omp_target_simd (void)
3488 {
3489   return match_omp (EXEC_OMP_TARGET_SIMD,
3490 		    OMP_TARGET_CLAUSES | OMP_SIMD_CLAUSES);
3491 }
3492 
3493 
3494 match
gfc_match_omp_target_teams(void)3495 gfc_match_omp_target_teams (void)
3496 {
3497   return match_omp (EXEC_OMP_TARGET_TEAMS,
3498 		    OMP_TARGET_CLAUSES | OMP_TEAMS_CLAUSES);
3499 }
3500 
3501 
3502 match
gfc_match_omp_target_teams_distribute(void)3503 gfc_match_omp_target_teams_distribute (void)
3504 {
3505   return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE,
3506 		    OMP_TARGET_CLAUSES | OMP_TEAMS_CLAUSES
3507 		    | OMP_DISTRIBUTE_CLAUSES);
3508 }
3509 
3510 
3511 match
gfc_match_omp_target_teams_distribute_parallel_do(void)3512 gfc_match_omp_target_teams_distribute_parallel_do (void)
3513 {
3514   return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO,
3515 		    (OMP_TARGET_CLAUSES | OMP_TEAMS_CLAUSES
3516 		     | OMP_DISTRIBUTE_CLAUSES | OMP_PARALLEL_CLAUSES
3517 		     | OMP_DO_CLAUSES)
3518 		    & ~(omp_mask (OMP_CLAUSE_ORDERED))
3519 		    & ~(omp_mask (OMP_CLAUSE_LINEAR)));
3520 }
3521 
3522 
3523 match
gfc_match_omp_target_teams_distribute_parallel_do_simd(void)3524 gfc_match_omp_target_teams_distribute_parallel_do_simd (void)
3525 {
3526   return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD,
3527 		    (OMP_TARGET_CLAUSES | OMP_TEAMS_CLAUSES
3528 		     | OMP_DISTRIBUTE_CLAUSES | OMP_PARALLEL_CLAUSES
3529 		     | OMP_DO_CLAUSES | OMP_SIMD_CLAUSES)
3530 		    & ~(omp_mask (OMP_CLAUSE_ORDERED)));
3531 }
3532 
3533 
3534 match
gfc_match_omp_target_teams_distribute_simd(void)3535 gfc_match_omp_target_teams_distribute_simd (void)
3536 {
3537   return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD,
3538 		    OMP_TARGET_CLAUSES | OMP_TEAMS_CLAUSES
3539 		    | OMP_DISTRIBUTE_CLAUSES | OMP_SIMD_CLAUSES);
3540 }
3541 
3542 
3543 match
gfc_match_omp_target_update(void)3544 gfc_match_omp_target_update (void)
3545 {
3546   return match_omp (EXEC_OMP_TARGET_UPDATE, OMP_TARGET_UPDATE_CLAUSES);
3547 }
3548 
3549 
3550 match
gfc_match_omp_task(void)3551 gfc_match_omp_task (void)
3552 {
3553   return match_omp (EXEC_OMP_TASK, OMP_TASK_CLAUSES);
3554 }
3555 
3556 
3557 match
gfc_match_omp_taskloop(void)3558 gfc_match_omp_taskloop (void)
3559 {
3560   return match_omp (EXEC_OMP_TASKLOOP, OMP_TASKLOOP_CLAUSES);
3561 }
3562 
3563 
3564 match
gfc_match_omp_taskloop_simd(void)3565 gfc_match_omp_taskloop_simd (void)
3566 {
3567   return match_omp (EXEC_OMP_TASKLOOP_SIMD,
3568 		    (OMP_TASKLOOP_CLAUSES | OMP_SIMD_CLAUSES)
3569 		    & ~(omp_mask (OMP_CLAUSE_REDUCTION)));
3570 }
3571 
3572 
3573 match
gfc_match_omp_taskwait(void)3574 gfc_match_omp_taskwait (void)
3575 {
3576   if (gfc_match_omp_eos () != MATCH_YES)
3577     {
3578       gfc_error ("Unexpected junk after TASKWAIT clause at %C");
3579       return MATCH_ERROR;
3580     }
3581   new_st.op = EXEC_OMP_TASKWAIT;
3582   new_st.ext.omp_clauses = NULL;
3583   return MATCH_YES;
3584 }
3585 
3586 
3587 match
gfc_match_omp_taskyield(void)3588 gfc_match_omp_taskyield (void)
3589 {
3590   if (gfc_match_omp_eos () != MATCH_YES)
3591     {
3592       gfc_error ("Unexpected junk after TASKYIELD clause at %C");
3593       return MATCH_ERROR;
3594     }
3595   new_st.op = EXEC_OMP_TASKYIELD;
3596   new_st.ext.omp_clauses = NULL;
3597   return MATCH_YES;
3598 }
3599 
3600 
3601 match
gfc_match_omp_teams(void)3602 gfc_match_omp_teams (void)
3603 {
3604   return match_omp (EXEC_OMP_TEAMS, OMP_TEAMS_CLAUSES);
3605 }
3606 
3607 
3608 match
gfc_match_omp_teams_distribute(void)3609 gfc_match_omp_teams_distribute (void)
3610 {
3611   return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE,
3612 		    OMP_TEAMS_CLAUSES | OMP_DISTRIBUTE_CLAUSES);
3613 }
3614 
3615 
3616 match
gfc_match_omp_teams_distribute_parallel_do(void)3617 gfc_match_omp_teams_distribute_parallel_do (void)
3618 {
3619   return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO,
3620 		    (OMP_TEAMS_CLAUSES | OMP_DISTRIBUTE_CLAUSES
3621 		     | OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES)
3622 		    & ~(omp_mask (OMP_CLAUSE_ORDERED))
3623 		    & ~(omp_mask (OMP_CLAUSE_LINEAR)));
3624 }
3625 
3626 
3627 match
gfc_match_omp_teams_distribute_parallel_do_simd(void)3628 gfc_match_omp_teams_distribute_parallel_do_simd (void)
3629 {
3630   return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD,
3631 		    (OMP_TEAMS_CLAUSES | OMP_DISTRIBUTE_CLAUSES
3632 		     | OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES
3633 		     | OMP_SIMD_CLAUSES) & ~(omp_mask (OMP_CLAUSE_ORDERED)));
3634 }
3635 
3636 
3637 match
gfc_match_omp_teams_distribute_simd(void)3638 gfc_match_omp_teams_distribute_simd (void)
3639 {
3640   return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_SIMD,
3641 		    OMP_TEAMS_CLAUSES | OMP_DISTRIBUTE_CLAUSES
3642 		    | OMP_SIMD_CLAUSES);
3643 }
3644 
3645 
3646 match
gfc_match_omp_workshare(void)3647 gfc_match_omp_workshare (void)
3648 {
3649   if (gfc_match_omp_eos () != MATCH_YES)
3650     {
3651       gfc_error ("Unexpected junk after $OMP WORKSHARE statement at %C");
3652       return MATCH_ERROR;
3653     }
3654   new_st.op = EXEC_OMP_WORKSHARE;
3655   new_st.ext.omp_clauses = gfc_get_omp_clauses ();
3656   return MATCH_YES;
3657 }
3658 
3659 
3660 match
gfc_match_omp_master(void)3661 gfc_match_omp_master (void)
3662 {
3663   if (gfc_match_omp_eos () != MATCH_YES)
3664     {
3665       gfc_error ("Unexpected junk after $OMP MASTER statement at %C");
3666       return MATCH_ERROR;
3667     }
3668   new_st.op = EXEC_OMP_MASTER;
3669   new_st.ext.omp_clauses = NULL;
3670   return MATCH_YES;
3671 }
3672 
3673 
3674 match
gfc_match_omp_ordered(void)3675 gfc_match_omp_ordered (void)
3676 {
3677   return match_omp (EXEC_OMP_ORDERED, OMP_ORDERED_CLAUSES);
3678 }
3679 
3680 
3681 match
gfc_match_omp_ordered_depend(void)3682 gfc_match_omp_ordered_depend (void)
3683 {
3684   return match_omp (EXEC_OMP_ORDERED, omp_mask (OMP_CLAUSE_DEPEND));
3685 }
3686 
3687 
3688 static match
gfc_match_omp_oacc_atomic(bool omp_p)3689 gfc_match_omp_oacc_atomic (bool omp_p)
3690 {
3691   gfc_omp_atomic_op op = GFC_OMP_ATOMIC_UPDATE;
3692   int seq_cst = 0;
3693   if (gfc_match ("% seq_cst") == MATCH_YES)
3694     seq_cst = 1;
3695   locus old_loc = gfc_current_locus;
3696   if (seq_cst && gfc_match_char (',') == MATCH_YES)
3697     seq_cst = 2;
3698   if (seq_cst == 2
3699       || gfc_match_space () == MATCH_YES)
3700     {
3701       gfc_gobble_whitespace ();
3702       if (gfc_match ("update") == MATCH_YES)
3703 	op = GFC_OMP_ATOMIC_UPDATE;
3704       else if (gfc_match ("read") == MATCH_YES)
3705 	op = GFC_OMP_ATOMIC_READ;
3706       else if (gfc_match ("write") == MATCH_YES)
3707 	op = GFC_OMP_ATOMIC_WRITE;
3708       else if (gfc_match ("capture") == MATCH_YES)
3709 	op = GFC_OMP_ATOMIC_CAPTURE;
3710       else
3711 	{
3712 	  if (seq_cst == 2)
3713 	    gfc_current_locus = old_loc;
3714 	  goto finish;
3715 	}
3716       if (!seq_cst
3717 	  && (gfc_match (", seq_cst") == MATCH_YES
3718 	      || gfc_match ("% seq_cst") == MATCH_YES))
3719 	seq_cst = 1;
3720     }
3721  finish:
3722   if (gfc_match_omp_eos () != MATCH_YES)
3723     {
3724       gfc_error ("Unexpected junk after $OMP ATOMIC statement at %C");
3725       return MATCH_ERROR;
3726     }
3727   new_st.op = (omp_p ? EXEC_OMP_ATOMIC : EXEC_OACC_ATOMIC);
3728   if (seq_cst)
3729     op = (gfc_omp_atomic_op) (op | GFC_OMP_ATOMIC_SEQ_CST);
3730   new_st.ext.omp_atomic = op;
3731   return MATCH_YES;
3732 }
3733 
3734 match
gfc_match_oacc_atomic(void)3735 gfc_match_oacc_atomic (void)
3736 {
3737   return gfc_match_omp_oacc_atomic (false);
3738 }
3739 
3740 match
gfc_match_omp_atomic(void)3741 gfc_match_omp_atomic (void)
3742 {
3743   return gfc_match_omp_oacc_atomic (true);
3744 }
3745 
3746 match
gfc_match_omp_barrier(void)3747 gfc_match_omp_barrier (void)
3748 {
3749   if (gfc_match_omp_eos () != MATCH_YES)
3750     {
3751       gfc_error ("Unexpected junk after $OMP BARRIER statement at %C");
3752       return MATCH_ERROR;
3753     }
3754   new_st.op = EXEC_OMP_BARRIER;
3755   new_st.ext.omp_clauses = NULL;
3756   return MATCH_YES;
3757 }
3758 
3759 
3760 match
gfc_match_omp_taskgroup(void)3761 gfc_match_omp_taskgroup (void)
3762 {
3763   if (gfc_match_omp_eos () != MATCH_YES)
3764     {
3765       gfc_error ("Unexpected junk after $OMP TASKGROUP statement at %C");
3766       return MATCH_ERROR;
3767     }
3768   new_st.op = EXEC_OMP_TASKGROUP;
3769   return MATCH_YES;
3770 }
3771 
3772 
3773 static enum gfc_omp_cancel_kind
gfc_match_omp_cancel_kind(void)3774 gfc_match_omp_cancel_kind (void)
3775 {
3776   if (gfc_match_space () != MATCH_YES)
3777     return OMP_CANCEL_UNKNOWN;
3778   if (gfc_match ("parallel") == MATCH_YES)
3779     return OMP_CANCEL_PARALLEL;
3780   if (gfc_match ("sections") == MATCH_YES)
3781     return OMP_CANCEL_SECTIONS;
3782   if (gfc_match ("do") == MATCH_YES)
3783     return OMP_CANCEL_DO;
3784   if (gfc_match ("taskgroup") == MATCH_YES)
3785     return OMP_CANCEL_TASKGROUP;
3786   return OMP_CANCEL_UNKNOWN;
3787 }
3788 
3789 
3790 match
gfc_match_omp_cancel(void)3791 gfc_match_omp_cancel (void)
3792 {
3793   gfc_omp_clauses *c;
3794   enum gfc_omp_cancel_kind kind = gfc_match_omp_cancel_kind ();
3795   if (kind == OMP_CANCEL_UNKNOWN)
3796     return MATCH_ERROR;
3797   if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_IF), false) != MATCH_YES)
3798     return MATCH_ERROR;
3799   c->cancel = kind;
3800   new_st.op = EXEC_OMP_CANCEL;
3801   new_st.ext.omp_clauses = c;
3802   return MATCH_YES;
3803 }
3804 
3805 
3806 match
gfc_match_omp_cancellation_point(void)3807 gfc_match_omp_cancellation_point (void)
3808 {
3809   gfc_omp_clauses *c;
3810   enum gfc_omp_cancel_kind kind = gfc_match_omp_cancel_kind ();
3811   if (kind == OMP_CANCEL_UNKNOWN)
3812     return MATCH_ERROR;
3813   if (gfc_match_omp_eos () != MATCH_YES)
3814     {
3815       gfc_error ("Unexpected junk after $OMP CANCELLATION POINT statement "
3816 		 "at %C");
3817       return MATCH_ERROR;
3818     }
3819   c = gfc_get_omp_clauses ();
3820   c->cancel = kind;
3821   new_st.op = EXEC_OMP_CANCELLATION_POINT;
3822   new_st.ext.omp_clauses = c;
3823   return MATCH_YES;
3824 }
3825 
3826 
3827 match
gfc_match_omp_end_nowait(void)3828 gfc_match_omp_end_nowait (void)
3829 {
3830   bool nowait = false;
3831   if (gfc_match ("% nowait") == MATCH_YES)
3832     nowait = true;
3833   if (gfc_match_omp_eos () != MATCH_YES)
3834     {
3835       gfc_error ("Unexpected junk after NOWAIT clause at %C");
3836       return MATCH_ERROR;
3837     }
3838   new_st.op = EXEC_OMP_END_NOWAIT;
3839   new_st.ext.omp_bool = nowait;
3840   return MATCH_YES;
3841 }
3842 
3843 
3844 match
gfc_match_omp_end_single(void)3845 gfc_match_omp_end_single (void)
3846 {
3847   gfc_omp_clauses *c;
3848   if (gfc_match ("% nowait") == MATCH_YES)
3849     {
3850       new_st.op = EXEC_OMP_END_NOWAIT;
3851       new_st.ext.omp_bool = true;
3852       return MATCH_YES;
3853     }
3854   if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_COPYPRIVATE))
3855       != MATCH_YES)
3856     return MATCH_ERROR;
3857   new_st.op = EXEC_OMP_END_SINGLE;
3858   new_st.ext.omp_clauses = c;
3859   return MATCH_YES;
3860 }
3861 
3862 
3863 static bool
oacc_is_loop(gfc_code * code)3864 oacc_is_loop (gfc_code *code)
3865 {
3866   return code->op == EXEC_OACC_PARALLEL_LOOP
3867 	 || code->op == EXEC_OACC_KERNELS_LOOP
3868 	 || code->op == EXEC_OACC_SERIAL_LOOP
3869 	 || code->op == EXEC_OACC_LOOP;
3870 }
3871 
3872 static void
resolve_scalar_int_expr(gfc_expr * expr,const char * clause)3873 resolve_scalar_int_expr (gfc_expr *expr, const char *clause)
3874 {
3875   if (!gfc_resolve_expr (expr)
3876       || expr->ts.type != BT_INTEGER
3877       || expr->rank != 0)
3878     gfc_error ("%s clause at %L requires a scalar INTEGER expression",
3879 	       clause, &expr->where);
3880 }
3881 
3882 static void
resolve_positive_int_expr(gfc_expr * expr,const char * clause)3883 resolve_positive_int_expr (gfc_expr *expr, const char *clause)
3884 {
3885   resolve_scalar_int_expr (expr, clause);
3886   if (expr->expr_type == EXPR_CONSTANT
3887       && expr->ts.type == BT_INTEGER
3888       && mpz_sgn (expr->value.integer) <= 0)
3889     gfc_warning (0, "INTEGER expression of %s clause at %L must be positive",
3890 		 clause, &expr->where);
3891 }
3892 
3893 static void
resolve_nonnegative_int_expr(gfc_expr * expr,const char * clause)3894 resolve_nonnegative_int_expr (gfc_expr *expr, const char *clause)
3895 {
3896   resolve_scalar_int_expr (expr, clause);
3897   if (expr->expr_type == EXPR_CONSTANT
3898       && expr->ts.type == BT_INTEGER
3899       && mpz_sgn (expr->value.integer) < 0)
3900     gfc_warning (0, "INTEGER expression of %s clause at %L must be "
3901 		 "non-negative", clause, &expr->where);
3902 }
3903 
3904 /* Emits error when symbol is pointer, cray pointer or cray pointee
3905    of derived of polymorphic type.  */
3906 
3907 static void
check_symbol_not_pointer(gfc_symbol * sym,locus loc,const char * name)3908 check_symbol_not_pointer (gfc_symbol *sym, locus loc, const char *name)
3909 {
3910   if (sym->ts.type == BT_DERIVED && sym->attr.cray_pointer)
3911     gfc_error ("Cray pointer object %qs of derived type in %s clause at %L",
3912 	       sym->name, name, &loc);
3913   if (sym->ts.type == BT_DERIVED && sym->attr.cray_pointee)
3914     gfc_error ("Cray pointee object %qs of derived type in %s clause at %L",
3915 	       sym->name, name, &loc);
3916 
3917   if ((sym->ts.type == BT_ASSUMED && sym->attr.pointer)
3918       || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)
3919 	  && CLASS_DATA (sym)->attr.pointer))
3920     gfc_error ("POINTER object %qs of polymorphic type in %s clause at %L",
3921 	       sym->name, name, &loc);
3922   if ((sym->ts.type == BT_ASSUMED && sym->attr.cray_pointer)
3923       || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)
3924 	  && CLASS_DATA (sym)->attr.cray_pointer))
3925     gfc_error ("Cray pointer object %qs of polymorphic type in %s clause at %L",
3926 	       sym->name, name, &loc);
3927   if ((sym->ts.type == BT_ASSUMED && sym->attr.cray_pointee)
3928       || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)
3929 	  && CLASS_DATA (sym)->attr.cray_pointee))
3930     gfc_error ("Cray pointee object %qs of polymorphic type in %s clause at %L",
3931 	       sym->name, name, &loc);
3932 }
3933 
3934 /* Emits error when symbol represents assumed size/rank array.  */
3935 
3936 static void
check_array_not_assumed(gfc_symbol * sym,locus loc,const char * name)3937 check_array_not_assumed (gfc_symbol *sym, locus loc, const char *name)
3938 {
3939   if (sym->as && sym->as->type == AS_ASSUMED_SIZE)
3940     gfc_error ("Assumed size array %qs in %s clause at %L",
3941 	       sym->name, name, &loc);
3942   if (sym->as && sym->as->type == AS_ASSUMED_RANK)
3943     gfc_error ("Assumed rank array %qs in %s clause at %L",
3944 	       sym->name, name, &loc);
3945 }
3946 
3947 static void
resolve_oacc_data_clauses(gfc_symbol * sym,locus loc,const char * name)3948 resolve_oacc_data_clauses (gfc_symbol *sym, locus loc, const char *name)
3949 {
3950   check_array_not_assumed (sym, loc, name);
3951 }
3952 
3953 static void
resolve_oacc_deviceptr_clause(gfc_symbol * sym,locus loc,const char * name)3954 resolve_oacc_deviceptr_clause (gfc_symbol *sym, locus loc, const char *name)
3955 {
3956   if (sym->attr.pointer
3957       || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)
3958 	  && CLASS_DATA (sym)->attr.class_pointer))
3959     gfc_error ("POINTER object %qs in %s clause at %L",
3960 	       sym->name, name, &loc);
3961   if (sym->attr.cray_pointer
3962       || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)
3963 	  && CLASS_DATA (sym)->attr.cray_pointer))
3964     gfc_error ("Cray pointer object %qs in %s clause at %L",
3965 	       sym->name, name, &loc);
3966   if (sym->attr.cray_pointee
3967       || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)
3968 	  && CLASS_DATA (sym)->attr.cray_pointee))
3969     gfc_error ("Cray pointee object %qs in %s clause at %L",
3970 	       sym->name, name, &loc);
3971   if (sym->attr.allocatable
3972       || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)
3973 	  && CLASS_DATA (sym)->attr.allocatable))
3974     gfc_error ("ALLOCATABLE object %qs in %s clause at %L",
3975 	       sym->name, name, &loc);
3976   if (sym->attr.value)
3977     gfc_error ("VALUE object %qs in %s clause at %L",
3978 	       sym->name, name, &loc);
3979   check_array_not_assumed (sym, loc, name);
3980 }
3981 
3982 
3983 struct resolve_omp_udr_callback_data
3984 {
3985   gfc_symbol *sym1, *sym2;
3986 };
3987 
3988 
3989 static int
resolve_omp_udr_callback(gfc_expr ** e,int *,void * data)3990 resolve_omp_udr_callback (gfc_expr **e, int *, void *data)
3991 {
3992   struct resolve_omp_udr_callback_data *rcd
3993     = (struct resolve_omp_udr_callback_data *) data;
3994   if ((*e)->expr_type == EXPR_VARIABLE
3995       && ((*e)->symtree->n.sym == rcd->sym1
3996 	  || (*e)->symtree->n.sym == rcd->sym2))
3997     {
3998       gfc_ref *ref = gfc_get_ref ();
3999       ref->type = REF_ARRAY;
4000       ref->u.ar.where = (*e)->where;
4001       ref->u.ar.as = (*e)->symtree->n.sym->as;
4002       ref->u.ar.type = AR_FULL;
4003       ref->u.ar.dimen = 0;
4004       ref->next = (*e)->ref;
4005       (*e)->ref = ref;
4006     }
4007   return 0;
4008 }
4009 
4010 
4011 static int
resolve_omp_udr_callback2(gfc_expr ** e,int *,void *)4012 resolve_omp_udr_callback2 (gfc_expr **e, int *, void *)
4013 {
4014   if ((*e)->expr_type == EXPR_FUNCTION
4015       && (*e)->value.function.isym == NULL)
4016     {
4017       gfc_symbol *sym = (*e)->symtree->n.sym;
4018       if (!sym->attr.intrinsic
4019 	  && sym->attr.if_source == IFSRC_UNKNOWN)
4020 	gfc_error ("Implicitly declared function %s used in "
4021 		   "!$OMP DECLARE REDUCTION at %L", sym->name, &(*e)->where);
4022     }
4023   return 0;
4024 }
4025 
4026 
4027 static gfc_code *
resolve_omp_udr_clause(gfc_omp_namelist * n,gfc_namespace * ns,gfc_symbol * sym1,gfc_symbol * sym2)4028 resolve_omp_udr_clause (gfc_omp_namelist *n, gfc_namespace *ns,
4029 			gfc_symbol *sym1, gfc_symbol *sym2)
4030 {
4031   gfc_code *copy;
4032   gfc_symbol sym1_copy, sym2_copy;
4033 
4034   if (ns->code->op == EXEC_ASSIGN)
4035     {
4036       copy = gfc_get_code (EXEC_ASSIGN);
4037       copy->expr1 = gfc_copy_expr (ns->code->expr1);
4038       copy->expr2 = gfc_copy_expr (ns->code->expr2);
4039     }
4040   else
4041     {
4042       copy = gfc_get_code (EXEC_CALL);
4043       copy->symtree = ns->code->symtree;
4044       copy->ext.actual = gfc_copy_actual_arglist (ns->code->ext.actual);
4045     }
4046   copy->loc = ns->code->loc;
4047   sym1_copy = *sym1;
4048   sym2_copy = *sym2;
4049   *sym1 = *n->sym;
4050   *sym2 = *n->sym;
4051   sym1->name = sym1_copy.name;
4052   sym2->name = sym2_copy.name;
4053   ns->proc_name = ns->parent->proc_name;
4054   if (n->sym->attr.dimension)
4055     {
4056       struct resolve_omp_udr_callback_data rcd;
4057       rcd.sym1 = sym1;
4058       rcd.sym2 = sym2;
4059       gfc_code_walker (&copy, gfc_dummy_code_callback,
4060 		       resolve_omp_udr_callback, &rcd);
4061     }
4062   gfc_resolve_code (copy, gfc_current_ns);
4063   if (copy->op == EXEC_CALL && copy->resolved_isym == NULL)
4064     {
4065       gfc_symbol *sym = copy->resolved_sym;
4066       if (sym
4067 	  && !sym->attr.intrinsic
4068 	  && sym->attr.if_source == IFSRC_UNKNOWN)
4069 	gfc_error ("Implicitly declared subroutine %s used in "
4070 		   "!$OMP DECLARE REDUCTION at %L", sym->name,
4071 		   &copy->loc);
4072     }
4073   gfc_code_walker (&copy, gfc_dummy_code_callback,
4074 		   resolve_omp_udr_callback2, NULL);
4075   *sym1 = sym1_copy;
4076   *sym2 = sym2_copy;
4077   return copy;
4078 }
4079 
4080 /* OpenMP directive resolving routines.  */
4081 
4082 static void
4083 resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
4084 		     gfc_namespace *ns, bool openacc = false)
4085 {
4086   gfc_omp_namelist *n;
4087   gfc_expr_list *el;
4088   int list;
4089   int ifc;
4090   bool if_without_mod = false;
4091   gfc_omp_linear_op linear_op = OMP_LINEAR_DEFAULT;
4092   static const char *clause_names[]
4093     = { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED",
4094 	"COPYIN", "UNIFORM", "ALIGNED", "LINEAR", "DEPEND", "MAP",
4095 	"TO", "FROM", "REDUCTION", "DEVICE_RESIDENT", "LINK", "USE_DEVICE",
4096 	"CACHE", "IS_DEVICE_PTR", "USE_DEVICE_PTR", "USE_DEVICE_ADDR" };
4097 
4098   if (omp_clauses == NULL)
4099     return;
4100 
4101   if (omp_clauses->orderedc && omp_clauses->orderedc < omp_clauses->collapse)
4102     gfc_error ("ORDERED clause parameter is less than COLLAPSE at %L",
4103 	       &code->loc);
4104 
4105   if (omp_clauses->if_expr)
4106     {
4107       gfc_expr *expr = omp_clauses->if_expr;
4108       if (!gfc_resolve_expr (expr)
4109 	  || expr->ts.type != BT_LOGICAL || expr->rank != 0)
4110 	gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
4111 		   &expr->where);
4112       if_without_mod = true;
4113     }
4114   for (ifc = 0; ifc < OMP_IF_LAST; ifc++)
4115     if (omp_clauses->if_exprs[ifc])
4116       {
4117 	gfc_expr *expr = omp_clauses->if_exprs[ifc];
4118 	bool ok = true;
4119 	if (!gfc_resolve_expr (expr)
4120 	    || expr->ts.type != BT_LOGICAL || expr->rank != 0)
4121 	  gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
4122 		     &expr->where);
4123 	else if (if_without_mod)
4124 	  {
4125 	    gfc_error ("IF clause without modifier at %L used together with "
4126 		       "IF clauses with modifiers",
4127 		       &omp_clauses->if_expr->where);
4128 	    if_without_mod = false;
4129 	  }
4130 	else
4131 	  switch (code->op)
4132 	    {
4133 	    case EXEC_OMP_PARALLEL:
4134 	    case EXEC_OMP_PARALLEL_DO:
4135 	    case EXEC_OMP_PARALLEL_SECTIONS:
4136 	    case EXEC_OMP_PARALLEL_WORKSHARE:
4137 	    case EXEC_OMP_PARALLEL_DO_SIMD:
4138 	    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
4139 	    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
4140 	    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
4141 	    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
4142 	      ok = ifc == OMP_IF_PARALLEL;
4143 	      break;
4144 
4145 	    case EXEC_OMP_TASK:
4146 	      ok = ifc == OMP_IF_TASK;
4147 	      break;
4148 
4149 	    case EXEC_OMP_TASKLOOP:
4150 	    case EXEC_OMP_TASKLOOP_SIMD:
4151 	      ok = ifc == OMP_IF_TASKLOOP;
4152 	      break;
4153 
4154 	    case EXEC_OMP_TARGET:
4155 	    case EXEC_OMP_TARGET_TEAMS:
4156 	    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
4157 	    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
4158 	    case EXEC_OMP_TARGET_SIMD:
4159 	      ok = ifc == OMP_IF_TARGET;
4160 	      break;
4161 
4162 	    case EXEC_OMP_TARGET_DATA:
4163 	      ok = ifc == OMP_IF_TARGET_DATA;
4164 	      break;
4165 
4166 	    case EXEC_OMP_TARGET_UPDATE:
4167 	      ok = ifc == OMP_IF_TARGET_UPDATE;
4168 	      break;
4169 
4170 	    case EXEC_OMP_TARGET_ENTER_DATA:
4171 	      ok = ifc == OMP_IF_TARGET_ENTER_DATA;
4172 	      break;
4173 
4174 	    case EXEC_OMP_TARGET_EXIT_DATA:
4175 	      ok = ifc == OMP_IF_TARGET_EXIT_DATA;
4176 	      break;
4177 
4178 	    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
4179 	    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
4180 	    case EXEC_OMP_TARGET_PARALLEL:
4181 	    case EXEC_OMP_TARGET_PARALLEL_DO:
4182 	    case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
4183 	      ok = ifc == OMP_IF_TARGET || ifc == OMP_IF_PARALLEL;
4184 	      break;
4185 
4186 	    default:
4187 	      ok = false;
4188 	      break;
4189 	  }
4190 	if (!ok)
4191 	  {
4192 	    static const char *ifs[] = {
4193 	      "PARALLEL",
4194 	      "TASK",
4195 	      "TASKLOOP",
4196 	      "TARGET",
4197 	      "TARGET DATA",
4198 	      "TARGET UPDATE",
4199 	      "TARGET ENTER DATA",
4200 	      "TARGET EXIT DATA"
4201 	    };
4202 	    gfc_error ("IF clause modifier %s at %L not appropriate for "
4203 		       "the current OpenMP construct", ifs[ifc], &expr->where);
4204 	  }
4205       }
4206 
4207   if (omp_clauses->final_expr)
4208     {
4209       gfc_expr *expr = omp_clauses->final_expr;
4210       if (!gfc_resolve_expr (expr)
4211 	  || expr->ts.type != BT_LOGICAL || expr->rank != 0)
4212 	gfc_error ("FINAL clause at %L requires a scalar LOGICAL expression",
4213 		   &expr->where);
4214     }
4215   if (omp_clauses->num_threads)
4216     resolve_positive_int_expr (omp_clauses->num_threads, "NUM_THREADS");
4217   if (omp_clauses->chunk_size)
4218     {
4219       gfc_expr *expr = omp_clauses->chunk_size;
4220       if (!gfc_resolve_expr (expr)
4221 	  || expr->ts.type != BT_INTEGER || expr->rank != 0)
4222 	gfc_error ("SCHEDULE clause's chunk_size at %L requires "
4223 		   "a scalar INTEGER expression", &expr->where);
4224       else if (expr->expr_type == EXPR_CONSTANT
4225 	       && expr->ts.type == BT_INTEGER
4226 	       && mpz_sgn (expr->value.integer) <= 0)
4227 	gfc_warning (0, "INTEGER expression of SCHEDULE clause's chunk_size "
4228 		     "at %L must be positive", &expr->where);
4229     }
4230   if (omp_clauses->sched_kind != OMP_SCHED_NONE
4231       && omp_clauses->sched_nonmonotonic)
4232     {
4233       if (omp_clauses->sched_kind != OMP_SCHED_DYNAMIC
4234 	  && omp_clauses->sched_kind != OMP_SCHED_GUIDED)
4235 	{
4236 	  const char *p;
4237 	  switch (omp_clauses->sched_kind)
4238 	    {
4239 	    case OMP_SCHED_STATIC: p = "STATIC"; break;
4240 	    case OMP_SCHED_RUNTIME: p = "RUNTIME"; break;
4241 	    case OMP_SCHED_AUTO: p = "AUTO"; break;
4242 	    default: gcc_unreachable ();
4243 	    }
4244 	  gfc_error ("NONMONOTONIC modifier specified for %s schedule kind "
4245 		     "at %L", p, &code->loc);
4246 	}
4247       else if (omp_clauses->sched_monotonic)
4248 	gfc_error ("Both MONOTONIC and NONMONOTONIC schedule modifiers "
4249 		   "specified at %L", &code->loc);
4250       else if (omp_clauses->ordered)
4251 	gfc_error ("NONMONOTONIC schedule modifier specified with ORDERED "
4252 		   "clause at %L", &code->loc);
4253     }
4254 
4255   /* Check that no symbol appears on multiple clauses, except that
4256      a symbol can appear on both firstprivate and lastprivate.  */
4257   for (list = 0; list < OMP_LIST_NUM; list++)
4258     for (n = omp_clauses->lists[list]; n; n = n->next)
4259       {
4260 	n->sym->mark = 0;
4261 	n->sym->comp_mark = 0;
4262 	if (n->sym->attr.flavor == FL_VARIABLE
4263 	    || n->sym->attr.proc_pointer
4264 	    || (!code && (!n->sym->attr.dummy || n->sym->ns != ns)))
4265 	  {
4266 	    if (!code && (!n->sym->attr.dummy || n->sym->ns != ns))
4267 	      gfc_error ("Variable %qs is not a dummy argument at %L",
4268 			 n->sym->name, &n->where);
4269 	    continue;
4270 	  }
4271 	if (n->sym->attr.flavor == FL_PROCEDURE
4272 	    && n->sym->result == n->sym
4273 	    && n->sym->attr.function)
4274 	  {
4275 	    if (gfc_current_ns->proc_name == n->sym
4276 		|| (gfc_current_ns->parent
4277 		    && gfc_current_ns->parent->proc_name == n->sym))
4278 	      continue;
4279 	    if (gfc_current_ns->proc_name->attr.entry_master)
4280 	      {
4281 		gfc_entry_list *el = gfc_current_ns->entries;
4282 		for (; el; el = el->next)
4283 		  if (el->sym == n->sym)
4284 		    break;
4285 		if (el)
4286 		  continue;
4287 	      }
4288 	    if (gfc_current_ns->parent
4289 		&& gfc_current_ns->parent->proc_name->attr.entry_master)
4290 	      {
4291 		gfc_entry_list *el = gfc_current_ns->parent->entries;
4292 		for (; el; el = el->next)
4293 		  if (el->sym == n->sym)
4294 		    break;
4295 		if (el)
4296 		  continue;
4297 	      }
4298 	  }
4299 	if (list == OMP_LIST_MAP
4300 	    && n->sym->attr.flavor == FL_PARAMETER)
4301 	  {
4302 	    if (openacc)
4303 	      gfc_error ("Object %qs is not a variable at %L; parameters"
4304 			 " cannot be and need not be copied", n->sym->name,
4305 			 &n->where);
4306 	    else
4307 	      gfc_error ("Object %qs is not a variable at %L; parameters"
4308 			 " cannot be and need not be mapped", n->sym->name,
4309 			 &n->where);
4310 	  }
4311 	else
4312 	  gfc_error ("Object %qs is not a variable at %L", n->sym->name,
4313 		     &n->where);
4314       }
4315 
4316   for (list = 0; list < OMP_LIST_NUM; list++)
4317     if (list != OMP_LIST_FIRSTPRIVATE
4318 	&& list != OMP_LIST_LASTPRIVATE
4319 	&& list != OMP_LIST_ALIGNED
4320 	&& list != OMP_LIST_DEPEND
4321 	&& (list != OMP_LIST_MAP || openacc)
4322 	&& list != OMP_LIST_FROM
4323 	&& list != OMP_LIST_TO
4324 	&& (list != OMP_LIST_REDUCTION || !openacc))
4325       for (n = omp_clauses->lists[list]; n; n = n->next)
4326 	{
4327 	  bool component_ref_p = false;
4328 
4329 	  /* Allow multiple components of the same (e.g. derived-type)
4330 	     variable here.  Duplicate components are detected elsewhere.  */
4331 	  if (n->expr && n->expr->expr_type == EXPR_VARIABLE)
4332 	    for (gfc_ref *ref = n->expr->ref; ref; ref = ref->next)
4333 	      if (ref->type == REF_COMPONENT)
4334 		component_ref_p = true;
4335 	  if ((!component_ref_p && n->sym->comp_mark)
4336 	      || (component_ref_p && n->sym->mark))
4337 	    gfc_error ("Symbol %qs has mixed component and non-component "
4338 		       "accesses at %L", n->sym->name, &n->where);
4339 	  else if (n->sym->mark)
4340 	    gfc_error ("Symbol %qs present on multiple clauses at %L",
4341 		       n->sym->name, &n->where);
4342 	  else
4343 	    {
4344 	      if (component_ref_p)
4345 		n->sym->comp_mark = 1;
4346 	      else
4347 		n->sym->mark = 1;
4348 	    }
4349 	}
4350 
4351   gcc_assert (OMP_LIST_LASTPRIVATE == OMP_LIST_FIRSTPRIVATE + 1);
4352   for (list = OMP_LIST_FIRSTPRIVATE; list <= OMP_LIST_LASTPRIVATE; list++)
4353     for (n = omp_clauses->lists[list]; n; n = n->next)
4354       if (n->sym->mark)
4355 	{
4356 	  gfc_error ("Symbol %qs present on multiple clauses at %L",
4357 		     n->sym->name, &n->where);
4358 	  n->sym->mark = 0;
4359 	}
4360 
4361   for (n = omp_clauses->lists[OMP_LIST_FIRSTPRIVATE]; n; n = n->next)
4362     {
4363       if (n->sym->mark)
4364 	gfc_error ("Symbol %qs present on multiple clauses at %L",
4365 		   n->sym->name, &n->where);
4366       else
4367 	n->sym->mark = 1;
4368     }
4369   for (n = omp_clauses->lists[OMP_LIST_LASTPRIVATE]; n; n = n->next)
4370     n->sym->mark = 0;
4371 
4372   for (n = omp_clauses->lists[OMP_LIST_LASTPRIVATE]; n; n = n->next)
4373     {
4374       if (n->sym->mark)
4375 	gfc_error ("Symbol %qs present on multiple clauses at %L",
4376 		   n->sym->name, &n->where);
4377       else
4378 	n->sym->mark = 1;
4379     }
4380 
4381   for (n = omp_clauses->lists[OMP_LIST_ALIGNED]; n; n = n->next)
4382     n->sym->mark = 0;
4383 
4384   for (n = omp_clauses->lists[OMP_LIST_ALIGNED]; n; n = n->next)
4385     {
4386       if (n->sym->mark)
4387 	gfc_error ("Symbol %qs present on multiple clauses at %L",
4388 		   n->sym->name, &n->where);
4389       else
4390 	n->sym->mark = 1;
4391     }
4392 
4393   /* OpenACC reductions.  */
4394   if (openacc)
4395     {
4396       for (n = omp_clauses->lists[OMP_LIST_REDUCTION]; n; n = n->next)
4397 	n->sym->mark = 0;
4398 
4399       for (n = omp_clauses->lists[OMP_LIST_REDUCTION]; n; n = n->next)
4400 	{
4401 	  if (n->sym->mark)
4402 	    gfc_error ("Symbol %qs present on multiple clauses at %L",
4403 		       n->sym->name, &n->where);
4404 	  else
4405 	    n->sym->mark = 1;
4406 
4407 	  /* OpenACC does not support reductions on arrays.  */
4408 	  if (n->sym->as)
4409 	    gfc_error ("Array %qs is not permitted in reduction at %L",
4410 		       n->sym->name, &n->where);
4411 	}
4412     }
4413 
4414   for (n = omp_clauses->lists[OMP_LIST_TO]; n; n = n->next)
4415     n->sym->mark = 0;
4416   for (n = omp_clauses->lists[OMP_LIST_FROM]; n; n = n->next)
4417     if (n->expr == NULL)
4418       n->sym->mark = 1;
4419   for (n = omp_clauses->lists[OMP_LIST_TO]; n; n = n->next)
4420     {
4421       if (n->expr == NULL && n->sym->mark)
4422 	gfc_error ("Symbol %qs present on both FROM and TO clauses at %L",
4423 		   n->sym->name, &n->where);
4424       else
4425 	n->sym->mark = 1;
4426     }
4427 
4428   for (list = 0; list < OMP_LIST_NUM; list++)
4429     if ((n = omp_clauses->lists[list]) != NULL)
4430       {
4431 	const char *name;
4432 
4433 	if (list < OMP_LIST_NUM)
4434 	  name = clause_names[list];
4435 	else
4436 	  gcc_unreachable ();
4437 
4438 	switch (list)
4439 	  {
4440 	  case OMP_LIST_COPYIN:
4441 	    for (; n != NULL; n = n->next)
4442 	      {
4443 		if (!n->sym->attr.threadprivate)
4444 		  gfc_error ("Non-THREADPRIVATE object %qs in COPYIN clause"
4445 			     " at %L", n->sym->name, &n->where);
4446 	      }
4447 	    break;
4448 	  case OMP_LIST_COPYPRIVATE:
4449 	    for (; n != NULL; n = n->next)
4450 	      {
4451 		if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE)
4452 		  gfc_error ("Assumed size array %qs in COPYPRIVATE clause "
4453 			     "at %L", n->sym->name, &n->where);
4454 		if (n->sym->attr.pointer && n->sym->attr.intent == INTENT_IN)
4455 		  gfc_error ("INTENT(IN) POINTER %qs in COPYPRIVATE clause "
4456 			     "at %L", n->sym->name, &n->where);
4457 	      }
4458 	    break;
4459 	  case OMP_LIST_SHARED:
4460 	    for (; n != NULL; n = n->next)
4461 	      {
4462 		if (n->sym->attr.threadprivate)
4463 		  gfc_error ("THREADPRIVATE object %qs in SHARED clause at "
4464 			     "%L", n->sym->name, &n->where);
4465 		if (n->sym->attr.cray_pointee)
4466 		  gfc_error ("Cray pointee %qs in SHARED clause at %L",
4467 			    n->sym->name, &n->where);
4468 		if (n->sym->attr.associate_var)
4469 		  gfc_error ("ASSOCIATE name %qs in SHARED clause at %L",
4470 			     n->sym->name, &n->where);
4471 	      }
4472 	    break;
4473 	  case OMP_LIST_ALIGNED:
4474 	    for (; n != NULL; n = n->next)
4475 	      {
4476 		if (!n->sym->attr.pointer
4477 		    && !n->sym->attr.allocatable
4478 		    && !n->sym->attr.cray_pointer
4479 		    && (n->sym->ts.type != BT_DERIVED
4480 			|| (n->sym->ts.u.derived->from_intmod
4481 			    != INTMOD_ISO_C_BINDING)
4482 			|| (n->sym->ts.u.derived->intmod_sym_id
4483 			    != ISOCBINDING_PTR)))
4484 		  gfc_error ("%qs in ALIGNED clause must be POINTER, "
4485 			     "ALLOCATABLE, Cray pointer or C_PTR at %L",
4486 			     n->sym->name, &n->where);
4487 		else if (n->expr)
4488 		  {
4489 		    gfc_expr *expr = n->expr;
4490 		    int alignment = 0;
4491 		    if (!gfc_resolve_expr (expr)
4492 			|| expr->ts.type != BT_INTEGER
4493 			|| expr->rank != 0
4494 			|| gfc_extract_int (expr, &alignment)
4495 			|| alignment <= 0)
4496 		      gfc_error ("%qs in ALIGNED clause at %L requires a scalar "
4497 				 "positive constant integer alignment "
4498 				 "expression", n->sym->name, &n->where);
4499 		  }
4500 	      }
4501 	    break;
4502 	  case OMP_LIST_DEPEND:
4503 	  case OMP_LIST_MAP:
4504 	  case OMP_LIST_TO:
4505 	  case OMP_LIST_FROM:
4506 	  case OMP_LIST_CACHE:
4507 	    for (; n != NULL; n = n->next)
4508 	      {
4509 		if (list == OMP_LIST_DEPEND)
4510 		  {
4511 		    if (n->u.depend_op == OMP_DEPEND_SINK_FIRST
4512 			|| n->u.depend_op == OMP_DEPEND_SINK)
4513 		      {
4514 			if (code->op != EXEC_OMP_ORDERED)
4515 			  gfc_error ("SINK dependence type only allowed "
4516 				     "on ORDERED directive at %L", &n->where);
4517 			else if (omp_clauses->depend_source)
4518 			  {
4519 			    gfc_error ("DEPEND SINK used together with "
4520 				       "DEPEND SOURCE on the same construct "
4521 				       "at %L", &n->where);
4522 			    omp_clauses->depend_source = false;
4523 			  }
4524 			else if (n->expr)
4525 			  {
4526 			    if (!gfc_resolve_expr (n->expr)
4527 				|| n->expr->ts.type != BT_INTEGER
4528 				|| n->expr->rank != 0)
4529 			      gfc_error ("SINK addend not a constant integer "
4530 					 "at %L", &n->where);
4531 			  }
4532 			continue;
4533 		      }
4534 		    else if (code->op == EXEC_OMP_ORDERED)
4535 		      gfc_error ("Only SOURCE or SINK dependence types "
4536 				 "are allowed on ORDERED directive at %L",
4537 				 &n->where);
4538 		  }
4539 		gfc_ref *array_ref = NULL;
4540 		bool resolved = false;
4541 		if (n->expr)
4542 		  {
4543 		    array_ref = n->expr->ref;
4544 		    resolved = gfc_resolve_expr (n->expr);
4545 
4546 		    /* Look through component refs to find last array
4547 		       reference.  */
4548 		    if (openacc && resolved)
4549 		      {
4550 			/* The "!$acc cache" directive allows rectangular
4551 			   subarrays to be specified, with some restrictions
4552 			   on the form of bounds (not implemented).
4553 			   Only raise an error here if we're really sure the
4554 			   array isn't contiguous.  An expression such as
4555 			   arr(-n:n,-n:n) could be contiguous even if it looks
4556 			   like it may not be.  */
4557 			if (list != OMP_LIST_CACHE
4558 			    && !gfc_is_simply_contiguous (n->expr, false, true)
4559 			    && gfc_is_not_contiguous (n->expr))
4560 			  gfc_error ("Array is not contiguous at %L",
4561 				     &n->where);
4562 
4563 			while (array_ref
4564 			       && (array_ref->type == REF_COMPONENT
4565 				   || (array_ref->type == REF_ARRAY
4566 				       && array_ref->next
4567 				       && (array_ref->next->type
4568 					   == REF_COMPONENT))))
4569 			  array_ref = array_ref->next;
4570 		      }
4571 		  }
4572 		if (array_ref
4573 		    || (n->expr
4574 			&& (!resolved || n->expr->expr_type != EXPR_VARIABLE)))
4575 		  {
4576 		    if (!resolved
4577 			|| n->expr->expr_type != EXPR_VARIABLE
4578 			|| array_ref->next
4579 			|| array_ref->type != REF_ARRAY)
4580 		      gfc_error ("%qs in %s clause at %L is not a proper "
4581 				 "array section", n->sym->name, name,
4582 				 &n->where);
4583 		    else
4584 		      {
4585 			int i;
4586 			gfc_array_ref *ar = &array_ref->u.ar;
4587 			for (i = 0; i < ar->dimen; i++)
4588 			  if (ar->stride[i])
4589 			    {
4590 			      gfc_error ("Stride should not be specified for "
4591 					 "array section in %s clause at %L",
4592 					 name, &n->where);
4593 			      break;
4594 			    }
4595 			  else if (ar->dimen_type[i] != DIMEN_ELEMENT
4596 				   && ar->dimen_type[i] != DIMEN_RANGE)
4597 			    {
4598 			      gfc_error ("%qs in %s clause at %L is not a "
4599 					 "proper array section",
4600 					 n->sym->name, name, &n->where);
4601 			      break;
4602 			    }
4603 			  else if (list == OMP_LIST_DEPEND
4604 				   && ar->start[i]
4605 				   && ar->start[i]->expr_type == EXPR_CONSTANT
4606 				   && ar->end[i]
4607 				   && ar->end[i]->expr_type == EXPR_CONSTANT
4608 				   && mpz_cmp (ar->start[i]->value.integer,
4609 					       ar->end[i]->value.integer) > 0)
4610 			    {
4611 			      gfc_error ("%qs in DEPEND clause at %L is a "
4612 					 "zero size array section",
4613 					 n->sym->name, &n->where);
4614 			      break;
4615 			    }
4616 		      }
4617 		  }
4618 		else if (openacc)
4619 		  {
4620 		    if (list == OMP_LIST_MAP
4621 			&& n->u.map_op == OMP_MAP_FORCE_DEVICEPTR)
4622 		      resolve_oacc_deviceptr_clause (n->sym, n->where, name);
4623 		    else
4624 		      resolve_oacc_data_clauses (n->sym, n->where, name);
4625 		  }
4626 		else if (list != OMP_LIST_DEPEND
4627 			 && n->sym->as
4628 			 && n->sym->as->type == AS_ASSUMED_SIZE)
4629 		  gfc_error ("Assumed size array %qs in %s clause at %L",
4630 			     n->sym->name, name, &n->where);
4631 		if (list == OMP_LIST_MAP && !openacc)
4632 		  switch (code->op)
4633 		    {
4634 		    case EXEC_OMP_TARGET:
4635 		    case EXEC_OMP_TARGET_DATA:
4636 		      switch (n->u.map_op)
4637 			{
4638 			case OMP_MAP_TO:
4639 			case OMP_MAP_ALWAYS_TO:
4640 			case OMP_MAP_FROM:
4641 			case OMP_MAP_ALWAYS_FROM:
4642 			case OMP_MAP_TOFROM:
4643 			case OMP_MAP_ALWAYS_TOFROM:
4644 			case OMP_MAP_ALLOC:
4645 			  break;
4646 			default:
4647 			  gfc_error ("TARGET%s with map-type other than TO, "
4648 				     "FROM, TOFROM, or ALLOC on MAP clause "
4649 				     "at %L",
4650 				     code->op == EXEC_OMP_TARGET
4651 				     ? "" : " DATA", &n->where);
4652 			  break;
4653 			}
4654 		      break;
4655 		    case EXEC_OMP_TARGET_ENTER_DATA:
4656 		      switch (n->u.map_op)
4657 			{
4658 			case OMP_MAP_TO:
4659 			case OMP_MAP_ALWAYS_TO:
4660 			case OMP_MAP_ALLOC:
4661 			  break;
4662 			default:
4663 			  gfc_error ("TARGET ENTER DATA with map-type other "
4664 				     "than TO, or ALLOC on MAP clause at %L",
4665 				     &n->where);
4666 			  break;
4667 			}
4668 		      break;
4669 		    case EXEC_OMP_TARGET_EXIT_DATA:
4670 		      switch (n->u.map_op)
4671 			{
4672 			case OMP_MAP_FROM:
4673 			case OMP_MAP_ALWAYS_FROM:
4674 			case OMP_MAP_RELEASE:
4675 			case OMP_MAP_DELETE:
4676 			  break;
4677 			default:
4678 			  gfc_error ("TARGET EXIT DATA with map-type other "
4679 				     "than FROM, RELEASE, or DELETE on MAP "
4680 				     "clause at %L", &n->where);
4681 			  break;
4682 			}
4683 		      break;
4684 		    default:
4685 		      break;
4686 		    }
4687 	      }
4688 
4689 	    if (list != OMP_LIST_DEPEND)
4690 	      for (n = omp_clauses->lists[list]; n != NULL; n = n->next)
4691 		{
4692 		  n->sym->attr.referenced = 1;
4693 		  if (n->sym->attr.threadprivate)
4694 		    gfc_error ("THREADPRIVATE object %qs in %s clause at %L",
4695 			       n->sym->name, name, &n->where);
4696 		  if (n->sym->attr.cray_pointee)
4697 		    gfc_error ("Cray pointee %qs in %s clause at %L",
4698 			       n->sym->name, name, &n->where);
4699 		}
4700 	    break;
4701 	  case OMP_LIST_IS_DEVICE_PTR:
4702 	    if (!n->sym->attr.dummy)
4703 	      gfc_error ("Non-dummy object %qs in %s clause at %L",
4704 			 n->sym->name, name, &n->where);
4705 	    if (n->sym->attr.allocatable
4706 		|| (n->sym->ts.type == BT_CLASS
4707 		    && CLASS_DATA (n->sym)->attr.allocatable))
4708 	      gfc_error ("ALLOCATABLE object %qs in %s clause at %L",
4709 			 n->sym->name, name, &n->where);
4710 	    if (n->sym->attr.pointer
4711 		|| (n->sym->ts.type == BT_CLASS
4712 		    && CLASS_DATA (n->sym)->attr.pointer))
4713 	      gfc_error ("POINTER object %qs in %s clause at %L",
4714 			 n->sym->name, name, &n->where);
4715 	    if (n->sym->attr.value)
4716 	      gfc_error ("VALUE object %qs in %s clause at %L",
4717 			 n->sym->name, name, &n->where);
4718 	    break;
4719 	  case OMP_LIST_USE_DEVICE_PTR:
4720 	  case OMP_LIST_USE_DEVICE_ADDR:
4721 	    /* FIXME: Handle OMP_LIST_USE_DEVICE_PTR.  */
4722 	    break;
4723 	  default:
4724 	    for (; n != NULL; n = n->next)
4725 	      {
4726 		bool bad = false;
4727 		if (n->sym->attr.threadprivate)
4728 		  gfc_error ("THREADPRIVATE object %qs in %s clause at %L",
4729 			     n->sym->name, name, &n->where);
4730 		if (n->sym->attr.cray_pointee)
4731 		  gfc_error ("Cray pointee %qs in %s clause at %L",
4732 			    n->sym->name, name, &n->where);
4733 		if (n->sym->attr.associate_var)
4734 		  gfc_error ("ASSOCIATE name %qs in %s clause at %L",
4735 			     n->sym->name, name, &n->where);
4736 		if (list != OMP_LIST_PRIVATE)
4737 		  {
4738 		    if (n->sym->attr.proc_pointer && list == OMP_LIST_REDUCTION)
4739 		      gfc_error ("Procedure pointer %qs in %s clause at %L",
4740 				 n->sym->name, name, &n->where);
4741 		    if (n->sym->attr.pointer && list == OMP_LIST_REDUCTION)
4742 		      gfc_error ("POINTER object %qs in %s clause at %L",
4743 				 n->sym->name, name, &n->where);
4744 		    if (n->sym->attr.cray_pointer && list == OMP_LIST_REDUCTION)
4745 		      gfc_error ("Cray pointer %qs in %s clause at %L",
4746 				 n->sym->name, name, &n->where);
4747 		  }
4748 		if (code
4749 		    && (oacc_is_loop (code)
4750 			|| code->op == EXEC_OACC_PARALLEL
4751 			|| code->op == EXEC_OACC_SERIAL))
4752 		  check_array_not_assumed (n->sym, n->where, name);
4753 		else if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE)
4754 		  gfc_error ("Assumed size array %qs in %s clause at %L",
4755 			     n->sym->name, name, &n->where);
4756 		if (n->sym->attr.in_namelist && list != OMP_LIST_REDUCTION)
4757 		  gfc_error ("Variable %qs in %s clause is used in "
4758 			     "NAMELIST statement at %L",
4759 			     n->sym->name, name, &n->where);
4760 		if (n->sym->attr.pointer && n->sym->attr.intent == INTENT_IN)
4761 		  switch (list)
4762 		    {
4763 		    case OMP_LIST_PRIVATE:
4764 		    case OMP_LIST_LASTPRIVATE:
4765 		    case OMP_LIST_LINEAR:
4766 		    /* case OMP_LIST_REDUCTION: */
4767 		      gfc_error ("INTENT(IN) POINTER %qs in %s clause at %L",
4768 				 n->sym->name, name, &n->where);
4769 		      break;
4770 		    default:
4771 		      break;
4772 		    }
4773 
4774 		switch (list)
4775 		  {
4776 		  case OMP_LIST_REDUCTION:
4777 		    switch (n->u.reduction_op)
4778 		      {
4779 		      case OMP_REDUCTION_PLUS:
4780 		      case OMP_REDUCTION_TIMES:
4781 		      case OMP_REDUCTION_MINUS:
4782 			if (!gfc_numeric_ts (&n->sym->ts))
4783 			  bad = true;
4784 			break;
4785 		      case OMP_REDUCTION_AND:
4786 		      case OMP_REDUCTION_OR:
4787 		      case OMP_REDUCTION_EQV:
4788 		      case OMP_REDUCTION_NEQV:
4789 			if (n->sym->ts.type != BT_LOGICAL)
4790 			  bad = true;
4791 			break;
4792 		      case OMP_REDUCTION_MAX:
4793 		      case OMP_REDUCTION_MIN:
4794 			if (n->sym->ts.type != BT_INTEGER
4795 			    && n->sym->ts.type != BT_REAL)
4796 			  bad = true;
4797 			break;
4798 		      case OMP_REDUCTION_IAND:
4799 		      case OMP_REDUCTION_IOR:
4800 		      case OMP_REDUCTION_IEOR:
4801 			if (n->sym->ts.type != BT_INTEGER)
4802 			  bad = true;
4803 			break;
4804 		      case OMP_REDUCTION_USER:
4805 			bad = true;
4806 			break;
4807 		      default:
4808 			break;
4809 		      }
4810 		    if (!bad)
4811 		      n->udr = NULL;
4812 		    else
4813 		      {
4814 			const char *udr_name = NULL;
4815 			if (n->udr)
4816 			  {
4817 			    udr_name = n->udr->udr->name;
4818 			    n->udr->udr
4819 			      = gfc_find_omp_udr (NULL, udr_name,
4820 						  &n->sym->ts);
4821 			    if (n->udr->udr == NULL)
4822 			      {
4823 				free (n->udr);
4824 				n->udr = NULL;
4825 			      }
4826 			  }
4827 			if (n->udr == NULL)
4828 			  {
4829 			    if (udr_name == NULL)
4830 			      switch (n->u.reduction_op)
4831 				{
4832 				case OMP_REDUCTION_PLUS:
4833 				case OMP_REDUCTION_TIMES:
4834 				case OMP_REDUCTION_MINUS:
4835 				case OMP_REDUCTION_AND:
4836 				case OMP_REDUCTION_OR:
4837 				case OMP_REDUCTION_EQV:
4838 				case OMP_REDUCTION_NEQV:
4839 				  udr_name = gfc_op2string ((gfc_intrinsic_op)
4840 							    n->u.reduction_op);
4841 				  break;
4842 				case OMP_REDUCTION_MAX:
4843 				  udr_name = "max";
4844 				  break;
4845 				case OMP_REDUCTION_MIN:
4846 				  udr_name = "min";
4847 				  break;
4848 				case OMP_REDUCTION_IAND:
4849 				  udr_name = "iand";
4850 				  break;
4851 				case OMP_REDUCTION_IOR:
4852 				  udr_name = "ior";
4853 				  break;
4854 				case OMP_REDUCTION_IEOR:
4855 				  udr_name = "ieor";
4856 				  break;
4857 				default:
4858 				  gcc_unreachable ();
4859 				}
4860 			    gfc_error ("!$OMP DECLARE REDUCTION %s not found "
4861 				       "for type %s at %L", udr_name,
4862 				       gfc_typename (&n->sym->ts), &n->where);
4863 			  }
4864 			else
4865 			  {
4866 			    gfc_omp_udr *udr = n->udr->udr;
4867 			    n->u.reduction_op = OMP_REDUCTION_USER;
4868 			    n->udr->combiner
4869 			      = resolve_omp_udr_clause (n, udr->combiner_ns,
4870 							udr->omp_out,
4871 							udr->omp_in);
4872 			    if (udr->initializer_ns)
4873 			      n->udr->initializer
4874 				= resolve_omp_udr_clause (n,
4875 							  udr->initializer_ns,
4876 							  udr->omp_priv,
4877 							  udr->omp_orig);
4878 			  }
4879 		      }
4880 		    break;
4881 		  case OMP_LIST_LINEAR:
4882 		    if (code
4883 			&& n->u.linear_op != OMP_LINEAR_DEFAULT
4884 			&& n->u.linear_op != linear_op)
4885 		      {
4886 			gfc_error ("LINEAR clause modifier used on DO or SIMD"
4887 				   " construct at %L", &n->where);
4888 			linear_op = n->u.linear_op;
4889 		      }
4890 		    else if (omp_clauses->orderedc)
4891 		      gfc_error ("LINEAR clause specified together with "
4892 				 "ORDERED clause with argument at %L",
4893 				 &n->where);
4894 		    else if (n->u.linear_op != OMP_LINEAR_REF
4895 			     && n->sym->ts.type != BT_INTEGER)
4896 		      gfc_error ("LINEAR variable %qs must be INTEGER "
4897 				 "at %L", n->sym->name, &n->where);
4898 		    else if ((n->u.linear_op == OMP_LINEAR_REF
4899 			      || n->u.linear_op == OMP_LINEAR_UVAL)
4900 			     && n->sym->attr.value)
4901 		      gfc_error ("LINEAR dummy argument %qs with VALUE "
4902 				 "attribute with %s modifier at %L",
4903 				 n->sym->name,
4904 				 n->u.linear_op == OMP_LINEAR_REF
4905 				 ? "REF" : "UVAL", &n->where);
4906 		    else if (n->expr)
4907 		      {
4908 			gfc_expr *expr = n->expr;
4909 			if (!gfc_resolve_expr (expr)
4910 			    || expr->ts.type != BT_INTEGER
4911 			    || expr->rank != 0)
4912 			  gfc_error ("%qs in LINEAR clause at %L requires "
4913 				     "a scalar integer linear-step expression",
4914 				     n->sym->name, &n->where);
4915 			else if (!code && expr->expr_type != EXPR_CONSTANT)
4916 			  {
4917 			    if (expr->expr_type == EXPR_VARIABLE
4918 				&& expr->symtree->n.sym->attr.dummy
4919 				&& expr->symtree->n.sym->ns == ns)
4920 			      {
4921 				gfc_omp_namelist *n2;
4922 				for (n2 = omp_clauses->lists[OMP_LIST_UNIFORM];
4923 				     n2; n2 = n2->next)
4924 				  if (n2->sym == expr->symtree->n.sym)
4925 				    break;
4926 				if (n2)
4927 				  break;
4928 			      }
4929 			    gfc_error ("%qs in LINEAR clause at %L requires "
4930 				       "a constant integer linear-step "
4931 				       "expression or dummy argument "
4932 				       "specified in UNIFORM clause",
4933 				       n->sym->name, &n->where);
4934 			  }
4935 		      }
4936 		    break;
4937 		  /* Workaround for PR middle-end/26316, nothing really needs
4938 		     to be done here for OMP_LIST_PRIVATE.  */
4939 		  case OMP_LIST_PRIVATE:
4940 		    gcc_assert (code && code->op != EXEC_NOP);
4941 		    break;
4942 		  case OMP_LIST_USE_DEVICE:
4943 		      if (n->sym->attr.allocatable
4944 			  || (n->sym->ts.type == BT_CLASS && CLASS_DATA (n->sym)
4945 			      && CLASS_DATA (n->sym)->attr.allocatable))
4946 			gfc_error ("ALLOCATABLE object %qs in %s clause at %L",
4947 				   n->sym->name, name, &n->where);
4948 		      if (n->sym->ts.type == BT_CLASS
4949 			  && CLASS_DATA (n->sym)
4950 			  && CLASS_DATA (n->sym)->attr.class_pointer)
4951 			gfc_error ("POINTER object %qs of polymorphic type in "
4952 				   "%s clause at %L", n->sym->name, name,
4953 				   &n->where);
4954 		      if (n->sym->attr.cray_pointer)
4955 			gfc_error ("Cray pointer object %qs in %s clause at %L",
4956 				   n->sym->name, name, &n->where);
4957 		      else if (n->sym->attr.cray_pointee)
4958 			gfc_error ("Cray pointee object %qs in %s clause at %L",
4959 				   n->sym->name, name, &n->where);
4960 		      else if (n->sym->attr.flavor == FL_VARIABLE
4961 			       && !n->sym->as
4962 			       && !n->sym->attr.pointer)
4963 			gfc_error ("%s clause variable %qs at %L is neither "
4964 				   "a POINTER nor an array", name,
4965 				   n->sym->name, &n->where);
4966 		      /* FALLTHRU */
4967 		  case OMP_LIST_DEVICE_RESIDENT:
4968 		    check_symbol_not_pointer (n->sym, n->where, name);
4969 		    check_array_not_assumed (n->sym, n->where, name);
4970 		    break;
4971 		  default:
4972 		    break;
4973 		  }
4974 	      }
4975 	    break;
4976 	  }
4977       }
4978   if (omp_clauses->safelen_expr)
4979     resolve_positive_int_expr (omp_clauses->safelen_expr, "SAFELEN");
4980   if (omp_clauses->simdlen_expr)
4981     resolve_positive_int_expr (omp_clauses->simdlen_expr, "SIMDLEN");
4982   if (omp_clauses->num_teams)
4983     resolve_positive_int_expr (omp_clauses->num_teams, "NUM_TEAMS");
4984   if (omp_clauses->device)
4985     resolve_nonnegative_int_expr (omp_clauses->device, "DEVICE");
4986   if (omp_clauses->hint)
4987     resolve_scalar_int_expr (omp_clauses->hint, "HINT");
4988   if (omp_clauses->priority)
4989     resolve_nonnegative_int_expr (omp_clauses->priority, "PRIORITY");
4990   if (omp_clauses->dist_chunk_size)
4991     {
4992       gfc_expr *expr = omp_clauses->dist_chunk_size;
4993       if (!gfc_resolve_expr (expr)
4994 	  || expr->ts.type != BT_INTEGER || expr->rank != 0)
4995 	gfc_error ("DIST_SCHEDULE clause's chunk_size at %L requires "
4996 		   "a scalar INTEGER expression", &expr->where);
4997     }
4998   if (omp_clauses->thread_limit)
4999     resolve_positive_int_expr (omp_clauses->thread_limit, "THREAD_LIMIT");
5000   if (omp_clauses->grainsize)
5001     resolve_positive_int_expr (omp_clauses->grainsize, "GRAINSIZE");
5002   if (omp_clauses->num_tasks)
5003     resolve_positive_int_expr (omp_clauses->num_tasks, "NUM_TASKS");
5004   if (omp_clauses->async)
5005     if (omp_clauses->async_expr)
5006       resolve_scalar_int_expr (omp_clauses->async_expr, "ASYNC");
5007   if (omp_clauses->num_gangs_expr)
5008     resolve_positive_int_expr (omp_clauses->num_gangs_expr, "NUM_GANGS");
5009   if (omp_clauses->num_workers_expr)
5010     resolve_positive_int_expr (omp_clauses->num_workers_expr, "NUM_WORKERS");
5011   if (omp_clauses->vector_length_expr)
5012     resolve_positive_int_expr (omp_clauses->vector_length_expr,
5013 			       "VECTOR_LENGTH");
5014   if (omp_clauses->gang_num_expr)
5015     resolve_positive_int_expr (omp_clauses->gang_num_expr, "GANG");
5016   if (omp_clauses->gang_static_expr)
5017     resolve_positive_int_expr (omp_clauses->gang_static_expr, "GANG");
5018   if (omp_clauses->worker_expr)
5019     resolve_positive_int_expr (omp_clauses->worker_expr, "WORKER");
5020   if (omp_clauses->vector_expr)
5021     resolve_positive_int_expr (omp_clauses->vector_expr, "VECTOR");
5022   for (el = omp_clauses->wait_list; el; el = el->next)
5023     resolve_scalar_int_expr (el->expr, "WAIT");
5024   if (omp_clauses->collapse && omp_clauses->tile_list)
5025     gfc_error ("Incompatible use of TILE and COLLAPSE at %L", &code->loc);
5026   if (omp_clauses->depend_source && code->op != EXEC_OMP_ORDERED)
5027     gfc_error ("SOURCE dependence type only allowed "
5028 	       "on ORDERED directive at %L", &code->loc);
5029   if (!openacc && code && omp_clauses->lists[OMP_LIST_MAP] == NULL)
5030     {
5031       const char *p = NULL;
5032       switch (code->op)
5033 	{
5034 	case EXEC_OMP_TARGET_DATA: p = "TARGET DATA"; break;
5035 	case EXEC_OMP_TARGET_ENTER_DATA: p = "TARGET ENTER DATA"; break;
5036 	case EXEC_OMP_TARGET_EXIT_DATA: p = "TARGET EXIT DATA"; break;
5037 	default: break;
5038 	}
5039       if (p)
5040 	gfc_error ("%s must contain at least one MAP clause at %L",
5041 		   p, &code->loc);
5042     }
5043 }
5044 
5045 
5046 /* Return true if SYM is ever referenced in EXPR except in the SE node.  */
5047 
5048 static bool
expr_references_sym(gfc_expr * e,gfc_symbol * s,gfc_expr * se)5049 expr_references_sym (gfc_expr *e, gfc_symbol *s, gfc_expr *se)
5050 {
5051   gfc_actual_arglist *arg;
5052   if (e == NULL || e == se)
5053     return false;
5054   switch (e->expr_type)
5055     {
5056     case EXPR_CONSTANT:
5057     case EXPR_NULL:
5058     case EXPR_VARIABLE:
5059     case EXPR_STRUCTURE:
5060     case EXPR_ARRAY:
5061       if (e->symtree != NULL
5062 	  && e->symtree->n.sym == s)
5063 	return true;
5064       return false;
5065     case EXPR_SUBSTRING:
5066       if (e->ref != NULL
5067 	  && (expr_references_sym (e->ref->u.ss.start, s, se)
5068 	      || expr_references_sym (e->ref->u.ss.end, s, se)))
5069 	return true;
5070       return false;
5071     case EXPR_OP:
5072       if (expr_references_sym (e->value.op.op2, s, se))
5073 	return true;
5074       return expr_references_sym (e->value.op.op1, s, se);
5075     case EXPR_FUNCTION:
5076       for (arg = e->value.function.actual; arg; arg = arg->next)
5077 	if (expr_references_sym (arg->expr, s, se))
5078 	  return true;
5079       return false;
5080     default:
5081       gcc_unreachable ();
5082     }
5083 }
5084 
5085 
5086 /* If EXPR is a conversion function that widens the type
5087    if WIDENING is true or narrows the type if WIDENING is false,
5088    return the inner expression, otherwise return NULL.  */
5089 
5090 static gfc_expr *
is_conversion(gfc_expr * expr,bool widening)5091 is_conversion (gfc_expr *expr, bool widening)
5092 {
5093   gfc_typespec *ts1, *ts2;
5094 
5095   if (expr->expr_type != EXPR_FUNCTION
5096       || expr->value.function.isym == NULL
5097       || expr->value.function.esym != NULL
5098       || expr->value.function.isym->id != GFC_ISYM_CONVERSION)
5099     return NULL;
5100 
5101   if (widening)
5102     {
5103       ts1 = &expr->ts;
5104       ts2 = &expr->value.function.actual->expr->ts;
5105     }
5106   else
5107     {
5108       ts1 = &expr->value.function.actual->expr->ts;
5109       ts2 = &expr->ts;
5110     }
5111 
5112   if (ts1->type > ts2->type
5113       || (ts1->type == ts2->type && ts1->kind > ts2->kind))
5114     return expr->value.function.actual->expr;
5115 
5116   return NULL;
5117 }
5118 
5119 
5120 static void
resolve_omp_atomic(gfc_code * code)5121 resolve_omp_atomic (gfc_code *code)
5122 {
5123   gfc_code *atomic_code = code;
5124   gfc_symbol *var;
5125   gfc_expr *expr2, *expr2_tmp;
5126   gfc_omp_atomic_op aop
5127     = (gfc_omp_atomic_op) (atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_MASK);
5128 
5129   code = code->block->next;
5130   /* resolve_blocks asserts this is initially EXEC_ASSIGN.
5131      If it changed to EXEC_NOP, assume an error has been emitted already.  */
5132   if (code->op == EXEC_NOP)
5133     return;
5134   if (code->op != EXEC_ASSIGN)
5135     {
5136     unexpected:
5137       gfc_error ("unexpected !$OMP ATOMIC expression at %L", &code->loc);
5138       return;
5139     }
5140   if (aop != GFC_OMP_ATOMIC_CAPTURE)
5141     {
5142       if (code->next != NULL)
5143 	goto unexpected;
5144     }
5145   else
5146     {
5147       if (code->next == NULL)
5148 	goto unexpected;
5149       if (code->next->op == EXEC_NOP)
5150 	return;
5151       if (code->next->op != EXEC_ASSIGN || code->next->next)
5152 	{
5153 	  code = code->next;
5154 	  goto unexpected;
5155 	}
5156     }
5157 
5158   if (code->expr1->expr_type != EXPR_VARIABLE
5159       || code->expr1->symtree == NULL
5160       || code->expr1->rank != 0
5161       || (code->expr1->ts.type != BT_INTEGER
5162 	  && code->expr1->ts.type != BT_REAL
5163 	  && code->expr1->ts.type != BT_COMPLEX
5164 	  && code->expr1->ts.type != BT_LOGICAL))
5165     {
5166       gfc_error ("!$OMP ATOMIC statement must set a scalar variable of "
5167 		 "intrinsic type at %L", &code->loc);
5168       return;
5169     }
5170 
5171   var = code->expr1->symtree->n.sym;
5172   expr2 = is_conversion (code->expr2, false);
5173   if (expr2 == NULL)
5174     {
5175       if (aop == GFC_OMP_ATOMIC_READ || aop == GFC_OMP_ATOMIC_WRITE)
5176 	expr2 = is_conversion (code->expr2, true);
5177       if (expr2 == NULL)
5178 	expr2 = code->expr2;
5179     }
5180 
5181   switch (aop)
5182     {
5183     case GFC_OMP_ATOMIC_READ:
5184       if (expr2->expr_type != EXPR_VARIABLE
5185 	  || expr2->symtree == NULL
5186 	  || expr2->rank != 0
5187 	  || (expr2->ts.type != BT_INTEGER
5188 	      && expr2->ts.type != BT_REAL
5189 	      && expr2->ts.type != BT_COMPLEX
5190 	      && expr2->ts.type != BT_LOGICAL))
5191 	gfc_error ("!$OMP ATOMIC READ statement must read from a scalar "
5192 		   "variable of intrinsic type at %L", &expr2->where);
5193       return;
5194     case GFC_OMP_ATOMIC_WRITE:
5195       if (expr2->rank != 0 || expr_references_sym (code->expr2, var, NULL))
5196 	gfc_error ("expr in !$OMP ATOMIC WRITE assignment var = expr "
5197 		   "must be scalar and cannot reference var at %L",
5198 		   &expr2->where);
5199       return;
5200     case GFC_OMP_ATOMIC_CAPTURE:
5201       expr2_tmp = expr2;
5202       if (expr2 == code->expr2)
5203 	{
5204 	  expr2_tmp = is_conversion (code->expr2, true);
5205 	  if (expr2_tmp == NULL)
5206 	    expr2_tmp = expr2;
5207 	}
5208       if (expr2_tmp->expr_type == EXPR_VARIABLE)
5209 	{
5210 	  if (expr2_tmp->symtree == NULL
5211 	      || expr2_tmp->rank != 0
5212 	      || (expr2_tmp->ts.type != BT_INTEGER
5213 		  && expr2_tmp->ts.type != BT_REAL
5214 		  && expr2_tmp->ts.type != BT_COMPLEX
5215 		  && expr2_tmp->ts.type != BT_LOGICAL)
5216 	      || expr2_tmp->symtree->n.sym == var)
5217 	    {
5218 	      gfc_error ("!$OMP ATOMIC CAPTURE capture statement must read from "
5219 			 "a scalar variable of intrinsic type at %L",
5220 			 &expr2_tmp->where);
5221 	      return;
5222 	    }
5223 	  var = expr2_tmp->symtree->n.sym;
5224 	  code = code->next;
5225 	  if (code->expr1->expr_type != EXPR_VARIABLE
5226 	      || code->expr1->symtree == NULL
5227 	      || code->expr1->rank != 0
5228 	      || (code->expr1->ts.type != BT_INTEGER
5229 		  && code->expr1->ts.type != BT_REAL
5230 		  && code->expr1->ts.type != BT_COMPLEX
5231 		  && code->expr1->ts.type != BT_LOGICAL))
5232 	    {
5233 	      gfc_error ("!$OMP ATOMIC CAPTURE update statement must set "
5234 			 "a scalar variable of intrinsic type at %L",
5235 			 &code->expr1->where);
5236 	      return;
5237 	    }
5238 	  if (code->expr1->symtree->n.sym != var)
5239 	    {
5240 	      gfc_error ("!$OMP ATOMIC CAPTURE capture statement reads from "
5241 			 "different variable than update statement writes "
5242 			 "into at %L", &code->expr1->where);
5243 	      return;
5244 	    }
5245 	  expr2 = is_conversion (code->expr2, false);
5246 	  if (expr2 == NULL)
5247 	    expr2 = code->expr2;
5248 	}
5249       break;
5250     default:
5251       break;
5252     }
5253 
5254   if (gfc_expr_attr (code->expr1).allocatable)
5255     {
5256       gfc_error ("!$OMP ATOMIC with ALLOCATABLE variable at %L",
5257 		 &code->loc);
5258       return;
5259     }
5260 
5261   if (aop == GFC_OMP_ATOMIC_CAPTURE
5262       && code->next == NULL
5263       && code->expr2->rank == 0
5264       && !expr_references_sym (code->expr2, var, NULL))
5265     atomic_code->ext.omp_atomic
5266       = (gfc_omp_atomic_op) (atomic_code->ext.omp_atomic
5267 			     | GFC_OMP_ATOMIC_SWAP);
5268   else if (expr2->expr_type == EXPR_OP)
5269     {
5270       gfc_expr *v = NULL, *e, *c;
5271       gfc_intrinsic_op op = expr2->value.op.op;
5272       gfc_intrinsic_op alt_op = INTRINSIC_NONE;
5273 
5274       switch (op)
5275 	{
5276 	case INTRINSIC_PLUS:
5277 	  alt_op = INTRINSIC_MINUS;
5278 	  break;
5279 	case INTRINSIC_TIMES:
5280 	  alt_op = INTRINSIC_DIVIDE;
5281 	  break;
5282 	case INTRINSIC_MINUS:
5283 	  alt_op = INTRINSIC_PLUS;
5284 	  break;
5285 	case INTRINSIC_DIVIDE:
5286 	  alt_op = INTRINSIC_TIMES;
5287 	  break;
5288 	case INTRINSIC_AND:
5289 	case INTRINSIC_OR:
5290 	  break;
5291 	case INTRINSIC_EQV:
5292 	  alt_op = INTRINSIC_NEQV;
5293 	  break;
5294 	case INTRINSIC_NEQV:
5295 	  alt_op = INTRINSIC_EQV;
5296 	  break;
5297 	default:
5298 	  gfc_error ("!$OMP ATOMIC assignment operator must be binary "
5299 		     "+, *, -, /, .AND., .OR., .EQV. or .NEQV. at %L",
5300 		     &expr2->where);
5301 	  return;
5302 	}
5303 
5304       /* Check for var = var op expr resp. var = expr op var where
5305 	 expr doesn't reference var and var op expr is mathematically
5306 	 equivalent to var op (expr) resp. expr op var equivalent to
5307 	 (expr) op var.  We rely here on the fact that the matcher
5308 	 for x op1 y op2 z where op1 and op2 have equal precedence
5309 	 returns (x op1 y) op2 z.  */
5310       e = expr2->value.op.op2;
5311       if (e->expr_type == EXPR_VARIABLE
5312 	  && e->symtree != NULL
5313 	  && e->symtree->n.sym == var)
5314 	v = e;
5315       else if ((c = is_conversion (e, true)) != NULL
5316 	       && c->expr_type == EXPR_VARIABLE
5317 	       && c->symtree != NULL
5318 	       && c->symtree->n.sym == var)
5319 	v = c;
5320       else
5321 	{
5322 	  gfc_expr **p = NULL, **q;
5323 	  for (q = &expr2->value.op.op1; (e = *q) != NULL; )
5324 	    if (e->expr_type == EXPR_VARIABLE
5325 		&& e->symtree != NULL
5326 		&& e->symtree->n.sym == var)
5327 	      {
5328 		v = e;
5329 		break;
5330 	      }
5331 	    else if ((c = is_conversion (e, true)) != NULL)
5332 	      q = &e->value.function.actual->expr;
5333 	    else if (e->expr_type != EXPR_OP
5334 		     || (e->value.op.op != op
5335 			 && e->value.op.op != alt_op)
5336 		     || e->rank != 0)
5337 	      break;
5338 	    else
5339 	      {
5340 		p = q;
5341 		q = &e->value.op.op1;
5342 	      }
5343 
5344 	  if (v == NULL)
5345 	    {
5346 	      gfc_error ("!$OMP ATOMIC assignment must be var = var op expr "
5347 			 "or var = expr op var at %L", &expr2->where);
5348 	      return;
5349 	    }
5350 
5351 	  if (p != NULL)
5352 	    {
5353 	      e = *p;
5354 	      switch (e->value.op.op)
5355 		{
5356 		case INTRINSIC_MINUS:
5357 		case INTRINSIC_DIVIDE:
5358 		case INTRINSIC_EQV:
5359 		case INTRINSIC_NEQV:
5360 		  gfc_error ("!$OMP ATOMIC var = var op expr not "
5361 			     "mathematically equivalent to var = var op "
5362 			     "(expr) at %L", &expr2->where);
5363 		  break;
5364 		default:
5365 		  break;
5366 		}
5367 
5368 	      /* Canonicalize into var = var op (expr).  */
5369 	      *p = e->value.op.op2;
5370 	      e->value.op.op2 = expr2;
5371 	      e->ts = expr2->ts;
5372 	      if (code->expr2 == expr2)
5373 		code->expr2 = expr2 = e;
5374 	      else
5375 		code->expr2->value.function.actual->expr = expr2 = e;
5376 
5377 	      if (!gfc_compare_types (&expr2->value.op.op1->ts, &expr2->ts))
5378 		{
5379 		  for (p = &expr2->value.op.op1; *p != v;
5380 		       p = &(*p)->value.function.actual->expr)
5381 		    ;
5382 		  *p = NULL;
5383 		  gfc_free_expr (expr2->value.op.op1);
5384 		  expr2->value.op.op1 = v;
5385 		  gfc_convert_type (v, &expr2->ts, 2);
5386 		}
5387 	    }
5388 	}
5389 
5390       if (e->rank != 0 || expr_references_sym (code->expr2, var, v))
5391 	{
5392 	  gfc_error ("expr in !$OMP ATOMIC assignment var = var op expr "
5393 		     "must be scalar and cannot reference var at %L",
5394 		     &expr2->where);
5395 	  return;
5396 	}
5397     }
5398   else if (expr2->expr_type == EXPR_FUNCTION
5399 	   && expr2->value.function.isym != NULL
5400 	   && expr2->value.function.esym == NULL
5401 	   && expr2->value.function.actual != NULL
5402 	   && expr2->value.function.actual->next != NULL)
5403     {
5404       gfc_actual_arglist *arg, *var_arg;
5405 
5406       switch (expr2->value.function.isym->id)
5407 	{
5408 	case GFC_ISYM_MIN:
5409 	case GFC_ISYM_MAX:
5410 	  break;
5411 	case GFC_ISYM_IAND:
5412 	case GFC_ISYM_IOR:
5413 	case GFC_ISYM_IEOR:
5414 	  if (expr2->value.function.actual->next->next != NULL)
5415 	    {
5416 	      gfc_error ("!$OMP ATOMIC assignment intrinsic IAND, IOR "
5417 			 "or IEOR must have two arguments at %L",
5418 			 &expr2->where);
5419 	      return;
5420 	    }
5421 	  break;
5422 	default:
5423 	  gfc_error ("!$OMP ATOMIC assignment intrinsic must be "
5424 		     "MIN, MAX, IAND, IOR or IEOR at %L",
5425 		     &expr2->where);
5426 	  return;
5427 	}
5428 
5429       var_arg = NULL;
5430       for (arg = expr2->value.function.actual; arg; arg = arg->next)
5431 	{
5432 	  if ((arg == expr2->value.function.actual
5433 	       || (var_arg == NULL && arg->next == NULL))
5434 	      && arg->expr->expr_type == EXPR_VARIABLE
5435 	      && arg->expr->symtree != NULL
5436 	      && arg->expr->symtree->n.sym == var)
5437 	    var_arg = arg;
5438 	  else if (expr_references_sym (arg->expr, var, NULL))
5439 	    {
5440 	      gfc_error ("!$OMP ATOMIC intrinsic arguments except one must "
5441 			 "not reference %qs at %L",
5442 			 var->name, &arg->expr->where);
5443 	      return;
5444 	    }
5445 	  if (arg->expr->rank != 0)
5446 	    {
5447 	      gfc_error ("!$OMP ATOMIC intrinsic arguments must be scalar "
5448 			 "at %L", &arg->expr->where);
5449 	      return;
5450 	    }
5451 	}
5452 
5453       if (var_arg == NULL)
5454 	{
5455 	  gfc_error ("First or last !$OMP ATOMIC intrinsic argument must "
5456 		     "be %qs at %L", var->name, &expr2->where);
5457 	  return;
5458 	}
5459 
5460       if (var_arg != expr2->value.function.actual)
5461 	{
5462 	  /* Canonicalize, so that var comes first.  */
5463 	  gcc_assert (var_arg->next == NULL);
5464 	  for (arg = expr2->value.function.actual;
5465 	       arg->next != var_arg; arg = arg->next)
5466 	    ;
5467 	  var_arg->next = expr2->value.function.actual;
5468 	  expr2->value.function.actual = var_arg;
5469 	  arg->next = NULL;
5470 	}
5471     }
5472   else
5473     gfc_error ("!$OMP ATOMIC assignment must have an operator or "
5474 	       "intrinsic on right hand side at %L", &expr2->where);
5475 
5476   if (aop == GFC_OMP_ATOMIC_CAPTURE && code->next)
5477     {
5478       code = code->next;
5479       if (code->expr1->expr_type != EXPR_VARIABLE
5480 	  || code->expr1->symtree == NULL
5481 	  || code->expr1->rank != 0
5482 	  || (code->expr1->ts.type != BT_INTEGER
5483 	      && code->expr1->ts.type != BT_REAL
5484 	      && code->expr1->ts.type != BT_COMPLEX
5485 	      && code->expr1->ts.type != BT_LOGICAL))
5486 	{
5487 	  gfc_error ("!$OMP ATOMIC CAPTURE capture statement must set "
5488 		     "a scalar variable of intrinsic type at %L",
5489 		     &code->expr1->where);
5490 	  return;
5491 	}
5492 
5493       expr2 = is_conversion (code->expr2, false);
5494       if (expr2 == NULL)
5495 	{
5496 	  expr2 = is_conversion (code->expr2, true);
5497 	  if (expr2 == NULL)
5498 	    expr2 = code->expr2;
5499 	}
5500 
5501       if (expr2->expr_type != EXPR_VARIABLE
5502 	  || expr2->symtree == NULL
5503 	  || expr2->rank != 0
5504 	  || (expr2->ts.type != BT_INTEGER
5505 	      && expr2->ts.type != BT_REAL
5506 	      && expr2->ts.type != BT_COMPLEX
5507 	      && expr2->ts.type != BT_LOGICAL))
5508 	{
5509 	  gfc_error ("!$OMP ATOMIC CAPTURE capture statement must read "
5510 		     "from a scalar variable of intrinsic type at %L",
5511 		     &expr2->where);
5512 	  return;
5513 	}
5514       if (expr2->symtree->n.sym != var)
5515 	{
5516 	  gfc_error ("!$OMP ATOMIC CAPTURE capture statement reads from "
5517 		     "different variable than update statement writes "
5518 		     "into at %L", &expr2->where);
5519 	  return;
5520 	}
5521     }
5522 }
5523 
5524 
5525 static struct fortran_omp_context
5526 {
5527   gfc_code *code;
5528   hash_set<gfc_symbol *> *sharing_clauses;
5529   hash_set<gfc_symbol *> *private_iterators;
5530   struct fortran_omp_context *previous;
5531   bool is_openmp;
5532 } *omp_current_ctx;
5533 static gfc_code *omp_current_do_code;
5534 static int omp_current_do_collapse;
5535 
5536 void
gfc_resolve_omp_do_blocks(gfc_code * code,gfc_namespace * ns)5537 gfc_resolve_omp_do_blocks (gfc_code *code, gfc_namespace *ns)
5538 {
5539   if (code->block->next && code->block->next->op == EXEC_DO)
5540     {
5541       int i;
5542       gfc_code *c;
5543 
5544       omp_current_do_code = code->block->next;
5545       if (code->ext.omp_clauses->orderedc)
5546 	omp_current_do_collapse = code->ext.omp_clauses->orderedc;
5547       else
5548 	omp_current_do_collapse = code->ext.omp_clauses->collapse;
5549       for (i = 1, c = omp_current_do_code; i < omp_current_do_collapse; i++)
5550 	{
5551 	  c = c->block;
5552 	  if (c->op != EXEC_DO || c->next == NULL)
5553 	    break;
5554 	  c = c->next;
5555 	  if (c->op != EXEC_DO)
5556 	    break;
5557 	}
5558       if (i < omp_current_do_collapse || omp_current_do_collapse <= 0)
5559 	omp_current_do_collapse = 1;
5560     }
5561   gfc_resolve_blocks (code->block, ns);
5562   omp_current_do_collapse = 0;
5563   omp_current_do_code = NULL;
5564 }
5565 
5566 
5567 void
gfc_resolve_omp_parallel_blocks(gfc_code * code,gfc_namespace * ns)5568 gfc_resolve_omp_parallel_blocks (gfc_code *code, gfc_namespace *ns)
5569 {
5570   struct fortran_omp_context ctx;
5571   gfc_omp_clauses *omp_clauses = code->ext.omp_clauses;
5572   gfc_omp_namelist *n;
5573   int list;
5574 
5575   ctx.code = code;
5576   ctx.sharing_clauses = new hash_set<gfc_symbol *>;
5577   ctx.private_iterators = new hash_set<gfc_symbol *>;
5578   ctx.previous = omp_current_ctx;
5579   ctx.is_openmp = true;
5580   omp_current_ctx = &ctx;
5581 
5582   for (list = 0; list < OMP_LIST_NUM; list++)
5583     switch (list)
5584       {
5585       case OMP_LIST_SHARED:
5586       case OMP_LIST_PRIVATE:
5587       case OMP_LIST_FIRSTPRIVATE:
5588       case OMP_LIST_LASTPRIVATE:
5589       case OMP_LIST_REDUCTION:
5590       case OMP_LIST_LINEAR:
5591 	for (n = omp_clauses->lists[list]; n; n = n->next)
5592 	  ctx.sharing_clauses->add (n->sym);
5593 	break;
5594       default:
5595 	break;
5596       }
5597 
5598   switch (code->op)
5599     {
5600     case EXEC_OMP_PARALLEL_DO:
5601     case EXEC_OMP_PARALLEL_DO_SIMD:
5602     case EXEC_OMP_TARGET_PARALLEL_DO:
5603     case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
5604     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
5605     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
5606     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
5607     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
5608     case EXEC_OMP_TASKLOOP:
5609     case EXEC_OMP_TASKLOOP_SIMD:
5610     case EXEC_OMP_TEAMS_DISTRIBUTE:
5611     case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
5612     case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
5613     case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
5614       gfc_resolve_omp_do_blocks (code, ns);
5615       break;
5616     default:
5617       gfc_resolve_blocks (code->block, ns);
5618     }
5619 
5620   omp_current_ctx = ctx.previous;
5621   delete ctx.sharing_clauses;
5622   delete ctx.private_iterators;
5623 }
5624 
5625 
5626 /* Save and clear openmp.c private state.  */
5627 
5628 void
gfc_omp_save_and_clear_state(struct gfc_omp_saved_state * state)5629 gfc_omp_save_and_clear_state (struct gfc_omp_saved_state *state)
5630 {
5631   state->ptrs[0] = omp_current_ctx;
5632   state->ptrs[1] = omp_current_do_code;
5633   state->ints[0] = omp_current_do_collapse;
5634   omp_current_ctx = NULL;
5635   omp_current_do_code = NULL;
5636   omp_current_do_collapse = 0;
5637 }
5638 
5639 
5640 /* Restore openmp.c private state from the saved state.  */
5641 
5642 void
gfc_omp_restore_state(struct gfc_omp_saved_state * state)5643 gfc_omp_restore_state (struct gfc_omp_saved_state *state)
5644 {
5645   omp_current_ctx = (struct fortran_omp_context *) state->ptrs[0];
5646   omp_current_do_code = (gfc_code *) state->ptrs[1];
5647   omp_current_do_collapse = state->ints[0];
5648 }
5649 
5650 
5651 /* Note a DO iterator variable.  This is special in !$omp parallel
5652    construct, where they are predetermined private.  */
5653 
5654 void
gfc_resolve_do_iterator(gfc_code * code,gfc_symbol * sym,bool add_clause)5655 gfc_resolve_do_iterator (gfc_code *code, gfc_symbol *sym, bool add_clause)
5656 {
5657   if (omp_current_ctx == NULL)
5658     return;
5659 
5660   int i = omp_current_do_collapse;
5661   gfc_code *c = omp_current_do_code;
5662 
5663   if (sym->attr.threadprivate)
5664     return;
5665 
5666   /* !$omp do and !$omp parallel do iteration variable is predetermined
5667      private just in the !$omp do resp. !$omp parallel do construct,
5668      with no implications for the outer parallel constructs.  */
5669 
5670   while (i-- >= 1)
5671     {
5672       if (code == c)
5673 	return;
5674 
5675       c = c->block->next;
5676     }
5677 
5678   /* An openacc context may represent a data clause.  Abort if so.  */
5679   if (!omp_current_ctx->is_openmp && !oacc_is_loop (omp_current_ctx->code))
5680     return;
5681 
5682   if (omp_current_ctx->sharing_clauses->contains (sym))
5683     return;
5684 
5685   if (! omp_current_ctx->private_iterators->add (sym) && add_clause)
5686     {
5687       gfc_omp_clauses *omp_clauses = omp_current_ctx->code->ext.omp_clauses;
5688       gfc_omp_namelist *p;
5689 
5690       p = gfc_get_omp_namelist ();
5691       p->sym = sym;
5692       p->next = omp_clauses->lists[OMP_LIST_PRIVATE];
5693       omp_clauses->lists[OMP_LIST_PRIVATE] = p;
5694     }
5695 }
5696 
5697 static void
handle_local_var(gfc_symbol * sym)5698 handle_local_var (gfc_symbol *sym)
5699 {
5700   if (sym->attr.flavor != FL_VARIABLE
5701       || sym->as != NULL
5702       || (sym->ts.type != BT_INTEGER && sym->ts.type != BT_REAL))
5703     return;
5704   gfc_resolve_do_iterator (sym->ns->code, sym, false);
5705 }
5706 
5707 void
gfc_resolve_omp_local_vars(gfc_namespace * ns)5708 gfc_resolve_omp_local_vars (gfc_namespace *ns)
5709 {
5710   if (omp_current_ctx)
5711     gfc_traverse_ns (ns, handle_local_var);
5712 }
5713 
5714 static void
resolve_omp_do(gfc_code * code)5715 resolve_omp_do (gfc_code *code)
5716 {
5717   gfc_code *do_code, *c;
5718   int list, i, collapse;
5719   gfc_omp_namelist *n;
5720   gfc_symbol *dovar;
5721   const char *name;
5722   bool is_simd = false;
5723 
5724   switch (code->op)
5725     {
5726     case EXEC_OMP_DISTRIBUTE: name = "!$OMP DISTRIBUTE"; break;
5727     case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
5728       name = "!$OMP DISTRIBUTE PARALLEL DO";
5729       break;
5730     case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
5731       name = "!$OMP DISTRIBUTE PARALLEL DO SIMD";
5732       is_simd = true;
5733       break;
5734     case EXEC_OMP_DISTRIBUTE_SIMD:
5735       name = "!$OMP DISTRIBUTE SIMD";
5736       is_simd = true;
5737       break;
5738     case EXEC_OMP_DO: name = "!$OMP DO"; break;
5739     case EXEC_OMP_DO_SIMD: name = "!$OMP DO SIMD"; is_simd = true; break;
5740     case EXEC_OMP_PARALLEL_DO: name = "!$OMP PARALLEL DO"; break;
5741     case EXEC_OMP_PARALLEL_DO_SIMD:
5742       name = "!$OMP PARALLEL DO SIMD";
5743       is_simd = true;
5744       break;
5745     case EXEC_OMP_SIMD: name = "!$OMP SIMD"; is_simd = true; break;
5746     case EXEC_OMP_TARGET_PARALLEL_DO: name = "!$OMP TARGET PARALLEL DO"; break;
5747     case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
5748       name = "!$OMP TARGET PARALLEL DO SIMD";
5749       is_simd = true;
5750       break;
5751     case EXEC_OMP_TARGET_SIMD:
5752       name = "!$OMP TARGET SIMD";
5753       is_simd = true;
5754       break;
5755     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
5756       name = "!$OMP TARGET TEAMS DISTRIBUTE";
5757       break;
5758     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
5759       name = "!$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO";
5760       break;
5761     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
5762       name = "!$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD";
5763       is_simd = true;
5764       break;
5765     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
5766       name = "!$OMP TARGET TEAMS DISTRIBUTE SIMD";
5767       is_simd = true;
5768       break;
5769     case EXEC_OMP_TASKLOOP: name = "!$OMP TASKLOOP"; break;
5770     case EXEC_OMP_TASKLOOP_SIMD:
5771       name = "!$OMP TASKLOOP SIMD";
5772       is_simd = true;
5773       break;
5774     case EXEC_OMP_TEAMS_DISTRIBUTE: name = "!$OMP TEAMS DISTRIBUTE"; break;
5775     case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
5776       name = "!$OMP TEAMS DISTRIBUTE PARALLEL DO";
5777       break;
5778     case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
5779       name = "!$OMP TEAMS DISTRIBUTE PARALLEL DO SIMD";
5780       is_simd = true;
5781       break;
5782     case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
5783       name = "!$OMP TEAMS DISTRIBUTE SIMD";
5784       is_simd = true;
5785       break;
5786     default: gcc_unreachable ();
5787     }
5788 
5789   if (code->ext.omp_clauses)
5790     resolve_omp_clauses (code, code->ext.omp_clauses, NULL);
5791 
5792   do_code = code->block->next;
5793   if (code->ext.omp_clauses->orderedc)
5794     collapse = code->ext.omp_clauses->orderedc;
5795   else
5796     {
5797       collapse = code->ext.omp_clauses->collapse;
5798       if (collapse <= 0)
5799 	collapse = 1;
5800     }
5801   for (i = 1; i <= collapse; i++)
5802     {
5803       if (do_code->op == EXEC_DO_WHILE)
5804 	{
5805 	  gfc_error ("%s cannot be a DO WHILE or DO without loop control "
5806 		     "at %L", name, &do_code->loc);
5807 	  break;
5808 	}
5809       if (do_code->op == EXEC_DO_CONCURRENT)
5810 	{
5811 	  gfc_error ("%s cannot be a DO CONCURRENT loop at %L", name,
5812 		     &do_code->loc);
5813 	  break;
5814 	}
5815       gcc_assert (do_code->op == EXEC_DO);
5816       if (do_code->ext.iterator->var->ts.type != BT_INTEGER)
5817 	gfc_error ("%s iteration variable must be of type integer at %L",
5818 		   name, &do_code->loc);
5819       dovar = do_code->ext.iterator->var->symtree->n.sym;
5820       if (dovar->attr.threadprivate)
5821 	gfc_error ("%s iteration variable must not be THREADPRIVATE "
5822 		   "at %L", name, &do_code->loc);
5823       if (code->ext.omp_clauses)
5824 	for (list = 0; list < OMP_LIST_NUM; list++)
5825 	  if (!is_simd
5826 	      ? (list != OMP_LIST_PRIVATE && list != OMP_LIST_LASTPRIVATE)
5827 	      : code->ext.omp_clauses->collapse > 1
5828 	      ? (list != OMP_LIST_LASTPRIVATE)
5829 	      : (list != OMP_LIST_LINEAR))
5830 	    for (n = code->ext.omp_clauses->lists[list]; n; n = n->next)
5831 	      if (dovar == n->sym)
5832 		{
5833 		  if (!is_simd)
5834 		    gfc_error ("%s iteration variable present on clause "
5835 			       "other than PRIVATE or LASTPRIVATE at %L",
5836 			       name, &do_code->loc);
5837 		  else if (code->ext.omp_clauses->collapse > 1)
5838 		    gfc_error ("%s iteration variable present on clause "
5839 			       "other than LASTPRIVATE at %L",
5840 			       name, &do_code->loc);
5841 		  else
5842 		    gfc_error ("%s iteration variable present on clause "
5843 			       "other than LINEAR at %L",
5844 			       name, &do_code->loc);
5845 		  break;
5846 		}
5847       if (i > 1)
5848 	{
5849 	  gfc_code *do_code2 = code->block->next;
5850 	  int j;
5851 
5852 	  for (j = 1; j < i; j++)
5853 	    {
5854 	      gfc_symbol *ivar = do_code2->ext.iterator->var->symtree->n.sym;
5855 	      if (dovar == ivar
5856 		  || gfc_find_sym_in_expr (ivar, do_code->ext.iterator->start)
5857 		  || gfc_find_sym_in_expr (ivar, do_code->ext.iterator->end)
5858 		  || gfc_find_sym_in_expr (ivar, do_code->ext.iterator->step))
5859 		{
5860 		  gfc_error ("%s collapsed loops don't form rectangular "
5861 			     "iteration space at %L", name, &do_code->loc);
5862 		  break;
5863 		}
5864 	      do_code2 = do_code2->block->next;
5865 	    }
5866 	}
5867       if (i == collapse)
5868 	break;
5869       for (c = do_code->next; c; c = c->next)
5870 	if (c->op != EXEC_NOP && c->op != EXEC_CONTINUE)
5871 	  {
5872 	    gfc_error ("collapsed %s loops not perfectly nested at %L",
5873 		       name, &c->loc);
5874 	    break;
5875 	  }
5876       if (c)
5877 	break;
5878       do_code = do_code->block;
5879       if (do_code->op != EXEC_DO && do_code->op != EXEC_DO_WHILE)
5880 	{
5881 	  gfc_error ("not enough DO loops for collapsed %s at %L",
5882 		     name, &code->loc);
5883 	  break;
5884 	}
5885       do_code = do_code->next;
5886       if (do_code == NULL
5887 	  || (do_code->op != EXEC_DO && do_code->op != EXEC_DO_WHILE))
5888 	{
5889 	  gfc_error ("not enough DO loops for collapsed %s at %L",
5890 		     name, &code->loc);
5891 	  break;
5892 	}
5893     }
5894 }
5895 
5896 static bool
oacc_is_parallel(gfc_code * code)5897 oacc_is_parallel (gfc_code *code)
5898 {
5899   return code->op == EXEC_OACC_PARALLEL || code->op == EXEC_OACC_PARALLEL_LOOP;
5900 }
5901 
5902 static gfc_statement
omp_code_to_statement(gfc_code * code)5903 omp_code_to_statement (gfc_code *code)
5904 {
5905   switch (code->op)
5906     {
5907     case EXEC_OMP_PARALLEL:
5908       return ST_OMP_PARALLEL;
5909     case EXEC_OMP_PARALLEL_SECTIONS:
5910       return ST_OMP_PARALLEL_SECTIONS;
5911     case EXEC_OMP_SECTIONS:
5912       return ST_OMP_SECTIONS;
5913     case EXEC_OMP_ORDERED:
5914       return ST_OMP_ORDERED;
5915     case EXEC_OMP_CRITICAL:
5916       return ST_OMP_CRITICAL;
5917     case EXEC_OMP_MASTER:
5918       return ST_OMP_MASTER;
5919     case EXEC_OMP_SINGLE:
5920       return ST_OMP_SINGLE;
5921     case EXEC_OMP_TASK:
5922       return ST_OMP_TASK;
5923     case EXEC_OMP_WORKSHARE:
5924       return ST_OMP_WORKSHARE;
5925     case EXEC_OMP_PARALLEL_WORKSHARE:
5926       return ST_OMP_PARALLEL_WORKSHARE;
5927     case EXEC_OMP_DO:
5928       return ST_OMP_DO;
5929     case EXEC_OMP_ATOMIC:
5930       return ST_OMP_ATOMIC;
5931     case EXEC_OMP_BARRIER:
5932       return ST_OMP_BARRIER;
5933     case EXEC_OMP_CANCEL:
5934       return ST_OMP_CANCEL;
5935     case EXEC_OMP_CANCELLATION_POINT:
5936       return ST_OMP_CANCELLATION_POINT;
5937     case EXEC_OMP_FLUSH:
5938       return ST_OMP_FLUSH;
5939     case EXEC_OMP_DISTRIBUTE:
5940       return ST_OMP_DISTRIBUTE;
5941     case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
5942       return ST_OMP_DISTRIBUTE_PARALLEL_DO;
5943     case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
5944       return ST_OMP_DISTRIBUTE_PARALLEL_DO_SIMD;
5945     case EXEC_OMP_DISTRIBUTE_SIMD:
5946       return ST_OMP_DISTRIBUTE_SIMD;
5947     case EXEC_OMP_DO_SIMD:
5948       return ST_OMP_DO_SIMD;
5949     case EXEC_OMP_SIMD:
5950       return ST_OMP_SIMD;
5951     case EXEC_OMP_TARGET:
5952       return ST_OMP_TARGET;
5953     case EXEC_OMP_TARGET_DATA:
5954       return ST_OMP_TARGET_DATA;
5955     case EXEC_OMP_TARGET_ENTER_DATA:
5956       return ST_OMP_TARGET_ENTER_DATA;
5957     case EXEC_OMP_TARGET_EXIT_DATA:
5958       return ST_OMP_TARGET_EXIT_DATA;
5959     case EXEC_OMP_TARGET_PARALLEL:
5960       return ST_OMP_TARGET_PARALLEL;
5961     case EXEC_OMP_TARGET_PARALLEL_DO:
5962       return ST_OMP_TARGET_PARALLEL_DO;
5963     case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
5964       return ST_OMP_TARGET_PARALLEL_DO_SIMD;
5965     case EXEC_OMP_TARGET_SIMD:
5966       return ST_OMP_TARGET_SIMD;
5967     case EXEC_OMP_TARGET_TEAMS:
5968       return ST_OMP_TARGET_TEAMS;
5969     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
5970       return ST_OMP_TARGET_TEAMS_DISTRIBUTE;
5971     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
5972       return ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO;
5973     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
5974       return ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD;
5975     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
5976       return ST_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD;
5977     case EXEC_OMP_TARGET_UPDATE:
5978       return ST_OMP_TARGET_UPDATE;
5979     case EXEC_OMP_TASKGROUP:
5980       return ST_OMP_TASKGROUP;
5981     case EXEC_OMP_TASKLOOP:
5982       return ST_OMP_TASKLOOP;
5983     case EXEC_OMP_TASKLOOP_SIMD:
5984       return ST_OMP_TASKLOOP_SIMD;
5985     case EXEC_OMP_TASKWAIT:
5986       return ST_OMP_TASKWAIT;
5987     case EXEC_OMP_TASKYIELD:
5988       return ST_OMP_TASKYIELD;
5989     case EXEC_OMP_TEAMS:
5990       return ST_OMP_TEAMS;
5991     case EXEC_OMP_TEAMS_DISTRIBUTE:
5992       return ST_OMP_TEAMS_DISTRIBUTE;
5993     case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
5994       return ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO;
5995     case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
5996       return ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD;
5997     case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
5998       return ST_OMP_TEAMS_DISTRIBUTE_SIMD;
5999     case EXEC_OMP_PARALLEL_DO:
6000       return ST_OMP_PARALLEL_DO;
6001     case EXEC_OMP_PARALLEL_DO_SIMD:
6002       return ST_OMP_PARALLEL_DO_SIMD;
6003 
6004     default:
6005       gcc_unreachable ();
6006     }
6007 }
6008 
6009 static gfc_statement
oacc_code_to_statement(gfc_code * code)6010 oacc_code_to_statement (gfc_code *code)
6011 {
6012   switch (code->op)
6013     {
6014     case EXEC_OACC_PARALLEL:
6015       return ST_OACC_PARALLEL;
6016     case EXEC_OACC_KERNELS:
6017       return ST_OACC_KERNELS;
6018     case EXEC_OACC_SERIAL:
6019       return ST_OACC_SERIAL;
6020     case EXEC_OACC_DATA:
6021       return ST_OACC_DATA;
6022     case EXEC_OACC_HOST_DATA:
6023       return ST_OACC_HOST_DATA;
6024     case EXEC_OACC_PARALLEL_LOOP:
6025       return ST_OACC_PARALLEL_LOOP;
6026     case EXEC_OACC_KERNELS_LOOP:
6027       return ST_OACC_KERNELS_LOOP;
6028     case EXEC_OACC_SERIAL_LOOP:
6029       return ST_OACC_SERIAL_LOOP;
6030     case EXEC_OACC_LOOP:
6031       return ST_OACC_LOOP;
6032     case EXEC_OACC_ATOMIC:
6033       return ST_OACC_ATOMIC;
6034     case EXEC_OACC_ROUTINE:
6035       return ST_OACC_ROUTINE;
6036     case EXEC_OACC_UPDATE:
6037       return ST_OACC_UPDATE;
6038     case EXEC_OACC_WAIT:
6039       return ST_OACC_WAIT;
6040     case EXEC_OACC_CACHE:
6041       return ST_OACC_CACHE;
6042     case EXEC_OACC_ENTER_DATA:
6043       return ST_OACC_ENTER_DATA;
6044     case EXEC_OACC_EXIT_DATA:
6045       return ST_OACC_EXIT_DATA;
6046     case EXEC_OACC_DECLARE:
6047       return ST_OACC_DECLARE;
6048     default:
6049       gcc_unreachable ();
6050     }
6051 }
6052 
6053 static void
resolve_oacc_directive_inside_omp_region(gfc_code * code)6054 resolve_oacc_directive_inside_omp_region (gfc_code *code)
6055 {
6056   if (omp_current_ctx != NULL && omp_current_ctx->is_openmp)
6057     {
6058       gfc_statement st = omp_code_to_statement (omp_current_ctx->code);
6059       gfc_statement oacc_st = oacc_code_to_statement (code);
6060       gfc_error ("The %s directive cannot be specified within "
6061 		 "a %s region at %L", gfc_ascii_statement (oacc_st),
6062 		 gfc_ascii_statement (st), &code->loc);
6063     }
6064 }
6065 
6066 static void
resolve_omp_directive_inside_oacc_region(gfc_code * code)6067 resolve_omp_directive_inside_oacc_region (gfc_code *code)
6068 {
6069   if (omp_current_ctx != NULL && !omp_current_ctx->is_openmp)
6070     {
6071       gfc_statement st = oacc_code_to_statement (omp_current_ctx->code);
6072       gfc_statement omp_st = omp_code_to_statement (code);
6073       gfc_error ("The %s directive cannot be specified within "
6074 		 "a %s region at %L", gfc_ascii_statement (omp_st),
6075 		 gfc_ascii_statement (st), &code->loc);
6076     }
6077 }
6078 
6079 
6080 static void
resolve_oacc_nested_loops(gfc_code * code,gfc_code * do_code,int collapse,const char * clause)6081 resolve_oacc_nested_loops (gfc_code *code, gfc_code* do_code, int collapse,
6082 			  const char *clause)
6083 {
6084   gfc_symbol *dovar;
6085   gfc_code *c;
6086   int i;
6087 
6088   for (i = 1; i <= collapse; i++)
6089     {
6090       if (do_code->op == EXEC_DO_WHILE)
6091 	{
6092 	  gfc_error ("!$ACC LOOP cannot be a DO WHILE or DO without loop control "
6093 		     "at %L", &do_code->loc);
6094 	  break;
6095 	}
6096       if (do_code->op == EXEC_DO_CONCURRENT)
6097 	{
6098 	  gfc_error ("!$ACC LOOP cannot be a DO CONCURRENT loop at %L",
6099 		     &do_code->loc);
6100 	  break;
6101 	}
6102       gcc_assert (do_code->op == EXEC_DO);
6103       if (do_code->ext.iterator->var->ts.type != BT_INTEGER)
6104 	gfc_error ("!$ACC LOOP iteration variable must be of type integer at %L",
6105 		   &do_code->loc);
6106       dovar = do_code->ext.iterator->var->symtree->n.sym;
6107       if (i > 1)
6108 	{
6109 	  gfc_code *do_code2 = code->block->next;
6110 	  int j;
6111 
6112 	  for (j = 1; j < i; j++)
6113 	    {
6114 	      gfc_symbol *ivar = do_code2->ext.iterator->var->symtree->n.sym;
6115 	      if (dovar == ivar
6116 		  || gfc_find_sym_in_expr (ivar, do_code->ext.iterator->start)
6117 		  || gfc_find_sym_in_expr (ivar, do_code->ext.iterator->end)
6118 		  || gfc_find_sym_in_expr (ivar, do_code->ext.iterator->step))
6119 		{
6120 		  gfc_error ("!$ACC LOOP %s loops don't form rectangular "
6121 			     "iteration space at %L", clause, &do_code->loc);
6122 		  break;
6123 		}
6124 	      do_code2 = do_code2->block->next;
6125 	    }
6126 	}
6127       if (i == collapse)
6128 	break;
6129       for (c = do_code->next; c; c = c->next)
6130 	if (c->op != EXEC_NOP && c->op != EXEC_CONTINUE)
6131 	  {
6132 	    gfc_error ("%s !$ACC LOOP loops not perfectly nested at %L",
6133 		       clause, &c->loc);
6134 	    break;
6135 	  }
6136       if (c)
6137 	break;
6138       do_code = do_code->block;
6139       if (do_code->op != EXEC_DO && do_code->op != EXEC_DO_WHILE
6140 	  && do_code->op != EXEC_DO_CONCURRENT)
6141 	{
6142 	  gfc_error ("not enough DO loops for %s !$ACC LOOP at %L",
6143 		     clause, &code->loc);
6144 	  break;
6145 	}
6146       do_code = do_code->next;
6147       if (do_code == NULL
6148 	  || (do_code->op != EXEC_DO && do_code->op != EXEC_DO_WHILE
6149 	      && do_code->op != EXEC_DO_CONCURRENT))
6150 	{
6151 	  gfc_error ("not enough DO loops for %s !$ACC LOOP at %L",
6152 		     clause, &code->loc);
6153 	  break;
6154 	}
6155     }
6156 }
6157 
6158 
6159 static void
resolve_oacc_params_in_parallel(gfc_code * code,const char * clause,const char * arg)6160 resolve_oacc_params_in_parallel (gfc_code *code, const char *clause,
6161 				 const char *arg)
6162 {
6163   fortran_omp_context *c;
6164 
6165   if (oacc_is_parallel (code))
6166     gfc_error ("!$ACC LOOP %s in PARALLEL region doesn't allow "
6167 	       "%s arguments at %L", clause, arg, &code->loc);
6168   for (c = omp_current_ctx; c; c = c->previous)
6169     {
6170       if (oacc_is_loop (c->code))
6171 	break;
6172       if (oacc_is_parallel (c->code))
6173 	gfc_error ("!$ACC LOOP %s in PARALLEL region doesn't allow "
6174 		   "%s arguments at %L", clause, arg, &code->loc);
6175     }
6176 }
6177 
6178 
6179 static void
resolve_oacc_loop_blocks(gfc_code * code)6180 resolve_oacc_loop_blocks (gfc_code *code)
6181 {
6182   if (!oacc_is_loop (code))
6183     return;
6184 
6185   if (code->ext.omp_clauses->tile_list && code->ext.omp_clauses->gang
6186       && code->ext.omp_clauses->worker && code->ext.omp_clauses->vector)
6187     gfc_error ("Tiled loop cannot be parallelized across gangs, workers and "
6188 	       "vectors at the same time at %L", &code->loc);
6189 
6190   if (code->ext.omp_clauses->gang
6191       && code->ext.omp_clauses->gang_num_expr)
6192     resolve_oacc_params_in_parallel (code, "GANG", "num");
6193 
6194   if (code->ext.omp_clauses->worker
6195       && code->ext.omp_clauses->worker_expr)
6196     resolve_oacc_params_in_parallel (code, "WORKER", "num");
6197 
6198   if (code->ext.omp_clauses->vector
6199       && code->ext.omp_clauses->vector_expr)
6200     resolve_oacc_params_in_parallel (code, "VECTOR", "length");
6201 
6202   if (code->ext.omp_clauses->tile_list)
6203     {
6204       gfc_expr_list *el;
6205       for (el = code->ext.omp_clauses->tile_list; el; el = el->next)
6206 	{
6207 	  if (el->expr == NULL)
6208 	    {
6209 	      /* NULL expressions are used to represent '*' arguments.
6210 		 Convert those to a 0 expressions.  */
6211 	      el->expr = gfc_get_constant_expr (BT_INTEGER,
6212 						gfc_default_integer_kind,
6213 						&code->loc);
6214 	      mpz_set_si (el->expr->value.integer, 0);
6215 	    }
6216 	  else
6217 	    {
6218 	      resolve_positive_int_expr (el->expr, "TILE");
6219 	      if (el->expr->expr_type != EXPR_CONSTANT)
6220 		gfc_error ("TILE requires constant expression at %L",
6221 			   &code->loc);
6222 	    }
6223 	}
6224     }
6225 }
6226 
6227 
6228 void
gfc_resolve_oacc_blocks(gfc_code * code,gfc_namespace * ns)6229 gfc_resolve_oacc_blocks (gfc_code *code, gfc_namespace *ns)
6230 {
6231   fortran_omp_context ctx;
6232   gfc_omp_clauses *omp_clauses = code->ext.omp_clauses;
6233   gfc_omp_namelist *n;
6234   int list;
6235 
6236   resolve_oacc_loop_blocks (code);
6237 
6238   ctx.code = code;
6239   ctx.sharing_clauses = new hash_set<gfc_symbol *>;
6240   ctx.private_iterators = new hash_set<gfc_symbol *>;
6241   ctx.previous = omp_current_ctx;
6242   ctx.is_openmp = false;
6243   omp_current_ctx = &ctx;
6244 
6245   for (list = 0; list < OMP_LIST_NUM; list++)
6246     switch (list)
6247       {
6248       case OMP_LIST_PRIVATE:
6249 	for (n = omp_clauses->lists[list]; n; n = n->next)
6250 	  ctx.sharing_clauses->add (n->sym);
6251 	break;
6252       default:
6253 	break;
6254       }
6255 
6256   gfc_resolve_blocks (code->block, ns);
6257 
6258   omp_current_ctx = ctx.previous;
6259   delete ctx.sharing_clauses;
6260   delete ctx.private_iterators;
6261 }
6262 
6263 
6264 static void
resolve_oacc_loop(gfc_code * code)6265 resolve_oacc_loop (gfc_code *code)
6266 {
6267   gfc_code *do_code;
6268   int collapse;
6269 
6270   if (code->ext.omp_clauses)
6271     resolve_omp_clauses (code, code->ext.omp_clauses, NULL, true);
6272 
6273   do_code = code->block->next;
6274   collapse = code->ext.omp_clauses->collapse;
6275 
6276   /* Both collapsed and tiled loops are lowered the same way, but are not
6277      compatible.  In gfc_trans_omp_do, the tile is prioritized.  */
6278   if (code->ext.omp_clauses->tile_list)
6279     {
6280       int num = 0;
6281       gfc_expr_list *el;
6282       for (el = code->ext.omp_clauses->tile_list; el; el = el->next)
6283 	++num;
6284       resolve_oacc_nested_loops (code, code->block->next, num, "tiled");
6285       return;
6286     }
6287 
6288   if (collapse <= 0)
6289     collapse = 1;
6290   resolve_oacc_nested_loops (code, do_code, collapse, "collapsed");
6291 }
6292 
6293 void
gfc_resolve_oacc_declare(gfc_namespace * ns)6294 gfc_resolve_oacc_declare (gfc_namespace *ns)
6295 {
6296   int list;
6297   gfc_omp_namelist *n;
6298   gfc_oacc_declare *oc;
6299 
6300   if (ns->oacc_declare == NULL)
6301     return;
6302 
6303   for (oc = ns->oacc_declare; oc; oc = oc->next)
6304     {
6305       for (list = 0; list < OMP_LIST_NUM; list++)
6306 	for (n = oc->clauses->lists[list]; n; n = n->next)
6307 	  {
6308 	    n->sym->mark = 0;
6309 	    if (n->sym->attr.flavor != FL_VARIABLE
6310 		&& (n->sym->attr.flavor != FL_PROCEDURE
6311 		    || n->sym->result != n->sym))
6312 	      {
6313 		gfc_error ("Object %qs is not a variable at %L",
6314 			   n->sym->name, &oc->loc);
6315 		continue;
6316 	      }
6317 
6318 	    if (n->expr && n->expr->ref->type == REF_ARRAY)
6319 	      {
6320 		gfc_error ("Array sections: %qs not allowed in"
6321 			   " !$ACC DECLARE at %L", n->sym->name, &oc->loc);
6322 		continue;
6323 	      }
6324 	  }
6325 
6326       for (n = oc->clauses->lists[OMP_LIST_DEVICE_RESIDENT]; n; n = n->next)
6327 	check_array_not_assumed (n->sym, oc->loc, "DEVICE_RESIDENT");
6328     }
6329 
6330   for (oc = ns->oacc_declare; oc; oc = oc->next)
6331     {
6332       for (list = 0; list < OMP_LIST_NUM; list++)
6333 	for (n = oc->clauses->lists[list]; n; n = n->next)
6334 	  {
6335 	    if (n->sym->mark)
6336 	      {
6337 		gfc_error ("Symbol %qs present on multiple clauses at %L",
6338 			   n->sym->name, &oc->loc);
6339 		continue;
6340 	      }
6341 	    else
6342 	      n->sym->mark = 1;
6343 	  }
6344     }
6345 
6346   for (oc = ns->oacc_declare; oc; oc = oc->next)
6347     {
6348       for (list = 0; list < OMP_LIST_NUM; list++)
6349 	for (n = oc->clauses->lists[list]; n; n = n->next)
6350 	  n->sym->mark = 0;
6351     }
6352 }
6353 
6354 
6355 void
gfc_resolve_oacc_routines(gfc_namespace * ns)6356 gfc_resolve_oacc_routines (gfc_namespace *ns)
6357 {
6358   for (gfc_oacc_routine_name *orn = ns->oacc_routine_names;
6359        orn;
6360        orn = orn->next)
6361     {
6362       gfc_symbol *sym = orn->sym;
6363       if (!sym->attr.external
6364 	  && !sym->attr.function
6365 	  && !sym->attr.subroutine)
6366 	{
6367 	  gfc_error ("NAME %qs does not refer to a subroutine or function"
6368 		     " in !$ACC ROUTINE ( NAME ) at %L", sym->name, &orn->loc);
6369 	  continue;
6370 	}
6371       if (!gfc_add_omp_declare_target (&sym->attr, sym->name, &orn->loc))
6372 	{
6373 	  gfc_error ("NAME %qs invalid"
6374 		     " in !$ACC ROUTINE ( NAME ) at %L", sym->name, &orn->loc);
6375 	  continue;
6376 	}
6377     }
6378 }
6379 
6380 
6381 void
gfc_resolve_oacc_directive(gfc_code * code,gfc_namespace * ns ATTRIBUTE_UNUSED)6382 gfc_resolve_oacc_directive (gfc_code *code, gfc_namespace *ns ATTRIBUTE_UNUSED)
6383 {
6384   resolve_oacc_directive_inside_omp_region (code);
6385 
6386   switch (code->op)
6387     {
6388     case EXEC_OACC_PARALLEL:
6389     case EXEC_OACC_KERNELS:
6390     case EXEC_OACC_SERIAL:
6391     case EXEC_OACC_DATA:
6392     case EXEC_OACC_HOST_DATA:
6393     case EXEC_OACC_UPDATE:
6394     case EXEC_OACC_ENTER_DATA:
6395     case EXEC_OACC_EXIT_DATA:
6396     case EXEC_OACC_WAIT:
6397     case EXEC_OACC_CACHE:
6398       resolve_omp_clauses (code, code->ext.omp_clauses, NULL, true);
6399       break;
6400     case EXEC_OACC_PARALLEL_LOOP:
6401     case EXEC_OACC_KERNELS_LOOP:
6402     case EXEC_OACC_SERIAL_LOOP:
6403     case EXEC_OACC_LOOP:
6404       resolve_oacc_loop (code);
6405       break;
6406     case EXEC_OACC_ATOMIC:
6407       resolve_omp_atomic (code);
6408       break;
6409     default:
6410       break;
6411     }
6412 }
6413 
6414 
6415 /* Resolve OpenMP directive clauses and check various requirements
6416    of each directive.  */
6417 
6418 void
gfc_resolve_omp_directive(gfc_code * code,gfc_namespace * ns ATTRIBUTE_UNUSED)6419 gfc_resolve_omp_directive (gfc_code *code, gfc_namespace *ns ATTRIBUTE_UNUSED)
6420 {
6421   resolve_omp_directive_inside_oacc_region (code);
6422 
6423   if (code->op != EXEC_OMP_ATOMIC)
6424     gfc_maybe_initialize_eh ();
6425 
6426   switch (code->op)
6427     {
6428     case EXEC_OMP_DISTRIBUTE:
6429     case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
6430     case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
6431     case EXEC_OMP_DISTRIBUTE_SIMD:
6432     case EXEC_OMP_DO:
6433     case EXEC_OMP_DO_SIMD:
6434     case EXEC_OMP_PARALLEL_DO:
6435     case EXEC_OMP_PARALLEL_DO_SIMD:
6436     case EXEC_OMP_SIMD:
6437     case EXEC_OMP_TARGET_PARALLEL_DO:
6438     case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
6439     case EXEC_OMP_TARGET_SIMD:
6440     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
6441     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
6442     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
6443     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
6444     case EXEC_OMP_TASKLOOP:
6445     case EXEC_OMP_TASKLOOP_SIMD:
6446     case EXEC_OMP_TEAMS_DISTRIBUTE:
6447     case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
6448     case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
6449     case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
6450       resolve_omp_do (code);
6451       break;
6452     case EXEC_OMP_CANCEL:
6453     case EXEC_OMP_PARALLEL_WORKSHARE:
6454     case EXEC_OMP_PARALLEL:
6455     case EXEC_OMP_PARALLEL_SECTIONS:
6456     case EXEC_OMP_SECTIONS:
6457     case EXEC_OMP_SINGLE:
6458     case EXEC_OMP_TARGET:
6459     case EXEC_OMP_TARGET_DATA:
6460     case EXEC_OMP_TARGET_ENTER_DATA:
6461     case EXEC_OMP_TARGET_EXIT_DATA:
6462     case EXEC_OMP_TARGET_PARALLEL:
6463     case EXEC_OMP_TARGET_TEAMS:
6464     case EXEC_OMP_TASK:
6465     case EXEC_OMP_TEAMS:
6466     case EXEC_OMP_WORKSHARE:
6467       if (code->ext.omp_clauses)
6468 	resolve_omp_clauses (code, code->ext.omp_clauses, NULL);
6469       break;
6470     case EXEC_OMP_TARGET_UPDATE:
6471       if (code->ext.omp_clauses)
6472 	resolve_omp_clauses (code, code->ext.omp_clauses, NULL);
6473       if (code->ext.omp_clauses == NULL
6474 	  || (code->ext.omp_clauses->lists[OMP_LIST_TO] == NULL
6475 	      && code->ext.omp_clauses->lists[OMP_LIST_FROM] == NULL))
6476 	gfc_error ("OMP TARGET UPDATE at %L requires at least one TO or "
6477 		   "FROM clause", &code->loc);
6478       break;
6479     case EXEC_OMP_ATOMIC:
6480       resolve_omp_atomic (code);
6481       break;
6482     default:
6483       break;
6484     }
6485 }
6486 
6487 /* Resolve !$omp declare simd constructs in NS.  */
6488 
6489 void
gfc_resolve_omp_declare_simd(gfc_namespace * ns)6490 gfc_resolve_omp_declare_simd (gfc_namespace *ns)
6491 {
6492   gfc_omp_declare_simd *ods;
6493 
6494   for (ods = ns->omp_declare_simd; ods; ods = ods->next)
6495     {
6496       if (ods->proc_name != NULL
6497 	  && ods->proc_name != ns->proc_name)
6498 	gfc_error ("!$OMP DECLARE SIMD should refer to containing procedure "
6499 		   "%qs at %L", ns->proc_name->name, &ods->where);
6500       if (ods->clauses)
6501 	resolve_omp_clauses (NULL, ods->clauses, ns);
6502     }
6503 }
6504 
6505 struct omp_udr_callback_data
6506 {
6507   gfc_omp_udr *omp_udr;
6508   bool is_initializer;
6509 };
6510 
6511 static int
omp_udr_callback(gfc_expr ** e,int * walk_subtrees ATTRIBUTE_UNUSED,void * data)6512 omp_udr_callback (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
6513 		  void *data)
6514 {
6515   struct omp_udr_callback_data *cd = (struct omp_udr_callback_data *) data;
6516   if ((*e)->expr_type == EXPR_VARIABLE)
6517     {
6518       if (cd->is_initializer)
6519 	{
6520 	  if ((*e)->symtree->n.sym != cd->omp_udr->omp_priv
6521 	      && (*e)->symtree->n.sym != cd->omp_udr->omp_orig)
6522 	    gfc_error ("Variable other than OMP_PRIV or OMP_ORIG used in "
6523 		       "INITIALIZER clause of !$OMP DECLARE REDUCTION at %L",
6524 		       &(*e)->where);
6525 	}
6526       else
6527 	{
6528 	  if ((*e)->symtree->n.sym != cd->omp_udr->omp_out
6529 	      && (*e)->symtree->n.sym != cd->omp_udr->omp_in)
6530 	    gfc_error ("Variable other than OMP_OUT or OMP_IN used in "
6531 		       "combiner of !$OMP DECLARE REDUCTION at %L",
6532 		       &(*e)->where);
6533 	}
6534     }
6535   return 0;
6536 }
6537 
6538 /* Resolve !$omp declare reduction constructs.  */
6539 
6540 static void
gfc_resolve_omp_udr(gfc_omp_udr * omp_udr)6541 gfc_resolve_omp_udr (gfc_omp_udr *omp_udr)
6542 {
6543   gfc_actual_arglist *a;
6544   const char *predef_name = NULL;
6545 
6546   switch (omp_udr->rop)
6547     {
6548     case OMP_REDUCTION_PLUS:
6549     case OMP_REDUCTION_TIMES:
6550     case OMP_REDUCTION_MINUS:
6551     case OMP_REDUCTION_AND:
6552     case OMP_REDUCTION_OR:
6553     case OMP_REDUCTION_EQV:
6554     case OMP_REDUCTION_NEQV:
6555     case OMP_REDUCTION_MAX:
6556     case OMP_REDUCTION_USER:
6557       break;
6558     default:
6559       gfc_error ("Invalid operator for !$OMP DECLARE REDUCTION %s at %L",
6560 		 omp_udr->name, &omp_udr->where);
6561       return;
6562     }
6563 
6564   if (gfc_omp_udr_predef (omp_udr->rop, omp_udr->name,
6565 			  &omp_udr->ts, &predef_name))
6566     {
6567       if (predef_name)
6568 	gfc_error_now ("Redefinition of predefined %s "
6569 		       "!$OMP DECLARE REDUCTION at %L",
6570 		       predef_name, &omp_udr->where);
6571       else
6572 	gfc_error_now ("Redefinition of predefined "
6573 		       "!$OMP DECLARE REDUCTION at %L", &omp_udr->where);
6574       return;
6575     }
6576 
6577   if (omp_udr->ts.type == BT_CHARACTER
6578       && omp_udr->ts.u.cl->length
6579       && omp_udr->ts.u.cl->length->expr_type != EXPR_CONSTANT)
6580     {
6581       gfc_error ("CHARACTER length in !$OMP DECLARE REDUCTION %s not "
6582 		 "constant at %L", omp_udr->name, &omp_udr->where);
6583       return;
6584     }
6585 
6586   struct omp_udr_callback_data cd;
6587   cd.omp_udr = omp_udr;
6588   cd.is_initializer = false;
6589   gfc_code_walker (&omp_udr->combiner_ns->code, gfc_dummy_code_callback,
6590 		   omp_udr_callback, &cd);
6591   if (omp_udr->combiner_ns->code->op == EXEC_CALL)
6592     {
6593       for (a = omp_udr->combiner_ns->code->ext.actual; a; a = a->next)
6594 	if (a->expr == NULL)
6595 	  break;
6596       if (a)
6597 	gfc_error ("Subroutine call with alternate returns in combiner "
6598 		   "of !$OMP DECLARE REDUCTION at %L",
6599 		   &omp_udr->combiner_ns->code->loc);
6600     }
6601   if (omp_udr->initializer_ns)
6602     {
6603       cd.is_initializer = true;
6604       gfc_code_walker (&omp_udr->initializer_ns->code, gfc_dummy_code_callback,
6605 		       omp_udr_callback, &cd);
6606       if (omp_udr->initializer_ns->code->op == EXEC_CALL)
6607 	{
6608 	  for (a = omp_udr->initializer_ns->code->ext.actual; a; a = a->next)
6609 	    if (a->expr == NULL)
6610 	      break;
6611 	  if (a)
6612 	    gfc_error ("Subroutine call with alternate returns in "
6613 		       "INITIALIZER clause of !$OMP DECLARE REDUCTION "
6614 		       "at %L", &omp_udr->initializer_ns->code->loc);
6615 	  for (a = omp_udr->initializer_ns->code->ext.actual; a; a = a->next)
6616 	    if (a->expr
6617 		&& a->expr->expr_type == EXPR_VARIABLE
6618 		&& a->expr->symtree->n.sym == omp_udr->omp_priv
6619 		&& a->expr->ref == NULL)
6620 	      break;
6621 	  if (a == NULL)
6622 	    gfc_error ("One of actual subroutine arguments in INITIALIZER "
6623 		       "clause of !$OMP DECLARE REDUCTION must be OMP_PRIV "
6624 		       "at %L", &omp_udr->initializer_ns->code->loc);
6625 	}
6626     }
6627   else if (omp_udr->ts.type == BT_DERIVED
6628 	   && !gfc_has_default_initializer (omp_udr->ts.u.derived))
6629     {
6630       gfc_error ("Missing INITIALIZER clause for !$OMP DECLARE REDUCTION "
6631 		 "of derived type without default initializer at %L",
6632 		 &omp_udr->where);
6633       return;
6634     }
6635 }
6636 
6637 void
gfc_resolve_omp_udrs(gfc_symtree * st)6638 gfc_resolve_omp_udrs (gfc_symtree *st)
6639 {
6640   gfc_omp_udr *omp_udr;
6641 
6642   if (st == NULL)
6643     return;
6644   gfc_resolve_omp_udrs (st->left);
6645   gfc_resolve_omp_udrs (st->right);
6646   for (omp_udr = st->n.omp_udr; omp_udr; omp_udr = omp_udr->next)
6647     gfc_resolve_omp_udr (omp_udr);
6648 }
6649