Skip to content

Commit 33a13f3

Browse files
committed
[flang] Handle parent component in select type
In select type construct the associating entity in a TYPE IS type guard statement is obtained with a fir.convert. Update the code for the parent component to support fir.convert defining op as well. Reviewed By: jeanPerier Differential Revision: https://reviews.llvm.org/D145367
1 parent 7eb36f5 commit 33a13f3

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

flang/lib/Lower/ConvertExpr.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7236,17 +7236,18 @@ updateBoxForParentComponent(Fortran::lower::AbstractConverter &converter,
72367236
auto &builder = converter.getFirOpBuilder();
72377237
mlir::Value boxBase = fir::getBase(box);
72387238
mlir::Operation *op = boxBase.getDefiningOp();
7239-
fir::BoxType boxTy = boxBase.getType().dyn_cast<fir::BoxType>();
7239+
auto boxTy = boxBase.getType().dyn_cast<fir::BaseBoxType>();
72407240
mlir::Type boxEleTy = fir::unwrapAllRefAndSeqType(boxTy.getEleTy());
72417241
auto originalRecTy = boxEleTy.dyn_cast<fir::RecordType>();
72427242
mlir::Type actualTy = converter.genType(expr);
72437243
mlir::Type eleTy = fir::unwrapAllRefAndSeqType(actualTy);
72447244
auto parentCompTy = eleTy.dyn_cast<fir::RecordType>();
72457245
assert(parentCompTy && "expecting derived-type");
72467246

7247-
assert(
7248-
(mlir::dyn_cast<fir::EmboxOp>(op) || mlir::dyn_cast<fir::ReboxOp>(op)) &&
7249-
"expecting fir.embox or fir.rebox operation");
7247+
assert((mlir::dyn_cast<fir::EmboxOp>(op) ||
7248+
mlir::dyn_cast<fir::ReboxOp>(op) ||
7249+
mlir::dyn_cast<fir::ConvertOp>(op)) &&
7250+
"expecting fir.embox or fir.rebox or fir.convert operation");
72507251

72517252
if (parentCompTy.getTypeList().empty())
72527253
TODO(loc, "parent component with no component");
@@ -7259,6 +7260,12 @@ updateBoxForParentComponent(Fortran::lower::AbstractConverter &converter,
72597260
loc, fieldTy, firstComponent.first, originalRecTy,
72607261
/*typeParams=*/mlir::ValueRange{});
72617262

7263+
if (auto convert = mlir::dyn_cast<fir::ConvertOp>(op)) {
7264+
auto rebox = builder.create<fir::ReboxOp>(loc, fir::BoxType::get(actualTy),
7265+
convert.getValue(), mlir::Value{},
7266+
mlir::Value{});
7267+
return fir::substBase(box, fir::getBase(rebox));
7268+
}
72627269
if (auto embox = mlir::dyn_cast<fir::EmboxOp>(op)) {
72637270
mlir::Value slice = createSliceForParentComp(builder, loc, embox, box,
72647271
field, expr.Rank() > 0);

flang/test/Lower/polymorphic.f90

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,30 @@ subroutine move_alloc_poly(a, b)
10011001
! CHECK: %[[TYPE_DESC_CONV:.*]] = fir.convert %[[TYPE_DESC]] : (!fir.tdesc<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> !fir.ref<none>
10021002
! CHECK: %{{.*}} = fir.call @_FortranAMoveAlloc(%[[B_CONV]], %[[A_CONV]], %[[TYPE_DESC_CONV]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
10031003

1004+
subroutine test_parent_comp_in_select_type(s)
1005+
class(p1), allocatable :: s
1006+
class(p1), allocatable :: p
1007+
1008+
allocate(p1::p)
1009+
1010+
select type(s)
1011+
type is(p2)
1012+
s%p1 = p
1013+
end select
1014+
end subroutine
1015+
1016+
! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_parent_comp_in_select_type(
1017+
! CHECK-SAME: %[[S:.*]]: !fir.ref<!fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>> {fir.bindc_name = "s"}) {
1018+
! CHECK: %[[P:.*]] = fir.alloca !fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>> {bindc_name = "p", uniq_name = "_QMpolymorphic_testFtest_parent_comp_in_select_typeEp"}
1019+
! CHECK: %[[LOAD_S:.*]] = fir.load %[[S]] : !fir.ref<!fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>>
1020+
! CHECK: fir.select_type %[[LOAD_S]] : !fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>> [#fir.type_is<!fir.type<_QMpolymorphic_testTp2{a:i32,b:i32,c:f32}>>, ^bb1, unit, ^bb2]
1021+
! CHECK: ^bb1:
1022+
! CHECK: %[[REBOX_P1:.*]] = fir.rebox %[[LOAD_S]] : (!fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>) -> !fir.box<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
1023+
! CHECK: %[[LOAD_P:.*]] = fir.load %[[P]] : !fir.ref<!fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>>
1024+
! CHECK: %[[LHS_CONV:.*]] = fir.convert %[[REBOX_P1]] : (!fir.box<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> !fir.ref<!fir.box<none>>
1025+
! CHECK: %[[RHS_CONV:.*]] = fir.convert %[[LOAD_P]] : (!fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>) -> !fir.box<none>
1026+
! CHECK: %{{.*}} = fir.call @_FortranAAssign(%[[LHS_CONV]], %[[RHS_CONV]], %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none
1027+
10041028
end module
10051029

10061030
program test

0 commit comments

Comments
 (0)