Skip to content

Commit b7a0482

Browse files
committed
[flang] Clarify edge case of host association and generic interfaces
Name resolution was mishandling cases of generic interfaces and specific procedures (sometimes complicatd by use of the same name for each) when the specific procedure was accessed by means of host association; only the scope of the generic interface definition was searched for the specific procedure. Also search enclosing scopes in the usual way. Differential Revision: https://reviews.llvm.org/D135213
1 parent eb04f32 commit b7a0482

File tree

2 files changed

+48
-20
lines changed

2 files changed

+48
-20
lines changed

flang/lib/Semantics/resolve-names.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7233,8 +7233,8 @@ void ResolveNamesVisitor::CreateGeneric(const parser::GenericSpec &x) {
72337233
Symbol *existing{nullptr};
72347234
// Check all variants of names, e.g. "operator(.ne.)" for "operator(/=)"
72357235
for (const std::string &n : GetAllNames(context(), symbolName)) {
7236-
if (auto iter{currScope().find(n)}; iter != currScope().end()) {
7237-
existing = &*iter->second;
7236+
existing = currScope().FindSymbol(SourceName{n});
7237+
if (existing) {
72387238
break;
72397239
}
72407240
}
@@ -7249,24 +7249,28 @@ void ResolveNamesVisitor::CreateGeneric(const parser::GenericSpec &x) {
72497249
genericDetails.set_specific(*existingGeneric->specific());
72507250
}
72517251
AddGenericUse(genericDetails, existing->name(), existingUse->symbol());
7252-
} else if (existing == &ultimate) {
7253-
// Extending an extant generic in the same scope
7254-
info.Resolve(existing);
7255-
return;
7256-
} else {
7257-
// Host association of a generic is handled in ResolveGeneric()
7258-
CHECK(existing->has<HostAssocDetails>());
7252+
} else if (&existing->owner() == &currScope()) {
7253+
if (existing == &ultimate) {
7254+
// Extending an extant generic in the same scope
7255+
info.Resolve(existing);
7256+
return;
7257+
} else {
7258+
// Host association of a generic is handled elsewhere
7259+
CHECK(existing->has<HostAssocDetails>());
7260+
}
72597261
}
72607262
} else if (ultimate.has<SubprogramDetails>() ||
72617263
ultimate.has<SubprogramNameDetails>()) {
72627264
genericDetails.set_specific(*existing);
72637265
} else if (ultimate.has<DerivedTypeDetails>()) {
72647266
genericDetails.set_derivedType(*existing);
7265-
} else {
7267+
} else if (&existing->owner() == &currScope()) {
72667268
SayAlreadyDeclared(symbolName, *existing);
72677269
return;
72687270
}
7269-
EraseSymbol(*existing);
7271+
if (&existing->owner() == &currScope()) {
7272+
EraseSymbol(*existing);
7273+
}
72707274
}
72717275
info.Resolve(&MakeSymbol(symbolName, Attrs{}, std::move(genericDetails)));
72727276
}

flang/test/Semantics/generic01.f90

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,24 +61,48 @@ subroutine test2
6161
end subroutine
6262
subroutine test3
6363
interface abs
64-
module procedure abs_int_redef2 ! override module's use of m1
64+
module procedure abs_complex_redef ! extend module's use of m1
6565
end interface
66-
!CHECK: abs_int_redef2(
66+
!CHECK: abs_int_redef(
6767
print *, abs(1)
6868
!CHECK: 1._4
6969
print *, abs(1.)
70-
!CHECK: 1.41421353816986083984375_4
70+
!CHECK: abs_complex_redef(
7171
print *, abs((1,1))
7272
!CHECK: abs_noargs(
7373
print *, abs()
7474
block
75-
use m1, only: abs ! override the override
76-
!CHECK: abs_int_redef(
77-
print *, abs(1)
75+
intrinsic abs ! override the extension
76+
!CHECK: 1.41421353816986083984375_4
77+
print *, abs((1,1))
7878
end block
7979
end subroutine
80-
integer function abs_int_redef2(j)
81-
integer, intent(in) :: j
82-
abs_int_redef2 = j
80+
real function abs_complex_redef(z)
81+
complex, intent(in) :: z
82+
abs_complex_redef = z
8383
end function
84+
subroutine test4
85+
!CHECK: abs(
86+
print *, abs(1)
87+
contains
88+
integer function abs(n) ! override module's use of m1
89+
integer, intent(in) :: n
90+
abs = n
91+
end function
92+
end subroutine
93+
end module
94+
95+
module m4
96+
contains
97+
integer function abs(n)
98+
integer, intent(in) :: n
99+
abs = n
100+
end function
101+
subroutine test5
102+
interface abs
103+
module procedure abs ! same name, host-associated
104+
end interface
105+
!CHECK: abs(
106+
print *, abs(1)
107+
end subroutine
84108
end module

0 commit comments

Comments
 (0)