Hello, I'm proposing here a fix for an OpenMP ICE regression introduced by me at http://gcc.gnu.org/r221586
That revision changed the order in which procedures are resolved, making it possible for a procedure to be resolved from within an OpenMP construct body. As the OpenMP constructs set some global state, the procedure's do loop were registered as OpenMP-managed loops. The attached patch clears the OpenMP state upon gfc_resolve entry and restores it upon return. I don't know the OpenMP code very well, but it seems reasonable to me to do that. Regression-tested on x86_64-linux. OK for trunk/5 ? Mikael
2015-06-18 Mikael Morin <mik...@gcc.gnu.org> PR fortran/66549 * resolve.c (resolve_global_procedure): Don't save and restore OpenMP state around the call to gfc_resolve. (gfc_resolve): Save OpenMP state on entry and restore it on return. 2015-06-18 Mikael Morin <mik...@gcc.gnu.org> PR fortran/66549 * gfortran.dg/gomp/omp_parallel_1.f90: New file.
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index e615cc6..23bee8f 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -2384,14 +2384,11 @@ resolve_global_procedure (gfc_symbol *sym, locus *where, if (!gsym->ns->resolved) { gfc_dt_list *old_dt_list; - struct gfc_omp_saved_state old_omp_state; /* Stash away derived types so that the backend_decls do not get mixed up. */ old_dt_list = gfc_derived_types; gfc_derived_types = NULL; - /* And stash away openmp state. */ - gfc_omp_save_and_clear_state (&old_omp_state); gfc_resolve (gsym->ns); @@ -2401,8 +2398,6 @@ resolve_global_procedure (gfc_symbol *sym, locus *where, /* Restore the derived types of this namespace. */ gfc_derived_types = old_dt_list; - /* And openmp state. */ - gfc_omp_restore_state (&old_omp_state); } /* Make sure that translation for the gsymbol occurs before @@ -15071,6 +15066,7 @@ gfc_resolve (gfc_namespace *ns) { gfc_namespace *old_ns; code_stack *old_cs_base; + struct gfc_omp_saved_state old_omp_state; if (ns->resolved) return; @@ -15079,6 +15075,11 @@ gfc_resolve (gfc_namespace *ns) old_ns = gfc_current_ns; old_cs_base = cs_base; + /* As gfc_resolve can be called during resolution of an OpenMP construct + body, we should clear any state associated to it, so that say NS's + DO loops are not interpreted as OpenMP loops. */ + gfc_omp_save_and_clear_state (&old_omp_state); + resolve_types (ns); component_assignment_level = 0; resolve_codes (ns); @@ -15088,4 +15089,6 @@ gfc_resolve (gfc_namespace *ns) ns->resolved = 1; gfc_run_passes (ns); + + gfc_omp_restore_state (&old_omp_state); }
! { dg-do compile } ! { dg-additional-options "-fdump-tree-original" } ! ! PR fortran/66549 ! The resolution of CVN in the middle CLWF's OpenMP construct was ! making the DO loop (wrongly) interpreted as an OpenMP-managed loop, leading ! to an ICE. ! ! Contributed by Andrew Benson <abenso...@gmail.com>. module smfa type :: sgc contains procedure :: sla => sa end type sgc class(sgc), pointer :: sg_ double precision, allocatable, dimension(:) :: vni contains double precision function sa(self,i) class(sgc), intent(in ) :: self end function sa subroutine cvn(sg_,vn) class(sgc), intent(inout) :: sg_ double precision, intent( out), dimension(:) :: vn integer :: i do i=1,2 vn(i)= sg_%sla(i) end do end subroutine cvn subroutine clwf() !$omp parallel call cvn(sg_,vni) !$omp end parallel end subroutine clwf end module smfa ! { dg-final { scan-tree-dump-times "#pragma\\s+omp\\s+parallel\\n" 1 "original" } }