diff options
author | Peter Klausler <pklausler@nvidia.com> | 2025-01-14 13:00:03 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-14 13:00:03 -0800 |
commit | 9f0f54a6290ead2e1581d75582759822a19fd885 (patch) | |
tree | f5bb632e462b91cc6278dc3772c8101c08535b96 | |
parent | 874a3ba868e3738d6ee21bfe032c89c6c8be3969 (diff) | |
download | llvm-9f0f54a6290ead2e1581d75582759822a19fd885.zip llvm-9f0f54a6290ead2e1581d75582759822a19fd885.tar.gz llvm-9f0f54a6290ead2e1581d75582759822a19fd885.tar.bz2 |
[flang] Improve error messages for module self-USE (#122747)
A module can't USE itself, either directly within the top-level module
or from one of its submodules. Add a test for this case (which we
already caught), and improve the diagnostic for the more confusing case
involving a submodule.
-rw-r--r-- | flang/include/flang/Semantics/tools.h | 1 | ||||
-rw-r--r-- | flang/lib/Semantics/resolve-names.cpp | 22 | ||||
-rw-r--r-- | flang/lib/Semantics/tools.cpp | 6 | ||||
-rw-r--r-- | flang/test/Semantics/self-use.f90 | 27 |
4 files changed, 50 insertions, 6 deletions
diff --git a/flang/include/flang/Semantics/tools.h b/flang/include/flang/Semantics/tools.h index 96d4dbb..1abe6cb 100644 --- a/flang/include/flang/Semantics/tools.h +++ b/flang/include/flang/Semantics/tools.h @@ -42,6 +42,7 @@ const Scope &GetProgramUnitOrBlockConstructContaining(const Scope &); const Scope &GetProgramUnitOrBlockConstructContaining(const Symbol &); const Scope *FindModuleContaining(const Scope &); +const Scope *FindModuleOrSubmoduleContaining(const Scope &); const Scope *FindModuleFileContaining(const Scope &); const Scope *FindPureProcedureContaining(const Scope &); const Scope *FindOpenACCConstructContaining(const Scope *); diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index 1b0fb02..f3c2a5b 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -3607,13 +3607,23 @@ Scope *ModuleVisitor::FindModule(const parser::Name &name, ModFileReader reader{context()}; Scope *scope{ reader.Read(name.source, isIntrinsic, ancestor, /*silent=*/false)}; - if (!scope) { - return nullptr; - } - if (DoesScopeContain(scope, currScope())) { // 14.2.2(1) - Say(name, "Module '%s' cannot USE itself"_err_en_US); + if (scope) { + if (DoesScopeContain(scope, currScope())) { // 14.2.2(1) + std::optional<SourceName> submoduleName; + if (const Scope * container{FindModuleOrSubmoduleContaining(currScope())}; + container && container->IsSubmodule()) { + submoduleName = container->GetName(); + } + if (submoduleName) { + Say(name.source, + "Module '%s' cannot USE itself from its own submodule '%s'"_err_en_US, + name.source, *submoduleName); + } else { + Say(name, "Module '%s' cannot USE itself"_err_en_US); + } + } + Resolve(name, scope->symbol()); } - Resolve(name, scope->symbol()); return scope; } diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp index 9091c6b..3832876 100644 --- a/flang/lib/Semantics/tools.cpp +++ b/flang/lib/Semantics/tools.cpp @@ -52,6 +52,12 @@ const Scope *FindModuleContaining(const Scope &start) { start, [](const Scope &scope) { return scope.IsModule(); }); } +const Scope *FindModuleOrSubmoduleContaining(const Scope &start) { + return FindScopeContaining(start, [](const Scope &scope) { + return scope.IsModule() || scope.IsSubmodule(); + }); +} + const Scope *FindModuleFileContaining(const Scope &start) { return FindScopeContaining( start, [](const Scope &scope) { return scope.IsModuleFile(); }); diff --git a/flang/test/Semantics/self-use.f90 b/flang/test/Semantics/self-use.f90 new file mode 100644 index 0000000..4bc66a2 --- /dev/null +++ b/flang/test/Semantics/self-use.f90 @@ -0,0 +1,27 @@ +! RUN: %python %S/test_errors.py %s %flang_fc1 +module m + interface + module subroutine separate + end + end interface + contains + subroutine modsub + !ERROR: Module 'm' cannot USE itself + use m + end +end + +submodule(m) submod1 + contains + module subroutine separate + !ERROR: Module 'm' cannot USE itself from its own submodule 'submod1' + !ERROR: Cannot use-associate 'separate'; it is already declared in this scope + use m + end +end + +submodule(m) submod2 + !ERROR: Module 'm' cannot USE itself from its own submodule 'submod2' + use m +end + |