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 <[email protected]>
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 <[email protected]>
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 <[email protected]>.
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" } }