[flang-commits] [flang] 9f33dd7 - [flang] Allow global scope names that clash with intrinsic modules

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Mon May 23 18:21:51 PDT 2022


Author: Peter Klausler
Date: 2022-05-23T18:21:42-07:00
New Revision: 9f33dd733ff507f4ebbf155f8e4c3be52a1e8406

URL: https://github.com/llvm/llvm-project/commit/9f33dd733ff507f4ebbf155f8e4c3be52a1e8406
DIFF: https://github.com/llvm/llvm-project/commit/9f33dd733ff507f4ebbf155f8e4c3be52a1e8406.diff

LOG: [flang] Allow global scope names that clash with intrinsic modules

Intrinsic module names are not in the user's namespace, so they
are free to declare global names that conflict with intrinsic
modules.

Differential Revision: https://reviews.llvm.org/D126140

Added: 
    flang/test/Semantics/modfile49.f90

Modified: 
    flang/lib/Semantics/mod-file.cpp
    flang/lib/Semantics/resolve-names.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp
index d7e6efcb3b398..466a49f9ab4d7 100644
--- a/flang/lib/Semantics/mod-file.cpp
+++ b/flang/lib/Semantics/mod-file.cpp
@@ -911,6 +911,8 @@ static bool VerifyHeader(llvm::ArrayRef<char> content) {
 Scope *ModFileReader::Read(const SourceName &name,
     std::optional<bool> isIntrinsic, Scope *ancestor, bool silent) {
   std::string ancestorName; // empty for module
+  Symbol *notAModule{nullptr};
+  bool fatalError{false};
   if (ancestor) {
     if (auto *scope{ancestor->FindSubmodule(name)}) {
       return scope;
@@ -920,7 +922,14 @@ Scope *ModFileReader::Read(const SourceName &name,
     if (!isIntrinsic.value_or(false)) {
       auto it{context_.globalScope().find(name)};
       if (it != context_.globalScope().end()) {
-        return it->second->scope();
+        Scope *scope{it->second->scope()};
+        if (scope->kind() == Scope::Kind::Module) {
+          return scope;
+        } else {
+          notAModule = scope->symbol();
+          // USE, NON_INTRINSIC global name isn't a module?
+          fatalError = isIntrinsic.has_value();
+        }
       }
     }
     if (isIntrinsic.value_or(true)) {
@@ -935,7 +944,8 @@ Scope *ModFileReader::Read(const SourceName &name,
   options.isModuleFile = true;
   options.features.Enable(common::LanguageFeature::BackslashEscapes);
   options.features.Enable(common::LanguageFeature::OpenMP);
-  if (!isIntrinsic.value_or(false)) {
+  if (!isIntrinsic.value_or(false) && !notAModule) {
+    // Scan non-intrinsic module directories
     options.searchDirectories = context_.searchDirectories();
     // If a directory is in both lists, the intrinsic module directory
     // takes precedence.
@@ -950,14 +960,21 @@ Scope *ModFileReader::Read(const SourceName &name,
     }
   }
   auto path{ModFileName(name, ancestorName, context_.moduleFileSuffix())};
-  const auto *sourceFile{parsing.Prescan(path, options)};
-  if (parsing.messages().AnyFatalError()) {
+  const auto *sourceFile{fatalError ? nullptr : parsing.Prescan(path, options)};
+  if (fatalError || parsing.messages().AnyFatalError()) {
     if (!silent) {
-      for (auto &msg : parsing.messages().messages()) {
-        std::string str{msg.ToString()};
-        Say(name, ancestorName,
-            parser::MessageFixedText{str.c_str(), str.size(), msg.severity()},
-            path);
+      if (notAModule) {
+        // Module is not explicitly INTRINSIC, and there's already a global
+        // symbol of the same name that is not a module.
+        context_.SayWithDecl(
+            *notAModule, name, "'%s' is not a module"_err_en_US, name);
+      } else {
+        for (auto &msg : parsing.messages().messages()) {
+          std::string str{msg.ToString()};
+          Say(name, ancestorName,
+              parser::MessageFixedText{str.c_str(), str.size(), msg.severity()},
+              path);
+        }
       }
     }
     return nullptr;

diff  --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 062c016cc7381..a31831301bd13 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -2934,10 +2934,6 @@ Scope *ModuleVisitor::FindModule(const parser::Name &name,
   if (!scope) {
     return nullptr;
   }
-  if (scope->kind() != Scope::Kind::Module) {
-    Say(name, "'%s' is not a module"_err_en_US);
-    return nullptr;
-  }
   if (DoesScopeContain(scope, currScope())) { // 14.2.2(1)
     Say(name, "Module '%s' cannot USE itself"_err_en_US);
   }

diff  --git a/flang/test/Semantics/modfile49.f90 b/flang/test/Semantics/modfile49.f90
new file mode 100644
index 0000000000000..030258098ff19
--- /dev/null
+++ b/flang/test/Semantics/modfile49.f90
@@ -0,0 +1,19 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+subroutine foo
+end
+subroutine iso_fortran_env
+end
+subroutine bad1
+  !ERROR: 'foo' is not a module
+  use foo
+end
+subroutine ok1
+  use, intrinsic :: iso_fortran_env
+end
+subroutine ok2
+  use iso_fortran_env
+end
+subroutine bad2
+  !ERROR: 'iso_fortran_env' is not a module
+  use, non_intrinsic :: iso_fortran_env
+end


        


More information about the flang-commits mailing list