Index: flang/lib/Semantics/mod-file.cpp =================================================================== --- flang/lib/Semantics/mod-file.cpp +++ flang/lib/Semantics/mod-file.cpp @@ -911,6 +911,8 @@ Scope *ModFileReader::Read(const SourceName &name, std::optional 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 @@ 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 @@ 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 @@ } } 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; Index: flang/lib/Semantics/resolve-names.cpp =================================================================== --- flang/lib/Semantics/resolve-names.cpp +++ flang/lib/Semantics/resolve-names.cpp @@ -2934,10 +2934,6 @@ 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); } Index: flang/test/Semantics/modfile49.f90 =================================================================== --- /dev/null +++ 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