Skip to content

Commit 44e3f51

Browse files
klausleraokblast
authored andcommitted
[flang] Non-generic interface must shadow outer generic (llvm#164469)
A procedure defined in non-generic INTERFACE block must completely shadow any generic interface of the same name in an outer scope. Fixes llvm#164303.
1 parent f6065a9 commit 44e3f51

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

flang/lib/Semantics/resolve-names.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5451,7 +5451,8 @@ void SubprogramVisitor::PushBlockDataScope(const parser::Name &name) {
54515451
}
54525452
}
54535453

5454-
// If name is a generic, return specific subprogram with the same name.
5454+
// If name is a generic in the same scope, return its specific subprogram with
5455+
// the same name, if any.
54555456
Symbol *SubprogramVisitor::GetSpecificFromGeneric(const parser::Name &name) {
54565457
// Search for the name but don't resolve it
54575458
if (auto *symbol{currScope().FindSymbol(name.source)}) {
@@ -5461,6 +5462,9 @@ Symbol *SubprogramVisitor::GetSpecificFromGeneric(const parser::Name &name) {
54615462
// symbol doesn't inherit it and ruin the ability to check it.
54625463
symbol->attrs().reset(Attr::MODULE);
54635464
}
5465+
} else if (&symbol->owner() != &currScope() && inInterfaceBlock() &&
5466+
!isGeneric()) {
5467+
// non-generic interface shadows outer definition
54645468
} else if (auto *details{symbol->detailsIf<GenericDetails>()}) {
54655469
// found generic, want specific procedure
54665470
auto *specific{details->specific()};

flang/test/Semantics/bug164303.f90

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
!RUN: %flang -fc1 -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s
2+
module foo_mod
3+
use, intrinsic :: iso_fortran_env
4+
use, intrinsic :: iso_c_binding
5+
implicit none
6+
7+
interface new_foo
8+
procedure :: foo_ctor
9+
end interface
10+
11+
contains
12+
13+
function foo_ctor(options) result(retval)
14+
implicit none
15+
integer, intent(in) :: options
16+
integer :: retval
17+
18+
interface
19+
!CHECK-NOT: error:
20+
subroutine new_foo(f, opt) bind(c, name='new_foo')
21+
import
22+
implicit none
23+
integer, intent(inout) :: f
24+
integer(c_int), intent(in) :: opt
25+
end subroutine
26+
end interface
27+
28+
call new_foo(retval, options)
29+
end function
30+
31+
end module

0 commit comments

Comments
 (0)