Skip to content

Commit d6acf3c

Browse files
committed
[flang] Fix use-associated procedure in generic
When a use-associated procedure was included in a generic, we weren't correctly recording that fact. The ultimate symbol was added rather than the local symbol. Also, improve the message emitted for the specific procedure by mentioning the module it came from. This fixes one of the problems in https://bugs.llvm.org/show_bug.cgi?id=48648. Differential Revision: https://reviews.llvm.org/D94696
1 parent 6e7094c commit d6acf3c

File tree

3 files changed

+45
-12
lines changed

3 files changed

+45
-12
lines changed

flang/lib/Semantics/resolve-names.cpp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2603,36 +2603,43 @@ void InterfaceVisitor::ResolveSpecificsInGeneric(Symbol &generic) {
26032603
Say(*name, "Procedure '%s' not found"_err_en_US);
26042604
continue;
26052605
}
2606-
symbol = &symbol->GetUltimate();
26072606
if (symbol == &generic) {
26082607
if (auto *specific{generic.get<GenericDetails>().specific()}) {
26092608
symbol = specific;
26102609
}
26112610
}
2612-
if (!symbol->has<SubprogramDetails>() &&
2613-
!symbol->has<SubprogramNameDetails>()) {
2611+
const Symbol &ultimate{symbol->GetUltimate()};
2612+
if (!ultimate.has<SubprogramDetails>() &&
2613+
!ultimate.has<SubprogramNameDetails>()) {
26142614
Say(*name, "'%s' is not a subprogram"_err_en_US);
26152615
continue;
26162616
}
26172617
if (kind == ProcedureKind::ModuleProcedure) {
2618-
if (const auto *nd{symbol->detailsIf<SubprogramNameDetails>()}) {
2618+
if (const auto *nd{ultimate.detailsIf<SubprogramNameDetails>()}) {
26192619
if (nd->kind() != SubprogramKind::Module) {
26202620
Say(*name, "'%s' is not a module procedure"_err_en_US);
26212621
}
26222622
} else {
26232623
// USE-associated procedure
2624-
const auto *sd{symbol->detailsIf<SubprogramDetails>()};
2624+
const auto *sd{ultimate.detailsIf<SubprogramDetails>()};
26252625
CHECK(sd);
2626-
if (symbol->owner().kind() != Scope::Kind::Module ||
2626+
if (ultimate.owner().kind() != Scope::Kind::Module ||
26272627
sd->isInterface()) {
26282628
Say(*name, "'%s' is not a module procedure"_err_en_US);
26292629
}
26302630
}
26312631
}
2632-
if (!symbolsSeen.insert(*symbol).second) {
2633-
Say(name->source,
2634-
"Procedure '%s' is already specified in generic '%s'"_err_en_US,
2635-
name->source, MakeOpName(generic.name()));
2632+
if (!symbolsSeen.insert(ultimate).second) {
2633+
if (symbol == &ultimate) {
2634+
Say(name->source,
2635+
"Procedure '%s' is already specified in generic '%s'"_err_en_US,
2636+
name->source, MakeOpName(generic.name()));
2637+
} else {
2638+
Say(name->source,
2639+
"Procedure '%s' from module '%s' is already specified in generic '%s'"_err_en_US,
2640+
ultimate.name(), ultimate.owner().GetName().value(),
2641+
MakeOpName(generic.name()));
2642+
}
26362643
continue;
26372644
}
26382645
details.AddSpecificProc(*symbol, name->source);

flang/test/Semantics/modfile07.f90

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,3 +598,29 @@ module m10d
598598
! end interface
599599
! private::operator(.ne.)
600600
!end
601+
602+
module m11a
603+
contains
604+
subroutine s1()
605+
end
606+
end
607+
!Expect: m11a.mod
608+
!module m11a
609+
!contains
610+
! subroutine s1()
611+
! end
612+
!end
613+
614+
module m11b
615+
use m11a
616+
interface g
617+
module procedure s1
618+
end interface
619+
end
620+
!Expect: m11b.mod
621+
!module m11b
622+
! use m11a,only:s1
623+
! interface g
624+
! procedure::s1
625+
! end interface
626+
!end

flang/test/Semantics/resolve53.f90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -471,11 +471,11 @@ real function f(x)
471471
subroutine s1()
472472
use m20
473473
interface operator(.not.)
474-
!ERROR: Procedure 'f' is already specified in generic 'OPERATOR(.NOT.)'
474+
!ERROR: Procedure 'f' from module 'm20' is already specified in generic 'OPERATOR(.NOT.)'
475475
procedure f
476476
end interface
477477
interface operator(+)
478-
!ERROR: Procedure 'f' is already specified in generic 'OPERATOR(+)'
478+
!ERROR: Procedure 'f' from module 'm20' is already specified in generic 'OPERATOR(+)'
479479
procedure f
480480
end interface
481481
end subroutine s1

0 commit comments

Comments
 (0)