I'm wondering if I've stumbled upon another compiler bug. I'm using ifort (IFORT) 13.0.2 20130314 on 64 bit Intel Mac OS X Mavericks.
Is this an error with ifort's interpretation of the standard, or with my interpretation? I think that allocation and deallocation of polymorphic local variables should be allowed inside pure and elemental subroutines.
With ifort 13.x when I check my code if it's valid I get the following error:
$ ifort -warn -stand f08 -syntax-only -fpp statN.F90 statN.F90(96): error #7146: This object must not be used as an allocate-object in an allocate-stmt or deallocate-stmt in a PURE procedure or an internal procedure contained in a PURE procedure. [LOCAL_RES] deallocate(local_res) ------------------------^ statN.F90(97): error #7146: This object must not be used as an allocate-object in an allocate-stmt or deallocate-stmt in a PURE procedure or an internal procedure contained in a PURE procedure. [LOCAL_RES] allocate(local_res,source=rhs) ----------------------^
However, gfortran makes no such complaints:
$ gfortran -fsyntax-only -Wall -pedantic statN.F90 $
local_res is a local, allocatable, polymorphic variable. At the end of the function it's allocation is moved to the result variable (which is also allocatable polymorphic but declared as the parent (abstract) type.
The lines of the procedure which cause the problem are listed below:
elemental function Reduce(lhs,rhs) result(res) !Associated covar objects must be reduced by client code !Calculate statistical moments of the union of two sets class(statN_t) ,intent(in) :: lhs class(spocs_t) ,intent(in) :: rhs class(spocs_t) ,allocatable :: res class(statN_t) ,allocatable :: local_res allocate(local_res,source=lhs) !Copy object and components select type(rhs) class is (statN_t) if ((BIGGEST_INT - lhs%n) < rhs%n) then !about to overflow if (rhs%n > lhs%n) then !return whichever set has the most samples deallocate(local_res) !ifort doesn't like these two allocate(local_res,source=rhs) !lines. :-( end if ! Do some error handling. Make an error state variable call move_alloc(from=local_res,to=res) return end if
Again, I'm quite pressed for time, but will try to come up with a suitable reproducer as soon as I can.