[flang-commits] [flang] [flang][runtime] Finalize polymorphic components using dynamic type (PR #67040)

via flang-commits flang-commits at lists.llvm.org
Thu Sep 21 10:00:09 PDT 2023


https://github.com/jeanPerier created https://github.com/llvm/llvm-project/pull/67040

Previous code was finalizing polymorphic components according to static type (calling the static type final routine, if any).

There is no way (I think) to know from a Fortran::runtime::typeInfo::Component if an allocatable component is polymorphic or not. So this patch just always uses the dynamic type descriptor to check for derived type allocatable component finalization.

>From 4bbb79124984c46f0124c2855abf69c61008c42e Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
Date: Thu, 21 Sep 2023 08:56:03 -0700
Subject: [PATCH] [flang][runtime] Finalize polymorphic components using
 dynamic type

Previous code was finalizing polymorphic components according to static
type (calling the static type final routine, if any).

There is no way (I think) to know from a Fortran::runtime::typeInfo::Component
if an allocatable component is polymorphic or not. So this patch just
always uses the dynamic type descriptor to check for derived type
allocatable component finalization.
---
 flang/runtime/derived.cpp | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/flang/runtime/derived.cpp b/flang/runtime/derived.cpp
index 5224c1426479a28..55545b41da8d479 100644
--- a/flang/runtime/derived.cpp
+++ b/flang/runtime/derived.cpp
@@ -209,7 +209,25 @@ void Finalize(const Descriptor &descriptor,
        k < myComponents; ++k) {
     const auto &comp{
         *componentDesc.ZeroBasedIndexedElement<typeInfo::Component>(k)};
-    if (comp.genre() == typeInfo::Component::Genre::Allocatable ||
+    if (comp.genre() == typeInfo::Component::Genre::Allocatable &&
+        comp.category() == TypeCategory::Derived) {
+      // Component may be polymorphic or unlimited polymorphic. Need to use the
+      // dynamic type to check if finalization is needed.
+      for (std::size_t j{0}; j < elements; ++j) {
+        const Descriptor &compDesc{*descriptor.OffsetElement<Descriptor>(
+            j * byteStride + comp.offset())};
+        if (compDesc.IsAllocated()) {
+          if (const DescriptorAddendum * addendum{compDesc.Addendum()}) {
+            if (const typeInfo::DerivedType *
+                compDynamicType{addendum->derivedType()}) {
+              if (!compDynamicType->noFinalizationNeeded()) {
+                Finalize(compDesc, *compDynamicType, terminator);
+              }
+            }
+          }
+        }
+      }
+    } else if (comp.genre() == typeInfo::Component::Genre::Allocatable ||
         comp.genre() == typeInfo::Component::Genre::Automatic) {
       if (const typeInfo::DerivedType * compType{comp.derivedType()}) {
         if (!compType->noFinalizationNeeded()) {



More information about the flang-commits mailing list