diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp --- a/flang/lib/Lower/ConvertVariable.cpp +++ b/flang/lib/Lower/ConvertVariable.cpp @@ -726,11 +726,26 @@ return; mlir::Location loc = converter.getCurrentLocation(); fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + auto genDeallocateWithTypeDesc = [&]() { + if (mutBox->isPolymorphic()) { + mlir::Value declaredTypeDesc; + assert(sym.GetType()); + if (const Fortran::semantics::DerivedTypeSpec *derivedTypeSpec = + sym.GetType()->AsDerived()) { + declaredTypeDesc = Fortran::lower::getTypeDescAddr( + converter, loc, *derivedTypeSpec); + } + genDeallocateBox(converter, *mutBox, loc, declaredTypeDesc); + } else { + genDeallocateBox(converter, *mutBox, loc); + } + }; + if (Fortran::semantics::IsOptional(sym)) { auto isPresent = builder.create( loc, builder.getI1Type(), fir::getBase(extVal)); builder.genIfThen(loc, isPresent) - .genThen([&]() { genDeallocateBox(converter, *mutBox, loc); }) + .genThen([&]() { genDeallocateWithTypeDesc(); }) .end(); } else { if (mutBox->isDerived() || mutBox->isPolymorphic() || @@ -738,20 +753,7 @@ mlir::Value isAlloc = fir::factory::genIsAllocatedOrAssociatedTest( builder, loc, *mutBox); builder.genIfThen(loc, isAlloc) - .genThen([&]() { - if (mutBox->isPolymorphic()) { - mlir::Value declaredTypeDesc; - assert(sym.GetType()); - if (const Fortran::semantics::DerivedTypeSpec - *derivedTypeSpec = sym.GetType()->AsDerived()) { - declaredTypeDesc = Fortran::lower::getTypeDescAddr( - converter, loc, *derivedTypeSpec); - } - genDeallocateBox(converter, *mutBox, loc, declaredTypeDesc); - } else { - genDeallocateBox(converter, *mutBox, loc); - } - }) + .genThen([&]() { genDeallocateWithTypeDesc(); }) .end(); } else { genDeallocateBox(converter, *mutBox, loc); diff --git a/flang/test/Lower/intentout-deallocate.f90 b/flang/test/Lower/intentout-deallocate.f90 --- a/flang/test/Lower/intentout-deallocate.f90 +++ b/flang/test/Lower/intentout-deallocate.f90 @@ -236,6 +236,20 @@ ! CHECK: %[[NULL_TYPE_DESC:.*]] = fir.zero_bits !fir.ref ! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ARG0]] : (!fir.ref>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%[[BOX_NONE]], %[[NULL_TYPE_DESC]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: } + + subroutine sub16(p) + class(t), optional, intent(out), allocatable :: p + end subroutine + +! CHECK-LABEL: func.func @_QMmod1Psub16( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref>>> {fir.bindc_name = "p", fir.optional}) { +! CHECK: %[[IS_PRESENT:.*]] = fir.is_present %[[ARG0]] : (!fir.ref>>>) -> i1 +! CHECK: fir.if %[[IS_PRESENT]] { +! CHECK: %[[TYPE_DESC:.*]] = fir.type_desc !fir.type<_QMmod1Tt{a:i32}> +! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ARG0]] : (!fir.ref>>>) -> !fir.ref> +! CHECK: %[[TYPE_NONE:.*]] = fir.convert %[[TYPE_DESC]] : (!fir.tdesc>) -> !fir.ref +! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%[[BOX_NONE]], %[[TYPE_NONE]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: } end module