Skip to content

Commit 6df27dd

Browse files
authored
[flang] Fix missed case of symbol renaming in module file generation (#132475)
The map of symbols requiring new local aliases for USE association needs to use the symbols' ultimate resolutions to avoid missing cases that can arise in convoluted codes with lots of confusing renamings. Fixes #132435.
1 parent 4ea5aa0 commit 6df27dd

File tree

3 files changed

+88
-2
lines changed

3 files changed

+88
-2
lines changed

flang/lib/Evaluate/formatting.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ llvm::raw_ostream &Constant<Type<TypeCategory::Character, KIND>>::AsFortran(
129129
llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, const Symbol &symbol,
130130
std::optional<parser::CharBlock> name = std::nullopt) {
131131
const auto &renamings{symbol.owner().context().moduleFileOutputRenamings()};
132-
if (auto iter{renamings.find(&symbol)}; iter != renamings.end()) {
132+
if (auto iter{renamings.find(&symbol.GetUltimate())};
133+
iter != renamings.end()) {
133134
return o << iter->second.ToString();
134135
} else if (name) {
135136
return o << name->ToString();

flang/lib/Semantics/mod-file.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ void ModFileWriter::PrepareRenamings(const Scope &scope) {
348348
uses_ << DEREF(sMod->symbol()).name() << ",only:";
349349
if (rename != s->name()) {
350350
uses_ << rename << "=>";
351-
renamings.emplace(&*s, rename);
351+
renamings.emplace(&s->GetUltimate(), rename);
352352
}
353353
uses_ << s->name() << '\n';
354354
useExtraAttrs_ << "private::" << rename << '\n';

flang/test/Semantics/bug132435.f90

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
! RUN: %python %S/test_modfile.py %s %flang_fc1
2+
module m1
3+
type foo
4+
integer :: c1 = 123
5+
end type
6+
end
7+
8+
module m2
9+
use m1, only: foo
10+
type baz
11+
type(foo) :: d = foo()
12+
end type
13+
type bar
14+
type(baz) :: e = baz()
15+
end type
16+
end
17+
18+
module m3
19+
use m1, only: m1foo => foo
20+
type foo
21+
type(m1foo), private :: c2 = m1foo()
22+
end type
23+
end
24+
25+
module m4
26+
use m2, only: m3foo => foo
27+
type foo
28+
type(m3foo), private :: c3 = m3foo()
29+
end type
30+
end
31+
32+
module m5
33+
use m2, only: m2bar => bar
34+
use m4, only: foo
35+
type blah
36+
type(m2bar) :: f = m2bar()
37+
end type
38+
end
39+
40+
!Expect: m1.mod
41+
!module m1
42+
!type::foo
43+
!integer(4)::c1=123_4
44+
!end type
45+
!end
46+
47+
!Expect: m2.mod
48+
!module m2
49+
!use m1,only:foo
50+
!type::baz
51+
!type(foo)::d=foo(c1=123_4)
52+
!end type
53+
!type::bar
54+
!type(baz)::e=baz(d=foo(c1=123_4))
55+
!end type
56+
!end
57+
58+
!Expect: m3.mod
59+
!module m3
60+
!use m1,only:m1foo=>foo
61+
!type::foo
62+
!type(m1foo),private::c2=m1foo(c1=123_4)
63+
!end type
64+
!end
65+
66+
!Expect: m4.mod
67+
!module m4
68+
!use m2,only:m3foo=>foo
69+
!type::foo
70+
!type(m3foo),private::c3=m3foo(c1=123_4)
71+
!end type
72+
!end
73+
74+
!Expect: m5.mod
75+
!module m5
76+
!use m2,only:m2$foo=>foo
77+
!use m2,only:baz
78+
!use m2,only:m2bar=>bar
79+
!use m4,only:foo
80+
!private::m2$foo
81+
!private::baz
82+
!type::blah
83+
!type(m2bar)::f=m2bar(e=baz(d=m2$foo(c1=123_4)))
84+
!end type
85+
!end

0 commit comments

Comments
 (0)