[flang] Carry over the derived type from MOLD
authorValentin Clement <clementval@gmail.com>
Wed, 8 Feb 2023 08:26:12 +0000 (09:26 +0100)
committerValentin Clement <clementval@gmail.com>
Wed, 8 Feb 2023 08:27:27 +0000 (09:27 +0100)
Derived type from the MOLD was not carried over
to the newly allocated pointer or allocatable.
This may lead to wrong dynamic type when the pointer or allocatable
is polymorphic as shown in the example below:

```
type :: p1
  integer :: a
end type

type, extends(p1) :: p2
  integer :: b
end type

class(p1), pointer :: p(:)

allocate(p(5), MOLD=p2(1,2))
```

Reviewed By: klausler

Differential Revision: https://reviews.llvm.org/D143525

flang/runtime/allocatable.cpp
flang/runtime/pointer.cpp

index 9a11ebf..a7cc75b 100644 (file)
@@ -94,6 +94,13 @@ void RTNAME(AllocatableApplyMold)(
   descriptor.set_base_addr(nullptr);
   descriptor.raw().attribute = CFI_attribute_allocatable;
   descriptor.raw().rank = rank;
+  if (auto *descAddendum{descriptor.Addendum()}) {
+    if (const auto *moldAddendum{mold.Addendum()}) {
+      if (const auto *derived{moldAddendum->derivedType()}) {
+        descAddendum->set_derivedType(derived);
+      }
+    }
+  }
 }
 
 int RTNAME(AllocatableAllocate)(Descriptor &descriptor, bool hasStat,
index 83fbb58..c5ea96f 100644 (file)
@@ -60,6 +60,13 @@ void RTNAME(PointerApplyMold)(
   pointer.set_base_addr(nullptr);
   pointer.raw().attribute = CFI_attribute_pointer;
   pointer.raw().rank = rank;
+  if (auto *pointerAddendum{pointer.Addendum()}) {
+    if (const auto *moldAddendum{mold.Addendum()}) {
+      if (const auto *derived{moldAddendum->derivedType()}) {
+        pointerAddendum->set_derivedType(derived);
+      }
+    }
+  }
 }
 
 void RTNAME(PointerAssociateScalar)(Descriptor &pointer, void *target) {