OSDN Git Service

* Makefile.in (CFLAGS-collect2.o, CFLAGS-c-family/c-opts.o)
[pf3gnuchains/gcc-fork.git] / gcc / fortran / openmp.c
1 /* OpenMP directive matching and resolving.
2    Copyright (C) 2005, 2006, 2007, 2008, 2010, 2011
3    Free Software Foundation, Inc.
4    Contributed by Jakub Jelinek
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "flags.h"
25 #include "gfortran.h"
26 #include "match.h"
27 #include "parse.h"
28 #include "pointer-set.h"
29
30 /* Match an end of OpenMP directive.  End of OpenMP directive is optional
31    whitespace, followed by '\n' or comment '!'.  */
32
33 match
34 gfc_match_omp_eos (void)
35 {
36   locus old_loc;
37   char c;
38
39   old_loc = gfc_current_locus;
40   gfc_gobble_whitespace ();
41
42   c = gfc_next_ascii_char ();
43   switch (c)
44     {
45     case '!':
46       do
47         c = gfc_next_ascii_char ();
48       while (c != '\n');
49       /* Fall through */
50
51     case '\n':
52       return MATCH_YES;
53     }
54
55   gfc_current_locus = old_loc;
56   return MATCH_NO;
57 }
58
59 /* Free an omp_clauses structure.  */
60
61 void
62 gfc_free_omp_clauses (gfc_omp_clauses *c)
63 {
64   int i;
65   if (c == NULL)
66     return;
67
68   gfc_free_expr (c->if_expr);
69   gfc_free_expr (c->final_expr);
70   gfc_free_expr (c->num_threads);
71   gfc_free_expr (c->chunk_size);
72   for (i = 0; i < OMP_LIST_NUM; i++)
73     gfc_free_namelist (c->lists[i]);
74   free (c);
75 }
76
77 /* Match a variable/common block list and construct a namelist from it.  */
78
79 static match
80 gfc_match_omp_variable_list (const char *str, gfc_namelist **list,
81                              bool allow_common)
82 {
83   gfc_namelist *head, *tail, *p;
84   locus old_loc;
85   char n[GFC_MAX_SYMBOL_LEN+1];
86   gfc_symbol *sym;
87   match m;
88   gfc_symtree *st;
89
90   head = tail = NULL;
91
92   old_loc = gfc_current_locus;
93
94   m = gfc_match (str);
95   if (m != MATCH_YES)
96     return m;
97
98   for (;;)
99     {
100       m = gfc_match_symbol (&sym, 1);
101       switch (m)
102         {
103         case MATCH_YES:
104           gfc_set_sym_referenced (sym);
105           p = gfc_get_namelist ();
106           if (head == NULL)
107             head = tail = p;
108           else
109             {
110               tail->next = p;
111               tail = tail->next;
112             }
113           tail->sym = sym;
114           goto next_item;
115         case MATCH_NO:
116           break;
117         case MATCH_ERROR:
118           goto cleanup;
119         }
120
121       if (!allow_common)
122         goto syntax;
123
124       m = gfc_match (" / %n /", n);
125       if (m == MATCH_ERROR)
126         goto cleanup;
127       if (m == MATCH_NO)
128         goto syntax;
129
130       st = gfc_find_symtree (gfc_current_ns->common_root, n);
131       if (st == NULL)
132         {
133           gfc_error ("COMMON block /%s/ not found at %C", n);
134           goto cleanup;
135         }
136       for (sym = st->n.common->head; sym; sym = sym->common_next)
137         {
138           gfc_set_sym_referenced (sym);
139           p = gfc_get_namelist ();
140           if (head == NULL)
141             head = tail = p;
142           else
143             {
144               tail->next = p;
145               tail = tail->next;
146             }
147           tail->sym = sym;
148         }
149
150     next_item:
151       if (gfc_match_char (')') == MATCH_YES)
152         break;
153       if (gfc_match_char (',') != MATCH_YES)
154         goto syntax;
155     }
156
157   while (*list)
158     list = &(*list)->next;
159
160   *list = head;
161   return MATCH_YES;
162
163 syntax:
164   gfc_error ("Syntax error in OpenMP variable list at %C");
165
166 cleanup:
167   gfc_free_namelist (head);
168   gfc_current_locus = old_loc;
169   return MATCH_ERROR;
170 }
171
172 #define OMP_CLAUSE_PRIVATE      (1 << 0)
173 #define OMP_CLAUSE_FIRSTPRIVATE (1 << 1)
174 #define OMP_CLAUSE_LASTPRIVATE  (1 << 2)
175 #define OMP_CLAUSE_COPYPRIVATE  (1 << 3)
176 #define OMP_CLAUSE_SHARED       (1 << 4)
177 #define OMP_CLAUSE_COPYIN       (1 << 5)
178 #define OMP_CLAUSE_REDUCTION    (1 << 6)
179 #define OMP_CLAUSE_IF           (1 << 7)
180 #define OMP_CLAUSE_NUM_THREADS  (1 << 8)
181 #define OMP_CLAUSE_SCHEDULE     (1 << 9)
182 #define OMP_CLAUSE_DEFAULT      (1 << 10)
183 #define OMP_CLAUSE_ORDERED      (1 << 11)
184 #define OMP_CLAUSE_COLLAPSE     (1 << 12)
185 #define OMP_CLAUSE_UNTIED       (1 << 13)
186 #define OMP_CLAUSE_FINAL        (1 << 14)
187 #define OMP_CLAUSE_MERGEABLE    (1 << 15)
188
189 /* Match OpenMP directive clauses. MASK is a bitmask of
190    clauses that are allowed for a particular directive.  */
191
192 static match
193 gfc_match_omp_clauses (gfc_omp_clauses **cp, int mask)
194 {
195   gfc_omp_clauses *c = gfc_get_omp_clauses ();
196   locus old_loc;
197   bool needs_space = true, first = true;
198
199   *cp = NULL;
200   while (1)
201     {
202       if ((first || gfc_match_char (',') != MATCH_YES)
203           && (needs_space && gfc_match_space () != MATCH_YES))
204         break;
205       needs_space = false;
206       first = false;
207       gfc_gobble_whitespace ();
208       if ((mask & OMP_CLAUSE_IF) && c->if_expr == NULL
209           && gfc_match ("if ( %e )", &c->if_expr) == MATCH_YES)
210         continue;
211       if ((mask & OMP_CLAUSE_FINAL) && c->final_expr == NULL
212           && gfc_match ("final ( %e )", &c->final_expr) == MATCH_YES)
213         continue;
214       if ((mask & OMP_CLAUSE_NUM_THREADS) && c->num_threads == NULL
215           && gfc_match ("num_threads ( %e )", &c->num_threads) == MATCH_YES)
216         continue;
217       if ((mask & OMP_CLAUSE_PRIVATE)
218           && gfc_match_omp_variable_list ("private (",
219                                           &c->lists[OMP_LIST_PRIVATE], true)
220              == MATCH_YES)
221         continue;
222       if ((mask & OMP_CLAUSE_FIRSTPRIVATE)
223           && gfc_match_omp_variable_list ("firstprivate (",
224                                           &c->lists[OMP_LIST_FIRSTPRIVATE],
225                                           true)
226              == MATCH_YES)
227         continue;
228       if ((mask & OMP_CLAUSE_LASTPRIVATE)
229           && gfc_match_omp_variable_list ("lastprivate (",
230                                           &c->lists[OMP_LIST_LASTPRIVATE],
231                                           true)
232              == MATCH_YES)
233         continue;
234       if ((mask & OMP_CLAUSE_COPYPRIVATE)
235           && gfc_match_omp_variable_list ("copyprivate (",
236                                           &c->lists[OMP_LIST_COPYPRIVATE],
237                                           true)
238              == MATCH_YES)
239         continue;
240       if ((mask & OMP_CLAUSE_SHARED)
241           && gfc_match_omp_variable_list ("shared (",
242                                           &c->lists[OMP_LIST_SHARED], true)
243              == MATCH_YES)
244         continue;
245       if ((mask & OMP_CLAUSE_COPYIN)
246           && gfc_match_omp_variable_list ("copyin (",
247                                           &c->lists[OMP_LIST_COPYIN], true)
248              == MATCH_YES)
249         continue;
250       old_loc = gfc_current_locus;
251       if ((mask & OMP_CLAUSE_REDUCTION)
252           && gfc_match ("reduction ( ") == MATCH_YES)
253         {
254           int reduction = OMP_LIST_NUM;
255           char buffer[GFC_MAX_SYMBOL_LEN + 1];
256           if (gfc_match_char ('+') == MATCH_YES)
257             reduction = OMP_LIST_PLUS;
258           else if (gfc_match_char ('*') == MATCH_YES)
259             reduction = OMP_LIST_MULT;
260           else if (gfc_match_char ('-') == MATCH_YES)
261             reduction = OMP_LIST_SUB;
262           else if (gfc_match (".and.") == MATCH_YES)
263             reduction = OMP_LIST_AND;
264           else if (gfc_match (".or.") == MATCH_YES)
265             reduction = OMP_LIST_OR;
266           else if (gfc_match (".eqv.") == MATCH_YES)
267             reduction = OMP_LIST_EQV;
268           else if (gfc_match (".neqv.") == MATCH_YES)
269             reduction = OMP_LIST_NEQV;
270           else if (gfc_match_name (buffer) == MATCH_YES)
271             {
272               gfc_symbol *sym;
273               const char *n = buffer;
274
275               gfc_find_symbol (buffer, NULL, 1, &sym);
276               if (sym != NULL)
277                 {
278                   if (sym->attr.intrinsic)
279                     n = sym->name;
280                   else if ((sym->attr.flavor != FL_UNKNOWN
281                             && sym->attr.flavor != FL_PROCEDURE)
282                            || sym->attr.external
283                            || sym->attr.generic
284                            || sym->attr.entry
285                            || sym->attr.result
286                            || sym->attr.dummy
287                            || sym->attr.subroutine
288                            || sym->attr.pointer
289                            || sym->attr.target
290                            || sym->attr.cray_pointer
291                            || sym->attr.cray_pointee
292                            || (sym->attr.proc != PROC_UNKNOWN
293                                && sym->attr.proc != PROC_INTRINSIC)
294                            || sym->attr.if_source != IFSRC_UNKNOWN
295                            || sym == sym->ns->proc_name)
296                     {
297                       gfc_error_now ("%s is not INTRINSIC procedure name "
298                                      "at %C", buffer);
299                       sym = NULL;
300                     }
301                   else
302                     n = sym->name;
303                 }
304               if (strcmp (n, "max") == 0)
305                 reduction = OMP_LIST_MAX;
306               else if (strcmp (n, "min") == 0)
307                 reduction = OMP_LIST_MIN;
308               else if (strcmp (n, "iand") == 0)
309                 reduction = OMP_LIST_IAND;
310               else if (strcmp (n, "ior") == 0)
311                 reduction = OMP_LIST_IOR;
312               else if (strcmp (n, "ieor") == 0)
313                 reduction = OMP_LIST_IEOR;
314               if (reduction != OMP_LIST_NUM
315                   && sym != NULL
316                   && ! sym->attr.intrinsic
317                   && ! sym->attr.use_assoc
318                   && ((sym->attr.flavor == FL_UNKNOWN
319                        && gfc_add_flavor (&sym->attr, FL_PROCEDURE,
320                                           sym->name, NULL) == FAILURE)
321                       || gfc_add_intrinsic (&sym->attr, NULL) == FAILURE))
322                 {
323                   gfc_free_omp_clauses (c);
324                   return MATCH_ERROR;
325                 }
326             }
327           if (reduction != OMP_LIST_NUM
328               && gfc_match_omp_variable_list (" :", &c->lists[reduction],
329                                               false)
330                  == MATCH_YES)
331             continue;
332           else
333             gfc_current_locus = old_loc;
334         }
335       if ((mask & OMP_CLAUSE_DEFAULT)
336           && c->default_sharing == OMP_DEFAULT_UNKNOWN)
337         {
338           if (gfc_match ("default ( shared )") == MATCH_YES)
339             c->default_sharing = OMP_DEFAULT_SHARED;
340           else if (gfc_match ("default ( private )") == MATCH_YES)
341             c->default_sharing = OMP_DEFAULT_PRIVATE;
342           else if (gfc_match ("default ( none )") == MATCH_YES)
343             c->default_sharing = OMP_DEFAULT_NONE;
344           else if (gfc_match ("default ( firstprivate )") == MATCH_YES)
345             c->default_sharing = OMP_DEFAULT_FIRSTPRIVATE;
346           if (c->default_sharing != OMP_DEFAULT_UNKNOWN)
347             continue;
348         }
349       old_loc = gfc_current_locus;
350       if ((mask & OMP_CLAUSE_SCHEDULE)
351           && c->sched_kind == OMP_SCHED_NONE
352           && gfc_match ("schedule ( ") == MATCH_YES)
353         {
354           if (gfc_match ("static") == MATCH_YES)
355             c->sched_kind = OMP_SCHED_STATIC;
356           else if (gfc_match ("dynamic") == MATCH_YES)
357             c->sched_kind = OMP_SCHED_DYNAMIC;
358           else if (gfc_match ("guided") == MATCH_YES)
359             c->sched_kind = OMP_SCHED_GUIDED;
360           else if (gfc_match ("runtime") == MATCH_YES)
361             c->sched_kind = OMP_SCHED_RUNTIME;
362           else if (gfc_match ("auto") == MATCH_YES)
363             c->sched_kind = OMP_SCHED_AUTO;
364           if (c->sched_kind != OMP_SCHED_NONE)
365             {
366               match m = MATCH_NO;
367               if (c->sched_kind != OMP_SCHED_RUNTIME
368                   && c->sched_kind != OMP_SCHED_AUTO)
369                 m = gfc_match (" , %e )", &c->chunk_size);
370               if (m != MATCH_YES)
371                 m = gfc_match_char (')');
372               if (m != MATCH_YES)
373                 c->sched_kind = OMP_SCHED_NONE;
374             }
375           if (c->sched_kind != OMP_SCHED_NONE)
376             continue;
377           else
378             gfc_current_locus = old_loc;
379         }
380       if ((mask & OMP_CLAUSE_ORDERED) && !c->ordered
381           && gfc_match ("ordered") == MATCH_YES)
382         {
383           c->ordered = needs_space = true;
384           continue;
385         }
386       if ((mask & OMP_CLAUSE_UNTIED) && !c->untied
387           && gfc_match ("untied") == MATCH_YES)
388         {
389           c->untied = needs_space = true;
390           continue;
391         }
392       if ((mask & OMP_CLAUSE_MERGEABLE) && !c->mergeable
393           && gfc_match ("mergeable") == MATCH_YES)
394         {
395           c->mergeable = needs_space = true;
396           continue;
397         }
398       if ((mask & OMP_CLAUSE_COLLAPSE) && !c->collapse)
399         {
400           gfc_expr *cexpr = NULL;
401           match m = gfc_match ("collapse ( %e )", &cexpr);
402
403           if (m == MATCH_YES)
404             {
405               int collapse;
406               const char *p = gfc_extract_int (cexpr, &collapse);
407               if (p)
408                 {
409                   gfc_error_now (p);
410                   collapse = 1;
411                 }
412               else if (collapse <= 0)
413                 {
414                   gfc_error_now ("COLLAPSE clause argument not"
415                                  " constant positive integer at %C");
416                   collapse = 1;
417                 }
418               c->collapse = collapse;
419               gfc_free_expr (cexpr);
420               continue;
421             }
422         }
423
424       break;
425     }
426
427   if (gfc_match_omp_eos () != MATCH_YES)
428     {
429       gfc_free_omp_clauses (c);
430       return MATCH_ERROR;
431     }
432
433   *cp = c;
434   return MATCH_YES;
435 }
436
437 #define OMP_PARALLEL_CLAUSES \
438   (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED     \
439    | OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF           \
440    | OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT)
441 #define OMP_DO_CLAUSES \
442   (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE                         \
443    | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION                      \
444    | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED | OMP_CLAUSE_COLLAPSE)
445 #define OMP_SECTIONS_CLAUSES \
446   (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE                         \
447    | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION)
448 #define OMP_TASK_CLAUSES \
449   (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED     \
450    | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED             \
451    | OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE)
452
453 match
454 gfc_match_omp_parallel (void)
455 {
456   gfc_omp_clauses *c;
457   if (gfc_match_omp_clauses (&c, OMP_PARALLEL_CLAUSES) != MATCH_YES)
458     return MATCH_ERROR;
459   new_st.op = EXEC_OMP_PARALLEL;
460   new_st.ext.omp_clauses = c;
461   return MATCH_YES;
462 }
463
464
465 match
466 gfc_match_omp_task (void)
467 {
468   gfc_omp_clauses *c;
469   if (gfc_match_omp_clauses (&c, OMP_TASK_CLAUSES) != MATCH_YES)
470     return MATCH_ERROR;
471   new_st.op = EXEC_OMP_TASK;
472   new_st.ext.omp_clauses = c;
473   return MATCH_YES;
474 }
475
476
477 match
478 gfc_match_omp_taskwait (void)
479 {
480   if (gfc_match_omp_eos () != MATCH_YES)
481     {
482       gfc_error ("Unexpected junk after TASKWAIT clause at %C");
483       return MATCH_ERROR;
484     }
485   new_st.op = EXEC_OMP_TASKWAIT;
486   new_st.ext.omp_clauses = NULL;
487   return MATCH_YES;
488 }
489
490
491 match
492 gfc_match_omp_taskyield (void)
493 {
494   if (gfc_match_omp_eos () != MATCH_YES)
495     {
496       gfc_error ("Unexpected junk after TASKYIELD clause at %C");
497       return MATCH_ERROR;
498     }
499   new_st.op = EXEC_OMP_TASKYIELD;
500   new_st.ext.omp_clauses = NULL;
501   return MATCH_YES;
502 }
503
504
505 match
506 gfc_match_omp_critical (void)
507 {
508   char n[GFC_MAX_SYMBOL_LEN+1];
509
510   if (gfc_match (" ( %n )", n) != MATCH_YES)
511     n[0] = '\0';
512   if (gfc_match_omp_eos () != MATCH_YES)
513     {
514       gfc_error ("Unexpected junk after $OMP CRITICAL statement at %C");
515       return MATCH_ERROR;
516     }
517   new_st.op = EXEC_OMP_CRITICAL;
518   new_st.ext.omp_name = n[0] ? xstrdup (n) : NULL;
519   return MATCH_YES;
520 }
521
522
523 match
524 gfc_match_omp_do (void)
525 {
526   gfc_omp_clauses *c;
527   if (gfc_match_omp_clauses (&c, OMP_DO_CLAUSES) != MATCH_YES)
528     return MATCH_ERROR;
529   new_st.op = EXEC_OMP_DO;
530   new_st.ext.omp_clauses = c;
531   return MATCH_YES;
532 }
533
534
535 match
536 gfc_match_omp_flush (void)
537 {
538   gfc_namelist *list = NULL;
539   gfc_match_omp_variable_list (" (", &list, true);
540   if (gfc_match_omp_eos () != MATCH_YES)
541     {
542       gfc_error ("Unexpected junk after $OMP FLUSH statement at %C");
543       gfc_free_namelist (list);
544       return MATCH_ERROR;
545     }
546   new_st.op = EXEC_OMP_FLUSH;
547   new_st.ext.omp_namelist = list;
548   return MATCH_YES;
549 }
550
551
552 match
553 gfc_match_omp_threadprivate (void)
554 {
555   locus old_loc;
556   char n[GFC_MAX_SYMBOL_LEN+1];
557   gfc_symbol *sym;
558   match m;
559   gfc_symtree *st;
560
561   old_loc = gfc_current_locus;
562
563   m = gfc_match (" (");
564   if (m != MATCH_YES)
565     return m;
566
567   for (;;)
568     {
569       m = gfc_match_symbol (&sym, 0);
570       switch (m)
571         {
572         case MATCH_YES:
573           if (sym->attr.in_common)
574             gfc_error_now ("Threadprivate variable at %C is an element of "
575                            "a COMMON block");
576           else if (gfc_add_threadprivate (&sym->attr, sym->name,
577                    &sym->declared_at) == FAILURE)
578             goto cleanup;
579           goto next_item;
580         case MATCH_NO:
581           break;
582         case MATCH_ERROR:
583           goto cleanup;
584         }
585
586       m = gfc_match (" / %n /", n);
587       if (m == MATCH_ERROR)
588         goto cleanup;
589       if (m == MATCH_NO || n[0] == '\0')
590         goto syntax;
591
592       st = gfc_find_symtree (gfc_current_ns->common_root, n);
593       if (st == NULL)
594         {
595           gfc_error ("COMMON block /%s/ not found at %C", n);
596           goto cleanup;
597         }
598       st->n.common->threadprivate = 1;
599       for (sym = st->n.common->head; sym; sym = sym->common_next)
600         if (gfc_add_threadprivate (&sym->attr, sym->name,
601                                    &sym->declared_at) == FAILURE)
602           goto cleanup;
603
604     next_item:
605       if (gfc_match_char (')') == MATCH_YES)
606         break;
607       if (gfc_match_char (',') != MATCH_YES)
608         goto syntax;
609     }
610
611   return MATCH_YES;
612
613 syntax:
614   gfc_error ("Syntax error in !$OMP THREADPRIVATE list at %C");
615
616 cleanup:
617   gfc_current_locus = old_loc;
618   return MATCH_ERROR;
619 }
620
621
622 match
623 gfc_match_omp_parallel_do (void)
624 {
625   gfc_omp_clauses *c;
626   if (gfc_match_omp_clauses (&c, OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES)
627       != MATCH_YES)
628     return MATCH_ERROR;
629   new_st.op = EXEC_OMP_PARALLEL_DO;
630   new_st.ext.omp_clauses = c;
631   return MATCH_YES;
632 }
633
634
635 match
636 gfc_match_omp_parallel_sections (void)
637 {
638   gfc_omp_clauses *c;
639   if (gfc_match_omp_clauses (&c, OMP_PARALLEL_CLAUSES | OMP_SECTIONS_CLAUSES)
640       != MATCH_YES)
641     return MATCH_ERROR;
642   new_st.op = EXEC_OMP_PARALLEL_SECTIONS;
643   new_st.ext.omp_clauses = c;
644   return MATCH_YES;
645 }
646
647
648 match
649 gfc_match_omp_parallel_workshare (void)
650 {
651   gfc_omp_clauses *c;
652   if (gfc_match_omp_clauses (&c, OMP_PARALLEL_CLAUSES) != MATCH_YES)
653     return MATCH_ERROR;
654   new_st.op = EXEC_OMP_PARALLEL_WORKSHARE;
655   new_st.ext.omp_clauses = c;
656   return MATCH_YES;
657 }
658
659
660 match
661 gfc_match_omp_sections (void)
662 {
663   gfc_omp_clauses *c;
664   if (gfc_match_omp_clauses (&c, OMP_SECTIONS_CLAUSES) != MATCH_YES)
665     return MATCH_ERROR;
666   new_st.op = EXEC_OMP_SECTIONS;
667   new_st.ext.omp_clauses = c;
668   return MATCH_YES;
669 }
670
671
672 match
673 gfc_match_omp_single (void)
674 {
675   gfc_omp_clauses *c;
676   if (gfc_match_omp_clauses (&c, OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE)
677       != MATCH_YES)
678     return MATCH_ERROR;
679   new_st.op = EXEC_OMP_SINGLE;
680   new_st.ext.omp_clauses = c;
681   return MATCH_YES;
682 }
683
684
685 match
686 gfc_match_omp_workshare (void)
687 {
688   if (gfc_match_omp_eos () != MATCH_YES)
689     {
690       gfc_error ("Unexpected junk after $OMP WORKSHARE statement at %C");
691       return MATCH_ERROR;
692     }
693   new_st.op = EXEC_OMP_WORKSHARE;
694   new_st.ext.omp_clauses = gfc_get_omp_clauses ();
695   return MATCH_YES;
696 }
697
698
699 match
700 gfc_match_omp_master (void)
701 {
702   if (gfc_match_omp_eos () != MATCH_YES)
703     {
704       gfc_error ("Unexpected junk after $OMP MASTER statement at %C");
705       return MATCH_ERROR;
706     }
707   new_st.op = EXEC_OMP_MASTER;
708   new_st.ext.omp_clauses = NULL;
709   return MATCH_YES;
710 }
711
712
713 match
714 gfc_match_omp_ordered (void)
715 {
716   if (gfc_match_omp_eos () != MATCH_YES)
717     {
718       gfc_error ("Unexpected junk after $OMP ORDERED statement at %C");
719       return MATCH_ERROR;
720     }
721   new_st.op = EXEC_OMP_ORDERED;
722   new_st.ext.omp_clauses = NULL;
723   return MATCH_YES;
724 }
725
726
727 match
728 gfc_match_omp_atomic (void)
729 {
730   gfc_omp_atomic_op op = GFC_OMP_ATOMIC_UPDATE;
731   if (gfc_match ("% update") == MATCH_YES)
732     op = GFC_OMP_ATOMIC_UPDATE;
733   else if (gfc_match ("% read") == MATCH_YES)
734     op = GFC_OMP_ATOMIC_READ;
735   else if (gfc_match ("% write") == MATCH_YES)
736     op = GFC_OMP_ATOMIC_WRITE;
737   else if (gfc_match ("% capture") == MATCH_YES)
738     op = GFC_OMP_ATOMIC_CAPTURE;
739   if (gfc_match_omp_eos () != MATCH_YES)
740     {
741       gfc_error ("Unexpected junk after $OMP ATOMIC statement at %C");
742       return MATCH_ERROR;
743     }
744   new_st.op = EXEC_OMP_ATOMIC;
745   new_st.ext.omp_atomic = op;
746   return MATCH_YES;
747 }
748
749
750 match
751 gfc_match_omp_barrier (void)
752 {
753   if (gfc_match_omp_eos () != MATCH_YES)
754     {
755       gfc_error ("Unexpected junk after $OMP BARRIER statement at %C");
756       return MATCH_ERROR;
757     }
758   new_st.op = EXEC_OMP_BARRIER;
759   new_st.ext.omp_clauses = NULL;
760   return MATCH_YES;
761 }
762
763
764 match
765 gfc_match_omp_end_nowait (void)
766 {
767   bool nowait = false;
768   if (gfc_match ("% nowait") == MATCH_YES)
769     nowait = true;
770   if (gfc_match_omp_eos () != MATCH_YES)
771     {
772       gfc_error ("Unexpected junk after NOWAIT clause at %C");
773       return MATCH_ERROR;
774     }
775   new_st.op = EXEC_OMP_END_NOWAIT;
776   new_st.ext.omp_bool = nowait;
777   return MATCH_YES;
778 }
779
780
781 match
782 gfc_match_omp_end_single (void)
783 {
784   gfc_omp_clauses *c;
785   if (gfc_match ("% nowait") == MATCH_YES)
786     {
787       new_st.op = EXEC_OMP_END_NOWAIT;
788       new_st.ext.omp_bool = true;
789       return MATCH_YES;
790     }
791   if (gfc_match_omp_clauses (&c, OMP_CLAUSE_COPYPRIVATE) != MATCH_YES)
792     return MATCH_ERROR;
793   new_st.op = EXEC_OMP_END_SINGLE;
794   new_st.ext.omp_clauses = c;
795   return MATCH_YES;
796 }
797
798
799 /* OpenMP directive resolving routines.  */
800
801 static void
802 resolve_omp_clauses (gfc_code *code)
803 {
804   gfc_omp_clauses *omp_clauses = code->ext.omp_clauses;
805   gfc_namelist *n;
806   int list;
807   static const char *clause_names[]
808     = { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED",
809         "COPYIN", "REDUCTION" };
810
811   if (omp_clauses == NULL)
812     return;
813
814   if (omp_clauses->if_expr)
815     {
816       gfc_expr *expr = omp_clauses->if_expr;
817       if (gfc_resolve_expr (expr) == FAILURE
818           || expr->ts.type != BT_LOGICAL || expr->rank != 0)
819         gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
820                    &expr->where);
821     }
822   if (omp_clauses->final_expr)
823     {
824       gfc_expr *expr = omp_clauses->final_expr;
825       if (gfc_resolve_expr (expr) == FAILURE
826           || expr->ts.type != BT_LOGICAL || expr->rank != 0)
827         gfc_error ("FINAL clause at %L requires a scalar LOGICAL expression",
828                    &expr->where);
829     }
830   if (omp_clauses->num_threads)
831     {
832       gfc_expr *expr = omp_clauses->num_threads;
833       if (gfc_resolve_expr (expr) == FAILURE
834           || expr->ts.type != BT_INTEGER || expr->rank != 0)
835         gfc_error ("NUM_THREADS clause at %L requires a scalar "
836                    "INTEGER expression", &expr->where);
837     }
838   if (omp_clauses->chunk_size)
839     {
840       gfc_expr *expr = omp_clauses->chunk_size;
841       if (gfc_resolve_expr (expr) == FAILURE
842           || expr->ts.type != BT_INTEGER || expr->rank != 0)
843         gfc_error ("SCHEDULE clause's chunk_size at %L requires "
844                    "a scalar INTEGER expression", &expr->where);
845     }
846
847   /* Check that no symbol appears on multiple clauses, except that
848      a symbol can appear on both firstprivate and lastprivate.  */
849   for (list = 0; list < OMP_LIST_NUM; list++)
850     for (n = omp_clauses->lists[list]; n; n = n->next)
851       {
852         n->sym->mark = 0;
853         if (n->sym->attr.flavor == FL_VARIABLE)
854           continue;
855         if (n->sym->attr.flavor == FL_PROCEDURE
856             && n->sym->result == n->sym
857             && n->sym->attr.function)
858           {
859             if (gfc_current_ns->proc_name == n->sym
860                 || (gfc_current_ns->parent
861                     && gfc_current_ns->parent->proc_name == n->sym))
862               continue;
863             if (gfc_current_ns->proc_name->attr.entry_master)
864               {
865                 gfc_entry_list *el = gfc_current_ns->entries;
866                 for (; el; el = el->next)
867                   if (el->sym == n->sym)
868                     break;
869                 if (el)
870                   continue;
871               }
872             if (gfc_current_ns->parent
873                 && gfc_current_ns->parent->proc_name->attr.entry_master)
874               {
875                 gfc_entry_list *el = gfc_current_ns->parent->entries;
876                 for (; el; el = el->next)
877                   if (el->sym == n->sym)
878                     break;
879                 if (el)
880                   continue;
881               }
882             if (n->sym->attr.proc_pointer)
883               continue;
884           }
885         gfc_error ("Object '%s' is not a variable at %L", n->sym->name,
886                    &code->loc);
887       }
888
889   for (list = 0; list < OMP_LIST_NUM; list++)
890     if (list != OMP_LIST_FIRSTPRIVATE && list != OMP_LIST_LASTPRIVATE)
891       for (n = omp_clauses->lists[list]; n; n = n->next)
892         {
893           if (n->sym->mark)
894             gfc_error ("Symbol '%s' present on multiple clauses at %L",
895                        n->sym->name, &code->loc);
896           else
897             n->sym->mark = 1;
898         }
899
900   gcc_assert (OMP_LIST_LASTPRIVATE == OMP_LIST_FIRSTPRIVATE + 1);
901   for (list = OMP_LIST_FIRSTPRIVATE; list <= OMP_LIST_LASTPRIVATE; list++)
902     for (n = omp_clauses->lists[list]; n; n = n->next)
903       if (n->sym->mark)
904         {
905           gfc_error ("Symbol '%s' present on multiple clauses at %L",
906                      n->sym->name, &code->loc);
907           n->sym->mark = 0;
908         }
909
910   for (n = omp_clauses->lists[OMP_LIST_FIRSTPRIVATE]; n; n = n->next)
911     {
912       if (n->sym->mark)
913         gfc_error ("Symbol '%s' present on multiple clauses at %L",
914                    n->sym->name, &code->loc);
915       else
916         n->sym->mark = 1;
917     }
918   for (n = omp_clauses->lists[OMP_LIST_LASTPRIVATE]; n; n = n->next)
919     n->sym->mark = 0;
920
921   for (n = omp_clauses->lists[OMP_LIST_LASTPRIVATE]; n; n = n->next)
922     {
923       if (n->sym->mark)
924         gfc_error ("Symbol '%s' present on multiple clauses at %L",
925                    n->sym->name, &code->loc);
926       else
927         n->sym->mark = 1;
928     }
929   for (list = 0; list < OMP_LIST_NUM; list++)
930     if ((n = omp_clauses->lists[list]) != NULL)
931       {
932         const char *name;
933
934         if (list < OMP_LIST_REDUCTION_FIRST)
935           name = clause_names[list];
936         else if (list <= OMP_LIST_REDUCTION_LAST)
937           name = clause_names[OMP_LIST_REDUCTION_FIRST];
938         else
939           gcc_unreachable ();
940
941         switch (list)
942           {
943           case OMP_LIST_COPYIN:
944             for (; n != NULL; n = n->next)
945               {
946                 if (!n->sym->attr.threadprivate)
947                   gfc_error ("Non-THREADPRIVATE object '%s' in COPYIN clause"
948                              " at %L", n->sym->name, &code->loc);
949                 if (n->sym->ts.type == BT_DERIVED && n->sym->ts.u.derived->attr.alloc_comp)
950                   gfc_error ("COPYIN clause object '%s' at %L has ALLOCATABLE components",
951                              n->sym->name, &code->loc);
952               }
953             break;
954           case OMP_LIST_COPYPRIVATE:
955             for (; n != NULL; n = n->next)
956               {
957                 if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE)
958                   gfc_error ("Assumed size array '%s' in COPYPRIVATE clause "
959                              "at %L", n->sym->name, &code->loc);
960                 if (n->sym->ts.type == BT_DERIVED && n->sym->ts.u.derived->attr.alloc_comp)
961                   gfc_error ("COPYPRIVATE clause object '%s' at %L has ALLOCATABLE components",
962                              n->sym->name, &code->loc);
963               }
964             break;
965           case OMP_LIST_SHARED:
966             for (; n != NULL; n = n->next)
967               {
968                 if (n->sym->attr.threadprivate)
969                   gfc_error ("THREADPRIVATE object '%s' in SHARED clause at "
970                              "%L", n->sym->name, &code->loc);
971                 if (n->sym->attr.cray_pointee)
972                   gfc_error ("Cray pointee '%s' in SHARED clause at %L",
973                             n->sym->name, &code->loc);
974               }
975             break;
976           default:
977             for (; n != NULL; n = n->next)
978               {
979                 if (n->sym->attr.threadprivate)
980                   gfc_error ("THREADPRIVATE object '%s' in %s clause at %L",
981                              n->sym->name, name, &code->loc);
982                 if (n->sym->attr.cray_pointee)
983                   gfc_error ("Cray pointee '%s' in %s clause at %L",
984                             n->sym->name, name, &code->loc);
985                 if (list != OMP_LIST_PRIVATE)
986                   {
987                     if (n->sym->attr.pointer
988                         && list >= OMP_LIST_REDUCTION_FIRST
989                         && list <= OMP_LIST_REDUCTION_LAST)
990                       gfc_error ("POINTER object '%s' in %s clause at %L",
991                                  n->sym->name, name, &code->loc);
992                     /* Variables in REDUCTION-clauses must be of intrinsic type (flagged below).  */
993                     if ((list < OMP_LIST_REDUCTION_FIRST || list > OMP_LIST_REDUCTION_LAST)
994                          && n->sym->ts.type == BT_DERIVED
995                          && n->sym->ts.u.derived->attr.alloc_comp)
996                       gfc_error ("%s clause object '%s' has ALLOCATABLE components at %L",
997                                  name, n->sym->name, &code->loc);
998                     if (n->sym->attr.cray_pointer
999                         && list >= OMP_LIST_REDUCTION_FIRST
1000                         && list <= OMP_LIST_REDUCTION_LAST)
1001                       gfc_error ("Cray pointer '%s' in %s clause at %L",
1002                                  n->sym->name, name, &code->loc);
1003                   }
1004                 if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE)
1005                   gfc_error ("Assumed size array '%s' in %s clause at %L",
1006                              n->sym->name, name, &code->loc);
1007                 if (n->sym->attr.in_namelist
1008                     && (list < OMP_LIST_REDUCTION_FIRST
1009                         || list > OMP_LIST_REDUCTION_LAST))
1010                   gfc_error ("Variable '%s' in %s clause is used in "
1011                              "NAMELIST statement at %L",
1012                              n->sym->name, name, &code->loc);
1013                 switch (list)
1014                   {
1015                   case OMP_LIST_PLUS:
1016                   case OMP_LIST_MULT:
1017                   case OMP_LIST_SUB:
1018                     if (!gfc_numeric_ts (&n->sym->ts))
1019                       gfc_error ("%c REDUCTION variable '%s' at %L must be of numeric type, got %s",
1020                                  list == OMP_LIST_PLUS ? '+'
1021                                  : list == OMP_LIST_MULT ? '*' : '-',
1022                                  n->sym->name, &code->loc,
1023                                  gfc_typename (&n->sym->ts));
1024                     break;
1025                   case OMP_LIST_AND:
1026                   case OMP_LIST_OR:
1027                   case OMP_LIST_EQV:
1028                   case OMP_LIST_NEQV:
1029                     if (n->sym->ts.type != BT_LOGICAL)
1030                       gfc_error ("%s REDUCTION variable '%s' must be LOGICAL "
1031                                  "at %L",
1032                                  list == OMP_LIST_AND ? ".AND."
1033                                  : list == OMP_LIST_OR ? ".OR."
1034                                  : list == OMP_LIST_EQV ? ".EQV." : ".NEQV.",
1035                                  n->sym->name, &code->loc);
1036                     break;
1037                   case OMP_LIST_MAX:
1038                   case OMP_LIST_MIN:
1039                     if (n->sym->ts.type != BT_INTEGER
1040                         && n->sym->ts.type != BT_REAL)
1041                       gfc_error ("%s REDUCTION variable '%s' must be "
1042                                  "INTEGER or REAL at %L",
1043                                  list == OMP_LIST_MAX ? "MAX" : "MIN",
1044                                  n->sym->name, &code->loc);
1045                     break;
1046                   case OMP_LIST_IAND:
1047                   case OMP_LIST_IOR:
1048                   case OMP_LIST_IEOR:
1049                     if (n->sym->ts.type != BT_INTEGER)
1050                       gfc_error ("%s REDUCTION variable '%s' must be INTEGER "
1051                                  "at %L",
1052                                  list == OMP_LIST_IAND ? "IAND"
1053                                  : list == OMP_LIST_MULT ? "IOR" : "IEOR",
1054                                  n->sym->name, &code->loc);
1055                     break;
1056                   /* Workaround for PR middle-end/26316, nothing really needs
1057                      to be done here for OMP_LIST_PRIVATE.  */
1058                   case OMP_LIST_PRIVATE:
1059                     gcc_assert (code->op != EXEC_NOP);
1060                   default:
1061                     break;
1062                   }
1063               }
1064             break;
1065           }
1066       }
1067 }
1068
1069
1070 /* Return true if SYM is ever referenced in EXPR except in the SE node.  */
1071
1072 static bool
1073 expr_references_sym (gfc_expr *e, gfc_symbol *s, gfc_expr *se)
1074 {
1075   gfc_actual_arglist *arg;
1076   if (e == NULL || e == se)
1077     return false;
1078   switch (e->expr_type)
1079     {
1080     case EXPR_CONSTANT:
1081     case EXPR_NULL:
1082     case EXPR_VARIABLE:
1083     case EXPR_STRUCTURE:
1084     case EXPR_ARRAY:
1085       if (e->symtree != NULL
1086           && e->symtree->n.sym == s)
1087         return true;
1088       return false;
1089     case EXPR_SUBSTRING:
1090       if (e->ref != NULL
1091           && (expr_references_sym (e->ref->u.ss.start, s, se)
1092               || expr_references_sym (e->ref->u.ss.end, s, se)))
1093         return true;
1094       return false;
1095     case EXPR_OP:
1096       if (expr_references_sym (e->value.op.op2, s, se))
1097         return true;
1098       return expr_references_sym (e->value.op.op1, s, se);
1099     case EXPR_FUNCTION:
1100       for (arg = e->value.function.actual; arg; arg = arg->next)
1101         if (expr_references_sym (arg->expr, s, se))
1102           return true;
1103       return false;
1104     default:
1105       gcc_unreachable ();
1106     }
1107 }
1108
1109
1110 /* If EXPR is a conversion function that widens the type
1111    if WIDENING is true or narrows the type if WIDENING is false,
1112    return the inner expression, otherwise return NULL.  */
1113
1114 static gfc_expr *
1115 is_conversion (gfc_expr *expr, bool widening)
1116 {
1117   gfc_typespec *ts1, *ts2;
1118
1119   if (expr->expr_type != EXPR_FUNCTION
1120       || expr->value.function.isym == NULL
1121       || expr->value.function.esym != NULL
1122       || expr->value.function.isym->id != GFC_ISYM_CONVERSION)
1123     return NULL;
1124
1125   if (widening)
1126     {
1127       ts1 = &expr->ts;
1128       ts2 = &expr->value.function.actual->expr->ts;
1129     }
1130   else
1131     {
1132       ts1 = &expr->value.function.actual->expr->ts;
1133       ts2 = &expr->ts;
1134     }
1135
1136   if (ts1->type > ts2->type
1137       || (ts1->type == ts2->type && ts1->kind > ts2->kind))
1138     return expr->value.function.actual->expr;
1139
1140   return NULL;
1141 }
1142
1143
1144 static void
1145 resolve_omp_atomic (gfc_code *code)
1146 {
1147   gfc_code *atomic_code = code;
1148   gfc_symbol *var;
1149   gfc_expr *expr2, *expr2_tmp;
1150
1151   code = code->block->next;
1152   gcc_assert (code->op == EXEC_ASSIGN);
1153   gcc_assert ((atomic_code->ext.omp_atomic != GFC_OMP_ATOMIC_CAPTURE
1154                && code->next == NULL)
1155               || (atomic_code->ext.omp_atomic == GFC_OMP_ATOMIC_CAPTURE
1156                   && code->next != NULL
1157                   && code->next->op == EXEC_ASSIGN
1158                   && code->next->next == NULL));
1159
1160   if (code->expr1->expr_type != EXPR_VARIABLE
1161       || code->expr1->symtree == NULL
1162       || code->expr1->rank != 0
1163       || (code->expr1->ts.type != BT_INTEGER
1164           && code->expr1->ts.type != BT_REAL
1165           && code->expr1->ts.type != BT_COMPLEX
1166           && code->expr1->ts.type != BT_LOGICAL))
1167     {
1168       gfc_error ("!$OMP ATOMIC statement must set a scalar variable of "
1169                  "intrinsic type at %L", &code->loc);
1170       return;
1171     }
1172
1173   var = code->expr1->symtree->n.sym;
1174   expr2 = is_conversion (code->expr2, false);
1175   if (expr2 == NULL)
1176     {
1177       if (atomic_code->ext.omp_atomic == GFC_OMP_ATOMIC_READ
1178           || atomic_code->ext.omp_atomic == GFC_OMP_ATOMIC_WRITE)
1179         expr2 = is_conversion (code->expr2, true);
1180       if (expr2 == NULL)
1181         expr2 = code->expr2;
1182     }
1183
1184   switch (atomic_code->ext.omp_atomic)
1185     {
1186     case GFC_OMP_ATOMIC_READ:
1187       if (expr2->expr_type != EXPR_VARIABLE
1188           || expr2->symtree == NULL
1189           || expr2->rank != 0
1190           || (expr2->ts.type != BT_INTEGER
1191               && expr2->ts.type != BT_REAL
1192               && expr2->ts.type != BT_COMPLEX
1193               && expr2->ts.type != BT_LOGICAL))
1194         gfc_error ("!$OMP ATOMIC READ statement must read from a scalar "
1195                    "variable of intrinsic type at %L", &expr2->where);
1196       return;
1197     case GFC_OMP_ATOMIC_WRITE:
1198       if (expr2->rank != 0 || expr_references_sym (code->expr2, var, NULL))
1199         gfc_error ("expr in !$OMP ATOMIC WRITE assignment var = expr "
1200                    "must be scalar and cannot reference var at %L",
1201                    &expr2->where);
1202       return;
1203     case GFC_OMP_ATOMIC_CAPTURE:
1204       expr2_tmp = expr2;
1205       if (expr2 == code->expr2)
1206         {
1207           expr2_tmp = is_conversion (code->expr2, true);
1208           if (expr2_tmp == NULL)
1209             expr2_tmp = expr2;
1210         }
1211       if (expr2_tmp->expr_type == EXPR_VARIABLE)
1212         {
1213           if (expr2_tmp->symtree == NULL
1214               || expr2_tmp->rank != 0
1215               || (expr2_tmp->ts.type != BT_INTEGER
1216                   && expr2_tmp->ts.type != BT_REAL
1217                   && expr2_tmp->ts.type != BT_COMPLEX
1218                   && expr2_tmp->ts.type != BT_LOGICAL)
1219               || expr2_tmp->symtree->n.sym == var)
1220             {
1221               gfc_error ("!$OMP ATOMIC CAPTURE capture statement must read from "
1222                          "a scalar variable of intrinsic type at %L",
1223                          &expr2_tmp->where);
1224               return;
1225             }
1226           var = expr2_tmp->symtree->n.sym;
1227           code = code->next;
1228           if (code->expr1->expr_type != EXPR_VARIABLE
1229               || code->expr1->symtree == NULL
1230               || code->expr1->rank != 0
1231               || (code->expr1->ts.type != BT_INTEGER
1232                   && code->expr1->ts.type != BT_REAL
1233                   && code->expr1->ts.type != BT_COMPLEX
1234                   && code->expr1->ts.type != BT_LOGICAL))
1235             {
1236               gfc_error ("!$OMP ATOMIC CAPTURE update statement must set "
1237                          "a scalar variable of intrinsic type at %L",
1238                          &code->expr1->where);
1239               return;
1240             }
1241           if (code->expr1->symtree->n.sym != var)
1242             {
1243               gfc_error ("!$OMP ATOMIC CAPTURE capture statement reads from "
1244                          "different variable than update statement writes "
1245                          "into at %L", &code->expr1->where);
1246               return;
1247             }
1248           expr2 = is_conversion (code->expr2, false);
1249           if (expr2 == NULL)
1250             expr2 = code->expr2;
1251         }
1252       break;
1253     default:
1254       break;
1255     }
1256
1257   if (expr2->expr_type == EXPR_OP)
1258     {
1259       gfc_expr *v = NULL, *e, *c;
1260       gfc_intrinsic_op op = expr2->value.op.op;
1261       gfc_intrinsic_op alt_op = INTRINSIC_NONE;
1262
1263       switch (op)
1264         {
1265         case INTRINSIC_PLUS:
1266           alt_op = INTRINSIC_MINUS;
1267           break;
1268         case INTRINSIC_TIMES:
1269           alt_op = INTRINSIC_DIVIDE;
1270           break;
1271         case INTRINSIC_MINUS:
1272           alt_op = INTRINSIC_PLUS;
1273           break;
1274         case INTRINSIC_DIVIDE:
1275           alt_op = INTRINSIC_TIMES;
1276           break;
1277         case INTRINSIC_AND:
1278         case INTRINSIC_OR:
1279           break;
1280         case INTRINSIC_EQV:
1281           alt_op = INTRINSIC_NEQV;
1282           break;
1283         case INTRINSIC_NEQV:
1284           alt_op = INTRINSIC_EQV;
1285           break;
1286         default:
1287           gfc_error ("!$OMP ATOMIC assignment operator must be "
1288                      "+, *, -, /, .AND., .OR., .EQV. or .NEQV. at %L",
1289                      &expr2->where);
1290           return;
1291         }
1292
1293       /* Check for var = var op expr resp. var = expr op var where
1294          expr doesn't reference var and var op expr is mathematically
1295          equivalent to var op (expr) resp. expr op var equivalent to
1296          (expr) op var.  We rely here on the fact that the matcher
1297          for x op1 y op2 z where op1 and op2 have equal precedence
1298          returns (x op1 y) op2 z.  */
1299       e = expr2->value.op.op2;
1300       if (e->expr_type == EXPR_VARIABLE
1301           && e->symtree != NULL
1302           && e->symtree->n.sym == var)
1303         v = e;
1304       else if ((c = is_conversion (e, true)) != NULL
1305                && c->expr_type == EXPR_VARIABLE
1306                && c->symtree != NULL
1307                && c->symtree->n.sym == var)
1308         v = c;
1309       else
1310         {
1311           gfc_expr **p = NULL, **q;
1312           for (q = &expr2->value.op.op1; (e = *q) != NULL; )
1313             if (e->expr_type == EXPR_VARIABLE
1314                 && e->symtree != NULL
1315                 && e->symtree->n.sym == var)
1316               {
1317                 v = e;
1318                 break;
1319               }
1320             else if ((c = is_conversion (e, true)) != NULL)
1321               q = &e->value.function.actual->expr;
1322             else if (e->expr_type != EXPR_OP
1323                      || (e->value.op.op != op
1324                          && e->value.op.op != alt_op)
1325                      || e->rank != 0)
1326               break;
1327             else
1328               {
1329                 p = q;
1330                 q = &e->value.op.op1;
1331               }
1332
1333           if (v == NULL)
1334             {
1335               gfc_error ("!$OMP ATOMIC assignment must be var = var op expr "
1336                          "or var = expr op var at %L", &expr2->where);
1337               return;
1338             }
1339
1340           if (p != NULL)
1341             {
1342               e = *p;
1343               switch (e->value.op.op)
1344                 {
1345                 case INTRINSIC_MINUS:
1346                 case INTRINSIC_DIVIDE:
1347                 case INTRINSIC_EQV:
1348                 case INTRINSIC_NEQV:
1349                   gfc_error ("!$OMP ATOMIC var = var op expr not "
1350                              "mathematically equivalent to var = var op "
1351                              "(expr) at %L", &expr2->where);
1352                   break;
1353                 default:
1354                   break;
1355                 }
1356
1357               /* Canonicalize into var = var op (expr).  */
1358               *p = e->value.op.op2;
1359               e->value.op.op2 = expr2;
1360               e->ts = expr2->ts;
1361               if (code->expr2 == expr2)
1362                 code->expr2 = expr2 = e;
1363               else
1364                 code->expr2->value.function.actual->expr = expr2 = e;
1365
1366               if (!gfc_compare_types (&expr2->value.op.op1->ts, &expr2->ts))
1367                 {
1368                   for (p = &expr2->value.op.op1; *p != v;
1369                        p = &(*p)->value.function.actual->expr)
1370                     ;
1371                   *p = NULL;
1372                   gfc_free_expr (expr2->value.op.op1);
1373                   expr2->value.op.op1 = v;
1374                   gfc_convert_type (v, &expr2->ts, 2);
1375                 }
1376             }
1377         }
1378
1379       if (e->rank != 0 || expr_references_sym (code->expr2, var, v))
1380         {
1381           gfc_error ("expr in !$OMP ATOMIC assignment var = var op expr "
1382                      "must be scalar and cannot reference var at %L",
1383                      &expr2->where);
1384           return;
1385         }
1386     }
1387   else if (expr2->expr_type == EXPR_FUNCTION
1388            && expr2->value.function.isym != NULL
1389            && expr2->value.function.esym == NULL
1390            && expr2->value.function.actual != NULL
1391            && expr2->value.function.actual->next != NULL)
1392     {
1393       gfc_actual_arglist *arg, *var_arg;
1394
1395       switch (expr2->value.function.isym->id)
1396         {
1397         case GFC_ISYM_MIN:
1398         case GFC_ISYM_MAX:
1399           break;
1400         case GFC_ISYM_IAND:
1401         case GFC_ISYM_IOR:
1402         case GFC_ISYM_IEOR:
1403           if (expr2->value.function.actual->next->next != NULL)
1404             {
1405               gfc_error ("!$OMP ATOMIC assignment intrinsic IAND, IOR "
1406                          "or IEOR must have two arguments at %L",
1407                          &expr2->where);
1408               return;
1409             }
1410           break;
1411         default:
1412           gfc_error ("!$OMP ATOMIC assignment intrinsic must be "
1413                      "MIN, MAX, IAND, IOR or IEOR at %L",
1414                      &expr2->where);
1415           return;
1416         }
1417
1418       var_arg = NULL;
1419       for (arg = expr2->value.function.actual; arg; arg = arg->next)
1420         {
1421           if ((arg == expr2->value.function.actual
1422                || (var_arg == NULL && arg->next == NULL))
1423               && arg->expr->expr_type == EXPR_VARIABLE
1424               && arg->expr->symtree != NULL
1425               && arg->expr->symtree->n.sym == var)
1426             var_arg = arg;
1427           else if (expr_references_sym (arg->expr, var, NULL))
1428             gfc_error ("!$OMP ATOMIC intrinsic arguments except one must not "
1429                        "reference '%s' at %L", var->name, &arg->expr->where);
1430           if (arg->expr->rank != 0)
1431             gfc_error ("!$OMP ATOMIC intrinsic arguments must be scalar "
1432                        "at %L", &arg->expr->where);
1433         }
1434
1435       if (var_arg == NULL)
1436         {
1437           gfc_error ("First or last !$OMP ATOMIC intrinsic argument must "
1438                      "be '%s' at %L", var->name, &expr2->where);
1439           return;
1440         }
1441
1442       if (var_arg != expr2->value.function.actual)
1443         {
1444           /* Canonicalize, so that var comes first.  */
1445           gcc_assert (var_arg->next == NULL);
1446           for (arg = expr2->value.function.actual;
1447                arg->next != var_arg; arg = arg->next)
1448             ;
1449           var_arg->next = expr2->value.function.actual;
1450           expr2->value.function.actual = var_arg;
1451           arg->next = NULL;
1452         }
1453     }
1454   else
1455     gfc_error ("!$OMP ATOMIC assignment must have an operator or intrinsic "
1456                "on right hand side at %L", &expr2->where);
1457
1458   if (atomic_code->ext.omp_atomic == GFC_OMP_ATOMIC_CAPTURE && code->next)
1459     {
1460       code = code->next;
1461       if (code->expr1->expr_type != EXPR_VARIABLE
1462           || code->expr1->symtree == NULL
1463           || code->expr1->rank != 0
1464           || (code->expr1->ts.type != BT_INTEGER
1465               && code->expr1->ts.type != BT_REAL
1466               && code->expr1->ts.type != BT_COMPLEX
1467               && code->expr1->ts.type != BT_LOGICAL))
1468         {
1469           gfc_error ("!$OMP ATOMIC CAPTURE capture statement must set "
1470                      "a scalar variable of intrinsic type at %L",
1471                      &code->expr1->where);
1472           return;
1473         }
1474
1475       expr2 = is_conversion (code->expr2, false);
1476       if (expr2 == NULL)
1477         {
1478           expr2 = is_conversion (code->expr2, true);
1479           if (expr2 == NULL)
1480             expr2 = code->expr2;
1481         }
1482
1483       if (expr2->expr_type != EXPR_VARIABLE
1484           || expr2->symtree == NULL
1485           || expr2->rank != 0
1486           || (expr2->ts.type != BT_INTEGER
1487               && expr2->ts.type != BT_REAL
1488               && expr2->ts.type != BT_COMPLEX
1489               && expr2->ts.type != BT_LOGICAL))
1490         {
1491           gfc_error ("!$OMP ATOMIC CAPTURE capture statement must read "
1492                      "from a scalar variable of intrinsic type at %L",
1493                      &expr2->where);
1494           return;
1495         }
1496       if (expr2->symtree->n.sym != var)
1497         {
1498           gfc_error ("!$OMP ATOMIC CAPTURE capture statement reads from "
1499                      "different variable than update statement writes "
1500                      "into at %L", &expr2->where);
1501           return;
1502         }
1503     }
1504 }
1505
1506
1507 struct omp_context
1508 {
1509   gfc_code *code;
1510   struct pointer_set_t *sharing_clauses;
1511   struct pointer_set_t *private_iterators;
1512   struct omp_context *previous;
1513 } *omp_current_ctx;
1514 static gfc_code *omp_current_do_code;
1515 static int omp_current_do_collapse;
1516
1517 void
1518 gfc_resolve_omp_do_blocks (gfc_code *code, gfc_namespace *ns)
1519 {
1520   if (code->block->next && code->block->next->op == EXEC_DO)
1521     {
1522       int i;
1523       gfc_code *c;
1524
1525       omp_current_do_code = code->block->next;
1526       omp_current_do_collapse = code->ext.omp_clauses->collapse;
1527       for (i = 1, c = omp_current_do_code; i < omp_current_do_collapse; i++)
1528         {
1529           c = c->block;
1530           if (c->op != EXEC_DO || c->next == NULL)
1531             break;
1532           c = c->next;
1533           if (c->op != EXEC_DO)
1534             break;
1535         }
1536       if (i < omp_current_do_collapse || omp_current_do_collapse <= 0)
1537         omp_current_do_collapse = 1;
1538     }
1539   gfc_resolve_blocks (code->block, ns);
1540   omp_current_do_collapse = 0;
1541   omp_current_do_code = NULL;
1542 }
1543
1544
1545 void
1546 gfc_resolve_omp_parallel_blocks (gfc_code *code, gfc_namespace *ns)
1547 {
1548   struct omp_context ctx;
1549   gfc_omp_clauses *omp_clauses = code->ext.omp_clauses;
1550   gfc_namelist *n;
1551   int list;
1552
1553   ctx.code = code;
1554   ctx.sharing_clauses = pointer_set_create ();
1555   ctx.private_iterators = pointer_set_create ();
1556   ctx.previous = omp_current_ctx;
1557   omp_current_ctx = &ctx;
1558
1559   for (list = 0; list < OMP_LIST_NUM; list++)
1560     for (n = omp_clauses->lists[list]; n; n = n->next)
1561       pointer_set_insert (ctx.sharing_clauses, n->sym);
1562
1563   if (code->op == EXEC_OMP_PARALLEL_DO)
1564     gfc_resolve_omp_do_blocks (code, ns);
1565   else
1566     gfc_resolve_blocks (code->block, ns);
1567
1568   omp_current_ctx = ctx.previous;
1569   pointer_set_destroy (ctx.sharing_clauses);
1570   pointer_set_destroy (ctx.private_iterators);
1571 }
1572
1573
1574 /* Save and clear openmp.c private state.  */
1575
1576 void
1577 gfc_omp_save_and_clear_state (struct gfc_omp_saved_state *state)
1578 {
1579   state->ptrs[0] = omp_current_ctx;
1580   state->ptrs[1] = omp_current_do_code;
1581   state->ints[0] = omp_current_do_collapse;
1582   omp_current_ctx = NULL;
1583   omp_current_do_code = NULL;
1584   omp_current_do_collapse = 0;
1585 }
1586
1587
1588 /* Restore openmp.c private state from the saved state.  */
1589
1590 void
1591 gfc_omp_restore_state (struct gfc_omp_saved_state *state)
1592 {
1593   omp_current_ctx = (struct omp_context *) state->ptrs[0];
1594   omp_current_do_code = (gfc_code *) state->ptrs[1];
1595   omp_current_do_collapse = state->ints[0];
1596 }
1597
1598
1599 /* Note a DO iterator variable.  This is special in !$omp parallel
1600    construct, where they are predetermined private.  */
1601
1602 void
1603 gfc_resolve_do_iterator (gfc_code *code, gfc_symbol *sym)
1604 {
1605   int i = omp_current_do_collapse;
1606   gfc_code *c = omp_current_do_code;
1607
1608   if (sym->attr.threadprivate)
1609     return;
1610
1611   /* !$omp do and !$omp parallel do iteration variable is predetermined
1612      private just in the !$omp do resp. !$omp parallel do construct,
1613      with no implications for the outer parallel constructs.  */
1614
1615   while (i-- >= 1)
1616     {
1617       if (code == c)
1618         return;
1619
1620       c = c->block->next;
1621     }
1622
1623   if (omp_current_ctx == NULL)
1624     return;
1625
1626   if (pointer_set_contains (omp_current_ctx->sharing_clauses, sym))
1627     return;
1628
1629   if (! pointer_set_insert (omp_current_ctx->private_iterators, sym))
1630     {
1631       gfc_omp_clauses *omp_clauses = omp_current_ctx->code->ext.omp_clauses;
1632       gfc_namelist *p;
1633
1634       p = gfc_get_namelist ();
1635       p->sym = sym;
1636       p->next = omp_clauses->lists[OMP_LIST_PRIVATE];
1637       omp_clauses->lists[OMP_LIST_PRIVATE] = p;
1638     }
1639 }
1640
1641
1642 static void
1643 resolve_omp_do (gfc_code *code)
1644 {
1645   gfc_code *do_code, *c;
1646   int list, i, collapse;
1647   gfc_namelist *n;
1648   gfc_symbol *dovar;
1649
1650   if (code->ext.omp_clauses)
1651     resolve_omp_clauses (code);
1652
1653   do_code = code->block->next;
1654   collapse = code->ext.omp_clauses->collapse;
1655   if (collapse <= 0)
1656     collapse = 1;
1657   for (i = 1; i <= collapse; i++)
1658     {
1659       if (do_code->op == EXEC_DO_WHILE)
1660         {
1661           gfc_error ("!$OMP DO cannot be a DO WHILE or DO without loop control "
1662                      "at %L", &do_code->loc);
1663           break;
1664         }
1665       gcc_assert (do_code->op == EXEC_DO);
1666       if (do_code->ext.iterator->var->ts.type != BT_INTEGER)
1667         gfc_error ("!$OMP DO iteration variable must be of type integer at %L",
1668                    &do_code->loc);
1669       dovar = do_code->ext.iterator->var->symtree->n.sym;
1670       if (dovar->attr.threadprivate)
1671         gfc_error ("!$OMP DO iteration variable must not be THREADPRIVATE "
1672                    "at %L", &do_code->loc);
1673       if (code->ext.omp_clauses)
1674         for (list = 0; list < OMP_LIST_NUM; list++)
1675           if (list != OMP_LIST_PRIVATE && list != OMP_LIST_LASTPRIVATE)
1676             for (n = code->ext.omp_clauses->lists[list]; n; n = n->next)
1677               if (dovar == n->sym)
1678                 {
1679                   gfc_error ("!$OMP DO iteration variable present on clause "
1680                              "other than PRIVATE or LASTPRIVATE at %L",
1681                              &do_code->loc);
1682                   break;
1683                 }
1684       if (i > 1)
1685         {
1686           gfc_code *do_code2 = code->block->next;
1687           int j;
1688
1689           for (j = 1; j < i; j++)
1690             {
1691               gfc_symbol *ivar = do_code2->ext.iterator->var->symtree->n.sym;
1692               if (dovar == ivar
1693                   || gfc_find_sym_in_expr (ivar, do_code->ext.iterator->start)
1694                   || gfc_find_sym_in_expr (ivar, do_code->ext.iterator->end)
1695                   || gfc_find_sym_in_expr (ivar, do_code->ext.iterator->step))
1696                 {
1697                   gfc_error ("!$OMP DO collapsed loops don't form rectangular iteration space at %L",
1698                              &do_code->loc);
1699                   break;
1700                 }
1701               if (j < i)
1702                 break;
1703               do_code2 = do_code2->block->next;
1704             }
1705         }
1706       if (i == collapse)
1707         break;
1708       for (c = do_code->next; c; c = c->next)
1709         if (c->op != EXEC_NOP && c->op != EXEC_CONTINUE)
1710           {
1711             gfc_error ("collapsed !$OMP DO loops not perfectly nested at %L",
1712                        &c->loc);
1713             break;
1714           }
1715       if (c)
1716         break;
1717       do_code = do_code->block;
1718       if (do_code->op != EXEC_DO && do_code->op != EXEC_DO_WHILE)
1719         {
1720           gfc_error ("not enough DO loops for collapsed !$OMP DO at %L",
1721                      &code->loc);
1722           break;
1723         }
1724       do_code = do_code->next;
1725       if (do_code == NULL
1726           || (do_code->op != EXEC_DO && do_code->op != EXEC_DO_WHILE))
1727         {
1728           gfc_error ("not enough DO loops for collapsed !$OMP DO at %L",
1729                      &code->loc);
1730           break;
1731         }
1732     }
1733 }
1734
1735
1736 /* Resolve OpenMP directive clauses and check various requirements
1737    of each directive.  */
1738
1739 void
1740 gfc_resolve_omp_directive (gfc_code *code, gfc_namespace *ns ATTRIBUTE_UNUSED)
1741 {
1742   if (code->op != EXEC_OMP_ATOMIC)
1743     gfc_maybe_initialize_eh ();
1744
1745   switch (code->op)
1746     {
1747     case EXEC_OMP_DO:
1748     case EXEC_OMP_PARALLEL_DO:
1749       resolve_omp_do (code);
1750       break;
1751     case EXEC_OMP_WORKSHARE:
1752     case EXEC_OMP_PARALLEL_WORKSHARE:
1753     case EXEC_OMP_PARALLEL:
1754     case EXEC_OMP_PARALLEL_SECTIONS:
1755     case EXEC_OMP_SECTIONS:
1756     case EXEC_OMP_SINGLE:
1757     case EXEC_OMP_TASK:
1758       if (code->ext.omp_clauses)
1759         resolve_omp_clauses (code);
1760       break;
1761     case EXEC_OMP_ATOMIC:
1762       resolve_omp_atomic (code);
1763       break;
1764     default:
1765       break;
1766     }
1767 }