[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 https://github.com/llvm/llvm-project/issues/131579.
This commit is contained in:
Peter Klausler 2025-03-19 12:02:03 -07:00 committed by GitHub
parent b99dab2587
commit 7f7d7d552b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 59 additions and 1 deletions

View File

@ -3268,7 +3268,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::FunctionReference &funcRef,
const auto &designator{std::get<parser::ProcedureDesignator>(call.t)};
if (const auto *name{std::get_if<parser::Name>(&designator.u)}) {
semantics::Scope &scope{context_.FindScope(name->source)};
semantics::DerivedTypeSpec dtSpec{name->source, symbol.GetUltimate()};
semantics::DerivedTypeSpec dtSpec{name->source, symbol};
if (!CheckIsValidForwardReference(dtSpec)) {
return std::nullopt;
}

View File

@ -0,0 +1,58 @@
! RUN: %python %S/test_modfile.py %s %flang_fc1
MODULE M1
TYPE T1
REAL(KIND=4), DIMENSION(:, :), POINTER :: ptr => Null()
END TYPE T1
TYPE O1
TYPE(T1), POINTER :: d => Null()
END TYPE O1
END MODULE
!Expect: m1.mod
!module m1
!type::t1
!real(4),pointer::ptr(:,:)=>NULL()
!end type
!intrinsic::null
!type::o1
!type(t1),pointer::d=>NULL()
!end type
!end
MODULE M2
USE M1,only : &
o1_prv => o1
public
TYPE D1
TYPE(o1_prv), PRIVATE :: prv = o1_prv ()
END TYPE D1
END MODULE
!Expect: m2.mod
!module m2
!use m1,only:o1_prv=>o1
!type::d1
!type(o1_prv),private::prv=o1_prv(d=NULL())
!end type
!end
MODULE M3
USE M2 , only : d1_prv => D1
PUBLIC
TYPE d1_ext
TYPE(d1_prv), PRIVATE :: prv = d1_prv()
END TYPE
END MODULE
!Expect: m3.mod
!module m3
!use m2,only:o1_prv
!use m2,only:d1_prv=>d1
!private::o1_prv
!type::d1_ext
!type(d1_prv),private::prv=d1_prv(prv=o1_prv(d=NULL()))
!end type
!end