[flang-commits] [flang] [flang][hlfir] Fixed some finalization/deallocation issues. (PR #67047)

Slava Zakharin via flang-commits flang-commits at lists.llvm.org
Fri Sep 22 09:25:35 PDT 2023


================
@@ -608,20 +632,68 @@ static void genFreeIfMustFree(mlir::Location loc, fir::FirOpBuilder &builder,
       var = builder.create<fir::LoadOp>(loc, var);
       assert(mlir::isa<fir::ClassType>(var.getType()) &&
              fir::isAllocatableType(var.getType()));
-      var = builder.create<fir::BoxAddrOp>(loc, heapType, var);
+      addr = builder.create<fir::BoxAddrOp>(loc, heapType, var);
+      // Lowering currently does not produce DestroyOp with 'finalize'
+      // for polymorphic temporaries. It will have to do so, for example,
+      // for MERGE with polymorphic results.
+      if (mustFinalize)
+        TODO(loc, "finalizing polymorphic temporary in HLFIR");
     } else if (var.getType().isa<fir::BaseBoxType, fir::BoxCharType>()) {
-      var = builder.create<fir::BoxAddrOp>(loc, heapType, var);
-    } else if (!var.getType().isa<fir::HeapType>()) {
-      var = builder.create<fir::ConvertOp>(loc, heapType, var);
+      if (mustFinalize && !mlir::isa<fir::BaseBoxType>(var.getType()))
+        fir::emitFatalError(loc, "non-finalizable variable");
+
+      addr = builder.create<fir::BoxAddrOp>(loc, heapType, var);
+    } else {
+      if (!var.getType().isa<fir::HeapType>())
+        addr = builder.create<fir::ConvertOp>(loc, heapType, var);
+
+      if (mustFinalize || deallocComponents) {
+        // Embox the raw pointer using proper shape and type params
+        // (note that the shape might be visible via the array finalization
+        // routines).
+        if (!hlfir::isFortranEntity(var))
+          TODO(loc, "need a Fortran entity to create a box");
+
+        hlfir::Entity entity{var};
+        llvm::SmallVector<mlir::Value> lenParams;
+        hlfir::genLengthParameters(loc, builder, entity, lenParams);
+        mlir::Value shape;
+        if (entity.isArray())
+          shape = hlfir::genShape(loc, builder, entity);
+        mlir::Type boxType = fir::BoxType::get(heapType);
+        var = builder.createBox(loc, boxType, addr, shape, /*slice=*/nullptr,
+                                lenParams, /*tdesc=*/nullptr);
+      }
     }
-    builder.create<fir::FreeMemOp>(loc, var);
+
+    if (mustFinalize)
+      fir::runtime::genDerivedTypeFinalize(builder, loc, var);
----------------
vzakhari wrote:

I believe the automatic components will be deallocated by `DestroyWithoutFinalization` call below.  Of course, `hlfir::mayHaveAllocatableComponent` have to return true, if there is either allocatable or automatic component, which might be not the case right now.

We may also call `Destroy` if both `mustFinalize` and `deallocComponent` are true.

https://github.com/llvm/llvm-project/pull/67047


More information about the flang-commits mailing list