Skip to content

Commit 77e965e

Browse files
committed
[flang] Allow for submodule override of module procedure
When checking that a module procedure definition is unique, allow for the possibility that a submodule may contain a module procedure interface that shadows a module procedure of the same name in its (sub)module parent. In other words, module procedure definitions need only be unique in the tree of submodules rooted at the (sub)module containing the relevant module procedure interface. Differential Revision: https://reviews.llvm.org/D159033
1 parent ef2b170 commit 77e965e

File tree

4 files changed

+26
-18
lines changed

4 files changed

+26
-18
lines changed

flang/include/flang/Semantics/tools.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,5 +679,8 @@ std::optional<R> GetConstExpr(
679679
return std::nullopt;
680680
}
681681

682+
// Returns "m" for a module, "m:sm" for a submodule.
683+
std::string GetModuleOrSubmoduleName(const Symbol &);
684+
682685
} // namespace Fortran::semantics
683686
#endif // FORTRAN_SEMANTICS_TOOLS_H_

flang/lib/Semantics/check-declarations.cpp

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3133,26 +3133,22 @@ void CheckHelper::CheckModuleProcedureDef(const Symbol &symbol) {
31333133
(procClass == ProcedureDefinitionClass::Module &&
31343134
symbol.attrs().test(Attr::MODULE)) &&
31353135
!subprogram->bindName() && !subprogram->isInterface()) {
3136-
const Symbol *module{nullptr};
3137-
if (const Scope * moduleScope{FindModuleContaining(symbol.owner())};
3138-
moduleScope && moduleScope->symbol()) {
3139-
if (const auto *details{
3140-
moduleScope->symbol()->detailsIf<ModuleDetails>()}) {
3141-
if (details->parent()) {
3142-
moduleScope = details->parent();
3143-
}
3144-
module = moduleScope->symbol();
3145-
}
3146-
}
3147-
if (module) {
3136+
const Symbol &interface {
3137+
subprogram->moduleInterface() ? *subprogram->moduleInterface() : symbol
3138+
};
3139+
if (const Symbol *
3140+
module{interface.owner().kind() == Scope::Kind::Module
3141+
? interface.owner().symbol()
3142+
: nullptr};
3143+
module && module->has<ModuleDetails>()) {
31483144
std::pair<SourceName, const Symbol *> key{symbol.name(), module};
31493145
auto iter{moduleProcs_.find(key)};
31503146
if (iter == moduleProcs_.end()) {
31513147
moduleProcs_.emplace(std::move(key), symbol);
31523148
} else if (
31533149
auto *msg{messages_.Say(symbol.name(),
3154-
"Module procedure '%s' in module '%s' has multiple definitions"_err_en_US,
3155-
symbol.name(), module->name())}) {
3150+
"Module procedure '%s' in '%s' has multiple definitions"_err_en_US,
3151+
symbol.name(), GetModuleOrSubmoduleName(*module))}) {
31563152
msg->Attach(iter->second->name(), "Previous definition of '%s'"_en_US,
31573153
symbol.name());
31583154
}

flang/lib/Semantics/tools.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1646,4 +1646,13 @@ bool CouldBeDataPointerValuedFunction(const Symbol *original) {
16461646
return false;
16471647
}
16481648

1649+
std::string GetModuleOrSubmoduleName(const Symbol &symbol) {
1650+
const auto &details{symbol.get<ModuleDetails>()};
1651+
std::string result{symbol.name().ToString()};
1652+
if (details.ancestor() && details.ancestor()->symbol()) {
1653+
result = details.ancestor()->symbol()->name().ToString() + ':' + result;
1654+
}
1655+
return result;
1656+
}
1657+
16491658
} // namespace Fortran::semantics

flang/test/Semantics/separate-mp04.f90

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,17 @@ module subroutine x003
2828

2929
submodule(m1) sm2
3030
contains
31-
!ERROR: Module procedure 'x002' in module 'm1' has multiple definitions
31+
!ERROR: Module procedure 'x002' in 'm1' has multiple definitions
3232
module subroutine x002
3333
end subroutine
3434
end
3535

3636
submodule(m1:sm2) sm3
3737
contains
38-
!ERROR: Module procedure 'x002' in module 'm1' has multiple definitions
38+
!ERROR: Module procedure 'x002' in 'm1' has multiple definitions
3939
module subroutine x002
4040
end subroutine
41-
!ERROR: Module procedure 'x003' in module 'm1' has multiple definitions
41+
!ERROR: Module procedure 'x003' in 'm1' has multiple definitions
4242
module subroutine x003
4343
end subroutine
4444
end
@@ -51,7 +51,7 @@ module subroutine x004
5151

5252
submodule(m1:sm1) sm5
5353
contains
54-
!ERROR: Module procedure 'x004' in module 'm1' has multiple definitions
54+
!ERROR: Module procedure 'x004' in 'm1:sm1' has multiple definitions
5555
module subroutine x004
5656
end subroutine
5757
end

0 commit comments

Comments
 (0)