The following simple code compiles ok but generates an unexpected run-time exception:
module m implicit none private type, public :: t end type end module
program p use m, only : t implicit none type(t), allocatable :: foo(:) type(t), allocatable :: bar(:) blk1: block allocate( foo(1) ) end block blk1 blk2: block allocate( bar(1) ) end block blk2 blk3: block print *, "allocated(foo)? = ", allocated(foo) print *, "allocated(bar)? = ", allocated(bar) bar = foo end block blk3 stop end program p
C:\..>ifort /c /standard-semantics /warn:all /stand /traceback m.f90 Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R ) 64, Version 126.96.36.199 Build 20160721 Copyright (C) 1985-2016 Intel Corporation. All rights reserved. C:\..>ifort /c /standard-semantics /warn:all /stand /traceback p.f90 Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R ) 64, Version 188.8.131.52 Build 20160721 Copyright (C) 1985-2016 Intel Corporation. All rights reserved. C:\..>link /out:p.exe /subsystem:console p.obj m.obj Microsoft (R) Incremental Linker Version 12.00.40629.0 Copyright (C) Microsoft Corporation. All rights reserved. C:\..>p.exe allocated(foo)? = T allocated(bar)? = T forrtl: severe (157): Program Exception - access violation Image PC Routine Line Source p.exe 000000013F6F1276 MAIN__ 21 p.f90 p.exe 000000013F73E2DE Unknown Unknown Unknown p.exe 000000013F73E5B4 Unknown Unknown Unknown kernel32.dll 00000000772259CD Unknown Unknown Unknown ntdll.dll 000000007745A2E1 Unknown Unknown Unknown
Looks like the block is handling the allocation(/deallocation) as it does for subroutine call. (edit, though the allocated status reports T, the pointer to the allocation within the array descriptor may have been deallocated)
Does it fail when you change allocatable to pointer? (pointers are not deallocated on subroutine exit)
It's not that simple. The arrays are not being deallocated as the blocks exit. I see the following:
I have escalated this as issue DPD200415609 because I think there is still a bug, it's just masked. That deallocate call doesn't belong, even if it isn't executed.
... does the use of POINTER suffice for a work around?
Note, use of POINTER will require explicit deallocation prior to procedure exit.
Thanks, Steve, for your feedback and the incident submission.
Re: "does the use of POINTER suffice for a work around?", not sure if you were addressing your suggestion to Steve or me. Just fyi, I just happened to stumble on the issue due to improperly constructed BLOCK sections; once the code was structured better, it became a non-issue. Nonetheless it will be most useful if the compiler is fixed per Steve's instructions.
I too prefer compiler fixes. This said, answers like #4 do not provide a work around, and therefor I feel are incomplete. My posts, here and on other forums, generally address both problem and potential work around. While it is good to know that Intel software engineering have a reproducer and are working on a solution, this often leads the OP's being stuck awaiting a solution. Considering the quality of your other posts on the forums, you likely have your own work around, while other readers of this thread may not be as adept.
I didn't suggest a workaround because I couldn't think of one that I thought was a "drop-in replacement". I am generally loathe to recommend replacing allocatables with pointers. I didn't assume that this small program was necessarily representative of the application as a whole.