[flang-commits] [flang] [flang][runtime] Establish derived type desc properly. (PR #67623)

Slava Zakharin via flang-commits flang-commits at lists.llvm.org
Wed Sep 27 17:26:12 PDT 2023


https://github.com/vzakhari created https://github.com/llvm/llvm-project/pull/67623

Example:
```
module types
  type t
     real,allocatable :: c
  end type t
contains
  function h(x)
    class(t),allocatable :: h
    ...
  end function h
  subroutine test
    type(t),allocatable :: b(:)
    allocate(b(2),source=h(2.5))
  end subroutine test7
end module type
```

`DoFromSourceAssign` creates two descriptors for initializing
`b(1)` and `b(2)` from the result of `h`. This Create call
creates a descriptor without properly initialized addendum,
so the Assign just does shallow copies of the descriptor
representing result of `h` into `b(1)` and `b(2)`.

I modified Create code to properly establish the descriptor
for derived type case.

I had to keep the `addendum` argument to keep the testing
in `flang/unittests/Runtime/TemporaryStack.cpp`.


>From d1573b796996aef6087f8dec2d6527dd42ce1b7d Mon Sep 17 00:00:00 2001
From: Slava Zakharin <szakharin at nvidia.com>
Date: Wed, 27 Sep 2023 16:56:25 -0700
Subject: [PATCH] [flang][runtime] Establish derived type desc properly.

Example:
```
module types
  type t
     real,allocatable :: c
  end type t
contains
  function h(x)
    class(t),allocatable :: h
    ...
  end function h
  subroutine test
    type(t),allocatable :: b(:)
    allocate(b(2),source=h(2.5))
  end subroutine test7
end module type
```

`DoFromSourceAssign` creates two descriptors for initializing
`b(1)` and `b(2)` from the result of `h`. This Create call
creates a descriptor without properly initialized addendum,
so the Assign just does shallow copies of the descriptor
representing result of `h` into `b(1)` and `b(2)`.

I modified Create code to properly establish the descriptor
for derived type case.

I had to keep the `addendum` argument to keep the testing
in `flang/unittests/Runtime/TemporaryStack.cpp`.
---
 flang/include/flang/Runtime/descriptor.h |  8 ++++++--
 flang/runtime/descriptor.cpp             | 15 +++++++++++----
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/flang/include/flang/Runtime/descriptor.h b/flang/include/flang/Runtime/descriptor.h
index 62a8d123bf2ee06..2aa881c535c1f32 100644
--- a/flang/include/flang/Runtime/descriptor.h
+++ b/flang/include/flang/Runtime/descriptor.h
@@ -180,12 +180,16 @@ class Descriptor {
       const SubscriptValue *extent = nullptr,
       ISO::CFI_attribute_t attribute = CFI_attribute_other);
 
-  // CUDA_TODO: Clang does not support unique_ptr on device.
+  // To create a descriptor for a derived type the caller
+  // must provide non-null dt argument.
+  // The addendum argument is only used for testing purposes,
+  // and it may force a descriptor with an addendum while
+  // dt may be null.
   static OwningPtr<Descriptor> Create(TypeCode t, std::size_t elementBytes,
       void *p = nullptr, int rank = maxRank,
       const SubscriptValue *extent = nullptr,
       ISO::CFI_attribute_t attribute = CFI_attribute_other,
-      int derivedTypeLenParameters = 0);
+      bool addendum = false, const typeInfo::DerivedType *dt = nullptr);
   static OwningPtr<Descriptor> Create(TypeCategory, int kind, void *p = nullptr,
       int rank = maxRank, const SubscriptValue *extent = nullptr,
       ISO::CFI_attribute_t attribute = CFI_attribute_other);
diff --git a/flang/runtime/descriptor.cpp b/flang/runtime/descriptor.cpp
index ab6460708e9b68f..95bba82a3a2963d 100644
--- a/flang/runtime/descriptor.cpp
+++ b/flang/runtime/descriptor.cpp
@@ -96,12 +96,19 @@ void Descriptor::Establish(const typeInfo::DerivedType &dt, void *p, int rank,
 
 OwningPtr<Descriptor> Descriptor::Create(TypeCode t, std::size_t elementBytes,
     void *p, int rank, const SubscriptValue *extent,
-    ISO::CFI_attribute_t attribute, int derivedTypeLenParameters) {
-  std::size_t bytes{SizeInBytes(rank, true, derivedTypeLenParameters)};
+    ISO::CFI_attribute_t attribute, bool addendum,
+    const typeInfo::DerivedType *dt) {
   Terminator terminator{__FILE__, __LINE__};
+  RUNTIME_CHECK(terminator, t.IsDerived() == (dt != nullptr));
+  int derivedTypeLenParameters = dt ? dt->LenParameters() : 0;
+  std::size_t bytes{SizeInBytes(rank, addendum, derivedTypeLenParameters)};
   Descriptor *result{
       reinterpret_cast<Descriptor *>(AllocateMemoryOrCrash(terminator, bytes))};
-  result->Establish(t, elementBytes, p, rank, extent, attribute, true);
+  if (dt) {
+    result->Establish(*dt, p, rank, extent, attribute);
+  } else {
+    result->Establish(t, elementBytes, p, rank, extent, attribute, addendum);
+  }
   return OwningPtr<Descriptor>{result};
 }
 
@@ -122,7 +129,7 @@ OwningPtr<Descriptor> Descriptor::Create(const typeInfo::DerivedType &dt,
     void *p, int rank, const SubscriptValue *extent,
     ISO::CFI_attribute_t attribute) {
   return Create(TypeCode{TypeCategory::Derived, 0}, dt.sizeInBytes(), p, rank,
-      extent, attribute, dt.LenParameters());
+      extent, attribute, /*addendum=*/true, &dt);
 }
 
 std::size_t Descriptor::SizeInBytes() const {



More information about the flang-commits mailing list