Message ID | 20171102010957.GA31553@troutmask.apl.washington.edu |
---|---|
State | New |
Headers | show |
Series | PR fortran/82796 -- common entity in equivalence in pure routine | expand |
Hi Steve, I read the correspondence on clf and your earlier posting here. With those in mind, the patch looks to be OK to commit. Thanks Paul On 2 November 2017 at 01:09, Steve Kargl <sgk@troutmask.apl.washington.edu> wrote: > The attached patch fixes a regression where gfortran was > issuing an error for an entity in a common block within > a module when it appears in equivalence, and the entity > *is not* use associated in a pure subprogram. OK to > commit? > > > 2017-11-01 Steven G. Kargl <kargl@gcc.gnu.org> > > PR fortran/82796 > * resolve.c (resolve_equivalence): An entity in a common block within > a module cannot appear in an equivalence statement if the entity is > with a pure procedure. > > 2017-11-01 Steven G. Kargl <kargl@gcc.gnu.org> > > PR fortran/82796 > * gfortran.dg/equiv_pure.f90: New test. > > -- > Steve
On Thu, Nov 02, 2017 at 11:48:36AM +0000, Paul Richard Thomas wrote: > Hi Steve, > > I read the correspondence on clf and your earlier posting here. With > those in mind, the patch looks to be OK to commit. > > Thanks > Thanks. The c.l.f posting is addressing a different issue. This patch simply fixes a regression that was introduced ages ago. Here, one needs the combination of COMMON, EQUIVALENCE, and a PURE subprogram. From F2003, it comes from C1272. The problem is that gfortran was issuing an error when it should not have. The patch suppresses that error.
Index: gcc/fortran/resolve.c =================================================================== --- gcc/fortran/resolve.c (revision 254241) +++ gcc/fortran/resolve.c (working copy) @@ -15936,9 +15936,22 @@ resolve_equivalence (gfc_equiv *eq) && sym->ns->proc_name->attr.pure && sym->attr.in_common) { - gfc_error ("Common block member %qs at %L cannot be an EQUIVALENCE " - "object in the pure procedure %qs", - sym->name, &e->where, sym->ns->proc_name->name); + /* Need to check for symbols that may have entered the pure + procedure via a USE statement. */ + bool saw_sym = false; + if (sym->ns->use_stmts) + { + gfc_use_rename *r; + for (r = sym->ns->use_stmts->rename; r; r = r->next) + if (strcmp(r->use_name, sym->name) == 0) saw_sym = true; + } + else + saw_sym = true; + + if (saw_sym) + gfc_error ("COMMON block member %qs at %L cannot be an " + "EQUIVALENCE object in the pure procedure %qs", + sym->name, &e->where, sym->ns->proc_name->name); break; } Index: gcc/testsuite/gfortran.dg/equiv_pure.f90 =================================================================== --- gcc/testsuite/gfortran.dg/equiv_pure.f90 (nonexistent) +++ gcc/testsuite/gfortran.dg/equiv_pure.f90 (working copy) @@ -0,0 +1,50 @@ +! { dg-do compile } +module eq + implicit none + integer :: n1, n2 + integer, dimension(2) :: a + equivalence (a(1), n1) + equivalence (a(2), n2) + common /a/ a +end module eq + +module m + use eq + implicit none + type, public :: t + integer :: i + end type t +end module m + +module p + implicit none + contains + pure integer function d(h) + use m + implicit none + integer, intent(in) :: h + d = h + end function +end module p + +module q + implicit none + contains + pure integer function d(h) + use m, only : t + implicit none + integer, intent(in) :: h + d = h + end function +end module q + +module r + implicit none + contains + pure integer function d(h) + use m, only : a ! { dg-error "cannot be an EQUIVALENCE object" } + implicit none + integer, intent(in) :: h + d = h + end function +end module r