diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -7233,8 +7233,8 @@ Symbol *existing{nullptr}; // Check all variants of names, e.g. "operator(.ne.)" for "operator(/=)" for (const std::string &n : GetAllNames(context(), symbolName)) { - if (auto iter{currScope().find(n)}; iter != currScope().end()) { - existing = &*iter->second; + existing = currScope().FindSymbol(SourceName{n}); + if (existing) { break; } } @@ -7249,24 +7249,28 @@ genericDetails.set_specific(*existingGeneric->specific()); } AddGenericUse(genericDetails, existing->name(), existingUse->symbol()); - } else if (existing == &ultimate) { - // Extending an extant generic in the same scope - info.Resolve(existing); - return; - } else { - // Host association of a generic is handled in ResolveGeneric() - CHECK(existing->has()); + } else if (&existing->owner() == &currScope()) { + if (existing == &ultimate) { + // Extending an extant generic in the same scope + info.Resolve(existing); + return; + } else { + // Host association of a generic is handled elsewhere + CHECK(existing->has()); + } } } else if (ultimate.has() || ultimate.has()) { genericDetails.set_specific(*existing); } else if (ultimate.has()) { genericDetails.set_derivedType(*existing); - } else { + } else if (&existing->owner() == &currScope()) { SayAlreadyDeclared(symbolName, *existing); return; } - EraseSymbol(*existing); + if (&existing->owner() == &currScope()) { + EraseSymbol(*existing); + } } info.Resolve(&MakeSymbol(symbolName, Attrs{}, std::move(genericDetails))); } diff --git a/flang/test/Semantics/generic01.f90 b/flang/test/Semantics/generic01.f90 --- a/flang/test/Semantics/generic01.f90 +++ b/flang/test/Semantics/generic01.f90 @@ -61,24 +61,48 @@ end subroutine subroutine test3 interface abs - module procedure abs_int_redef2 ! override module's use of m1 + module procedure abs_complex_redef ! extend module's use of m1 end interface - !CHECK: abs_int_redef2( + !CHECK: abs_int_redef( print *, abs(1) !CHECK: 1._4 print *, abs(1.) - !CHECK: 1.41421353816986083984375_4 + !CHECK: abs_complex_redef( print *, abs((1,1)) !CHECK: abs_noargs( print *, abs() block - use m1, only: abs ! override the override - !CHECK: abs_int_redef( - print *, abs(1) + intrinsic abs ! override the extension + !CHECK: 1.41421353816986083984375_4 + print *, abs((1,1)) end block end subroutine - integer function abs_int_redef2(j) - integer, intent(in) :: j - abs_int_redef2 = j + real function abs_complex_redef(z) + complex, intent(in) :: z + abs_complex_redef = z end function + subroutine test4 + !CHECK: abs( + print *, abs(1) + contains + integer function abs(n) ! override module's use of m1 + integer, intent(in) :: n + abs = n + end function + end subroutine +end module + +module m4 + contains + integer function abs(n) + integer, intent(in) :: n + abs = n + end function + subroutine test5 + interface abs + module procedure abs ! same name, host-associated + end interface + !CHECK: abs( + print *, abs(1) + end subroutine end module