Skip to content

Commit 9c25ca7

Browse files
authored
[flang] Don't generate module file for hermetic USE'd dependency (#144143)
It's possible for the module file generation code to think that it needs to (re)generate a module file for a dependent module read from a hermetic module file, if it defines contains a procedure imported via renaming due to a name clash. Adjust the logic that determines whether a module file should be written to include a check for having originated in a module file.
1 parent 95418bc commit 9c25ca7

File tree

2 files changed

+56
-21
lines changed

2 files changed

+56
-21
lines changed

flang/lib/Semantics/mod-file.cpp

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,14 @@ bool ModFileWriter::WriteAll() {
109109
}
110110

111111
void ModFileWriter::WriteAll(const Scope &scope) {
112-
for (const auto &child : scope.children()) {
112+
for (const Scope &child : scope.children()) {
113113
WriteOne(child);
114114
}
115115
}
116116

117117
void ModFileWriter::WriteOne(const Scope &scope) {
118118
if (scope.kind() == Scope::Kind::Module) {
119-
auto *symbol{scope.symbol()};
120-
if (!symbol->test(Symbol::Flag::ModFile)) {
119+
if (const auto *symbol{scope.symbol()}) {
121120
Write(*symbol);
122121
}
123122
WriteAll(scope); // write out submodules
@@ -134,7 +133,7 @@ static std::string ModFileName(const SourceName &name,
134133
// Write the module file for symbol, which must be a module or submodule.
135134
void ModFileWriter::Write(const Symbol &symbol) {
136135
const auto &module{symbol.get<ModuleDetails>()};
137-
if (module.moduleFileHash()) {
136+
if (symbol.test(Symbol::Flag::ModFile) || module.moduleFileHash()) {
138137
return; // already written
139138
}
140139
const auto *ancestor{module.ancestor()};
@@ -372,16 +371,19 @@ void ModFileWriter::PutSymbols(
372371
CollectSymbols(scope, sorted, uses, modules);
373372
// Write module files for dependencies first so that their
374373
// hashes are known.
375-
for (auto ref : modules) {
374+
for (const Symbol &mod : modules) {
376375
if (hermeticModules) {
377-
hermeticModules->insert(*ref);
376+
hermeticModules->insert(mod);
378377
} else {
379-
Write(*ref);
380-
needs_ << ModHeader::need
381-
<< CheckSumString(
382-
ref->get<ModuleDetails>().moduleFileHash().value())
383-
<< (ref->owner().IsIntrinsicModules() ? " i " : " n ")
384-
<< ref->name().ToString() << '\n';
378+
Write(mod);
379+
// It's possible that the module's file already existed and
380+
// without its own hash due to being embedded in a hermetic
381+
// module file.
382+
if (auto hash{mod.get<ModuleDetails>().moduleFileHash()}) {
383+
needs_ << ModHeader::need << CheckSumString(*hash)
384+
<< (mod.owner().IsIntrinsicModules() ? " i " : " n ")
385+
<< mod.name().ToString() << '\n';
386+
}
385387
}
386388
}
387389
std::string buf; // stuff after CONTAINS in derived type
@@ -855,25 +857,25 @@ void CollectSymbols(const Scope &scope, SymbolVector &sorted,
855857
auto symbols{scope.GetSymbols()};
856858
std::size_t commonSize{scope.commonBlocks().size()};
857859
sorted.reserve(symbols.size() + commonSize);
858-
for (SymbolRef symbol : symbols) {
859-
const auto *generic{symbol->detailsIf<GenericDetails>()};
860+
for (const Symbol &symbol : symbols) {
861+
const auto *generic{symbol.detailsIf<GenericDetails>()};
860862
if (generic) {
861863
uses.insert(uses.end(), generic->uses().begin(), generic->uses().end());
862-
for (auto ref : generic->uses()) {
863-
modules.insert(GetUsedModule(ref->get<UseDetails>()));
864+
for (const Symbol &used : generic->uses()) {
865+
modules.insert(GetUsedModule(used.get<UseDetails>()));
864866
}
865-
} else if (const auto *use{symbol->detailsIf<UseDetails>()}) {
867+
} else if (const auto *use{symbol.detailsIf<UseDetails>()}) {
866868
modules.insert(GetUsedModule(*use));
867869
}
868-
if (symbol->test(Symbol::Flag::ParentComp)) {
869-
} else if (symbol->has<NamelistDetails>()) {
870+
if (symbol.test(Symbol::Flag::ParentComp)) {
871+
} else if (symbol.has<NamelistDetails>()) {
870872
namelist.push_back(symbol);
871873
} else if (generic) {
872874
if (generic->specific() &&
873-
&generic->specific()->owner() == &symbol->owner()) {
875+
&generic->specific()->owner() == &symbol.owner()) {
874876
sorted.push_back(*generic->specific());
875877
} else if (generic->derivedType() &&
876-
&generic->derivedType()->owner() == &symbol->owner()) {
878+
&generic->derivedType()->owner() == &symbol.owner()) {
877879
sorted.push_back(*generic->derivedType());
878880
}
879881
generics.push_back(symbol);

flang/test/Semantics/modfile79.F90

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
!RUN: %flang -c -DWHICH=1 %s && FileCheck %s <modfile79a.mod && %flang -c -fhermetic-module-files -DWHICH=2 %s && %flang -c %s && FileCheck %s <modfile79a.mod
2+
3+
!Ensure that writing modfile79c.mod doesn't cause a spurious
4+
!regeneration of modfile79a.mod from its copy in the hermetic
5+
!module file modfile79b.mod.
6+
!CHECK: !mod$ v1 sum:93ec75fe672c5b6c
7+
!CHECK-NEXT: module modfile79a
8+
9+
#if WHICH == 1
10+
module modfile79a
11+
interface foo
12+
module procedure foo
13+
end interface
14+
contains
15+
subroutine foo
16+
end
17+
end
18+
#elif WHICH == 2
19+
module modfile79b
20+
use modfile79a
21+
interface bar
22+
procedure foo
23+
end interface
24+
end
25+
#else
26+
module modfile79c
27+
use modfile79b
28+
contains
29+
subroutine test
30+
call bar
31+
end
32+
end
33+
#endif

0 commit comments

Comments
 (0)