[J3] surprisingly PURE

Van Snyder van.snyder at jpl.nasa.gov
Mon Apr 20 23:04:28 EDT 2020


On Mon, 2020-04-20 at 21:18 -0400, Vipul Parekh via J3 wrote:

> C1589a A local variable of a pure subprogram, or of a BLOCK construct
> within a pure subprogram, shall not be used in a variable-definition
> context (19.6.7) if the variable is a derived type where the type has
> a default-initialized ultimate component at any level of component
> selection that is a data pointer component and such a data pointer
> component has an initial-data-target that is not a local variable of
> the subprogram. 


I don't think this can catch problems related to polymorphism.

Consider

program P
  real, target :: X = 1.0
  type :: T1
  end type T1
  type, extends(t1) :: T2
    real, pointer :: P => X
  end type T2
  type(t2) :: V
  print *, 'X =', x
  call s ( v )
  print *, 'X =', x
contains
  pure subroutine S ( A )
    class(T1), intent(in) :: A
    class(T1), allocatable :: Y
    allocate ( Y, mold=A )
    select type ( Y )
    type is ( T2 )
      Y%P = 42.0
    end select
  end subroutine S
end program P

Subroutine S doesn't "have" a local variable of type T2, but it
nevertheless assigns a value to X other than by way of its dummy
argument, unless you consider it got access to X by way of its dummy
argument by default initialization during allocation with MOLD=.

More hammering is maybe necessary. Maybe prohibiting an <associate-name>
of such a type to appear in a variable-definition context, if the
<selector> is not a dummy argument or subobject thereof, is enough. But
even that might not cover all the bases. Or maybe we decide it's OK for
S to assign to X by way of Y because Y%P got a pointer to X by way of
default initialization during allocation using the dummy argument as the
mold.

I tried some things, running on Scientific Linux 6.10 (Carbon):

ifort  19.0.4.227 Build 20190416 gets ICE 101003_17. If I comment out S
and the call to it, it doesn't complain,
  but it doesn't do anything interesting.
nagfor 7.0(Yurakucho) Build 7005 says line 6 is invalid
  line 6: X is not permitted in a constant expression
  even with S and the call to it commented out.

Removing the default initialization, adding
  v%p => x
before the first print statement, and changing MOLD= to SOURCE=

nagfor 7.0(Yurakucho) Build 7005 prints
 X =   1.0000000
 X =  42.0000000

using Y=A instead of allocation with SOURCE= works the same way.

Maybe prohibiting a variable-definition context for a local variable or
<selector> of a type with default pointer initialization to a verboten
variable isn't enough.  Unless we thing it's OK that S can change X
other than by way of A if it got a pointer that is associated with X by
way of A, even by way of default initialization during allocation with
SOURCE=. If we think that's OK, then maybe there's no problem related to
polymorphism. Maybe, or maybe not.

gfortran 8.3.0 on Debian 4.19.98-1 apparently didn't like the type
definition:
     real, pointer :: P => X
                           1
Error: Bad target in pointer assignment in PURE procedure at (1)
     real, pointer :: P => X
                           1
Error: Invalid expression in the structure constructor for pointer
component âpâ

It doesn't complain if S is not PURE.

Maybe it saw the type T2 in the select type, and somehow decided it
ought to complain about the definition of T2 (which isn't inside the
PURE procedure), not the use of it at line 18 (which is inside the PURE
procedure).

But there's not a problem with "type is ( T2 )" if the pointer component
of the <associate-name> doesn't appear in a variable-definition context.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.j3-fortran.org/pipermail/j3/attachments/20200420/5625ef63/attachment.htm>


More information about the J3 mailing list