aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Semantics/mod-file.cpp
diff options
context:
space:
mode:
authorPeter Klausler <pklausler@nvidia.com>2025-01-27 08:43:41 -0800
committerGitHub <noreply@github.com>2025-01-27 08:43:41 -0800
commit038b42ba5b47b1aa2d47ef5706a713f6bfbbc37c (patch)
treedcbbca1b697594bccd1b0223e00f0705a5306174 /flang/lib/Semantics/mod-file.cpp
parentc3a0fcc982061f9a69cfc1199dc91bd1fc3158c0 (diff)
downloadllvm-038b42ba5b47b1aa2d47ef5706a713f6bfbbc37c.zip
llvm-038b42ba5b47b1aa2d47ef5706a713f6bfbbc37c.tar.gz
llvm-038b42ba5b47b1aa2d47ef5706a713f6bfbbc37c.tar.bz2
[flang] Safer hermetic module file reading (#121002)
When a hermetic module file is read, use a new scope to hold its dependent modules so that they don't conflict with any modules in the global scope.
Diffstat (limited to 'flang/lib/Semantics/mod-file.cpp')
-rw-r--r--flang/lib/Semantics/mod-file.cpp19
1 files changed, 19 insertions, 0 deletions
diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp
index 51ff70c..4367dd1 100644
--- a/flang/lib/Semantics/mod-file.cpp
+++ b/flang/lib/Semantics/mod-file.cpp
@@ -1366,6 +1366,12 @@ Scope *ModFileReader::Read(SourceName name, std::optional<bool> isIntrinsic,
name.ToString(), isIntrinsic.value_or(false))};
if (!isIntrinsic.value_or(false) && !ancestor) {
// Already present in the symbol table as a usable non-intrinsic module?
+ if (Scope * hermeticScope{context_.currentHermeticModuleFileScope()}) {
+ auto it{hermeticScope->find(name)};
+ if (it != hermeticScope->end()) {
+ return it->second->scope();
+ }
+ }
auto it{context_.globalScope().find(name)};
if (it != context_.globalScope().end()) {
Scope *scope{it->second->scope()};
@@ -1544,9 +1550,22 @@ Scope *ModFileReader::Read(SourceName name, std::optional<bool> isIntrinsic,
// Process declarations from the module file
auto wasModuleFileName{context_.foldingContext().moduleFileName()};
context_.foldingContext().set_moduleFileName(name);
+ // Are there multiple modules in the module file due to it having been
+ // created under -fhermetic-module-files? If so, process them first in
+ // their own nested scope that will be visible only to USE statements
+ // within the module file.
+ if (parseTree.v.size() > 1) {
+ parser::Program hermeticModules{std::move(parseTree.v)};
+ parseTree.v.emplace_back(std::move(hermeticModules.v.front()));
+ hermeticModules.v.pop_front();
+ Scope &hermeticScope{topScope.MakeScope(Scope::Kind::Global)};
+ context_.set_currentHermeticModuleFileScope(&hermeticScope);
+ ResolveNames(context_, hermeticModules, hermeticScope);
+ }
GetModuleDependences(context_.moduleDependences(), sourceFile->content());
ResolveNames(context_, parseTree, topScope);
context_.foldingContext().set_moduleFileName(wasModuleFileName);
+ context_.set_currentHermeticModuleFileScope(nullptr);
if (!moduleSymbol) {
// Submodule symbols' storage are owned by their parents' scopes,
// but their names are not in their parents' dictionaries -- we