[llvm] [flang][runtime] Fix AllocateAssignmentLHS for monomorphic LHS (PR #153073)

Peter Klausler via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 13 15:50:32 PDT 2025


https://github.com/klausler updated https://github.com/llvm/llvm-project/pull/153073

>From 131f28bf8f8fceac281887eb52b9e3fb19c4e2ee Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Mon, 11 Aug 2025 12:25:59 -0700
Subject: [PATCH] [flang][runtime] Fix AllocateAssignmentLHS for monomorphic
 LHS

When the left-hand side of an assignment statement is an allocatable
that has a monomorphic derived type, and the right-hand side of the
assignment has a type that is an extension of that type, *don't*
change the incoming type or element size of the descriptor before
allocating it.

Fixes https://github.com/llvm/llvm-project/issues/152758.
---
 flang-rt/lib/runtime/assign.cpp | 31 ++++++++++++++++++++-----------
 1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/flang-rt/lib/runtime/assign.cpp b/flang-rt/lib/runtime/assign.cpp
index 6aeb103208785..2c29a98d5a5cb 100644
--- a/flang-rt/lib/runtime/assign.cpp
+++ b/flang-rt/lib/runtime/assign.cpp
@@ -88,23 +88,32 @@ static inline RT_API_ATTRS bool MustDeallocateLHS(
 // originally deallocated or because it required reallocation
 static RT_API_ATTRS int AllocateAssignmentLHS(
     Descriptor &to, const Descriptor &from, Terminator &terminator, int flags) {
-  to.raw().type = from.raw().type;
-  if (!(flags & ExplicitLengthCharacterLHS)) {
-    to.raw().elem_len = from.ElementBytes();
-  }
-  const typeInfo::DerivedType *derived{nullptr};
   DescriptorAddendum *toAddendum{to.Addendum()};
+  const typeInfo::DerivedType *derived{nullptr};
+  if (toAddendum) {
+    derived = toAddendum->derivedType();
+  }
   if (const DescriptorAddendum * fromAddendum{from.Addendum()}) {
-    derived = fromAddendum->derivedType();
-    if (toAddendum) {
-      toAddendum->set_derivedType(derived);
-      std::size_t lenParms{derived ? derived->LenParameters() : 0};
+    if (!derived || (flags & PolymorphicLHS)) {
+      derived = fromAddendum->derivedType();
+    }
+    if (toAddendum && derived) {
+      std::size_t lenParms{derived->LenParameters()};
       for (std::size_t j{0}; j < lenParms; ++j) {
         toAddendum->SetLenParameterValue(j, fromAddendum->LenParameterValue(j));
       }
     }
-  } else if (toAddendum) {
-    toAddendum->set_derivedType(nullptr);
+  } else {
+    derived = nullptr;
+  }
+  if (toAddendum) {
+    toAddendum->set_derivedType(derived);
+  }
+  to.raw().type = from.raw().type;
+  if (derived) {
+    to.raw().elem_len = derived->sizeInBytes();
+  } else if (!(flags & ExplicitLengthCharacterLHS)) {
+    to.raw().elem_len = from.ElementBytes();
   }
   // subtle: leave bounds in place when "from" is scalar (10.2.1.3(3))
   int rank{from.rank()};



More information about the llvm-commits mailing list