Index: flang/lib/Semantics/resolve-names.cpp =================================================================== --- flang/lib/Semantics/resolve-names.cpp +++ flang/lib/Semantics/resolve-names.cpp @@ -2899,9 +2899,7 @@ auto checkAmbiguousDerivedType{[this, location, localName]( const Symbol *t1, const Symbol *t2) { - if (!t1 || !t2) { - return true; - } else { + if (t1 && t2) { t1 = &t1->GetUltimate(); t2 = &t2->GetUltimate(); if (&t1 != &t2) { @@ -2912,6 +2910,7 @@ return false; } } + return true; }}; auto *localGeneric{localUltimate.detailsIf()}; @@ -2919,29 +2918,18 @@ auto combine{false}; if (localGeneric) { if (useGeneric) { - if (!checkAmbiguousDerivedType( - localGeneric->derivedType(), useGeneric->derivedType())) { - return; - } - combine = true; + combine = checkAmbiguousDerivedType( + localGeneric->derivedType(), useGeneric->derivedType()); } else if (useUltimate.has()) { - if (checkAmbiguousDerivedType( - &useUltimate, localGeneric->derivedType())) { - combine = true; - } else { - return; - } + combine = + checkAmbiguousDerivedType(&useUltimate, localGeneric->derivedType()); } else if (&useUltimate == &BypassGeneric(localUltimate).GetUltimate()) { return; // nothing to do; used subprogram is local's specific } } else if (useGeneric) { if (localUltimate.has()) { - if (checkAmbiguousDerivedType( - &localUltimate, useGeneric->derivedType())) { - combine = true; - } else { - return; - } + combine = + checkAmbiguousDerivedType(&localUltimate, useGeneric->derivedType()); } else if (&localUltimate == &BypassGeneric(useUltimate).GetUltimate()) { // Local is the specific of the used generic; replace it. EraseSymbol(localSymbol); @@ -2995,9 +2983,6 @@ // it can be locally extended without corrupting the original. GenericDetails generic; generic.CopyFrom(*localGeneric); - if (localGeneric->specific()) { - generic.set_specific(*localGeneric->specific()); - } EraseSymbol(localSymbol); Symbol &newSymbol{MakeSymbol( localSymbol.name(), localSymbol.attrs(), std::move(generic))}; @@ -3012,19 +2997,6 @@ localSymbol.flags() = useSymbol.flags(); AddGenericUse(*localGeneric, localName, useUltimate); localGeneric->CopyFrom(*useGeneric); - if (useGeneric->specific()) { - if (!localGeneric->specific()) { - localGeneric->set_specific( - *const_cast(useGeneric->specific())); - } else if (&localGeneric->specific()->GetUltimate() != - &useGeneric->specific()->GetUltimate()) { - Say(location, - "Cannot use-associate generic interface '%s' with specific procedure of the same name when another such generic is in scope"_err_en_US, - localName) - .Attach( - localSymbol.name(), "Previous USE of '%s'"_en_US, localName); - } - } } else { CHECK(useUltimate.has()); localGeneric->set_derivedType( @@ -3037,9 +3009,6 @@ // with the local derived type. GenericDetails generic; generic.CopyFrom(*useGeneric); - if (useGeneric->specific()) { - generic.set_specific(*const_cast(useGeneric->specific())); - } EraseSymbol(localSymbol); Symbol &newSymbol{MakeSymbol(localName, useUltimate.attrs() & ~Attrs{Attr::PUBLIC, Attr::PRIVATE}, Index: flang/test/Semantics/resolve17.f90 =================================================================== --- flang/test/Semantics/resolve17.f90 +++ flang/test/Semantics/resolve17.f90 @@ -190,14 +190,12 @@ end module subroutine s9a use m9a - !ERROR: Cannot use-associate generic interface 'g' with specific procedure of the same name when another such generic is in scope - use m9b + use m9b ! ok end subroutine s9b !ERROR: USE-associated generic 'g' may not have specific procedures 'g' and 'g' as their interfaces are not distinguishable use m9a - !ERROR: Cannot use-associate generic interface 'g' with specific procedure of the same name when another such generic is in scope - use m9c + use m9c ! ok end module m10a Index: flang/test/Semantics/symbol27.f90 =================================================================== --- /dev/null +++ flang/test/Semantics/symbol27.f90 @@ -0,0 +1,43 @@ +! RUN: %python %S/test_symbols.py %s %flang_fc1 +! Regression test for https://github.com/llvm/llvm-project/issues/60228 +!DEF: /m1 Module +module m1 + !DEF: /m1/foo PUBLIC (Subroutine) Generic + interface foo + !REF: /m1/foo + module procedure :: foo + end interface +contains + !DEF: /m1/foo (Subroutine) Subprogram + !DEF: /m1/foo/x INTENT(IN) ObjectEntity CHARACTER(1_8,1) + subroutine foo (x) + !REF: /m1/foo/x + character, intent(in) :: x + end subroutine +end module +!DEF: /m2 Module +module m2 + !DEF: /m2/foo PUBLIC (Subroutine) Generic + interface foo + !REF: /m2/foo + module procedure :: foo + end interface +contains + !DEF: /m2/foo (Subroutine) Subprogram + !DEF: /m2/foo/x INTENT(IN) ObjectEntity INTEGER(4) + subroutine foo (x) + !REF: /m2/foo/x + integer, intent(in) :: x + end subroutine +end module +!DEF: /main MainProgram +program main + !REF: /m1 + use :: m1 + !REF: /m2 + use :: m2 + !REF: /m1/foo + call foo("a") + !REF: /m2/foo + call foo(1) +end program