[flang] Cope with specific procedures with same name as generic

When accessing a specific procedure of a USE-associated generic
interface, we need to allow for the case in which that specific
procedure has the same name as the generic when testing for
its availability in the current scope.

Differential Revision: https://reviews.llvm.org/D96467

GitOrigin-RevId: 9895ba86a842bfea10c731ed6c5ed05d77e30d91
diff --git a/lib/Semantics/expression.cpp b/lib/Semantics/expression.cpp
index 37207e6..c5ca412 100644
--- a/lib/Semantics/expression.cpp
+++ b/lib/Semantics/expression.cpp
@@ -1980,20 +1980,26 @@
   } else if (const auto *used{
                  originalGeneric.detailsIf<semantics::UseDetails>()}) {
     const auto &scope{originalGeneric.owner()};
-    auto iter{scope.find(specific.name())};
-    if (iter != scope.end() && iter->second->has<semantics::UseDetails>() &&
-        &iter->second->get<semantics::UseDetails>().symbol() == &specific) {
-      return specific;
-    } else {
-      // Create a renaming USE of the specific procedure.
-      auto rename{context_.SaveTempName(
-          used->symbol().owner().GetName().value().ToString() + "$" +
-          specific.name().ToString())};
-      return *const_cast<semantics::Scope &>(scope)
-                  .try_emplace(rename, specific.attrs(),
-                      semantics::UseDetails{rename, specific})
-                  .first->second;
+    if (auto iter{scope.find(specific.name())}; iter != scope.end()) {
+      if (const auto *useDetails{
+              iter->second->detailsIf<semantics::UseDetails>()}) {
+        const Symbol &usedSymbol{useDetails->symbol()};
+        const auto *usedGeneric{
+            usedSymbol.detailsIf<semantics::GenericDetails>()};
+        if (&usedSymbol == &specific ||
+            (usedGeneric && usedGeneric->specific() == &specific)) {
+          return specific;
+        }
+      }
     }
+    // Create a renaming USE of the specific procedure.
+    auto rename{context_.SaveTempName(
+        used->symbol().owner().GetName().value().ToString() + "$" +
+        specific.name().ToString())};
+    return *const_cast<semantics::Scope &>(scope)
+                .try_emplace(rename, specific.attrs(),
+                    semantics::UseDetails{rename, specific})
+                .first->second;
   } else {
     return specific;
   }