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

via flang-commits flang-commits at lists.llvm.org
Fri Sep 22 01:33:29 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);
----------------
jeanPerier wrote:

I think Destroy may actually be a better runtime call here since automatic component should be deallocated if any. Currently, this does not make a difference since "automatic component" requires support for derived type with length parameter in lowering.
In general, the only place where we would want to use Finalize instead of Destroy is when the entity will be used again after finalization (I only see assignment LHS, and INTENT(OUT) dummies that fit this pattern), otherwise we will have memory leaks.
Now, we do not support length PDTs, so I am also fine with calling Finalize here and wait until we see how lengths PDTs are implemented.

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


More information about the flang-commits mailing list