diff options
author | Thomas Schwinge <thomas@codesourcery.com> | 2019-02-28 21:31:36 +0100 |
---|---|---|
committer | Thomas Schwinge <tschwinge@gcc.gnu.org> | 2019-02-28 21:31:36 +0100 |
commit | 80d6ca01843d2119c913e3adf27d20204846072f (patch) | |
tree | c1472e54a6fb1e359f39c9dfb1aa8c53d2fdfa2a /gcc/fortran | |
parent | e5fd6684b9577e822997ceedabfeaa7d61722fe2 (diff) | |
download | gcc-80d6ca01843d2119c913e3adf27d20204846072f.zip gcc-80d6ca01843d2119c913e3adf27d20204846072f.tar.gz gcc-80d6ca01843d2119c913e3adf27d20204846072f.tar.bz2 |
[PR72741, PR89433] Repeated use of the Fortran OpenACC 'routine' directive
gcc/fortran/
PR fortran/72741
PR fortran/89433
* openmp.c (gfc_match_oacc_routine): Handle repeated use of the
Fortran OpenACC 'routine' directive.
gcc/testsuite/
PR fortran/72741
PR fortran/89433
* gfortran.dg/goacc/routine-multiple-directives-1.f90: New file.
* gfortran.dg/goacc/routine-multiple-directives-2.f90: Likewise.
Co-Authored-By: Cesar Philippidis <cesar@codesourcery.com>
From-SVN: r269287
Diffstat (limited to 'gcc/fortran')
-rw-r--r-- | gcc/fortran/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/fortran/openmp.c | 43 |
2 files changed, 40 insertions, 8 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 1c8f712..6adb90a 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -2,6 +2,11 @@ Cesar Philippidis <cesar@codesourcery.com> PR fortran/72741 + PR fortran/89433 + * openmp.c (gfc_match_oacc_routine): Handle repeated use of the + Fortran OpenACC 'routine' directive. + + PR fortran/72741 * gfortran.h (enum oacc_routine_lop): Add OACC_ROUTINE_LOP_ERROR. * openmp.c (gfc_oacc_routine_lop, gfc_match_oacc_routine): Use it. * trans-decl.c (add_attributes_to_decl): Likewise. diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index 50b91f2..7a06eb5 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -2374,17 +2374,44 @@ gfc_match_oacc_routine (void) } else if (sym != NULL) { - n = gfc_get_oacc_routine_name (); - n->sym = sym; - n->clauses = NULL; - n->next = NULL; - if (gfc_current_ns->oacc_routine_names != NULL) - n->next = gfc_current_ns->oacc_routine_names; - - gfc_current_ns->oacc_routine_names = n; + bool add = true; + + /* For a repeated OpenACC 'routine' directive, diagnose if it doesn't + match the first one. */ + for (gfc_oacc_routine_name *n_p = gfc_current_ns->oacc_routine_names; + n_p; + n_p = n_p->next) + if (n_p->sym == sym) + { + add = false; + if (lop != gfc_oacc_routine_lop (n_p->clauses)) + { + gfc_error ("!$ACC ROUTINE already applied at %C"); + goto cleanup; + } + } + + if (add) + { + n = gfc_get_oacc_routine_name (); + n->sym = sym; + n->clauses = c; + n->next = gfc_current_ns->oacc_routine_names; + gfc_current_ns->oacc_routine_names = n; + } } else if (gfc_current_ns->proc_name) { + /* For a repeated OpenACC 'routine' directive, diagnose if it doesn't + match the first one. */ + oacc_routine_lop lop_p = gfc_current_ns->proc_name->attr.oacc_routine_lop; + if (lop_p != OACC_ROUTINE_LOP_NONE + && lop != lop_p) + { + gfc_error ("!$ACC ROUTINE already applied at %C"); + goto cleanup; + } + if (!gfc_add_omp_declare_target (&gfc_current_ns->proc_name->attr, gfc_current_ns->proc_name->name, &old_loc)) |