diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp --- a/flang/lib/Lower/ConvertExpr.cpp +++ b/flang/lib/Lower/ConvertExpr.cpp @@ -2692,32 +2692,36 @@ if (box.getType().isa() && fir::isPolymorphicType(argTy)) { + mlir::Type actualTy = argTy; + if (Fortran::lower::isParentComponent(*expr)) + actualTy = fir::BoxType::get(converter.genType(*expr)); // Rebox can only be performed on a present argument. if (arg.isOptional()) { mlir::Value isPresent = genActualIsPresentTest(builder, loc, box); box = builder - .genIfOp(loc, {argTy}, isPresent, + .genIfOp(loc, {actualTy}, isPresent, /*withElseRegion=*/true) .genThen([&]() { - auto rebox = builder - .create( - loc, argTy, box, mlir::Value{}, - /*slice=*/mlir::Value{}) - .getResult(); + auto rebox = + builder + .create( + loc, actualTy, box, mlir::Value{}, + /*slice=*/mlir::Value{}) + .getResult(); builder.create(loc, rebox); }) .genElse([&]() { auto absent = - builder.create(loc, argTy) + builder.create(loc, actualTy) .getResult(); builder.create(loc, absent); }) .getResults()[0]; } else { - box = - builder.create(loc, argTy, box, mlir::Value{}, - /*slice=*/mlir::Value{}); + box = builder.create(loc, actualTy, box, + mlir::Value{}, + /*slice=*/mlir::Value{}); } } else if (Fortran::lower::isParentComponent(*expr)) { fir::ExtendedValue newExv = diff --git a/flang/test/Lower/polymorphic.f90 b/flang/test/Lower/polymorphic.f90 --- a/flang/test/Lower/polymorphic.f90 +++ b/flang/test/Lower/polymorphic.f90 @@ -1067,6 +1067,25 @@ ! CHECK: %[[CONV:.*]] = fir.convert %[[REBOX]] : (!fir.box>) -> !fir.class> ! CHECK: fir.call @_QMpolymorphic_testPprint(%[[CONV]]) {{.*}} : (!fir.class>) -> () + subroutine takes_p1_opt(a) + class(p1), optional :: a + end subroutine + + subroutine test_parent_comp_opt(p) + type(p2), allocatable :: p + allocate(p) + call takes_p1_opt(p%p1) + end subroutine + +! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_parent_comp_opt( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref>>> {fir.bindc_name = "p"}) { +! CHECK: %[[LOAD_ARG0:.*]] = fir.load %[[ARG0]] : !fir.ref>>> +! CHECK: %[[RES:.*]] = fir.if %{{.*}} -> (!fir.box>) { +! CHECK: %[[REBOX:.*]] = fir.rebox %[[LOAD_ARG0:.*]] : (!fir.box>>) -> !fir.box> +! CHECK: fir.result %[[REBOX]] : !fir.box> +! CHECK: %[[CONV:.*]] = fir.convert %[[RES]] : (!fir.box>) -> !fir.class> +! CHECK: fir.call @_QMpolymorphic_testPtakes_p1_opt(%[[CONV]]) {{.*}} : (!fir.class>) -> () + end module program test