[flang-commits] [flang] 9f0f54a - [flang] Improve error messages for module self-USE (#122747)
via flang-commits
flang-commits at lists.llvm.org
Tue Jan 14 13:00:07 PST 2025
Author: Peter Klausler
Date: 2025-01-14T13:00:03-08:00
New Revision: 9f0f54a6290ead2e1581d75582759822a19fd885
URL: https://github.com/llvm/llvm-project/commit/9f0f54a6290ead2e1581d75582759822a19fd885
DIFF: https://github.com/llvm/llvm-project/commit/9f0f54a6290ead2e1581d75582759822a19fd885.diff
LOG: [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.
Added:
flang/test/Semantics/self-use.f90
Modified:
flang/include/flang/Semantics/tools.h
flang/lib/Semantics/resolve-names.cpp
flang/lib/Semantics/tools.cpp
Removed:
################################################################################
diff --git a/flang/include/flang/Semantics/tools.h b/flang/include/flang/Semantics/tools.h
index 96d4dbb2acaa11..1abe6cbffcf2eb 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 1b0fb02160123b..f3c2a5bf094d04 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 9091c6b49c20e1..3832876aca7525 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 00000000000000..4bc66a24343c6a
--- /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
+
More information about the flang-commits
mailing list