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

Access violation with pointers, derived types and inlining

bdforbes
Beginner
862 Views
I'm getting an access violation in some linked-list code when using a combination of pointers, derived types and inlining. I believe it is a compiler bug. Here is the code:
[fortran]module foo_module
    
    type list
        type(list),pointer::next=>null()
    end type list
    
    type(list),target::foo_list
    
    contains
        
    !___________________________________
    subroutine add()
        type(list),pointer::l
        
        write(*,*) 'Entering add()'
        
        call get_foo_list(l)
        
        if (associated(l)) call list_add(l%next)
        
    end subroutine add
    
    !DEC$ ATTRIBUTES NOINLINE :: get_foo_list
    subroutine get_foo_list(l)
        type(list),intent(out),pointer::l
        l=>foo_list
    end subroutine
     
    !DEC$ ATTRIBUTES FORCEINLINE :: list_add
    subroutine list_add(l)
        implicit none
        type(list),intent(inout),pointer::l        
        
        type(list),pointer::curr,curr2,next
        
        if (.not.associated(l)) then
            allocate(l)     
        else            
            curr=>l
            
            do while (associated(curr%next))
                curr=>curr%next
            enddo
            
            allocate(curr%next)
        
        endif
    end subroutine list_add
     
end module[/fortran]
[fortran]program foo
    use foo_module
        call add()
        call add()
        call add()
        call add()
        call add()
        call add()
        
        read(*,*)
        
end program foo[/fortran]
The string'Entering add()' is outputted 2 times before the following exception occurs:
Unhandled exception at 0x00000001400010b1 in foo.exe: 0xC0000005: Access violation writing location 0x0000000000000000.
The exception can be avoided by making a SINGLE tweak from the following list:
  • The subroutine list_add() can be changed to NOINLINE.
  • The subroutine get_foo_list() can be changed FORCEINLINE.
  • The statement "allocate(l)" can be inserted before the call to get_foo_list().
  • Instead of "allocate(l)" in list_add(), "allocate(curr);l=>curr" will fix the problem.
  • Instead of "allocate(curr%next)" in list_add(), "allocate(curr2);curr%next=>curr2" will fix the problem (where curr2 is another list pointer).
  • And some other tweaks here and there.
I can't see any obvious problems with my code, and the fact that inlining makes a difference strongly suggests to me a compiler bug.
I'm usingIntel Visual Fortran Compiler XE 12.0.1.127 [Intel 64].
0 Kudos
5 Replies
Steven_L_Intel1
Employee
862 Views
I can't reproduce this yet. Please show me the command line you are using to compile.
0 Kudos
bdforbes
Beginner
862 Views
[bash]/nologo /debug:full /Ob1 /heap-arrays0 /Qopenmp /warn:declarations /warn:interfaces /module:"x64Debug\" /object:"x64Debug\" /Fd"x64Debugvc90.pdb" /traceback /libs:static /threads /dbglibs /c

[/bash]
Disabling /Qopenmp also fixes the problem.
0 Kudos
Steven_L_Intel1
Employee
862 Views
Ok, I can now reproduce the problem. I'll look into this - thanks.
0 Kudos
Steven_L_Intel1
Employee
862 Views
/Qauto is sufficient to trigger the error - this is implied by /Qopenmp. Escalated to development as DPD200173191.
0 Kudos
Steven_L_Intel1
Employee
862 Views

This problem seems to have been fixed several releases ago.

0 Kudos
Reply