Skip to content

Commit 7f7d7d5

Browse files
authored
[flang] Use local name for structure constructor (#132047)
When reinterpreting an ambiguously parsed function reference as a structure constructor, use the original symbol of the type in the representation of the derived type spec of the structure constructor, not its ultimate resolution. The distinction turns out to matter when generating module files containing derived type constants as initializers when the derived types' names have undergone USE association renaming. Fixes #131579.
1 parent b99dab2 commit 7f7d7d5

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

flang/lib/Semantics/expression.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3268,7 +3268,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::FunctionReference &funcRef,
32683268
const auto &designator{std::get<parser::ProcedureDesignator>(call.t)};
32693269
if (const auto *name{std::get_if<parser::Name>(&designator.u)}) {
32703270
semantics::Scope &scope{context_.FindScope(name->source)};
3271-
semantics::DerivedTypeSpec dtSpec{name->source, symbol.GetUltimate()};
3271+
semantics::DerivedTypeSpec dtSpec{name->source, symbol};
32723272
if (!CheckIsValidForwardReference(dtSpec)) {
32733273
return std::nullopt;
32743274
}

flang/test/Semantics/bug131579.f90

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
! RUN: %python %S/test_modfile.py %s %flang_fc1
2+
MODULE M1
3+
TYPE T1
4+
REAL(KIND=4), DIMENSION(:, :), POINTER :: ptr => Null()
5+
END TYPE T1
6+
7+
TYPE O1
8+
TYPE(T1), POINTER :: d => Null()
9+
END TYPE O1
10+
END MODULE
11+
12+
!Expect: m1.mod
13+
!module m1
14+
!type::t1
15+
!real(4),pointer::ptr(:,:)=>NULL()
16+
!end type
17+
!intrinsic::null
18+
!type::o1
19+
!type(t1),pointer::d=>NULL()
20+
!end type
21+
!end
22+
23+
MODULE M2
24+
USE M1,only : &
25+
o1_prv => o1
26+
27+
public
28+
TYPE D1
29+
TYPE(o1_prv), PRIVATE :: prv = o1_prv ()
30+
END TYPE D1
31+
END MODULE
32+
33+
!Expect: m2.mod
34+
!module m2
35+
!use m1,only:o1_prv=>o1
36+
!type::d1
37+
!type(o1_prv),private::prv=o1_prv(d=NULL())
38+
!end type
39+
!end
40+
41+
MODULE M3
42+
USE M2 , only : d1_prv => D1
43+
44+
PUBLIC
45+
TYPE d1_ext
46+
TYPE(d1_prv), PRIVATE :: prv = d1_prv()
47+
END TYPE
48+
END MODULE
49+
50+
!Expect: m3.mod
51+
!module m3
52+
!use m2,only:o1_prv
53+
!use m2,only:d1_prv=>d1
54+
!private::o1_prv
55+
!type::d1_ext
56+
!type(d1_prv),private::prv=d1_prv(prv=o1_prv(d=NULL()))
57+
!end type
58+
!end

0 commit comments

Comments
 (0)