[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