llvm / llvm/llvm-project

[Flang] Compilation error for polymorphic local variables in PURE procedures

Open
#222,845 1 comment 0 reactions 0 assignees View on GitHub
flang:frontend
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.