diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index ac5cdd57f2fd6..f27902c9c08cb 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -2849,7 +2849,13 @@ class FirConverter : public Fortran::lower::AbstractConverter { for (const Fortran::evaluate::ExtentExpr &lbExpr : lbExprs) lbounds.push_back( fir::getBase(genExprValue(toEvExpr(lbExpr), stmtCtx))); - mlir::Value lhs = genExprMutableBox(loc, assign.lhs).getAddr(); + fir::MutableBoxValue lhsMutableBox = genExprMutableBox(loc, assign.lhs); + if (Fortran::evaluate::UnwrapExpr( + assign.rhs)) { + fir::factory::disassociateMutableBox(*builder, loc, lhsMutableBox); + return; + } + mlir::Value lhs = lhsMutableBox.getAddr(); mlir::Value rhs = fir::getBase(genExprBox(loc, assign.rhs, stmtCtx)); if (!lbounds.empty()) { mlir::Value boundsDesc = createLboundArray(lbounds, loc); @@ -2936,7 +2942,13 @@ class FirConverter : public Fortran::lower::AbstractConverter { if (!lowerToHighLevelFIR() && explicitIterationSpace()) TODO(loc, "polymorphic pointer assignment in FORALL"); - mlir::Value lhs = genExprMutableBox(loc, assign.lhs).getAddr(); + fir::MutableBoxValue lhsMutableBox = genExprMutableBox(loc, assign.lhs); + if (Fortran::evaluate::UnwrapExpr( + assign.rhs)) { + fir::factory::disassociateMutableBox(*builder, loc, lhsMutableBox); + return; + } + mlir::Value lhs = lhsMutableBox.getAddr(); mlir::Value rhs = fir::getBase(genExprBox(loc, assign.rhs, stmtCtx)); mlir::Value boundsDesc = createBoundArray(lbounds, ubounds, loc); Fortran::lower::genPointerAssociateRemapping(*builder, loc, lhs, rhs, diff --git a/flang/lib/Optimizer/Builder/MutableBox.cpp b/flang/lib/Optimizer/Builder/MutableBox.cpp index d092f3a2876b8..3c4169643e487 100644 --- a/flang/lib/Optimizer/Builder/MutableBox.cpp +++ b/flang/lib/Optimizer/Builder/MutableBox.cpp @@ -674,10 +674,11 @@ void fir::factory::disassociateMutableBox(fir::FirOpBuilder &builder, auto boxTy = box.getBoxTy().dyn_cast(); auto eleTy = fir::dyn_cast_ptrOrBoxEleTy(boxTy.getEleTy()); mlir::Type derivedType = fir::getDerivedType(eleTy); - if (auto recTy = derivedType.dyn_cast()) + if (auto recTy = derivedType.dyn_cast()) { fir::runtime::genNullifyDerivedType(builder, loc, box.getAddr(), recTy, box.rank()); - return; + return; + } } MutablePropertyWriter{builder, loc, box}.setUnallocatedStatus(); } diff --git a/flang/test/Lower/pointer-disassociate.f90 b/flang/test/Lower/pointer-disassociate.f90 index 753db13f63395..7e090b6406dce 100644 --- a/flang/test/Lower/pointer-disassociate.f90 +++ b/flang/test/Lower/pointer-disassociate.f90 @@ -1,5 +1,5 @@ ! Test lowering of pointer disassociation -! RUN: bbc -emit-fir %s -o - | FileCheck %s +! RUN: bbc -emit-fir --polymorphic-type %s -o - | FileCheck %s ! ----------------------------------------------------------------------------- @@ -104,3 +104,30 @@ subroutine test_array_mold(p, x) ! CHECK: fir.store %[[VAL_9]] to %[[p]] : !fir.ref>>> p => NULL(x) end subroutine + +subroutine test_polymorphic_null(p) + type t + end type + class(t), pointer :: p(:) + p => null() +end subroutine +! CHECK-LABEL: func.func @_QPtest_polymorphic_null( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>> +! CHECK: %[[VAL_1:.*]] = fir.address_of(@_QFtest_polymorphic_nullE.dt.t) +! CHECK: %[[VAL_2:.*]] = fir.convert %[[VAL_0]] : (!fir.ref>>>>) -> !fir.ref> +! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<{{.*}}>) -> !fir.ref +! CHECK: %[[VAL_4:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_5:.*]] = arith.constant 0 : i32 +! CHECK: %[[VAL_6:.*]] = fir.call @_FortranAPointerNullifyDerived(%[[VAL_2]], %[[VAL_3]], %[[VAL_4]], %[[VAL_5]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> none + +subroutine test_unlimited_polymorphic_null(p) + class(*), pointer :: p(:) + p => null() +end subroutine +! CHECK-LABEL: func.func @_QPtest_unlimited_polymorphic_null( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>> +! CHECK: %[[VAL_1:.*]] = fir.zero_bits !fir.ptr> +! CHECK: %[[VAL_2:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_3:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_4:.*]] = fir.embox %[[VAL_1]](%[[VAL_3]]) : (!fir.ptr>, !fir.shape<1>) -> !fir.class>> +! CHECK: fir.store %[[VAL_4]] to %[[VAL_0]] : !fir.ref>>>