diff --git a/flang/include/flang/Lower/ConvertType.h b/flang/include/flang/Lower/ConvertType.h index 179a682584046..3c726595c0f76 100644 --- a/flang/include/flang/Lower/ConvertType.h +++ b/flang/include/flang/Lower/ConvertType.h @@ -118,6 +118,9 @@ class ComponentReverseIterator { /// Advance iterator to the last components of the current type parent. const Fortran::semantics::DerivedTypeSpec &advanceToParentType(); + /// Get the parent component symbol for the current type. + const Fortran::semantics::Symbol *getParentComponent() const; + private: void setCurrentType(const Fortran::semantics::DerivedTypeSpec &derived); const Fortran::semantics::DerivedTypeSpec *currentParentType = nullptr; diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp index 9689f920840fb..906a689821882 100644 --- a/flang/lib/Lower/ConvertExprToHLFIR.cpp +++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp @@ -1848,8 +1848,15 @@ class HlfirBuilder { for (Fortran::lower::ComponentReverseIterator compIterator( ctor.result().derivedTypeSpec()); !compIterator.lookup(compSym.name());) { - const auto &parentType = compIterator.advanceToParentType(); - llvm::StringRef parentName = toStringRef(parentType.name()); + // Private parent components have mangled names. Get the name from the + // parent symbol. + const Fortran::semantics::Symbol *parentCompSym = + compIterator.getParentComponent(); + assert(parentCompSym && "failed to get parent component symbol"); + std::string parentName = + converter.getRecordTypeFieldName(*parentCompSym); + // Advance the iterator, but don't use its return value. + compIterator.advanceToParentType(); auto baseRecTy = mlir::cast( hlfir::getFortranElementType(currentParent.getType())); auto parentCompType = baseRecTy.getType(parentName); diff --git a/flang/lib/Lower/ConvertType.cpp b/flang/lib/Lower/ConvertType.cpp index 7a2e8e5095186..0fde61465fb85 100644 --- a/flang/lib/Lower/ConvertType.cpp +++ b/flang/lib/Lower/ConvertType.cpp @@ -669,6 +669,18 @@ Fortran::lower::ComponentReverseIterator::advanceToParentType() { return *currentParentType; } +const Fortran::semantics::Symbol * +Fortran::lower::ComponentReverseIterator::getParentComponent() const { + if (!currentTypeDetails->GetParentComponentName()) + return nullptr; + const Fortran::semantics::Scope *scope = currentParentType->GetScope(); + auto parentComp = + DEREF(scope).find(currentTypeDetails->GetParentComponentName().value()); + if (parentComp == scope->cend()) + return nullptr; + return &*parentComp->second; +} + void Fortran::lower::ComponentReverseIterator::setCurrentType( const Fortran::semantics::DerivedTypeSpec &derived) { currentParentType = &derived; diff --git a/flang/test/Lower/derived-type-private.f90 b/flang/test/Lower/derived-type-private.f90 new file mode 100644 index 0000000000000..8edcdeedad8b2 --- /dev/null +++ b/flang/test/Lower/derived-type-private.f90 @@ -0,0 +1,29 @@ +! Test lowering of derived type with private attribute +! RUN: bbc -emit-hlfir %s -o - | FileCheck %s + +program main + call test02() + print *,"pass" +end program main + +module mod2 + type,private:: tt + integer :: ip = 1 + end type tt + type,extends(tt):: ty1 + ! CHECK: fir.global @_QMmod2Estr : !fir.type<_QMmod2Tty1{_QMmod2Tty1.tt:!fir.type<_QMmod2Ttt{ip:i32}>,i1:i32,i1p:!fir.type<_QMmod2Ttt{ip:i32}>,i1a:!fir.box>>}> + integer :: i1 = 1 + type(tt) :: i1p = tt(2) + integer,allocatable :: i1a(:) + end type ty1 + type(ty1) :: str +end module mod2 + +subroutine test02() + use mod2 + integer,allocatable :: ia(:) + allocate(ia(10)) + ia=2 + str=ty1(i1a=ia) + if (str%i1.ne.1) print *,'ng' +end subroutine test02