diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp index 69b07a1916691..b5470e5210fcf 100644 --- a/flang/lib/Lower/ConvertVariable.cpp +++ b/flang/lib/Lower/ConvertVariable.cpp @@ -727,15 +727,26 @@ static void deallocateIntentOut(Fortran::lower::AbstractConverter &converter, 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); + if (mutBox->isDerived() || mutBox->isPolymorphic() || + mutBox->isUnlimitedPolymorphic()) { + 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); + } + }) + .end(); } else { genDeallocateBox(converter, *mutBox, loc); } @@ -748,16 +759,7 @@ static void deallocateIntentOut(Fortran::lower::AbstractConverter &converter, .genThen([&]() { genDeallocateWithTypeDesc(); }) .end(); } else { - if (mutBox->isDerived() || mutBox->isPolymorphic() || - mutBox->isUnlimitedPolymorphic()) { - mlir::Value isAlloc = fir::factory::genIsAllocatedOrAssociatedTest( - builder, loc, *mutBox); - builder.genIfThen(loc, isAlloc) - .genThen([&]() { genDeallocateWithTypeDesc(); }) - .end(); - } else { - genDeallocateBox(converter, *mutBox, loc); - } + genDeallocateWithTypeDesc(); } } } diff --git a/flang/test/Lower/intentout-deallocate.f90 b/flang/test/Lower/intentout-deallocate.f90 index 936d8a434c1b3..d27d7e2e7a966 100644 --- a/flang/test/Lower/intentout-deallocate.f90 +++ b/flang/test/Lower/intentout-deallocate.f90 @@ -246,10 +246,17 @@ subroutine sub16(p) ! 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: %[[BOX:.*]] = fir.load %[[ARG0]] : !fir.ref>>> +! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.class>>) -> !fir.heap> +! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap>) -> i64 +! CHECK: %[[C0:.*]] = arith.constant 0 : i64 +! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64 +! CHECK: fir.if %[[IS_ALLOCATED]] { +! 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: } ! CHECK: } end module