diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index 0af1c94502bb4..d1160cc25a08b 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -5433,7 +5433,8 @@ void SubprogramVisitor::PushBlockDataScope(const parser::Name &name) { } } -// If name is a generic, return specific subprogram with the same name. +// If name is a generic in the same scope, return its specific subprogram with +// the same name, if any. Symbol *SubprogramVisitor::GetSpecificFromGeneric(const parser::Name &name) { // Search for the name but don't resolve it if (auto *symbol{currScope().FindSymbol(name.source)}) { @@ -5443,6 +5444,9 @@ Symbol *SubprogramVisitor::GetSpecificFromGeneric(const parser::Name &name) { // symbol doesn't inherit it and ruin the ability to check it. symbol->attrs().reset(Attr::MODULE); } + } else if (&symbol->owner() != &currScope() && inInterfaceBlock() && + !isGeneric()) { + // non-generic interface shadows outer definition } else if (auto *details{symbol->detailsIf()}) { // found generic, want specific procedure auto *specific{details->specific()}; diff --git a/flang/test/Semantics/bug164303.f90 b/flang/test/Semantics/bug164303.f90 new file mode 100644 index 0000000000000..c356c07392577 --- /dev/null +++ b/flang/test/Semantics/bug164303.f90 @@ -0,0 +1,31 @@ +!RUN: %flang -fc1 -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s +module foo_mod + use, intrinsic :: iso_fortran_env + use, intrinsic :: iso_c_binding + implicit none + + interface new_foo + procedure :: foo_ctor + end interface + +contains + +function foo_ctor(options) result(retval) + implicit none + integer, intent(in) :: options + integer :: retval + + interface +!CHECK-NOT: error: + subroutine new_foo(f, opt) bind(c, name='new_foo') + import + implicit none + integer, intent(inout) :: f + integer(c_int), intent(in) :: opt + end subroutine + end interface + + call new_foo(retval, options) +end function + +end module