diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp index cee267a894ffd..8684eb1fbd332 100644 --- a/flang/lib/Semantics/mod-file.cpp +++ b/flang/lib/Semantics/mod-file.cpp @@ -1183,30 +1183,49 @@ Scope *ModFileReader::Read(const SourceName &name, } Scope &topScope{isIntrinsic.value_or(false) ? context_.intrinsicModulesScope() : context_.globalScope()}; - if (!ancestor) { + Symbol *moduleSymbol{nullptr}; + if (!ancestor) { // module, not submodule parentScope = &topScope; + auto pair{parentScope->try_emplace(name, UnknownDetails{})}; + if (!pair.second) { + return nullptr; + } + moduleSymbol = &*pair.first->second; + moduleSymbol->set(Symbol::Flag::ModFile); } else if (std::optional parent{GetSubmoduleParent(parseTree)}) { + // submodule with submodule parent parentScope = Read(*parent, false /*not intrinsic*/, ancestor, silent); } else { + // submodule with module parent parentScope = ancestor; } - auto pair{parentScope->try_emplace(name, UnknownDetails{})}; - if (!pair.second) { - return nullptr; - } // Process declarations from the module file - Symbol &modSymbol{*pair.first->second}; - modSymbol.set(Symbol::Flag::ModFile); bool wasInModuleFile{context_.foldingContext().inModuleFile()}; context_.foldingContext().set_inModuleFile(true); ResolveNames(context_, parseTree, topScope); context_.foldingContext().set_inModuleFile(wasInModuleFile); - CHECK(modSymbol.has()); - CHECK(modSymbol.test(Symbol::Flag::ModFile)); - if (isIntrinsic.value_or(false)) { - modSymbol.attrs().set(Attr::INTRINSIC); + if (!moduleSymbol) { + // Submodule symbols' storage are owned by their parents' scopes, + // but their names are not in their parents' dictionaries -- we + // don't want to report bogus errors about clashes between submodule + // names and other objects in the parent scopes. + if (Scope * submoduleScope{ancestor->FindSubmodule(name)}) { + moduleSymbol = submoduleScope->symbol(); + if (moduleSymbol) { + moduleSymbol->set(Symbol::Flag::ModFile); + } + } + } + if (moduleSymbol) { + CHECK(moduleSymbol->has()); + CHECK(moduleSymbol->test(Symbol::Flag::ModFile)); + if (isIntrinsic.value_or(false)) { + moduleSymbol->attrs().set(Attr::INTRINSIC); + } + return moduleSymbol->scope(); + } else { + return nullptr; } - return modSymbol.scope(); } parser::Message &ModFileReader::Say(const SourceName &name, diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index 40f5ab9eb6e27..b4deac9cf5ccd 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -3230,7 +3230,11 @@ bool ModuleVisitor::BeginSubmodule( } void ModuleVisitor::BeginModule(const parser::Name &name, bool isSubmodule) { - auto &symbol{MakeSymbol(name, ModuleDetails{isSubmodule})}; + // Submodule symbols are not visible in their parents' scopes. + Symbol &symbol{isSubmodule ? Resolve(name, + currScope().MakeSymbol(name.source, Attrs{}, + ModuleDetails{true})) + : MakeSymbol(name, ModuleDetails{false})}; auto &details{symbol.get()}; PushScope(Scope::Kind::Module, &symbol); details.set_scope(&currScope()); diff --git a/flang/test/Semantics/modproc01.f90 b/flang/test/Semantics/modproc01.f90 index c7d05783335e6..5652e15750c7e 100644 --- a/flang/test/Semantics/modproc01.f90 +++ b/flang/test/Semantics/modproc01.f90 @@ -22,11 +22,12 @@ module subroutine ms(f) procedure(mf) :: f end subroutine end interface + integer sm end module !CHECK: mf, MODULE, PUBLIC (Function): Subprogram isInterface result:TYPE(pdt2(k2=2_4,l2=n)) res (INTEGER(4) n,CHARACTER(n,1) str,TYPE(pdt1(k1=1_4,l1=n)) x1) !CHECK: pdt1, PUBLIC: DerivedType components: a1 !CHECK: pdt2, PUBLIC: DerivedType components: j2,a2 -!CHECK: sm: Module (m) +!CHECK: sm, PUBLIC size=4 offset=0: ObjectEntity type: INTEGER(4) !CHECK: DerivedType scope: pdt1 !CHECK: a1, ALLOCATABLE: ObjectEntity type: TYPE(pdt2(int(k1,kind=4),int(l1,kind=4))) !CHECK: k1: TypeParam type:INTEGER(4) Kind @@ -128,6 +129,7 @@ program test !CHECK: mf, MODULE (Function): Use from mf in m !CHECK: pdt1: Use from pdt1 in m !CHECK: pdt2: Use from pdt2 in m +!CHECK: sm: Use from sm in m !CHECK: x size=88 offset=0: ObjectEntity type: TYPE(pdt2(k2=2_4,l2=3_4)) !CHECK: DerivedType scope: size=88 alignment=8 instantiation of pdt2(k2=2_4,l2=3_4) !CHECK: a2 size=80 offset=8: ObjectEntity type: TYPE(pdt1(k1=2_4,l1=3_4)) shape: 1_8:2_8 diff --git a/flang/test/Semantics/modproc02.f90 b/flang/test/Semantics/modproc02.f90 index 229ef72e6bcf0..f47f473f081d2 100644 --- a/flang/test/Semantics/modproc02.f90 +++ b/flang/test/Semantics/modproc02.f90 @@ -16,7 +16,6 @@ module subroutine s(x) ! implicitly typed !CHECK: Module scope: m size=0 alignment=1 sourceRange=63 bytes !CHECK: s, MODULE, PUBLIC (Subroutine): Subprogram isInterface (REAL(4) x) -!CHECK: sm: Module (m) !CHECK: Subprogram scope: s size=4 alignment=4 sourceRange=26 bytes !CHECK: s (Subroutine): HostAssoc !CHECK: x (Implicit) size=4 offset=0: ObjectEntity dummy type: REAL(4)