[Flang] Compilation error for polymorphic local variables in PURE procedures
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
## Summary
According to the Fortran 2023 standard, pure procedures have certain restrictions on polymorphic entities. However, Flang's enforcement of these rules seems overly restrictive.
* 15.7 Pure procedures
> C1594 The function result of a pure function shall not be both polymorphic and allocatable, or have a polymorphic allocatable ultimate component.
> C1597 An INTENT (OUT) dummy argument of a pure procedure shall not be polymorphic or have a polymorphic allocatable ultimate component.
> C1598 A local variable of a pure subprogram, or of a BLOCK construct within a pure subprogram, shall not have the SAVE or VOLATILE attribute.
> C15106 A statement that might result in the deallocation of a polymorphic entity is not permitted in a pure procedure.
The reproducer program below uses MOVE_ALLOC for a polymorphic entity. However, the standard does not state that MOVE_ALLOC causes the deallocation of the FROM argument.
* 16.9.147 MOVE_ALLOC (FROM, TO [, STAT, ERRMSG])
> * On invocation of MOVE_ALLOC, if the allocation status of TO is allocated, it is deallocated.
> * The allocation status of FROM becomes unallocated.
### Reproducer
* test.f90
```fortran
module mod
implicit none
type :: ty
integer::k
end type
contains
pure subroutine sub(arg)
class(ty), allocatable, intent(inout) :: arg(:)
class(ty), allocatable :: local(:)
if (.not.allocated(arg)) then
allocate(local(2),source=[ty(1),ty(2)])
call move_alloc(local,arg)
end if
end subroutine
end module
program main
use mod
class(ty), allocatable :: arg(:)
call sub(arg)
if (arg(1)%k/=1 .or. arg(2)%k/=2) print *,'error',arg(1)%k,arg(2)%k
print *,'pass'
end
```
* commands
```console
$ flang --version
flang version 24.0.0git (https://github.com/llvm/llvm-project.git 012428c5e864d5e976638eb9e19ea207cd2cb829)
Target: aarch64-unknown-linux-gnu
Thread model: posix
InstalledDir: /path/to/llvm/build/bin
Build config: +assertions
$ flang test.f90 && ./a.out
error: Semantic errors in test.f90
test.f90:11:29: error: 'local' may not be a local variable in a pure subprogram
class(ty), allocatable :: local(:)
^^^^^
test.f90:11:29: because: 'local' is a whole polymorphic object in a pure subprogram
class(ty), allocatable :: local(:)
^^^^^
test.f90:11:29: Declaration of 'local'
class(ty), allocatable :: local(:)
^^^^^
```
## Other Compilers
* GFortran
```console
$ gfortran --version
GNU Fortran (GCC) 16.2.0
Copyright (C) 2026 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.
$ gfortran test.f90 && ./a.out
pass
```
* Intel Fortran
```console
$ ifx --version
ifx (IFX) 2026.1.0 20260617
Copyright (C) 1985-2026 Intel Corporation. All rights reserved.
$ ifx -O0 test.f90 && ./a.out
pass
```
Contributor guide
Research direction
Start with the test.f90 reproducer and the Flang diagnostic for the polymorphic local variable declaration. Compare the pure-procedure checks against constraints C1594, C1597, C1598, and C15106 and the MOVE_ALLOC description in 16.9.147. Done means the reproducer compiles and prints “pass”, with a regression test covering the accepted case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- fortran
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100