Skip to content

[flang] Don't duplicate hermetic module file dependencies #143605

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions flang/lib/Semantics/mod-file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,18 +143,22 @@ void ModFileWriter::Write(const Symbol &symbol) {
std::string path{context_.moduleDirectory() + '/' +
ModFileName(symbol.name(), ancestorName, context_.moduleFileSuffix())};

UnorderedSymbolSet hermeticModules;
hermeticModules.insert(symbol);
std::set<std::string> hermeticModuleNames;
hermeticModuleNames.insert(symbol.name().ToString());
UnorderedSymbolSet additionalModules;
PutSymbols(DEREF(symbol.scope()),
hermeticModuleFileOutput_ ? &additionalModules : nullptr);
auto asStr{GetAsString(symbol)};
while (!additionalModules.empty()) {
for (auto ref : UnorderedSymbolSet{std::move(additionalModules)}) {
if (hermeticModules.insert(*ref).second &&
!ref->owner().IsIntrinsicModules()) {
PutSymbols(DEREF(ref->scope()), &additionalModules);
asStr += GetAsString(*ref);
UnorderedSymbolSet nextPass{std::move(additionalModules)};
additionalModules.clear();
for (const Symbol &modSym : nextPass) {
if (!modSym.owner().IsIntrinsicModules() &&
hermeticModuleNames.find(modSym.name().ToString()) ==
hermeticModuleNames.end()) {
hermeticModuleNames.insert(modSym.name().ToString());
PutSymbols(DEREF(modSym.scope()), &additionalModules);
asStr += GetAsString(modSym);
}
}
}
Expand Down
37 changes: 37 additions & 0 deletions flang/test/Semantics/modfile77.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
!RUN: %flang -c -fhermetic-module-files -DWHICH=1 %s && %flang -c -fhermetic-module-files -DWHICH=2 %s && %flang -c -fhermetic-module-files %s && cat modfile77c.mod | FileCheck %s

#if WHICH == 1
module modfile77a
interface gen
procedure proc
end interface
contains
subroutine proc
print *, 'ok'
end
end
#elif WHICH == 2
module modfile77b
use modfile77a
end
#else
module modfile77c
use modfile77a
use modfile77b
end
#endif

!CHECK: module modfile77c
!CHECK: use modfile77a,only:proc
!CHECK: use modfile77a,only:gen
!CHECK: interface gen
!CHECK: end interface
!CHECK: end
!CHECK: module modfile77a
!CHECK: interface gen
!CHECK: procedure::proc
!CHECK: end interface
!CHECK: contains
!CHECK: subroutine proc()
!CHECK: end
!CHECK: end
33 changes: 33 additions & 0 deletions flang/test/Semantics/modfile78.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
!RUN: %flang -c -fhermetic-module-files -DWHICH=1 %s && %flang -c -fhermetic-module-files -DWHICH=2 %s && %flang -c -fhermetic-module-files %s && cat modfile78c.mod | FileCheck %s

#if WHICH == 1
module modfile78a
integer :: global_variable = 0
end
#elif WHICH == 2
module modfile78b
use modfile78a
contains
subroutine test
end
end
#else
module modfile78c
use modfile78a
use modfile78b
end
#endif

!CHECK: module modfile78c
!CHECK: use modfile78a,only:global_variable
!CHECK: use modfile78b,only:test
!CHECK: end
!CHECK: module modfile78a
!CHECK: integer(4)::global_variable
!CHECK: end
!CHECK: module modfile78b
!CHECK: use modfile78a,only:global_variable
!CHECK: contains
!CHECK: subroutine test()
!CHECK: end
!CHECK: end