aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Klausler <pklausler@nvidia.com>2025-01-14 13:00:03 -0800
committerGitHub <noreply@github.com>2025-01-14 13:00:03 -0800
commit9f0f54a6290ead2e1581d75582759822a19fd885 (patch)
treef5bb632e462b91cc6278dc3772c8101c08535b96
parent874a3ba868e3738d6ee21bfe032c89c6c8be3969 (diff)
downloadllvm-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.h1
-rw-r--r--flang/lib/Semantics/resolve-names.cpp22
-rw-r--r--flang/lib/Semantics/tools.cpp6
-rw-r--r--flang/test/Semantics/self-use.f9027
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
+