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

Possible bug in ifort: using polymorphic types

Luckner__Paul
Novice
444 Views

I get different results depending if I comment specific lines out or not (even as those are not accessed at runtime). The bug does not appear using gfortran.

program main

  implicit none

  type :: parent
    integer              :: i1
    integer, allocatable :: i2
  end type

  type, extends(parent) :: child
    integer              :: i3
    integer, allocatable :: i4
  end type

  type :: parent_alc
    class(parent), allocatable :: p
  end type

  type(parent_alc) :: p_alc

  if (.false.) then
    block
      ! type(child) :: e            ! comment this line in/out for different results
    end block
  else
    block
      type(child)      :: c

      c%i1 = 1
      c%i2 = 1
      c%i3 = 1
      c%i4 = 1

      ! ====================
      ! method 1: broken in ifort
      ! p_alc%p = c         
      ! ====================

      ! ==================== 
      ! method 2: broken in ifort 
      ! allocate (p_alc%p, source=c)
      ! ====================

      ! ====================
      ! workaround
      allocate (child :: p_alc%p)
      select type (x => p_alc%p)
        type is (child)
          x%i1 = c%i1
          x%i2 = c%i2
          x%i3 = c%i3
          x%i4 = c%i4
      end select
      ! =====================

      c%i1 = 0
      c%i2 = 0
      c%i3 = 0
      c%i4 = 0
    end block
  end if

  select type (x => p_alc%p)
    type is (child)
      print *, 'p_alc%p%i1..4', x%i1, x%i2, x%i3, x%i4
  end select
end program

Running the program using method 1,2 and commenting in/out the highlighted line 23 yields different results with ifort and the same in gfortran.

Line commented out

$ ifort main.f90 && ./a.out
p_alc%p%i1..4           1           1           1           1

$ gfortran main.f90 && ./a.out
p_alc%p%i1..4           1           1           1           1

Line not commented out

$ ifort main.f90 && ./a.out
p_alc%p%i1..4           1           0           1           0

$ gfortran main.f90 && ./a.out
p_alc%p%i1..4           1           1           1           1

Program versions

$ ifort --version
ifort (IFORT) 19.0.1.144 20181018
Copyright (C) 1985-2018 Intel Corporation.  All rights reserved.

$ gfortran --version
GNU Fortran (Arch Linux 9.3.0-1) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

The "workaround" code actually works under ifort/gfortran with and without line 23.

0 Kudos
4 Replies
FortranFan
Honored Contributor II
444 Views

An option you may want to consider if possible is to update your compiler version.  Version 19.1 appears not to face the issue:

C:\Temp>type p.f90
program main

   implicit none

   type :: parent
      integer              :: i1
      integer, allocatable :: i2
   end type

   type, extends(parent) :: child
      integer              :: i3
      integer, allocatable :: i4
   end type

   type :: parent_alc
      class(parent), allocatable :: p
   end type

   type(parent_alc) :: p_alc

   if (.false.) then
      block
         type(child) :: e            ! comment this line in/out for different results
      end block
   else
      block
         type(child)      :: c

         c%i1 = 1
         c%i2 = 1
         c%i3 = 1
         c%i4 = 1

         ! ====================
         ! method 1: broken in ifort
         p_alc%p = c

      end block
   end if

   select type (x => p_alc%p)
      type is (child)
         print *, 'p_alc%p%i1..4', x%i1, x%i2, x%i3, x%i4
   end select
end program

C:\Temp>ifort /standard-semantics /warn:all /stand:f18 p.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.1.0.166 Build 20191121
Copyright (C) 1985-2019 Intel Corporation.  All rights reserved.

p.f90(23): remark #7712: This variable has not been used.   
         type(child) :: e            ! comment this line in/out for different results
------------------------^
Microsoft (R) Incremental Linker Version 14.24.28316.0
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:p.exe
-subsystem:console
p.obj

C:\Temp>p.exe
 p_alc%p%i1..4 1 1 1 1

C:\Temp>
C:\Temp>type p.f90
program main

   implicit none

   type :: parent
      integer              :: i1
      integer, allocatable :: i2
   end type

   type, extends(parent) :: child
      integer              :: i3
      integer, allocatable :: i4
   end type

   type :: parent_alc
      class(parent), allocatable :: p
   end type

   type(parent_alc) :: p_alc

   if (.false.) then
      block
         type(child) :: e            ! comment this line in/out for different results
      end block
   else
      block
         type(child)      :: c

         c%i1 = 1
         c%i2 = 1
         c%i3 = 1
         c%i4 = 1

         ! ====================
         ! method 2: broken in ifort
         allocate (p_alc%p, source=c)

      end block
   end if

   select type (x => p_alc%p)
      type is (child)
         print *, 'p_alc%p%i1..4', x%i1, x%i2, x%i3, x%i4
   end select
end program

C:\Temp>ifort /standard-semantics /warn:all /stand:f18 p.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.1.0.166 Build 20191121
Copyright (C) 1985-2019 Intel Corporation.  All rights reserved.

p.f90(23): remark #7712: This variable has not been used.   
         type(child) :: e            ! comment this line in/out for different results
------------------------^
Microsoft (R) Incremental Linker Version 14.24.28316.0
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:p.exe
-subsystem:console
p.obj

C:\Temp>p.exe
 p_alc%p%i1..4 1 1 1 1

C:\Temp>

 

0 Kudos
Luckner__Paul
Novice
444 Views

Thanks for the fast reply!

I will try it out with the newer version. Hope it works and not some internal thing caused by the underlying OS (linux/windows).

0 Kudos
IanH
Honored Contributor II
444 Views

The code in #2 is missing the trailing assignment statements necessary to see the bug - 19.1 is still problematic.

I have encountered issues previously with over-enthusiastic deallocation of block local variables (or components of block local variables) with the current compiler.  I suspect that is going on here - move the block local variables up to the enclosing scope and the symptoms disappear.

0 Kudos
FortranFan
Honored Contributor II
444 Views

IanH (Blackbelt) wrote:

The code in #2 is missing the trailing assignment statements necessary to see the bug - 19.1 is still problematic.

I have encountered issues previously with over-enthusiastic deallocation of block local variables (or components of block local variables) with the current compiler.  I suspect that is going on here - move the block local variables up to the enclosing scope and the symptoms disappear.

Bummer!  Support request at Intel OSC appears to be in order: https://supporttickets.intel.com/servicecenter?lang=en-US ;

0 Kudos
Reply