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

Segfault with pointer valued functions

may_ka
Beginner
611 Views

Hi there, the code below compiles and runs without error:

Module Mod_Bla
  Implicit none
  Type :: bla
    Real, Allocatable, Private :: aa(:,:)
  contains
    Private
    Generic, Public :: getaa => getaamatrix, getaaelement
    Procedure, Pass :: getaamatrix => fungetaamatrix
    Procedure, Pass :: getaaelement => fungetaaelement
    Procedure, Pass, Public :: set => SubSet
  end type bla
  Interface
    Module Subroutine SubSet(this,RMIn)
      Implicit none
      Class(bla), Intent(InOut), Target :: this
      Real, Intent(In) :: RMIn(:,:)
    End Subroutine
    Module Function FunGetAaMatrix(this)
      Class(bla), Intent(In), Target :: this
      Real, Pointer :: FunGetAAMatrix(:,:)
    end Function
    Module Function FunGetAaElement(this,rowpos,colpos)
      Class(bla), Intent(In), Target :: this
      Integer, Intent(In) :: rowpos, colpos
      Real, Pointer :: FunGetAAElement
    end Function
  End Interface
End Module Mod_Bla
Submodule(Mod_Bla) GetSet
contains
  Module Procedure SubSet
    Implicit none
    Allocate(this%aa,source=RMIn)
  End Procedure
  Module Procedure FunGetAAMatrix
    Implicit none
    FunGetAAMatrix=>this%aa
  End Procedure
  Module Procedure FunGetAAElement
    Implicit none
    FunGetAAElement=>this%aa(rowpos,colpos)
  End Procedure
End Submodule GetSet
Program Test
  use Mod_bla
  Type(bla), Target :: xx
  Class(*), Pointer :: zzz
  Real, Pointer :: y
  Real, Allocatable :: bb(:,:)
  Integer :: i
  Allocate(bb(3,3))
  Do i=1,3
    bb(i,:)=i
  end do
  zzz=>xx
  Select Type(xxx=>zzz)
  Class Is(bla)
    call xxx%set(bb)
    y=>xxx%getaa(2,2)
    !!y=xxx%getaa(2,2)
  End Select
End Program Test

However, if the pointer assigment in the fourth line (counted from the end) is commented and the line below is uncommented, it still compiles without error but yields a segfault at runtime. From my understanding that line could be interpreted as sourced allocation (which is not possible for pointers from my understanding), but the funtion returns a pointer which results in a segfault (this also happens with gfortran). But this is already obvious at compile time. Am I wrong or is this a compiler bug / improper defined in the standard??

Thanks

ifort version 17.1 on linux kernel 4.8.13

0 Kudos
7 Replies
Kevin_D_Intel
Employee
611 Views

Thanks for the post. We'll look into this.

0 Kudos
FortranFan
Honored Contributor II
611 Views

may.ka wrote:

.. it still compiles without error but yields a segfault at runtime. From my understanding that line could be interpreted as sourced allocation (which is not possible for pointers from my understanding), but the funtion returns a pointer which results in a segfault (this also happens with gfortran). But this is already obvious at compile time. Am I wrong or is this a compiler bug / improper defined in the standard??

If you use "=" (assignment) instead of "=>" (association) in the situation where the right-hand side is a function returning a pointer, I don't think the standard requires the compiler to issue a diagnostic and I think most compilers will not catch this.  I think what you are doing is the equivalent of the following and see if you can find a processor that can issue a compile-time diagnostics for it:

program p

   implicit none

   integer, pointer :: x

   x = f()

   stop

contains

   function f() result( p )

      !.. Function result
      integer, pointer :: p

      allocate( p, source=42 )

      return

   end function f

end program p

 

0 Kudos
FortranFan
Honored Contributor II
611 Views

Kevin D (Intel) wrote:

Thanks for the post. We'll look into this.

Kevin,

Keeping Message #3 above in mind (and putting aside any considerations involving "good coding practices" involving pointers), I think the following code is standard-conforming and it executes without any run-time issues when compiled with either Intel Fortran or gfortran:

program p

   implicit none

   integer, pointer :: x

   allocate( x )

   x = f()
   print *, "x = ", x

   stop

contains

   function f() result( p )

      !.. Function result
      integer, pointer :: p

      allocate( p, source=42 )

      return

   end function f

end program p

So it will be quite an advancement for Intel Fortran if some warning diagnostic were to be issued with the code in Message #3.  Note for the code in Message #3, gfortran does warn with a suitable compile-time option:

p.f90:9:0:
    x = f()
 
Warning: 'x' may be used uninitialized in this function [-Wmaybe-uninitialized]

But then Intel Fortran offers little or no warning diagnostics at compile-time generally with uninitialized variables.

0 Kudos
may_ka
Beginner
611 Views

Hi,

if #3 is standard compliant, then this should be as well:

Program Test
  Real, Pointer :: y
  y=5.0
End Program Test

It appears to be a sourced allocation. While it compiles without error, it immediately crashes.

Cheers

0 Kudos
IanH
Honored Contributor II
611 Views

FortranFan's point is that it is not standard compliant.  The code in #5 is just a simplified variant of the original (the commented out variant) "problem".

Reallocation on assignment only applies to allocatables.

Attempting to (value) assign something to a pointer that does not have a defined pointer association status is a programming error.  Whether the thing being assigned comes from a function that happens to have a pointer result is not relevant.

In the general case you cannot rely on a diagnostic from a compiler at compile time for this programming error, because, in the general case, the compiler will not know the pointer association status of a pointer. 

0 Kudos
may_ka
Beginner
611 Views

Ah ................... that clarifies because:

Program Test
  use Mod_bla
  Type(bla), Target :: xx
  Class(*), Pointer :: zzz
  Real, Pointer :: y
  Real, Allocatable :: bb(:,:)
  Integer :: i
  Allocate(bb(3,3))
  Do i=1,3
    bb(i,:)=i
  end do
  zzz=>xx
  Allocate(y)
  Select Type(xxx=>zzz)
  Class Is(bla)
    call xxx%set(bb)
    y=xxx%getaa(2,2)
  End Select
  write(*,*) y
End Program Test

compiles and runs without error. Also changing y from being a pointer to allocatable and deleting allocate(y) runs.

Thanks.

Karl

0 Kudos
Kevin_D_Intel
Employee
611 Views

@FortranFan – I submitted a feature enhancement request for ifort to produce a warning on par w/gfortran as you outlined in post #4. Thank you for suggesting this enhancement.

(Internal tracking id: DPD200417049)

0 Kudos
Reply