Skip to content

Commit 8be575e

Browse files
authored
[flang] Fix edge case regression (llvm#109350)
A recent fix to the emission of derived type names to module files exposed a regression in the case of a derived type that (1) has the same name as a generic procedure interface and (2) has undergone renaming through USE association before (3) being used in a declaration significant to a module procedure interface. Fix.
1 parent e8335ae commit 8be575e

File tree

3 files changed

+55
-7
lines changed

3 files changed

+55
-7
lines changed

flang/lib/Semantics/mod-file.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1626,8 +1626,8 @@ void SubprogramSymbolCollector::Collect() {
16261626
// &/or derived type that it shadows may be needed.
16271627
const Symbol *spec{generic->specific()};
16281628
const Symbol *dt{generic->derivedType()};
1629-
needed = needed || (spec && useSet_.count(*spec) > 0) ||
1630-
(dt && useSet_.count(*dt) > 0);
1629+
needed = needed || (spec && useSet_.count(spec->GetUltimate()) > 0) ||
1630+
(dt && useSet_.count(dt->GetUltimate()) > 0);
16311631
} else if (const auto *subp{ultimate.detailsIf<SubprogramDetails>()}) {
16321632
const Symbol *interface { subp->moduleInterface() };
16331633
needed = needed || (interface && useSet_.count(*interface) > 0);

flang/lib/Semantics/resolve-names.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3059,10 +3059,10 @@ void ModuleVisitor::DoAddUse(SourceName location, SourceName localName,
30593059
(useGeneric->derivedType() &&
30603060
useUltimate.name() != localSymbol->name()))) {
30613061
// We are use-associating a generic that either shadows a procedure
3062-
// pointer or shadows a derived type of the same name.
3062+
// pointer or shadows a derived type with a distinct name.
30633063
// Local references that might be made to the procedure pointer should
30643064
// use a UseDetails symbol for proper data addressing, and a derived
3065-
// type needs to be in scope with the renamed name. So create an
3065+
// type needs to be in scope with its local name. So create an
30663066
// empty local generic now into which the use-associated generic may
30673067
// be copied.
30683068
localSymbol->set_details(GenericDetails{});
@@ -3143,6 +3143,7 @@ void ModuleVisitor::DoAddUse(SourceName location, SourceName localName,
31433143
// scope's name map.
31443144
auto CreateLocalUseError{[&]() {
31453145
EraseSymbol(*localSymbol);
3146+
CHECK(localSymbol->has<UseDetails>());
31463147
UseErrorDetails details{localSymbol->get<UseDetails>()};
31473148
details.add_occurrence(location, *useModuleScope_);
31483149
Symbol *newSymbol{&MakeSymbol(localName, Attrs{}, std::move(details))};
@@ -3161,10 +3162,13 @@ void ModuleVisitor::DoAddUse(SourceName location, SourceName localName,
31613162
if (useDerivedType->name() == localName) {
31623163
combinedDerivedType = useDerivedType;
31633164
} else {
3164-
Symbol &combined{currScope().MakeSymbol(localName,
3165-
useDerivedType->attrs(), UseDetails{localName, *useDerivedType})};
3166-
combinedDerivedType = &combined;
3165+
combinedDerivedType =
3166+
&currScope().MakeSymbol(localSymbol->name(), useDerivedType->attrs(),
3167+
UseDetails{localSymbol->name(), *useDerivedType});
31673168
}
3169+
} else if (&localDerivedType->GetUltimate() ==
3170+
&useDerivedType->GetUltimate()) {
3171+
combinedDerivedType = localDerivedType;
31683172
} else {
31693173
const Scope *localScope{localDerivedType->GetUltimate().scope()};
31703174
const Scope *useScope{useDerivedType->GetUltimate().scope()};

flang/test/Semantics/modfile69.f90

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
! RUN: %python %S/test_modfile.py %s %flang_fc1
2+
module m1
3+
type foo
4+
end type
5+
interface foo
6+
end interface
7+
end
8+
9+
!Expect: m1.mod
10+
!module m1
11+
!type::foo
12+
!end type
13+
!interface foo
14+
!end interface
15+
!end
16+
17+
module m2
18+
use m1, only: bar => foo
19+
end
20+
21+
!Expect: m2.mod
22+
!module m2
23+
!use m1,only:bar=>foo
24+
!use m1,only:bar=>foo
25+
!interface bar
26+
!end interface
27+
!end
28+
29+
module m3
30+
contains
31+
subroutine sub(x)
32+
use m2
33+
type(bar) x
34+
end
35+
end
36+
37+
!Expect: m3.mod
38+
!module m3
39+
!contains
40+
!subroutine sub(x)
41+
!use m2,only:bar
42+
!type(bar)::x
43+
!end
44+
!end

0 commit comments

Comments
 (0)