Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29235 Discussions

Compiler bug? Incorrect error message RE: (de)allocation of local polymorphic variable in element/pure procedure

Izaak_Beekman
New Contributor II
698 Views

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: 

[bash]$ 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) 
----------------------^ [/bash]

However, gfortran makes no such complaints: 

[bash]$ gfortran -fsyntax-only -Wall -pedantic statN.F90 
$ [/bash]


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: 

[fortran]
  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 [/fortran]

Again, I'm quite pressed for time, but will try to come up with a suitable reproducer as soon as I can.

0 Kudos
2 Replies
Izaak_Beekman
New Contributor II
698 Views

After further review, it looks like I am mistaken, and my code is violating the standard. I was refered to F08/0033: PURE polymorphic finalization here: ftp://ftp.nag.co.uk/sc22wg5/N1851-N1900/N1875.txt

It seems that deallocate() statements called with polymorphic arguments are not allowed within pure procedurs because it is not known at compile time whether or not such objects have impure finalization procedures. Additionally, the problem with the sourced allocation is the pointer components of the source, which could dereference to global variables etc.

Sorry for the false alarm.

0 Kudos
Steven_L_Intel1
Employee
698 Views

Thanks for the update.

0 Kudos
Reply