Skip to content

Commit 9bb31e8

Browse files
authored
[Flang] Fix crash when a derived type with private attribute is specified in extends (#151051)
While lowering to HLFIR, when a parent type is private, its name is mangled, so we need to get it from the parent symbol. Fixes #120922
1 parent 1c0ac80 commit 9bb31e8

File tree

4 files changed

+53
-2
lines changed

4 files changed

+53
-2
lines changed

flang/include/flang/Lower/ConvertType.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ class ComponentReverseIterator {
118118
/// Advance iterator to the last components of the current type parent.
119119
const Fortran::semantics::DerivedTypeSpec &advanceToParentType();
120120

121+
/// Get the parent component symbol for the current type.
122+
const Fortran::semantics::Symbol *getParentComponent() const;
123+
121124
private:
122125
void setCurrentType(const Fortran::semantics::DerivedTypeSpec &derived);
123126
const Fortran::semantics::DerivedTypeSpec *currentParentType = nullptr;

flang/lib/Lower/ConvertExprToHLFIR.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1848,8 +1848,15 @@ class HlfirBuilder {
18481848
for (Fortran::lower::ComponentReverseIterator compIterator(
18491849
ctor.result().derivedTypeSpec());
18501850
!compIterator.lookup(compSym.name());) {
1851-
const auto &parentType = compIterator.advanceToParentType();
1852-
llvm::StringRef parentName = toStringRef(parentType.name());
1851+
// Private parent components have mangled names. Get the name from the
1852+
// parent symbol.
1853+
const Fortran::semantics::Symbol *parentCompSym =
1854+
compIterator.getParentComponent();
1855+
assert(parentCompSym && "failed to get parent component symbol");
1856+
std::string parentName =
1857+
converter.getRecordTypeFieldName(*parentCompSym);
1858+
// Advance the iterator, but don't use its return value.
1859+
compIterator.advanceToParentType();
18531860
auto baseRecTy = mlir::cast<fir::RecordType>(
18541861
hlfir::getFortranElementType(currentParent.getType()));
18551862
auto parentCompType = baseRecTy.getType(parentName);

flang/lib/Lower/ConvertType.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,18 @@ Fortran::lower::ComponentReverseIterator::advanceToParentType() {
669669
return *currentParentType;
670670
}
671671

672+
const Fortran::semantics::Symbol *
673+
Fortran::lower::ComponentReverseIterator::getParentComponent() const {
674+
if (!currentTypeDetails->GetParentComponentName())
675+
return nullptr;
676+
const Fortran::semantics::Scope *scope = currentParentType->GetScope();
677+
auto parentComp =
678+
DEREF(scope).find(currentTypeDetails->GetParentComponentName().value());
679+
if (parentComp == scope->cend())
680+
return nullptr;
681+
return &*parentComp->second;
682+
}
683+
672684
void Fortran::lower::ComponentReverseIterator::setCurrentType(
673685
const Fortran::semantics::DerivedTypeSpec &derived) {
674686
currentParentType = &derived;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
! Test lowering of derived type with private attribute
2+
! RUN: bbc -emit-hlfir %s -o - | FileCheck %s
3+
4+
program main
5+
call test02()
6+
print *,"pass"
7+
end program main
8+
9+
module mod2
10+
type,private:: tt
11+
integer :: ip = 1
12+
end type tt
13+
type,extends(tt):: ty1
14+
! 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<!fir.heap<!fir.array<?xi32>>>}>
15+
integer :: i1 = 1
16+
type(tt) :: i1p = tt(2)
17+
integer,allocatable :: i1a(:)
18+
end type ty1
19+
type(ty1) :: str
20+
end module mod2
21+
22+
subroutine test02()
23+
use mod2
24+
integer,allocatable :: ia(:)
25+
allocate(ia(10))
26+
ia=2
27+
str=ty1(i1a=ia)
28+
if (str%i1.ne.1) print *,'ng'
29+
end subroutine test02

0 commit comments

Comments
 (0)