llvm / llvm/llvm-project

[flang] ASYNCHRONOUS/VOLATILE acquired by host association in a submodule is not representable in the module file (HostAssocDetails omitted by the writer)

Open
#208,613 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

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::` and/or `asynchronous::` 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
```

Contributor guide

Open the contributing guide

Research direction

Start in flang/lib/Semantics/mod-file.cpp at ModFileWriter::PutSymbol and inspect its empty HostAssocDetails case, then compare how PrepareRenamings handles those symbols. Run the m1.f90, submod.f90, and subsub.f90 separate-compilation reproducer. Done means the submodule module file preserves locally acquired VOLATILE and ASYNCHRONOUS attributes as attribute statements, so descendants reconstruct them when compiled separately.

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
Quiet
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.