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

Calling type bound procedures on derived type components trashes data

MDK
Beginner
424 Views
[plain]module data_type

    implicit none
    type :: data_t
        integer :: val = -1
    contains
        procedure :: set
    end type

contains

    subroutine set(this, val)
        implicit none
        class(data_t), intent(out) :: this
        integer, intent(in) :: val
        this%val = val
    end subroutine

end module


module container_type

    use data_type
    
    implicit none
    
    type :: container_t
        type(data_t) :: data1
        type(data_t) :: data2
    contains
        procedure :: set_good 
        procedure :: set_clobber
        procedure :: print => print_container
    end type
        
contains

    subroutine set_clobber(this, val)
        implicit none
        class(container_t), intent(out) :: this
        integer, intent(in) :: val
        call this%data1%set(val)  ! TBP call: bad!
        call this%data2%set(2*val)
    end subroutine    

    subroutine set_good(this, val)
        implicit none
        class(container_t), intent(out) :: this
        integer, intent(in) :: val
        call set(this%data1, val)  ! regular call: ok
        call set(this%data2, 2*val)
    end subroutine    

    subroutine print_container(this)
        implicit none
        class(container_t), intent(in) :: this
        write (*, *) this%data1%val, this%data2%val        
    end subroutine

end module


program ifort_bug

    use container_type
    
    implicit none
    type(container_t) :: x
    
    call x%set_good(-3)
    call x%print()

    call x%set_clobber(10)  ! data2 gets written to data1
    call x%print()
        
    read (*, *)  ! pause        

end program[/plain]


This might be related to a previous bug (<>), but this doesn't involve procedure pointers. This is with 11.1.054, which I just downloaded today.

If you have one derived type that contains derived type components, calling type-bound procedures on the components will clobber the values of other components. In the example above, attempting to set the value of 'data2' using a TBP will change the value of 'data1' instead. The workaround is to use regular calls--'set(data2, val)' instead of 'set(data1, val)'--but this gets increasingly undesirable as you start working with multiple derived types across several modules.
0 Kudos
5 Replies
Steven_L_Intel1
Employee
424 Views
Thanks - we'll look into this.
0 Kudos
Steven_L_Intel1
Employee
424 Views
I believe this is a different problem, the issue ID is DPD200148795. What appears to be happening is that in set_clobber, the compiler is passing set_clobber's THIS as the THIS argument to set rather than the individual data1 and data2 components. Thanks for letting us know of the problem.
0 Kudos
abhimodak
New Contributor I
424 Views
May be this is related to what Steve said but just an FYI:

I find that when stepping through the debugger the values shown for the components are messed up. This is true even when the results are not "messed up". On the other hand, printing the values in the set* subroutines do show them correctly.

Abhi
0 Kudos
Lorri_M_Intel
Employee
424 Views
Quoting - abhimodak
May be this is related to what Steve said but just an FYI:

I find that when stepping through the debugger the values shown for the components are messed up. This is true even when the results are not "messed up". On the other hand, printing the values in the set* subroutines do show them correctly.

Abhi

Dummy arguments that are CLASSes do not display correctly in the debugger. We know (really!) and are working on fixing that.

Sorry for the inconvenience --

- Lorri
0 Kudos
Steven_L_Intel1
Employee
424 Views
The problem reported in this thread (wrong results) is expected to be fixed in Update 5, due late this month (or maybe early Feb.)
0 Kudos
Reply