| Issue |
208613
|
| Summary |
[flang] ASYNCHRONOUS/VOLATILE acquired by host association in a submodule is not representable in the module file (HostAssocDetails omitted by the writer)
|
| Labels |
flang:semantics
|
| Assignees |
|
| Reporter |
eugeneepshteyn
|
## Summary
F2023 19.5.1.4 p1 lets a submodule give a host-associated variable the ASYNCHRONOUS or VOLATILE attribute locally, and requires a descendant submodule to see host-associated entities with "the same attributes as in the host" — so an attribute acquired in an intermediate submodule must be visible to descendants, including descendants compiled **separately** from the intermediate submodule's module file. flang's module-file writer cannot represent this: `ModFileWriter::PutSymbol` (`flang/lib/Semantics/mod-file.cpp`) has an explicitly empty case for `HostAssocDetails`, so a host-associated symbol that carries a locally-acquired attribute leaves no trace in the `.mod` file of the submodule that acquired it.
This is currently **masked** by #208362: today semantics mishandles `VOLATILE :: n` in a submodule specification part by creating a brand-new implicitly-typed local instead of a `HostAssocDetails` symbol, and the module file faithfully records that bogus new variable (evidence below). Once #208362 is fixed the natural in-memory representation becomes a `HostAssocDetails` symbol with the locally-added attribute — exactly the thing the writer silently drops — so separate compilation of a descendant submodule would then silently lose the attribute while same-file compilation keeps it. Filing this now so the module-file half is tracked alongside the semantics fix.
## Reproducer (separate compilation chain)
`m1.f90`:
```fortran
module m1
integer :: n = 1, k = 2
interface
module subroutine sub()
end subroutine
end interface
end module
```
`submod.f90` — acquires the attributes for the host-associated module variables (F2023 19.5.1.4 p1, 8.5.20 p2, 8.5.4 p4):
```fortran
submodule (m1) submod
volatile :: n
asynchronous :: k
end submodule
```
`subsub.f90` — no attribute statements of its own; per 19.5.1.4 p1 its host is `submod`, so `n`/`k` should arrive VOLATILE/ASYNCHRONOUS here purely by inheritance, and when this file is compiled separately that fact can only come from `m1-submod.mod`:
```fortran
submodule (m1:submod) subsub
contains
module subroutine sub()
implicit none
if (n /= 1) print *, 'Error n=', n
if (k /= 2) print *, 'Error k=', k
end subroutine
end submodule
```
`main.f90`:
```fortran
use m1
call sub
print *, 'pass'
end
```
Commands:
```console
$ flang -c m1.f90
$ flang -c submod.f90
$ flang -c subsub.f90
$ flang main.f90 m1.o submod.o subsub.o && ./a.out
Error n= 0
Error k= 0
pass
```
(The wrong runtime values are #208362 reproduced through separate compilation; they are shown here to document today's baseline.)
## Actual module file today (the mod-file image of #208362)
`m1-submod.mod` currently contains full **entity declarations**, i.e. two new variables belonging to the submodule:
```
!mod$ v1 sum:23029ebc2b91bdbe
submodule(m1) submod
integer(4),volatile::n
integer(4),asynchronous::k
end
```
## Expected module file
The submodule's module file should record that the *host-associated* `n`/`k` acquired the attributes locally — i.e. bare attribute statements, not declarations of new entities:
```
submodule(m1) submod
volatile::n
asynchronous::k
end
```
Re-parsing that (with #208362 fixed) reconstructs exactly the right in-memory state — a `HostAssocDetails` symbol with the locally-added attribute — because module files are ordinary Fortran source processed by the same name resolution.
## What happens if the writer is left unchanged after #208362 is fixed
With semantics fixed, `n`/`k` in the submodule scope become `HostAssocDetails` symbols, `PutSymbol` writes nothing for them, and `m1-submod.mod` degenerates to just `submodule(m1) submod` + `end`. A separately compiled `subsub.f90` then resolves `n` straight through to `m1`'s plain non-volatile `n`: the attribute required by 19.5.1.4 p1 ("same attributes as in the host") is silently lost, and separate compilation diverges from same-file compilation of the identical program. The user-visible consequence is missing volatile/asynchronous semantics in descendant submodules (observable in codegen once the related lowering issue #208588 is also fixed).
## Analysis
- `ModFileWriter::PutSymbol` (`flang/lib/Semantics/mod-file.cpp`) handles symbols with a `common::visitors` chain whose `HostAssocDetails` case is explicitly empty: `[](const HostAssocDetails &) {}`.
- That empty case is *correct* for the other place host-associated names matter in module files — interface bodies — because those are serialized through a separate channel (`SubprogramSymbolCollector::NeedImport` emitting `import::name` lines). But for a submodule scope's `HostAssocDetails` symbols carrying locally-acquired ASYNCHRONOUS/VOLATILE there is no other serialization channel, so the information is simply unrepresentable.
- `ModFileWriter::PrepareRenamings` (same file) already walks through `HostAssocDetails` links when mapping use-associated symbols, so the writer does anticipate meeting such symbols in scopes it serializes.
- Suggested direction: in `PutSymbol` (or where a module/submodule scope's symbols are emitted), emit `volatile::<name>` and/or `asynchronous::<name>` for a `HostAssocDetails` symbol whose own attributes contain those bits, instead of emitting nothing. `Symbol::implicitAttrs()` distinguishes the attributes inherited from the host from ones acquired locally, if only the locally-acquired ones should be re-emitted.
## Environment
```
flang version 23.0.0git (llvm-project commit d776ee4d4cae)
Target: x86_64-unknown-linux-gnu
Build config: +assertions
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs